From d343a127aaa87ec6536a74542abc56c3fbf1e09a Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Sun, 31 May 2026 20:12:22 +0200 Subject: [PATCH 1/2] Deploy httpcore2 docs as a standalone site Repoint the httpcore2 mkdocs config at pydantic/httpx2, align its mkdocstrings setup with the httpx2 site so the API reference and objects.inv render, and rewrite httpcore references to httpcore2. Add a second zensical build plus a Cloudflare Worker so the docs publish to httpcore2.pydantic.dev with their own objects.inv. --- .github/workflows/main.yml | 11 +++ .github/workflows/publish.yml | 34 ++++++++ .gitignore | 2 + scripts/build | 1 + src/httpcore2/docs/async.md | 40 ++++----- src/httpcore2/docs/connection-pools.md | 24 +++--- src/httpcore2/docs/connections.md | 12 +-- src/httpcore2/docs/exceptions.md | 28 +++---- src/httpcore2/docs/extensions.md | 42 +++++----- src/httpcore2/docs/http2.md | 34 ++++---- src/httpcore2/docs/index.md | 14 ++-- src/httpcore2/docs/logging.md | 40 ++++----- src/httpcore2/docs/network-backends.md | 82 +++++++++---------- src/httpcore2/docs/proxies.md | 54 ++++++------ src/httpcore2/docs/quickstart.md | 48 +++++------ src/httpcore2/docs/requests-responses-urls.md | 22 ++--- src/httpcore2/docs/table-of-contents.md | 72 ++++++++-------- src/httpcore2/mkdocs.yml | 59 +++++++++---- wrangler-httpcore2.toml | 10 +++ 19 files changed, 355 insertions(+), 274 deletions(-) create mode 100644 wrangler-httpcore2.toml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dfb96700..f28e7903 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -83,6 +83,9 @@ jobs: - name: Build docs run: uv run zensical build --clean + - name: Build httpcore2 docs + run: uv run zensical build --clean -f src/httpcore2/mkdocs.yml + - uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 id: deploy with: @@ -90,8 +93,16 @@ jobs: accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: versions upload --tag pr-${{ github.event.pull_request.number }} + - uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 + id: deploy-httpcore2 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: versions upload --config wrangler-httpcore2.toml --tag pr-${{ github.event.pull_request.number }} + - name: Comment preview URL uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 with: message: | **Docs preview:** ${{ steps.deploy.outputs.deployment-url }} + **httpcore2 docs preview:** ${{ steps.deploy-httpcore2.outputs.deployment-url }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f13618df..e8c54c95 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -47,6 +47,12 @@ jobs: name: documentation path: site/ + - name: Upload httpcore2 documentation + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: documentation-httpcore2 + path: src/httpcore2/site-httpcore2/ + publish: runs-on: ubuntu-latest needs: build @@ -94,3 +100,31 @@ jobs: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: deploy + + docs-cloudflare-httpcore2: + runs-on: ubuntu-latest + needs: build + + permissions: + contents: read + + environment: + name: cloudflare + url: https://httpcore2.pydantic.dev + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Download artifacts + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: documentation-httpcore2 + path: src/httpcore2/site-httpcore2/ + + - uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: deploy --config wrangler-httpcore2.toml diff --git a/.gitignore b/.gitignore index 18967b8a..26ffdd6a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ __pycache__/ htmlcov/ site/ +site-httpcore2/ +src/httpcore2/site-httpcore2/ .wrangler/ *.egg-info/ venv*/ diff --git a/scripts/build b/scripts/build index 0000f39b..99a0ad8d 100755 --- a/scripts/build +++ b/scripts/build @@ -5,3 +5,4 @@ set -x uv build --all-packages uv run twine check dist/* uv run zensical build -c -f mkdocs.yml +uv run zensical build -c -f src/httpcore2/mkdocs.yml diff --git a/src/httpcore2/docs/async.md b/src/httpcore2/docs/async.md index cd7866df..9926dc1f 100644 --- a/src/httpcore2/docs/async.md +++ b/src/httpcore2/docs/async.md @@ -13,13 +13,13 @@ Launching concurrent async tasks is far more resource efficient than spawning mu If you're using async with [Python's stdlib `asyncio` support](https://docs.python.org/3/library/asyncio.html), install the optional dependencies using: ```shell -pip install 'httpcore[asyncio]' +pip install 'httpcore2[asyncio]' ``` Alternatively, if you're working with [the Python `trio` package](https://trio.readthedocs.io/en/stable/): ```shell -pip install 'httpcore[trio]' +pip install 'httpcore2[trio]' ``` We highly recommend `trio` for async support. The `trio` project [pioneered the principles of structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency), and has a more carefully constrained API against which to work from. @@ -29,21 +29,21 @@ We highly recommend `trio` for async support. The `trio` project [pioneered the When using async support, you need make sure to use an async connection pool class: ```python -# The async variation of `httpcore.ConnectionPool` -async with httpcore.AsyncConnectionPool() as http: +# The async variation of `httpcore2.ConnectionPool` +async with httpcore2.AsyncConnectionPool() as http: ... ``` ### Sending requests -Sending requests with the async version of `httpcore` requires the `await` keyword: +Sending requests with the async version of `httpcore2` requires the `await` keyword: ```python import asyncio -import httpcore +import httpcore2 async def main(): - async with httpcore.AsyncConnectionPool() as http: + async with httpcore2.AsyncConnectionPool() as http: response = await http.request("GET", "https://www.example.com/") @@ -65,11 +65,11 @@ For example: ```python import asyncio -import httpcore +import httpcore2 async def main(): - async with httpcore.AsyncConnectionPool() as http: + async with httpcore2.AsyncConnectionPool() as http: async with http.stream("GET", "https://www.example.com/") as response: async for chunk in response.aiter_stream(): print(f"Downloaded: {chunk}") @@ -80,10 +80,10 @@ asyncio.run(main()) ### Pool lifespans -When using `httpcore` in an async environment it is strongly recommended that you instantiate and use connection pools using the context managed style: +When using `httpcore2` in an async environment it is strongly recommended that you instantiate and use connection pools using the context managed style: ```python -async with httpcore.AsyncConnectionPool() as http: +async with httpcore2.AsyncConnectionPool() as http: ... ``` @@ -93,7 +93,7 @@ If you do want to use a connection pool without this style then you'll need to e ```python try: - http = httpcore.AsyncConnectionPool() + http = httpcore2.AsyncConnectionPool() ... finally: await http.aclose() @@ -117,7 +117,7 @@ Let's take a look at sending several outgoing HTTP requests concurrently, using ```python import asyncio -import httpcore +import httpcore2 import time @@ -126,7 +126,7 @@ async def download(http, year): async def main(): - async with httpcore.AsyncConnectionPool() as http: + async with httpcore2.AsyncConnectionPool() as http: started = time.time() # Here we use `asyncio.gather()` in order to run several tasks concurrently... tasks = [download(http, year) for year in range(2000, 2020)] @@ -146,7 +146,7 @@ asyncio.run(main()) Trio is [an alternative async library](https://trio.readthedocs.io/en/stable/), designed around the [the principles of structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency). ```python -import httpcore +import httpcore2 import trio import time @@ -156,7 +156,7 @@ async def download(http, year): async def main(): - async with httpcore.AsyncConnectionPool() as http: + async with httpcore2.AsyncConnectionPool() as http: started = time.time() async with trio.open_nursery() as nursery: for year in range(2000, 2020): @@ -178,7 +178,7 @@ AnyIO is an [asynchronous networking and concurrency library](https://anyio.read The `anyio` library is designed around the [the principles of structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency), and brings many of the same correctness and usability benefits that Trio provides, while interoperating with existing `asyncio` libraries. ```python -import httpcore +import httpcore2 import anyio import time @@ -188,7 +188,7 @@ async def download(http, year): async def main(): - async with httpcore.AsyncConnectionPool() as http: + async with httpcore2.AsyncConnectionPool() as http: started = time.time() async with anyio.create_task_group() as task_group: for year in range(2000, 2020): @@ -207,9 +207,9 @@ anyio.run(main) # Reference -## `httpcore.AsyncConnectionPool` +## `httpcore2.AsyncConnectionPool` -::: httpcore.AsyncConnectionPool +::: httpcore2.AsyncConnectionPool handler: python rendering: show_source: False diff --git a/src/httpcore2/docs/connection-pools.md b/src/httpcore2/docs/connection-pools.md index cb461a98..1203aabe 100644 --- a/src/httpcore2/docs/connection-pools.md +++ b/src/httpcore2/docs/connection-pools.md @@ -1,15 +1,15 @@ # Connection Pools -While the top-level API provides convenience functions for working with `httpcore`, +While the top-level API provides convenience functions for working with `httpcore2`, in practice you'll almost always want to take advantage of the connection pooling functionality that it provides. To do so, instantiate a pool instance, and use it to send requests: ```python -import httpcore +import httpcore2 -http = httpcore.ConnectionPool() +http = httpcore2.ConnectionPool() r = http.request("GET", "https://www.example.com/") print(r) @@ -21,11 +21,11 @@ Connection pools support the same `.request()` and `.stream()` APIs [as describe We can observe the benefits of connection pooling with a simple script like so: ```python -import httpcore +import httpcore2 import time -http = httpcore.ConnectionPool() +http = httpcore2.ConnectionPool() for counter in range(5): started = time.time() response = http.request("GET", "https://www.example.com/") @@ -52,7 +52,7 @@ The connection pool instance is also the main point of configuration. Let's take ### SSL configuration * `ssl_context`: An SSL context to use for verifying connections. - If not specified, the default `httpcore.default_ssl_context()` + If not specified, the default `httpcore2.default_ssl_context()` will be used. ### Pooling configuration @@ -93,20 +93,20 @@ Working with a single global instance isn't a bad idea for many use case, since # This is perfectly fine for most purposes. # The connection pool will automatically be closed when it is garbage collected, # or when the Python interpreter exits. -http = httpcore.ConnectionPool() +http = httpcore2.ConnectionPool() ``` However, to be more explicit around the resource usage, we can use the connection pool within a context manager: ```python -with httpcore.ConnectionPool() as http: +with httpcore2.ConnectionPool() as http: ... ``` Or else close the pool explicitly: ```python -http = httpcore.ConnectionPool() +http = httpcore2.ConnectionPool() try: ... finally: @@ -115,7 +115,7 @@ finally: ## Thread and task safety -Connection pools are designed to be thread-safe. Similarly, when using `httpcore` in an async context connection pools are task-safe. +Connection pools are designed to be thread-safe. Similarly, when using `httpcore2` in an async context connection pools are task-safe. This means that you can have a single connection pool instance shared by multiple threads. @@ -123,9 +123,9 @@ This means that you can have a single connection pool instance shared by multipl # Reference -## `httpcore.ConnectionPool` +## `httpcore2.ConnectionPool` -::: httpcore.ConnectionPool +::: httpcore2.ConnectionPool handler: python rendering: show_source: False diff --git a/src/httpcore2/docs/connections.md b/src/httpcore2/docs/connections.md index 0ca21556..8ad87b39 100644 --- a/src/httpcore2/docs/connections.md +++ b/src/httpcore2/docs/connections.md @@ -6,23 +6,23 @@ TODO # Reference -## `httpcore.HTTPConnection` +## `httpcore2.HTTPConnection` -::: httpcore.HTTPConnection +::: httpcore2.HTTPConnection handler: python rendering: show_source: False -## `httpcore.HTTP11Connection` +## `httpcore2.HTTP11Connection` -::: httpcore.HTTP11Connection +::: httpcore2.HTTP11Connection handler: python rendering: show_source: False -## `httpcore.HTTP2Connection` +## `httpcore2.HTTP2Connection` -::: httpcore.HTTP2Connection +::: httpcore2.HTTP2Connection handler: python rendering: show_source: False diff --git a/src/httpcore2/docs/exceptions.md b/src/httpcore2/docs/exceptions.md index 63ef3f28..fa85fd1b 100644 --- a/src/httpcore2/docs/exceptions.md +++ b/src/httpcore2/docs/exceptions.md @@ -2,17 +2,17 @@ The following exceptions may be raised when sending a request: -* `httpcore.TimeoutException` - * `httpcore.PoolTimeout` - * `httpcore.ConnectTimeout` - * `httpcore.ReadTimeout` - * `httpcore.WriteTimeout` -* `httpcore.NetworkError` - * `httpcore.ConnectError` - * `httpcore.ReadError` - * `httpcore.WriteError` -* `httpcore.ProtocolError` - * `httpcore.RemoteProtocolError` - * `httpcore.LocalProtocolError` -* `httpcore.ProxyError` -* `httpcore.UnsupportedProtocol` +* `httpcore2.TimeoutException` + * `httpcore2.PoolTimeout` + * `httpcore2.ConnectTimeout` + * `httpcore2.ReadTimeout` + * `httpcore2.WriteTimeout` +* `httpcore2.NetworkError` + * `httpcore2.ConnectError` + * `httpcore2.ReadError` + * `httpcore2.WriteError` +* `httpcore2.ProtocolError` + * `httpcore2.RemoteProtocolError` + * `httpcore2.LocalProtocolError` +* `httpcore2.ProxyError` +* `httpcore2.UnsupportedProtocol` diff --git a/src/httpcore2/docs/extensions.md b/src/httpcore2/docs/extensions.md index 7a24a418..0dd4b584 100644 --- a/src/httpcore2/docs/extensions.md +++ b/src/httpcore2/docs/extensions.md @@ -1,6 +1,6 @@ # Extensions -The request/response API used by `httpcore` is kept deliberately simple and explicit. +The request/response API used by `httpcore2` is kept deliberately simple and explicit. The `Request` and `Response` models are pretty slim wrappers around this core API: @@ -24,7 +24,7 @@ Well... almost. There is a maxim in Computer Science that *"All non-trivial abstractions, to some degree, are leaky"*. When an expression is leaky, it's important that it ought to at least leak only in well-defined places. -In order to handle cases that don't otherwise fit inside this core abstraction, `httpcore` requests and responses have 'extensions'. These are a dictionary of optional additional information. +In order to handle cases that don't otherwise fit inside this core abstraction, `httpcore2` requests and responses have 'extensions'. These are a dictionary of optional additional information. Let's expand on our request/response abstraction... @@ -49,7 +49,7 @@ Let's expand on our request/response abstraction... Several extensions are supported both on the request: ```python -r = httpcore.request( +r = httpcore2.request( "GET", "https://www.example.com", extensions={"timeout": {"connect": 5.0}} @@ -59,7 +59,7 @@ r = httpcore.request( And on the response: ```python -r = httpcore.request("GET", "https://www.example.com") +r = httpcore2.request("GET", "https://www.example.com") print(r.extensions["http_version"]) # When using HTTP/1.1 on the client side, the server HTTP response @@ -79,7 +79,7 @@ For example: ```python # Timeout if a connection takes more than 5 seconds to established, or if # we are blocked waiting on the connection pool for more than 10 seconds. -r = httpcore.request( +r = httpcore2.request( "GET", "https://www.example.com", extensions={"timeout": {"connect": 5.0, "pool": 10.0}} @@ -89,19 +89,19 @@ r = httpcore.request( ### `"trace"` The trace extension allows a callback handler to be installed to monitor the internal -flow of events within `httpcore`. The simplest way to explain this is with an example: +flow of events within `httpcore2`. The simplest way to explain this is with an example: ```python -import httpcore +import httpcore2 def log(event_name, info): print(event_name, info) -r = httpcore.request("GET", "https://www.example.com/", extensions={"trace": log}) +r = httpcore2.request("GET", "https://www.example.com/", extensions={"trace": log}) # connection.connect_tcp.started {'host': 'www.example.com', 'port': 443, 'local_address': None, 'timeout': None} -# connection.connect_tcp.complete {'return_value': } +# connection.connect_tcp.complete {'return_value': } # connection.start_tls.started {'ssl_context': , 'server_hostname': b'www.example.com', 'timeout': None} -# connection.start_tls.complete {'return_value': } +# connection.start_tls.complete {'return_value': } # http11.send_request_headers.started {'request': } # http11.send_request_headers.complete {'return_value': None} # http11.send_request_body.started {'request': } @@ -120,7 +120,7 @@ The `event_name` and `info` arguments here will be one of the following: * `{event_type}.{event_name}.complete`, `{"return_value": <...>}` * `{event_type}.{event_name}.failed`, `{"exception": <...>}` -Note that when using the async variant of `httpcore` the handler function passed to `"trace"` must be an `async def ...` function. +Note that when using the async variant of `httpcore2` the handler function passed to `"trace"` must be an `async def ...` function. The following event types are currently exposed... @@ -147,7 +147,7 @@ The following event types are currently exposed... * `"http2.receive_response_body"` * `"http2.response_closed"` -The exact set of trace events may be subject to change across different versions of `httpcore`. If you need to rely on a particular set of events it is recommended that you pin installation of the package to a fixed version. +The exact set of trace events may be subject to change across different versions of `httpcore2`. If you need to rely on a particular set of events it is recommended that you pin installation of the package to a fixed version. ### `"sni_hostname"` @@ -158,7 +158,7 @@ For example: ``` python headers = {"Host": "www.encode.io"} extensions = {"sni_hostname": "www.encode.io"} -response = httpcore.request( +response = httpcore2.request( "GET", "https://185.199.108.153", headers=headers, @@ -180,7 +180,7 @@ For example: ```python extensions = {"target": b"www.encode.io:443"} -response = httpcore.request( +response = httpcore2.request( "CONNECT", "http://your-tunnel-proxy.com", headers=headers, @@ -238,18 +238,18 @@ A proxy CONNECT request using the network stream: # CONNECT http://www.example.com HTTP/1.1 url = "http://127.0.0.1:8080" extensions = {"target: "http://www.example.com"} -with httpcore.stream("CONNECT", url, extensions=extensions) as response: +with httpcore2.stream("CONNECT", url, extensions=extensions) as response: network_stream = response.extensions["network_stream"] # Upgrade to an SSL stream... network_stream = network_stream.start_tls( - ssl_context=httpcore.default_ssl_context(), + ssl_context=httpcore2.default_ssl_context(), hostname=b"www.example.com", ) # Manually send an HTTP request over the network stream, and read the response... # - # For a more complete example see the httpcore `TunnelHTTPConnection` implementation. + # For a more complete example see the httpcore2 `TunnelHTTPConnection` implementation. network_stream.write(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n") data = network_stream.read() print(data) @@ -260,7 +260,7 @@ with httpcore.stream("CONNECT", url, extensions=extensions) as response: Using the `wsproto` package to handle a websockets session: ```python -import httpcore +import httpcore2 import wsproto import os import base64 @@ -273,7 +273,7 @@ headers = { b"Sec-WebSocket-Key": base64.b64encode(os.urandom(16)), b"Sec-WebSocket-Version": b"13" } -with httpcore.stream("GET", url, headers=headers) as response: +with httpcore2.stream("GET", url, headers=headers) as response: if response.status != 101: raise Exception("Failed to upgrade to websockets", response) @@ -304,7 +304,7 @@ with httpcore.stream("GET", url, headers=headers) as response: The network stream abstraction also allows access to various low-level information that may be exposed by the underlying socket: ```python -response = httpcore.request("GET", "https://www.example.com") +response = httpcore2.request("GET", "https://www.example.com") network_stream = response.extensions["network_stream"] client_addr = network_stream.get_extra_info("client_addr") @@ -316,7 +316,7 @@ print("Server address", server_addr) The socket SSL information is also available through this interface, although you need to ensure that the underlying connection is still open, in order to access it... ```python -with httpcore.stream("GET", "https://www.example.com") as response: +with httpcore2.stream("GET", "https://www.example.com") as response: network_stream = response.extensions["network_stream"] ssl_object = network_stream.get_extra_info("ssl_object") diff --git a/src/httpcore2/docs/http2.md b/src/httpcore2/docs/http2.md index f136a95d..6ebb2767 100644 --- a/src/httpcore2/docs/http2.md +++ b/src/httpcore2/docs/http2.md @@ -10,20 +10,20 @@ For a comprehensive guide to HTTP/2 you may want to check out "[HTTP2 Explained] ## Enabling HTTP/2 -When using the `httpcore` client, HTTP/2 support is not enabled by default, because HTTP/1.1 is a mature, battle-hardened transport layer, and our HTTP/1.1 implementation may be considered the more robust option at this point in time. It is possible that a future version of `httpcore` may enable HTTP/2 support by default. +When using the `httpcore2` client, HTTP/2 support is not enabled by default, because HTTP/1.1 is a mature, battle-hardened transport layer, and our HTTP/1.1 implementation may be considered the more robust option at this point in time. It is possible that a future version of `httpcore2` may enable HTTP/2 support by default. If you're issuing highly concurrent requests you might want to consider trying out our HTTP/2 support. You can do so by first making sure to install the optional HTTP/2 dependencies... ```shell -pip install 'httpcore[http2]' +pip install 'httpcore2[http2]' ``` And then instantiating a connection pool with HTTP/2 support enabled: ```python -import httpcore +import httpcore2 -pool = httpcore.ConnectionPool(http2=True) +pool = httpcore2.ConnectionPool(http2=True) ``` We can take a look at the difference in behaviour by issuing several outgoing requests in parallel. @@ -31,7 +31,7 @@ We can take a look at the difference in behaviour by issuing several outgoing re Start out by using a standard HTTP/1.1 connection pool: ```python -import httpcore +import httpcore2 import concurrent.futures import time @@ -41,7 +41,7 @@ def download(http, year): def main(): - with httpcore.ConnectionPool() as http: + with httpcore2.ConnectionPool() as http: started = time.time() with concurrent.futures.ThreadPoolExecutor(max_workers=10) as threads: for year in range(2000, 2020): @@ -75,7 +75,7 @@ We can see that the connection pool required a number of connections in order to If we now upgrade our connection pool to support HTTP/2: ```python -with httpcore.ConnectionPool(http2=True) as http: +with httpcore2.ConnectionPool(http2=True) as http: ... ``` @@ -97,9 +97,9 @@ Enabling HTTP/2 support on the client does not *necessarily* mean that your requ You can determine which version of the HTTP protocol was used by examining the `"http_version"` response extension. ```python -import httpcore +import httpcore2 -pool = httpcore.ConnectionPool(http2=True) +pool = httpcore2.ConnectionPool(http2=True) response = pool.request("GET", "https://www.example.com/") # Should be one of b"HTTP/2", b"HTTP/1.1", b"HTTP/1.0", or b"HTTP/0.9". @@ -116,13 +116,13 @@ Robust servers need to support both HTTP/2 and HTTP/1.1 capable clients, and so Generally the method used is for the server to advertise if it has HTTP/2 support during the part of the SSL connection handshake. This is known as ALPN - "Application Layer Protocol Negotiation". -Most browsers only provide HTTP/2 support over HTTPS connections, and this is also the default behaviour that `httpcore` provides. If you enable HTTP/2 support you should still expect to see HTTP/1.1 connections for any `http://` URLs. +Most browsers only provide HTTP/2 support over HTTPS connections, and this is also the default behaviour that `httpcore2` provides. If you enable HTTP/2 support you should still expect to see HTTP/1.1 connections for any `http://` URLs. ### HTTP/2 over HTTP Servers can optionally also support HTTP/2 over HTTP by supporting the `Upgrade: h2c` header. -This mechanism is not supported by `httpcore`. It requires an additional round-trip between the client and server, and also requires any request body to be sent twice. +This mechanism is not supported by `httpcore2`. It requires an additional round-trip between the client and server, and also requires any request body to be sent twice. ### Prior Knowledge @@ -131,14 +131,14 @@ If you know in advance that the server you are communicating with will support H This is managed by disabling HTTP/1.1 support on the connection pool: ```python -pool = httpcore.ConnectionPool(http1=False, http2=True) +pool = httpcore2.ConnectionPool(http1=False, http2=True) ``` ## Request & response headers Because HTTP/2 frames the requests and responses somewhat differently to HTTP/1.1, there is a difference in some of the headers that are used. -In order for the `httpcore` library to support both HTTP/1.1 and HTTP/2 transparently, the HTTP/1.1 style is always used throughout the API. Any differences in header styles are only mapped onto HTTP/2 at the internal network layer. +In order for the `httpcore2` library to support both HTTP/1.1 and HTTP/2 transparently, the HTTP/1.1 style is always used throughout the API. Any differences in header styles are only mapped onto HTTP/2 at the internal network layer. ## Request headers @@ -146,16 +146,16 @@ The following pseudo-headers are used by HTTP/2 in the request: * `:method` - The request method. * `:path` - Taken from the URL of the request. -* `:authority` - Equivalent to the `Host` header in HTTP/1.1. In `httpcore` this is represented using the request `Host` header, which is automatically populated from the request URL if no `Host` header is explicitly included. +* `:authority` - Equivalent to the `Host` header in HTTP/1.1. In `httpcore2` this is represented using the request `Host` header, which is automatically populated from the request URL if no `Host` header is explicitly included. * `:scheme` - Taken from the URL of the request. -These pseudo-headers are included in `httpcore` as part of the `request.method` and `request.url` attributes, and through the `request.headers["Host"]` header. *They are not exposed directly by their psuedo-header names.* +These pseudo-headers are included in `httpcore2` as part of the `request.method` and `request.url` attributes, and through the `request.headers["Host"]` header. *They are not exposed directly by their psuedo-header names.* The one other difference to be aware of is the `Transfer-Encoding: chunked` header. In HTTP/2 this header is never used, since streaming data is framed using a different mechanism. -In `httpcore` the `Transfer-Encoding: chunked` header is always used to represent the presence of a streaming body on the request, and is automatically populated if required. However the header is only sent if the underlying connection ends up being HTTP/1.1, and is omitted if the underlying connection ends up being HTTP/2. +In `httpcore2` the `Transfer-Encoding: chunked` header is always used to represent the presence of a streaming body on the request, and is automatically populated if required. However the header is only sent if the underlying connection ends up being HTTP/1.1, and is omitted if the underlying connection ends up being HTTP/2. ## Response headers @@ -163,4 +163,4 @@ The following pseudo-header is used by HTTP/2 in the response: * `:status` - The response status code. -In `httpcore` this *is represented by the `response.status` attribute, rather than being exposed as a psuedo-header*. +In `httpcore2` this *is represented by the `response.status` attribute, rather than being exposed as a psuedo-header*. diff --git a/src/httpcore2/docs/index.md b/src/httpcore2/docs/index.md index 6505febe..96af14c9 100644 --- a/src/httpcore2/docs/index.md +++ b/src/httpcore2/docs/index.md @@ -1,7 +1,7 @@ # HTTPCore -[![Test Suite](https://github.com/encode/httpcore/workflows/Test%20Suite/badge.svg)](https://github.com/encode/httpcore/actions) -[![Package version](https://badge.fury.io/py/httpcore.svg)](https://pypi.org/project/httpcore/) +[![Test Suite](https://github.com/pydantic/httpx2/workflows/Test%20Suite/badge.svg)](https://github.com/pydantic/httpx2/actions) +[![Package version](https://badge.fury.io/py/httpcore2.svg)](https://pypi.org/project/httpcore2/) > *Do one thing, and do it well.* @@ -28,19 +28,19 @@ Some things HTTP Core does do: For HTTP/1.1 only support, install with: ```shell -pip install httpcore +pip install httpcore2 ``` For HTTP/1.1 and HTTP/2 support, install with: ```shell -pip install httpcore[http2] +pip install httpcore2[http2] ``` For SOCKS proxy support, install with: ```shell -pip install httpcore[socks] +pip install httpcore2[socks] ``` ## Example @@ -48,9 +48,9 @@ pip install httpcore[socks] Let's check we're able to send HTTP requests: ```python -import httpcore +import httpcore2 -response = httpcore.request("GET", "https://www.example.com/") +response = httpcore2.request("GET", "https://www.example.com/") print(response) # diff --git a/src/httpcore2/docs/logging.md b/src/httpcore2/docs/logging.md index 8db85875..122e9b47 100644 --- a/src/httpcore2/docs/logging.md +++ b/src/httpcore2/docs/logging.md @@ -1,12 +1,12 @@ # Logging -If you need to inspect the internal behaviour of `httpcore`, you can use Python's standard logging to output debug level information. +If you need to inspect the internal behaviour of `httpcore2`, you can use Python's standard logging to output debug level information. For example, the following configuration... ```python import logging -import httpcore +import httpcore2 logging.basicConfig( format="%(levelname)s [%(asctime)s] %(name)s - %(message)s", @@ -14,28 +14,28 @@ logging.basicConfig( level=logging.DEBUG ) -httpcore.request('GET', 'https://www.example.com') +httpcore2.request('GET', 'https://www.example.com') ``` Will send debug level output to the console, or wherever `stdout` is directed too... ``` -DEBUG [2023-01-09 14:44:00] httpcore.connection - connect_tcp.started host='www.example.com' port=443 local_address=None timeout=None -DEBUG [2023-01-09 14:44:00] httpcore.connection - connect_tcp.complete return_value= -DEBUG [2023-01-09 14:44:00] httpcore.connection - start_tls.started ssl_context= server_hostname='www.example.com' timeout=None -DEBUG [2023-01-09 14:44:00] httpcore.connection - start_tls.complete return_value= -DEBUG [2023-01-09 14:44:00] httpcore.http11 - send_request_headers.started request= -DEBUG [2023-01-09 14:44:00] httpcore.http11 - send_request_headers.complete -DEBUG [2023-01-09 14:44:00] httpcore.http11 - send_request_body.started request= -DEBUG [2023-01-09 14:44:00] httpcore.http11 - send_request_body.complete -DEBUG [2023-01-09 14:44:00] httpcore.http11 - receive_response_headers.started request= -DEBUG [2023-01-09 14:44:00] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Age', b'572646'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Mon, 09 Jan 2023 14:44:00 GMT'), (b'Etag', b'"3147526947+ident"'), (b'Expires', b'Mon, 16 Jan 2023 14:44:00 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1D18)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')]) -DEBUG [2023-01-09 14:44:00] httpcore.http11 - receive_response_body.started request= -DEBUG [2023-01-09 14:44:00] httpcore.http11 - receive_response_body.complete -DEBUG [2023-01-09 14:44:00] httpcore.http11 - response_closed.started -DEBUG [2023-01-09 14:44:00] httpcore.http11 - response_closed.complete -DEBUG [2023-01-09 14:44:00] httpcore.connection - close.started -DEBUG [2023-01-09 14:44:00] httpcore.connection - close.complete +DEBUG [2023-01-09 14:44:00] httpcore2.connection - connect_tcp.started host='www.example.com' port=443 local_address=None timeout=None +DEBUG [2023-01-09 14:44:00] httpcore2.connection - connect_tcp.complete return_value= +DEBUG [2023-01-09 14:44:00] httpcore2.connection - start_tls.started ssl_context= server_hostname='www.example.com' timeout=None +DEBUG [2023-01-09 14:44:00] httpcore2.connection - start_tls.complete return_value= +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_headers.started request= +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_headers.complete +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_body.started request= +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_body.complete +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_headers.started request= +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Age', b'572646'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Mon, 09 Jan 2023 14:44:00 GMT'), (b'Etag', b'"3147526947+ident"'), (b'Expires', b'Mon, 16 Jan 2023 14:44:00 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1D18)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')]) +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_body.started request= +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_body.complete +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - response_closed.started +DEBUG [2023-01-09 14:44:00] httpcore2.http11 - response_closed.complete +DEBUG [2023-01-09 14:44:00] httpcore2.connection - close.started +DEBUG [2023-01-09 14:44:00] httpcore2.connection - close.complete ``` -The exact formatting of the debug logging may be subject to change across different versions of `httpcore`. If you need to rely on a particular format it is recommended that you pin installation of the package to a fixed version. \ No newline at end of file +The exact formatting of the debug logging may be subject to change across different versions of `httpcore2`. If you need to rely on a particular format it is recommended that you pin installation of the package to a fixed version. diff --git a/src/httpcore2/docs/network-backends.md b/src/httpcore2/docs/network-backends.md index fbb6bfdb..169b5364 100644 --- a/src/httpcore2/docs/network-backends.md +++ b/src/httpcore2/docs/network-backends.md @@ -1,6 +1,6 @@ # Network Backends -The API layer at which `httpcore` interacts with the network is described as the network backend. Various backend implementations are provided, allowing `httpcore` to handle networking in different runtime contexts. +The API layer at which `httpcore2` interacts with the network is described as the network backend. Various backend implementations are provided, allowing `httpcore2` to handle networking in different runtime contexts. ## Working with network backends @@ -11,9 +11,9 @@ Typically you won't need to specify a network backend, as a default will automat First we're making a standard HTTP request, using a connection pool: ```python -import httpcore +import httpcore2 -with httpcore.ConnectionPool() as http: +with httpcore2.ConnectionPool() as http: response = http.request('GET', 'https://www.example.com') print(response) ``` @@ -21,23 +21,23 @@ with httpcore.ConnectionPool() as http: We can also have the same behavior, but be explicit with our selection of the network backend: ```python -import httpcore +import httpcore2 -network_backend = httpcore.SyncBackend() -with httpcore.ConnectionPool(network_backend=network_backend) as http: +network_backend = httpcore2.SyncBackend() +with httpcore2.ConnectionPool(network_backend=network_backend) as http: response = http.request('GET', 'https://www.example.com') print(response) ``` -The `httpcore.SyncBackend()` implementation handles the opening of TCP connections, and operations on the socket stream, such as reading, writing, and closing the connection. +The `httpcore2.SyncBackend()` implementation handles the opening of TCP connections, and operations on the socket stream, such as reading, writing, and closing the connection. We can get a better understanding of this by using a network backend to send a basic HTTP/1.1 request directly: ```python -import httpcore +import httpcore2 # Create an SSL context using 'certifi' for the certificates. -ssl_context = httpcore.default_ssl_context() +ssl_context = httpcore2.default_ssl_context() # A basic HTTP/1.1 request as a plain bytestring. request = b'\r\n'.join([ @@ -49,7 +49,7 @@ request = b'\r\n'.join([ ]) # Open a TCP stream and upgrade it to SSL. -network_backend = httpcore.SyncBackend() +network_backend = httpcore2.SyncBackend() network_stream = network_backend.connect_tcp("www.example.com", 443) network_stream = network_stream.start_tls(ssl_context, server_hostname="www.example.com") @@ -73,32 +73,32 @@ while True: If we're working with an `async` codebase, then we need to select a different backend. -The `httpcore.AnyIOBackend` is suitable for usage if you're running under `asyncio`. This is a networking backend implemented using [the `anyio` package](https://anyio.readthedocs.io/en/3.x/). +The `httpcore2.AnyIOBackend` is suitable for usage if you're running under `asyncio`. This is a networking backend implemented using [the `anyio` package](https://anyio.readthedocs.io/en/3.x/). ```python -import httpcore +import httpcore2 import asyncio async def main(): - network_backend = httpcore.AnyIOBackend() - async with httpcore.AsyncConnectionPool(network_backend=network_backend) as http: + network_backend = httpcore2.AnyIOBackend() + async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as http: response = await http.request('GET', 'https://www.example.com') print(response) asyncio.run(main()) ``` -The `AnyIOBackend` will work when running under either `asyncio` or `trio`. However, if you're working with async using the [`trio` framework](https://trio.readthedocs.io/en/stable/), then we recommend using the `httpcore.TrioBackend`. +The `AnyIOBackend` will work when running under either `asyncio` or `trio`. However, if you're working with async using the [`trio` framework](https://trio.readthedocs.io/en/stable/), then we recommend using the `httpcore2.TrioBackend`. This will give you the same kind of networking behavior you'd have using `AnyIOBackend`, but there will be a little less indirection so it will be marginally more efficient and will present cleaner tracebacks in error cases. ```python -import httpcore +import httpcore2 import trio async def main(): - network_backend = httpcore.TrioBackend() - async with httpcore.AsyncConnectionPool(network_backend=network_backend) as http: + network_backend = httpcore2.TrioBackend() + async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as http: response = await http.request('GET', 'https://www.example.com') print(response) @@ -113,16 +113,16 @@ These backends accept a list of bytes, and return network stream interfaces that Here's an example of mocking a simple HTTP/1.1 response... ```python -import httpcore +import httpcore2 -network_backend = httpcore.MockBackend([ +network_backend = httpcore2.MockBackend([ b"HTTP/1.1 200 OK\r\n", b"Content-Type: plain/text\r\n", b"Content-Length: 13\r\n", b"\r\n", b"Hello, world!", ]) -with httpcore.ConnectionPool(network_backend=network_backend) as http: +with httpcore2.ConnectionPool(network_backend=network_backend) as http: response = http.request("GET", "https://example.com/") print(response.extensions['http_version']) print(response.status) @@ -134,7 +134,7 @@ Mocking a HTTP/2 response is more complex, since it uses a binary format... ```python import hpack import hyperframe.frame -import httpcore +import httpcore2 content = [ hyperframe.frame.SettingsFrame().serialize(), @@ -155,8 +155,8 @@ content = [ # Note that we instantiate the mock backend with an `http2=True` argument. # This ensures that the mock network stream acts as if the `h2` ALPN flag has been set, # and causes the connection pool to interact with the connection using HTTP/2. -network_backend = httpcore.MockBackend(content, http2=True) -with httpcore.ConnectionPool(network_backend=network_backend) as http: +network_backend = httpcore2.MockBackend(content, http2=True) +with httpcore2.ConnectionPool(network_backend=network_backend) as http: response = http.request("GET", "https://example.com/") print(response.extensions['http_version']) print(response.status) @@ -176,10 +176,10 @@ You can use this to provide advanced networking functionality such as: Here's an example that records the network response to a file on disk: ```python -import httpcore +import httpcore2 -class RecordingNetworkStream(httpcore.NetworkStream): +class RecordingNetworkStream(httpcore2.NetworkStream): def __init__(self, record_file, stream): self.record_file = record_file self.stream = stream @@ -210,13 +210,13 @@ class RecordingNetworkStream(httpcore.NetworkStream): return self.stream.get_extra_info(info) -class RecordingNetworkBackend(httpcore.NetworkBackend): +class RecordingNetworkBackend(httpcore2.NetworkBackend): """ A custom network backend that records network responses. """ def __init__(self, record_file): self.record_file = record_file - self.backend = httpcore.SyncBackend() + self.backend = httpcore2.SyncBackend() def connect_tcp( self, @@ -243,13 +243,13 @@ class RecordingNetworkBackend(httpcore.NetworkBackend): # Once you make the request, the raw HTTP/1.1 response will be available -# in the 'network-recording' file. +# in the 'network-recording' file. # # Try switching to `http2=True` to see the difference when recording HTTP/2 binary network traffic, # or add `headers={'Accept-Encoding': 'gzip'}` to see HTTP content compression. with open("network-recording", "wb") as record_file: network_backend = RecordingNetworkBackend(record_file) - with httpcore.ConnectionPool(network_backend=network_backend) as http: + with httpcore2.ConnectionPool(network_backend=network_backend) as http: response = http.request("GET", "https://www.example.com/") print(response) ``` @@ -260,20 +260,20 @@ with open("network-recording", "wb") as record_file: ### Networking Backends -* `httpcore.SyncBackend` -* `httpcore.AnyIOBackend` -* `httpcore.TrioBackend` +* `httpcore2.SyncBackend` +* `httpcore2.AnyIOBackend` +* `httpcore2.TrioBackend` ### Mock Backends -* `httpcore.MockBackend` -* `httpcore.MockStream` -* `httpcore.AsyncMockBackend` -* `httpcore.AsyncMockStream` +* `httpcore2.MockBackend` +* `httpcore2.MockStream` +* `httpcore2.AsyncMockBackend` +* `httpcore2.AsyncMockStream` ### Base Interface -* `httpcore.NetworkBackend` -* `httpcore.NetworkStream` -* `httpcore.AsyncNetworkBackend` -* `httpcore.AsyncNetworkStream` +* `httpcore2.NetworkBackend` +* `httpcore2.NetworkStream` +* `httpcore2.AsyncNetworkBackend` +* `httpcore2.AsyncNetworkStream` diff --git a/src/httpcore2/docs/proxies.md b/src/httpcore2/docs/proxies.md index 492ea86f..75198dc3 100644 --- a/src/httpcore2/docs/proxies.md +++ b/src/httpcore2/docs/proxies.md @@ -1,21 +1,21 @@ # Proxies -The `httpcore` package provides support for HTTP proxies, using either "HTTP Forwarding" or "HTTP Tunnelling". Forwarding is a proxy mechanism for sending requests to `http` URLs via an intermediate proxy. Tunnelling is a proxy mechanism for sending requests to `https` URLs via an intermediate proxy. +The `httpcore2` package provides support for HTTP proxies, using either "HTTP Forwarding" or "HTTP Tunnelling". Forwarding is a proxy mechanism for sending requests to `http` URLs via an intermediate proxy. Tunnelling is a proxy mechanism for sending requests to `https` URLs via an intermediate proxy. Sending requests via a proxy is very similar to sending requests using a standard connection pool: ```python -import httpcore +import httpcore2 -proxy = httpcore.Proxy("http://127.0.0.1:8080/") -pool = httpcore.ConnectionPool(proxy=proxy) +proxy = httpcore2.Proxy("http://127.0.0.1:8080/") +pool = httpcore2.ConnectionPool(proxy=proxy) r = proxy.request("GET", "https://www.example.com/") print(r) # ``` -You can test the `httpcore` proxy support, using the Python [`proxy.py`](https://pypi.org/project/proxy.py/) tool: +You can test the `httpcore2` proxy support, using the Python [`proxy.py`](https://pypi.org/project/proxy.py/) tool: ```shell pip install proxy.py @@ -29,88 +29,88 @@ Requests will automatically use either forwarding or tunnelling, depending on if Proxy authentication can be included in the initial configuration: ```python -import httpcore +import httpcore2 # A `Proxy-Authorization` header will be included on the initial proxy connection. -proxy = httpcore.Proxy( +proxy = httpcore2.Proxy( url="http://127.0.0.1:8080/", auth=("", "") ) -pool = httpcore.ConnectionPool(proxy=proxy) +pool = httpcore2.ConnectionPool(proxy=proxy) ``` Custom headers can also be included: ```python -import httpcore +import httpcore2 import base64 # Construct and include a `Proxy-Authorization` header. auth = base64.b64encode(b":") -proxy = httpcore.Proxy( +proxy = httpcore2.Proxy( url="http://127.0.0.1:8080/", headers={"Proxy-Authorization": b"Basic " + auth} ) -pool = httpcore.ConnectionPool(proxy=proxy) +pool = httpcore2.ConnectionPool(proxy=proxy) ``` ## Proxy SSL -The `httpcore` package also supports HTTPS proxies for http and https destinations. +The `httpcore2` package also supports HTTPS proxies for http and https destinations. HTTPS proxies can be used in the same way that HTTP proxies are. ```python -proxy = httpcore.Proxy(url="https://127.0.0.1:8080/") +proxy = httpcore2.Proxy(url="https://127.0.0.1:8080/") ``` Also, when using HTTPS proxies, you may need to configure the SSL context, which you can do with the `ssl_context` argument. ```python import ssl -import httpcore +import httpcore2 proxy_ssl_context = ssl.create_default_context() proxy_ssl_context.check_hostname = False -proxy = httpcore.Proxy( +proxy = httpcore2.Proxy( url='https://127.0.0.1:8080/', ssl_context=proxy_ssl_context ) -pool = httpcore.ConnectionPool(proxy=proxy) +pool = httpcore2.ConnectionPool(proxy=proxy) ``` ## HTTP Versions -If you use proxies, keep in mind that the `httpcore` package only supports proxies to HTTP/1.1 servers. +If you use proxies, keep in mind that the `httpcore2` package only supports proxies to HTTP/1.1 servers. ## SOCKS proxy support -The `httpcore` package also supports proxies using the SOCKS5 protocol. +The `httpcore2` package also supports proxies using the SOCKS5 protocol. -Make sure to install the optional dependency using `pip install 'httpcore[socks]'`. +Make sure to install the optional dependency using `pip install 'httpcore2[socks]'`. The `SOCKSProxy` class should be using instead of a standard connection pool: ```python -import httpcore +import httpcore2 # Note that the SOCKS port is 1080. -proxy = httpcore.Proxy(url="socks5://127.0.0.1:1080/") -pool = httpcore.ConnectionPool(proxy=proxy) +proxy = httpcore2.Proxy(url="socks5://127.0.0.1:1080/") +pool = httpcore2.ConnectionPool(proxy=proxy) r = pool.request("GET", "https://www.example.com/") ``` Authentication via SOCKS is also supported: ```python -import httpcore +import httpcore2 -proxy = httpcore.Proxy( +proxy = httpcore2.Proxy( url="socks5://127.0.0.1:1080/", auth=("", ""), ) -pool = httpcore.ConnectionPool(proxy=proxy) +pool = httpcore2.ConnectionPool(proxy=proxy) r = pool.request("GET", "https://www.example.com/") ``` @@ -118,9 +118,9 @@ r = pool.request("GET", "https://www.example.com/") # Reference -## `httpcore.Proxy` +## `httpcore2.Proxy` -::: httpcore.Proxy +::: httpcore2.Proxy handler: python rendering: show_source: False diff --git a/src/httpcore2/docs/quickstart.md b/src/httpcore2/docs/quickstart.md index e43b0596..c63a1d19 100644 --- a/src/httpcore2/docs/quickstart.md +++ b/src/httpcore2/docs/quickstart.md @@ -1,15 +1,15 @@ # Quickstart -For convenience, the `httpcore` package provides a couple of top-level functions that you can use for sending HTTP requests. You probably don't want to integrate against functions if you're writing a library that uses `httpcore`, but you might find them useful for testing `httpcore` from the command-line, or if you're writing a simple script that doesn't require any of the connection pooling or advanced configuration that `httpcore` offers. +For convenience, the `httpcore2` package provides a couple of top-level functions that you can use for sending HTTP requests. You probably don't want to integrate against functions if you're writing a library that uses `httpcore2`, but you might find them useful for testing `httpcore2` from the command-line, or if you're writing a simple script that doesn't require any of the connection pooling or advanced configuration that `httpcore2` offers. ## Sending a request We'll start off by sending a request... ```python -import httpcore +import httpcore2 -response = httpcore.request("GET", "https://www.example.com/") +response = httpcore2.request("GET", "https://www.example.com/") print(response) # @@ -26,17 +26,17 @@ print(response.content) Request headers may be included either in a dictionary style, or as a list of two-tuples. ```python -import httpcore +import httpcore2 import json -headers = {'User-Agent': 'httpcore'} -r = httpcore.request('GET', 'https://httpbin.org/headers', headers=headers) +headers = {'User-Agent': 'httpcore2'} +r = httpcore2.request('GET', 'https://httpbin.org/headers', headers=headers) print(json.loads(r.content)) # { # 'headers': { # 'Host': 'httpbin.org', -# 'User-Agent': 'httpcore', +# 'User-Agent': 'httpcore2', # 'X-Amzn-Trace-Id': 'Root=1-616ff5de-5ea1b7e12766f1cf3b8e3a33' # } # } @@ -53,10 +53,10 @@ The `Host` header will always be automatically included in any outgoing request, A request body can be included either as bytes... ```python -import httpcore +import httpcore2 import json -r = httpcore.request('POST', 'https://httpbin.org/post', content=b'Hello, world') +r = httpcore2.request('POST', 'https://httpbin.org/post', content=b'Hello, world') print(json.loads(r.content)) # { @@ -78,11 +78,11 @@ print(json.loads(r.content)) Or as an iterable that returns bytes... ```python -import httpcore +import httpcore2 import json with open("hello-world.txt", "rb") as input_file: - r = httpcore.request('POST', 'https://httpbin.org/post', content=input_file) + r = httpcore2.request('POST', 'https://httpbin.org/post', content=input_file) print(json.loads(r.content)) # { @@ -109,14 +109,14 @@ The `Transfer-Encoding: chunked` header is the mechanism that HTTP/1.1 uses for ## Streaming responses -When using the `httpcore.request()` function, the response body will automatically be read to completion, and made available in the `response.content` attribute. +When using the `httpcore2.request()` function, the response body will automatically be read to completion, and made available in the `response.content` attribute. -Sometimes you may be dealing with large responses and not want to read the entire response into memory. The `httpcore.stream()` function provides a mechanism for sending a request and dealing with a streaming response: +Sometimes you may be dealing with large responses and not want to read the entire response into memory. The `httpcore2.stream()` function provides a mechanism for sending a request and dealing with a streaming response: ```python -import httpcore +import httpcore2 -with httpcore.stream('GET', 'https://example.com') as response: +with httpcore2.stream('GET', 'https://example.com') as response: for chunk in response.iter_stream(): print(f"Downloaded: {chunk}") ``` @@ -124,20 +124,20 @@ with httpcore.stream('GET', 'https://example.com') as response: Here's a more complete example that demonstrates downloading a response: ```python -import httpcore +import httpcore2 -with httpcore.stream('GET', 'https://speed.hetzner.de/100MB.bin') as response: +with httpcore2.stream('GET', 'https://speed.hetzner.de/100MB.bin') as response: with open("download.bin", "wb") as output_file: for chunk in response.iter_stream(): output_file.write(chunk) ``` -The `httpcore.stream()` API also allows you to *conditionally* read the response... +The `httpcore2.stream()` API also allows you to *conditionally* read the response... ```python -import httpcore +import httpcore2 -with httpcore.stream('GET', 'https://example.com') as response: +with httpcore2.stream('GET', 'https://example.com') as response: content_length = [int(v) for k, v in response.headers if k.lower() == b'content-length'][0] if content_length > 100_000_000: raise Exception("Response too large.") @@ -148,16 +148,16 @@ with httpcore.stream('GET', 'https://example.com') as response: # Reference -## `httpcore.request()` +## `httpcore2.request()` -::: httpcore.request +::: httpcore2.request handler: python rendering: show_source: False -## `httpcore.stream()` +## `httpcore2.stream()` -::: httpcore.stream +::: httpcore2.stream handler: python rendering: show_source: False diff --git a/src/httpcore2/docs/requests-responses-urls.md b/src/httpcore2/docs/requests-responses-urls.md index 7919a54c..f4e8fb74 100644 --- a/src/httpcore2/docs/requests-responses-urls.md +++ b/src/httpcore2/docs/requests-responses-urls.md @@ -4,27 +4,27 @@ TODO ## Requests -Request instances in `httpcore` are deliberately simple, and only include the essential information required to represent an HTTP request. +Request instances in `httpcore2` are deliberately simple, and only include the essential information required to represent an HTTP request. Properties on the request are plain byte-wise representations. ```python ->>> request = httpcore.Request("GET", "https://www.example.com/") +>>> request = httpcore2.Request("GET", "https://www.example.com/") >>> request.method b"GET" >>> request.url -httpcore.URL(scheme=b"https", host=b"www.example.com", port=None, target=b"/") +httpcore2.URL(scheme=b"https", host=b"www.example.com", port=None, target=b"/") >>> request.headers [(b'Host', b'www.example.com')] >>> request.stream - + ``` The interface is liberal in the types that it accepts, but specific in the properties that it uses to represent them. For example, headers may be specified as a dictionary of strings, but internally are represented as a list of `(byte, byte)` tuples. ```python >>> headers = {"User-Agent": "custom"} ->>> request = httpcore.Request("GET", "https://www.example.com/", headers=headers) +>>> request = httpcore2.Request("GET", "https://www.example.com/", headers=headers) >>> request.headers [(b'Host', b'www.example.com'), (b"User-Agent", b"custom")] @@ -40,23 +40,23 @@ The interface is liberal in the types that it accepts, but specific in the prope # Reference -## `httpcore.Request` +## `httpcore2.Request` -::: httpcore.Request +::: httpcore2.Request handler: python rendering: show_source: False -## `httpcore.Response` +## `httpcore2.Response` -::: httpcore.Response +::: httpcore2.Response handler: python rendering: show_source: False -## `httpcore.URL` +## `httpcore2.URL` -::: httpcore.URL +::: httpcore2.URL handler: python rendering: show_source: False diff --git a/src/httpcore2/docs/table-of-contents.md b/src/httpcore2/docs/table-of-contents.md index 5dc9a10b..e8c4ea18 100644 --- a/src/httpcore2/docs/table-of-contents.md +++ b/src/httpcore2/docs/table-of-contents.md @@ -1,49 +1,49 @@ # API Reference * Quickstart - * `httpcore.request()` - * `httpcore.stream()` + * `httpcore2.request()` + * `httpcore2.stream()` * Requests, Responses, and URLs - * `httpcore.Request` - * `httpcore.Response` - * `httpcore.URL` + * `httpcore2.Request` + * `httpcore2.Response` + * `httpcore2.URL` * Connection Pools - * `httpcore.ConnectionPool` + * `httpcore2.ConnectionPool` * Proxies - * `httpcore.Proxy` + * `httpcore2.Proxy` * Connections - * `httpcore.HTTPConnection` - * `httpcore.HTTP11Connection` - * `httpcore.HTTP2Connection` + * `httpcore2.HTTPConnection` + * `httpcore2.HTTP11Connection` + * `httpcore2.HTTP2Connection` * Async Support - * `httpcore.AsyncConnectionPool` - * `httpcore.AsyncHTTPConnection` - * `httpcore.AsyncHTTP11Connection` - * `httpcore.AsyncHTTP2Connection` + * `httpcore2.AsyncConnectionPool` + * `httpcore2.AsyncHTTPConnection` + * `httpcore2.AsyncHTTP11Connection` + * `httpcore2.AsyncHTTP2Connection` * Network Backends * Sync - * `httpcore.backends.sync.SyncBackend` - * `httpcore.backends.mock.MockBackend` + * `httpcore2.backends.sync.SyncBackend` + * `httpcore2.backends.mock.MockBackend` * Async - * `httpcore.backends.auto.AutoBackend` - * `httpcore.backends.asyncio.AsyncioBackend` - * `httpcore.backends.trio.TrioBackend` - * `httpcore.backends.mock.AsyncMockBackend` + * `httpcore2.backends.auto.AutoBackend` + * `httpcore2.backends.asyncio.AsyncioBackend` + * `httpcore2.backends.trio.TrioBackend` + * `httpcore2.backends.mock.AsyncMockBackend` * Base interfaces - * `httpcore.backends.base.NetworkBackend` - * `httpcore.backends.base.AsyncNetworkBackend` + * `httpcore2.backends.base.NetworkBackend` + * `httpcore2.backends.base.AsyncNetworkBackend` * Exceptions - * `httpcore.TimeoutException` - * `httpcore.PoolTimeout` - * `httpcore.ConnectTimeout` - * `httpcore.ReadTimeout` - * `httpcore.WriteTimeout` - * `httpcore.NetworkError` - * `httpcore.ConnectError` - * `httpcore.ReadError` - * `httpcore.WriteError` - * `httpcore.ProtocolError` - * `httpcore.RemoteProtocolError` - * `httpcore.LocalProtocolError` - * `httpcore.ProxyError` - * `httpcore.UnsupportedProtocol` + * `httpcore2.TimeoutException` + * `httpcore2.PoolTimeout` + * `httpcore2.ConnectTimeout` + * `httpcore2.ReadTimeout` + * `httpcore2.WriteTimeout` + * `httpcore2.NetworkError` + * `httpcore2.ConnectError` + * `httpcore2.ReadError` + * `httpcore2.WriteError` + * `httpcore2.ProtocolError` + * `httpcore2.RemoteProtocolError` + * `httpcore2.LocalProtocolError` + * `httpcore2.ProxyError` + * `httpcore2.UnsupportedProtocol` diff --git a/src/httpcore2/mkdocs.yml b/src/httpcore2/mkdocs.yml index 9f4200ba..f189d3af 100644 --- a/src/httpcore2/mkdocs.yml +++ b/src/httpcore2/mkdocs.yml @@ -1,14 +1,33 @@ -site_name: HTTPCore +site_name: HTTPCore2 site_description: A minimal HTTP client for Python. -site_url: https://www.encode.io/httpcore/ +site_url: https://httpcore2.pydantic.dev/ +site_dir: site-httpcore2 -repo_name: encode/httpcore -repo_url: https://github.com/encode/httpcore/ +theme: + name: 'material' + palette: + - scheme: 'default' + media: '(prefers-color-scheme: light)' + toggle: + icon: 'material/lightbulb' + name: "Switch to dark mode" + - scheme: 'slate' + media: '(prefers-color-scheme: dark)' + primary: 'blue' + toggle: + icon: 'material/lightbulb-outline' + name: 'Switch to light mode' + +repo_name: pydantic/httpx2 +repo_url: https://github.com/pydantic/httpx2/ +edit_uri: "" nav: - Introduction: 'index.md' - Quickstart: 'quickstart.md' + - Requests, Responses, and URLs: 'requests-responses-urls.md' - Connection Pools: 'connection-pools.md' + - Connections: 'connections.md' - Proxies: 'proxies.md' - HTTP/2: 'http2.md' - Async Support: 'async.md' @@ -17,20 +36,24 @@ nav: - Logging: 'logging.md' - Exceptions: 'exceptions.md' -theme: - name: "material" - plugins: - - search - - mkdocstrings: - default_handler: python - watch: - - httpcore - handlers: - python: - members_order: - - "source" + - mkdocstrings: + handlers: + python: + inventories: + - https://docs.python.org/3/objects.inv + options: + show_root_heading: true + show_source: false + show_signature_annotations: true + separate_signature: true + line_length: 60 + heading_level: 3 + inherited_members: true markdown_extensions: - - codehilite: - css_class: highlight + - admonition + - pymdownx.highlight: + use_pygments: true + pygments_lang_class: true + - pymdownx.superfences diff --git a/wrangler-httpcore2.toml b/wrangler-httpcore2.toml new file mode 100644 index 00000000..97592a65 --- /dev/null +++ b/wrangler-httpcore2.toml @@ -0,0 +1,10 @@ +name = "httpcore2-docs" +compatibility_date = "2026-05-22" + +[[routes]] +pattern = "httpcore2.pydantic.dev" +custom_domain = true + +[assets] +directory = "./src/httpcore2/site-httpcore2" +not_found_handling = "404-page" From 09897f9db9b604a22601a4b61da9680eaa52add6 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Sun, 31 May 2026 20:22:44 +0200 Subject: [PATCH 2/2] Restructure docs into per-package directories Move the httpx2 docs to docs/httpx2 and the httpcore2 docs to docs/httpcore2, each as a self-contained mkdocs project (mkdocs.yml, docs/ source, site/ output, wrangler.toml). Update the build/serve scripts and the Cloudflare deploy + preview jobs to the new paths. --- .github/workflows/main.yml | 8 +- .github/workflows/publish.yml | 12 +- .gitignore | 2 - {src => docs}/httpcore2/docs/async.md | 0 .../httpcore2/docs/connection-pools.md | 0 {src => docs}/httpcore2/docs/connections.md | 0 {src => docs}/httpcore2/docs/exceptions.md | 0 {src => docs}/httpcore2/docs/extensions.md | 0 {src => docs}/httpcore2/docs/http2.md | 0 {src => docs}/httpcore2/docs/index.md | 0 {src => docs}/httpcore2/docs/logging.md | 0 .../httpcore2/docs/network-backends.md | 0 {src => docs}/httpcore2/docs/proxies.md | 0 {src => docs}/httpcore2/docs/quickstart.md | 0 .../httpcore2/docs/requests-responses-urls.md | 0 .../httpcore2/docs/table-of-contents.md | 0 {src => docs}/httpcore2/mkdocs.yml | 2 +- .../httpcore2/wrangler.toml | 2 +- .../docs}/advanced/authentication.md | 0 docs/{ => httpx2/docs}/advanced/clients.md | 0 .../{ => httpx2/docs}/advanced/event-hooks.md | 0 docs/{ => httpx2/docs}/advanced/extensions.md | 0 docs/{ => httpx2/docs}/advanced/proxies.md | 0 .../docs}/advanced/resource-limits.md | 0 docs/{ => httpx2/docs}/advanced/ssl.md | 0 .../docs}/advanced/text-encodings.md | 0 docs/{ => httpx2/docs}/advanced/timeouts.md | 0 docs/{ => httpx2/docs}/advanced/transports.md | 0 docs/{ => httpx2/docs}/api.md | 0 docs/{ => httpx2/docs}/async.md | 0 docs/{ => httpx2/docs}/code_of_conduct.md | 0 docs/{ => httpx2/docs}/compatibility.md | 0 docs/{ => httpx2/docs}/contributing.md | 0 docs/{ => httpx2/docs}/css/custom.css | 0 .../docs}/environment_variables.md | 0 docs/{ => httpx2/docs}/exceptions.md | 0 docs/{ => httpx2/docs}/http2.md | 0 docs/{ => httpx2/docs}/img/butterfly.png | Bin .../docs}/img/gh-actions-fail-check.png | Bin .../docs}/img/gh-actions-fail-test.png | Bin .../{ => httpx2/docs}/img/gh-actions-fail.png | Bin docs/{ => httpx2/docs}/img/logo.jpg | Bin docs/{ => httpx2/docs}/img/rich-progress.gif | Bin docs/{ => httpx2/docs}/img/tqdm-progress.gif | Bin docs/{ => httpx2/docs}/index.md | 0 docs/{ => httpx2/docs}/logging.md | 0 docs/{ => httpx2/docs}/quickstart.md | 0 .../{ => httpx2/docs}/third_party_packages.md | 0 docs/{ => httpx2/docs}/troubleshooting.md | 0 mkdocs.yml => docs/httpx2/mkdocs.yml | 1 + wrangler.toml => docs/httpx2/wrangler.toml | 0 scripts/build | 4 +- scripts/docs | 2 +- src/httpcore2/site-httpcore2/404.html | 620 +++++++ .../site-httpcore2/assets/images/favicon.png | Bin 0 -> 1870 bytes .../site-httpcore2/assets/javascripts/LICENSE | 29 + .../assets/javascripts/bundle.dbc0afdc.min.js | 3 + .../workers/search.e2d2d235.min.js | 1 + .../stylesheets/classic/main.a2001754.min.css | 1 + .../classic/palette.7dc9a0ad.min.css | 1 + .../stylesheets/modern/main.fba56155.min.css | 1 + .../modern/palette.dfe2e883.min.css | 1 + src/httpcore2/site-httpcore2/async/index.html | 1429 +++++++++++++++++ .../connection-pools/index.html | 1309 +++++++++++++++ .../site-httpcore2/connections/index.html | 803 +++++++++ .../site-httpcore2/exceptions/index.html | 681 ++++++++ .../site-httpcore2/extensions/index.html | 1284 +++++++++++++++ src/httpcore2/site-httpcore2/http2/index.html | 1028 ++++++++++++ src/httpcore2/site-httpcore2/index.html | 800 +++++++++ .../site-httpcore2/logging/index.html | 692 ++++++++ .../network-backends/index.html | 1172 ++++++++++++++ src/httpcore2/site-httpcore2/objects.inv | Bin 0 -> 568 bytes .../site-httpcore2/proxies/index.html | 926 +++++++++++ .../site-httpcore2/quickstart/index.html | 1222 ++++++++++++++ .../requests-responses-urls/index.html | 1353 ++++++++++++++++ src/httpcore2/site-httpcore2/search.json | 1 + src/httpcore2/site-httpcore2/sitemap.xml | 39 + .../table-of-contents/index.html | 723 +++++++++ 78 files changed, 14135 insertions(+), 17 deletions(-) rename {src => docs}/httpcore2/docs/async.md (100%) rename {src => docs}/httpcore2/docs/connection-pools.md (100%) rename {src => docs}/httpcore2/docs/connections.md (100%) rename {src => docs}/httpcore2/docs/exceptions.md (100%) rename {src => docs}/httpcore2/docs/extensions.md (100%) rename {src => docs}/httpcore2/docs/http2.md (100%) rename {src => docs}/httpcore2/docs/index.md (100%) rename {src => docs}/httpcore2/docs/logging.md (100%) rename {src => docs}/httpcore2/docs/network-backends.md (100%) rename {src => docs}/httpcore2/docs/proxies.md (100%) rename {src => docs}/httpcore2/docs/quickstart.md (100%) rename {src => docs}/httpcore2/docs/requests-responses-urls.md (100%) rename {src => docs}/httpcore2/docs/table-of-contents.md (100%) rename {src => docs}/httpcore2/mkdocs.yml (98%) rename wrangler-httpcore2.toml => docs/httpcore2/wrangler.toml (78%) rename docs/{ => httpx2/docs}/advanced/authentication.md (100%) rename docs/{ => httpx2/docs}/advanced/clients.md (100%) rename docs/{ => httpx2/docs}/advanced/event-hooks.md (100%) rename docs/{ => httpx2/docs}/advanced/extensions.md (100%) rename docs/{ => httpx2/docs}/advanced/proxies.md (100%) rename docs/{ => httpx2/docs}/advanced/resource-limits.md (100%) rename docs/{ => httpx2/docs}/advanced/ssl.md (100%) rename docs/{ => httpx2/docs}/advanced/text-encodings.md (100%) rename docs/{ => httpx2/docs}/advanced/timeouts.md (100%) rename docs/{ => httpx2/docs}/advanced/transports.md (100%) rename docs/{ => httpx2/docs}/api.md (100%) rename docs/{ => httpx2/docs}/async.md (100%) rename docs/{ => httpx2/docs}/code_of_conduct.md (100%) rename docs/{ => httpx2/docs}/compatibility.md (100%) rename docs/{ => httpx2/docs}/contributing.md (100%) rename docs/{ => httpx2/docs}/css/custom.css (100%) rename docs/{ => httpx2/docs}/environment_variables.md (100%) rename docs/{ => httpx2/docs}/exceptions.md (100%) rename docs/{ => httpx2/docs}/http2.md (100%) rename docs/{ => httpx2/docs}/img/butterfly.png (100%) rename docs/{ => httpx2/docs}/img/gh-actions-fail-check.png (100%) rename docs/{ => httpx2/docs}/img/gh-actions-fail-test.png (100%) rename docs/{ => httpx2/docs}/img/gh-actions-fail.png (100%) rename docs/{ => httpx2/docs}/img/logo.jpg (100%) rename docs/{ => httpx2/docs}/img/rich-progress.gif (100%) rename docs/{ => httpx2/docs}/img/tqdm-progress.gif (100%) rename docs/{ => httpx2/docs}/index.md (100%) rename docs/{ => httpx2/docs}/logging.md (100%) rename docs/{ => httpx2/docs}/quickstart.md (100%) rename docs/{ => httpx2/docs}/third_party_packages.md (100%) rename docs/{ => httpx2/docs}/troubleshooting.md (100%) rename mkdocs.yml => docs/httpx2/mkdocs.yml (99%) rename wrangler.toml => docs/httpx2/wrangler.toml (100%) create mode 100644 src/httpcore2/site-httpcore2/404.html create mode 100644 src/httpcore2/site-httpcore2/assets/images/favicon.png create mode 100644 src/httpcore2/site-httpcore2/assets/javascripts/LICENSE create mode 100644 src/httpcore2/site-httpcore2/assets/javascripts/bundle.dbc0afdc.min.js create mode 100644 src/httpcore2/site-httpcore2/assets/javascripts/workers/search.e2d2d235.min.js create mode 100644 src/httpcore2/site-httpcore2/assets/stylesheets/classic/main.a2001754.min.css create mode 100644 src/httpcore2/site-httpcore2/assets/stylesheets/classic/palette.7dc9a0ad.min.css create mode 100644 src/httpcore2/site-httpcore2/assets/stylesheets/modern/main.fba56155.min.css create mode 100644 src/httpcore2/site-httpcore2/assets/stylesheets/modern/palette.dfe2e883.min.css create mode 100644 src/httpcore2/site-httpcore2/async/index.html create mode 100644 src/httpcore2/site-httpcore2/connection-pools/index.html create mode 100644 src/httpcore2/site-httpcore2/connections/index.html create mode 100644 src/httpcore2/site-httpcore2/exceptions/index.html create mode 100644 src/httpcore2/site-httpcore2/extensions/index.html create mode 100644 src/httpcore2/site-httpcore2/http2/index.html create mode 100644 src/httpcore2/site-httpcore2/index.html create mode 100644 src/httpcore2/site-httpcore2/logging/index.html create mode 100644 src/httpcore2/site-httpcore2/network-backends/index.html create mode 100644 src/httpcore2/site-httpcore2/objects.inv create mode 100644 src/httpcore2/site-httpcore2/proxies/index.html create mode 100644 src/httpcore2/site-httpcore2/quickstart/index.html create mode 100644 src/httpcore2/site-httpcore2/requests-responses-urls/index.html create mode 100644 src/httpcore2/site-httpcore2/search.json create mode 100644 src/httpcore2/site-httpcore2/sitemap.xml create mode 100644 src/httpcore2/site-httpcore2/table-of-contents/index.html diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f28e7903..e2f87282 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -81,24 +81,24 @@ jobs: run: scripts/install - name: Build docs - run: uv run zensical build --clean + run: uv run zensical build --clean -f docs/httpx2/mkdocs.yml - name: Build httpcore2 docs - run: uv run zensical build --clean -f src/httpcore2/mkdocs.yml + run: uv run zensical build --clean -f docs/httpcore2/mkdocs.yml - uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 id: deploy with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: versions upload --tag pr-${{ github.event.pull_request.number }} + command: versions upload --config docs/httpx2/wrangler.toml --tag pr-${{ github.event.pull_request.number }} - uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 id: deploy-httpcore2 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: versions upload --config wrangler-httpcore2.toml --tag pr-${{ github.event.pull_request.number }} + command: versions upload --config docs/httpcore2/wrangler.toml --tag pr-${{ github.event.pull_request.number }} - name: Comment preview URL uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e8c54c95..176a8bd2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -45,13 +45,13 @@ jobs: uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: documentation - path: site/ + path: docs/httpx2/site/ - name: Upload httpcore2 documentation uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: documentation-httpcore2 - path: src/httpcore2/site-httpcore2/ + path: docs/httpcore2/site/ publish: runs-on: ubuntu-latest @@ -93,13 +93,13 @@ jobs: uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: documentation - path: site/ + path: docs/httpx2/site/ - uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: deploy + command: deploy --config docs/httpx2/wrangler.toml docs-cloudflare-httpcore2: runs-on: ubuntu-latest @@ -121,10 +121,10 @@ jobs: uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: documentation-httpcore2 - path: src/httpcore2/site-httpcore2/ + path: docs/httpcore2/site/ - uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: deploy --config wrangler-httpcore2.toml + command: deploy --config docs/httpcore2/wrangler.toml diff --git a/.gitignore b/.gitignore index 26ffdd6a..18967b8a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,6 @@ __pycache__/ htmlcov/ site/ -site-httpcore2/ -src/httpcore2/site-httpcore2/ .wrangler/ *.egg-info/ venv*/ diff --git a/src/httpcore2/docs/async.md b/docs/httpcore2/docs/async.md similarity index 100% rename from src/httpcore2/docs/async.md rename to docs/httpcore2/docs/async.md diff --git a/src/httpcore2/docs/connection-pools.md b/docs/httpcore2/docs/connection-pools.md similarity index 100% rename from src/httpcore2/docs/connection-pools.md rename to docs/httpcore2/docs/connection-pools.md diff --git a/src/httpcore2/docs/connections.md b/docs/httpcore2/docs/connections.md similarity index 100% rename from src/httpcore2/docs/connections.md rename to docs/httpcore2/docs/connections.md diff --git a/src/httpcore2/docs/exceptions.md b/docs/httpcore2/docs/exceptions.md similarity index 100% rename from src/httpcore2/docs/exceptions.md rename to docs/httpcore2/docs/exceptions.md diff --git a/src/httpcore2/docs/extensions.md b/docs/httpcore2/docs/extensions.md similarity index 100% rename from src/httpcore2/docs/extensions.md rename to docs/httpcore2/docs/extensions.md diff --git a/src/httpcore2/docs/http2.md b/docs/httpcore2/docs/http2.md similarity index 100% rename from src/httpcore2/docs/http2.md rename to docs/httpcore2/docs/http2.md diff --git a/src/httpcore2/docs/index.md b/docs/httpcore2/docs/index.md similarity index 100% rename from src/httpcore2/docs/index.md rename to docs/httpcore2/docs/index.md diff --git a/src/httpcore2/docs/logging.md b/docs/httpcore2/docs/logging.md similarity index 100% rename from src/httpcore2/docs/logging.md rename to docs/httpcore2/docs/logging.md diff --git a/src/httpcore2/docs/network-backends.md b/docs/httpcore2/docs/network-backends.md similarity index 100% rename from src/httpcore2/docs/network-backends.md rename to docs/httpcore2/docs/network-backends.md diff --git a/src/httpcore2/docs/proxies.md b/docs/httpcore2/docs/proxies.md similarity index 100% rename from src/httpcore2/docs/proxies.md rename to docs/httpcore2/docs/proxies.md diff --git a/src/httpcore2/docs/quickstart.md b/docs/httpcore2/docs/quickstart.md similarity index 100% rename from src/httpcore2/docs/quickstart.md rename to docs/httpcore2/docs/quickstart.md diff --git a/src/httpcore2/docs/requests-responses-urls.md b/docs/httpcore2/docs/requests-responses-urls.md similarity index 100% rename from src/httpcore2/docs/requests-responses-urls.md rename to docs/httpcore2/docs/requests-responses-urls.md diff --git a/src/httpcore2/docs/table-of-contents.md b/docs/httpcore2/docs/table-of-contents.md similarity index 100% rename from src/httpcore2/docs/table-of-contents.md rename to docs/httpcore2/docs/table-of-contents.md diff --git a/src/httpcore2/mkdocs.yml b/docs/httpcore2/mkdocs.yml similarity index 98% rename from src/httpcore2/mkdocs.yml rename to docs/httpcore2/mkdocs.yml index f189d3af..6281fe88 100644 --- a/src/httpcore2/mkdocs.yml +++ b/docs/httpcore2/mkdocs.yml @@ -1,7 +1,7 @@ site_name: HTTPCore2 site_description: A minimal HTTP client for Python. site_url: https://httpcore2.pydantic.dev/ -site_dir: site-httpcore2 +site_dir: site theme: name: 'material' diff --git a/wrangler-httpcore2.toml b/docs/httpcore2/wrangler.toml similarity index 78% rename from wrangler-httpcore2.toml rename to docs/httpcore2/wrangler.toml index 97592a65..4eee64cc 100644 --- a/wrangler-httpcore2.toml +++ b/docs/httpcore2/wrangler.toml @@ -6,5 +6,5 @@ pattern = "httpcore2.pydantic.dev" custom_domain = true [assets] -directory = "./src/httpcore2/site-httpcore2" +directory = "./site" not_found_handling = "404-page" diff --git a/docs/advanced/authentication.md b/docs/httpx2/docs/advanced/authentication.md similarity index 100% rename from docs/advanced/authentication.md rename to docs/httpx2/docs/advanced/authentication.md diff --git a/docs/advanced/clients.md b/docs/httpx2/docs/advanced/clients.md similarity index 100% rename from docs/advanced/clients.md rename to docs/httpx2/docs/advanced/clients.md diff --git a/docs/advanced/event-hooks.md b/docs/httpx2/docs/advanced/event-hooks.md similarity index 100% rename from docs/advanced/event-hooks.md rename to docs/httpx2/docs/advanced/event-hooks.md diff --git a/docs/advanced/extensions.md b/docs/httpx2/docs/advanced/extensions.md similarity index 100% rename from docs/advanced/extensions.md rename to docs/httpx2/docs/advanced/extensions.md diff --git a/docs/advanced/proxies.md b/docs/httpx2/docs/advanced/proxies.md similarity index 100% rename from docs/advanced/proxies.md rename to docs/httpx2/docs/advanced/proxies.md diff --git a/docs/advanced/resource-limits.md b/docs/httpx2/docs/advanced/resource-limits.md similarity index 100% rename from docs/advanced/resource-limits.md rename to docs/httpx2/docs/advanced/resource-limits.md diff --git a/docs/advanced/ssl.md b/docs/httpx2/docs/advanced/ssl.md similarity index 100% rename from docs/advanced/ssl.md rename to docs/httpx2/docs/advanced/ssl.md diff --git a/docs/advanced/text-encodings.md b/docs/httpx2/docs/advanced/text-encodings.md similarity index 100% rename from docs/advanced/text-encodings.md rename to docs/httpx2/docs/advanced/text-encodings.md diff --git a/docs/advanced/timeouts.md b/docs/httpx2/docs/advanced/timeouts.md similarity index 100% rename from docs/advanced/timeouts.md rename to docs/httpx2/docs/advanced/timeouts.md diff --git a/docs/advanced/transports.md b/docs/httpx2/docs/advanced/transports.md similarity index 100% rename from docs/advanced/transports.md rename to docs/httpx2/docs/advanced/transports.md diff --git a/docs/api.md b/docs/httpx2/docs/api.md similarity index 100% rename from docs/api.md rename to docs/httpx2/docs/api.md diff --git a/docs/async.md b/docs/httpx2/docs/async.md similarity index 100% rename from docs/async.md rename to docs/httpx2/docs/async.md diff --git a/docs/code_of_conduct.md b/docs/httpx2/docs/code_of_conduct.md similarity index 100% rename from docs/code_of_conduct.md rename to docs/httpx2/docs/code_of_conduct.md diff --git a/docs/compatibility.md b/docs/httpx2/docs/compatibility.md similarity index 100% rename from docs/compatibility.md rename to docs/httpx2/docs/compatibility.md diff --git a/docs/contributing.md b/docs/httpx2/docs/contributing.md similarity index 100% rename from docs/contributing.md rename to docs/httpx2/docs/contributing.md diff --git a/docs/css/custom.css b/docs/httpx2/docs/css/custom.css similarity index 100% rename from docs/css/custom.css rename to docs/httpx2/docs/css/custom.css diff --git a/docs/environment_variables.md b/docs/httpx2/docs/environment_variables.md similarity index 100% rename from docs/environment_variables.md rename to docs/httpx2/docs/environment_variables.md diff --git a/docs/exceptions.md b/docs/httpx2/docs/exceptions.md similarity index 100% rename from docs/exceptions.md rename to docs/httpx2/docs/exceptions.md diff --git a/docs/http2.md b/docs/httpx2/docs/http2.md similarity index 100% rename from docs/http2.md rename to docs/httpx2/docs/http2.md diff --git a/docs/img/butterfly.png b/docs/httpx2/docs/img/butterfly.png similarity index 100% rename from docs/img/butterfly.png rename to docs/httpx2/docs/img/butterfly.png diff --git a/docs/img/gh-actions-fail-check.png b/docs/httpx2/docs/img/gh-actions-fail-check.png similarity index 100% rename from docs/img/gh-actions-fail-check.png rename to docs/httpx2/docs/img/gh-actions-fail-check.png diff --git a/docs/img/gh-actions-fail-test.png b/docs/httpx2/docs/img/gh-actions-fail-test.png similarity index 100% rename from docs/img/gh-actions-fail-test.png rename to docs/httpx2/docs/img/gh-actions-fail-test.png diff --git a/docs/img/gh-actions-fail.png b/docs/httpx2/docs/img/gh-actions-fail.png similarity index 100% rename from docs/img/gh-actions-fail.png rename to docs/httpx2/docs/img/gh-actions-fail.png diff --git a/docs/img/logo.jpg b/docs/httpx2/docs/img/logo.jpg similarity index 100% rename from docs/img/logo.jpg rename to docs/httpx2/docs/img/logo.jpg diff --git a/docs/img/rich-progress.gif b/docs/httpx2/docs/img/rich-progress.gif similarity index 100% rename from docs/img/rich-progress.gif rename to docs/httpx2/docs/img/rich-progress.gif diff --git a/docs/img/tqdm-progress.gif b/docs/httpx2/docs/img/tqdm-progress.gif similarity index 100% rename from docs/img/tqdm-progress.gif rename to docs/httpx2/docs/img/tqdm-progress.gif diff --git a/docs/index.md b/docs/httpx2/docs/index.md similarity index 100% rename from docs/index.md rename to docs/httpx2/docs/index.md diff --git a/docs/logging.md b/docs/httpx2/docs/logging.md similarity index 100% rename from docs/logging.md rename to docs/httpx2/docs/logging.md diff --git a/docs/quickstart.md b/docs/httpx2/docs/quickstart.md similarity index 100% rename from docs/quickstart.md rename to docs/httpx2/docs/quickstart.md diff --git a/docs/third_party_packages.md b/docs/httpx2/docs/third_party_packages.md similarity index 100% rename from docs/third_party_packages.md rename to docs/httpx2/docs/third_party_packages.md diff --git a/docs/troubleshooting.md b/docs/httpx2/docs/troubleshooting.md similarity index 100% rename from docs/troubleshooting.md rename to docs/httpx2/docs/troubleshooting.md diff --git a/mkdocs.yml b/docs/httpx2/mkdocs.yml similarity index 99% rename from mkdocs.yml rename to docs/httpx2/mkdocs.yml index 2e1654a3..c09b3403 100644 --- a/mkdocs.yml +++ b/docs/httpx2/mkdocs.yml @@ -1,5 +1,6 @@ site_name: HTTPX2 site_description: A next-generation HTTP client for Python. +site_dir: site theme: name: 'material' diff --git a/wrangler.toml b/docs/httpx2/wrangler.toml similarity index 100% rename from wrangler.toml rename to docs/httpx2/wrangler.toml diff --git a/scripts/build b/scripts/build index 99a0ad8d..b9229c43 100755 --- a/scripts/build +++ b/scripts/build @@ -4,5 +4,5 @@ set -x uv build --all-packages uv run twine check dist/* -uv run zensical build -c -f mkdocs.yml -uv run zensical build -c -f src/httpcore2/mkdocs.yml +uv run zensical build -c -f docs/httpx2/mkdocs.yml +uv run zensical build -c -f docs/httpcore2/mkdocs.yml diff --git a/scripts/docs b/scripts/docs index 64cf93b3..bfb35abd 100755 --- a/scripts/docs +++ b/scripts/docs @@ -2,4 +2,4 @@ set -x -uv run zensical serve -f mkdocs.yml +uv run zensical serve -f docs/httpx2/mkdocs.yml diff --git a/src/httpcore2/site-httpcore2/404.html b/src/httpcore2/site-httpcore2/404.html new file mode 100644 index 00000000..3707a763 --- /dev/null +++ b/src/httpcore2/site-httpcore2/404.html @@ -0,0 +1,620 @@ + + + + + + + + + + + + + + + + + + + + + + + + HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + + + + + +
+
+ + + + + + +
+ + + + +
+
+
+ + + +
+ +
+ +

404 - Not found

+ +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/assets/images/favicon.png b/src/httpcore2/site-httpcore2/assets/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..1cf13b9f9d978896599290a74f77d5dbe7d1655c GIT binary patch literal 1870 zcmV-U2eJ5xP)Gc)JR9QMau)O=X#!i9;T z37kk-upj^(fsR36MHs_+1RCI)NNu9}lD0S{B^g8PN?Ww(5|~L#Ng*g{WsqleV}|#l zz8@ri&cTzw_h33bHI+12+kK6WN$h#n5cD8OQt`5kw6p~9H3()bUQ8OS4Q4HTQ=1Ol z_JAocz`fLbT2^{`8n~UAo=#AUOf=SOq4pYkt;XbC&f#7lb$*7=$na!mWCQ`dBQsO0 zLFBSPj*N?#u5&pf2t4XjEGH|=pPQ8xh7tpx;US5Cx_Ju;!O`ya-yF`)b%TEt5>eP1ZX~}sjjA%FJF?h7cX8=b!DZl<6%Cv z*G0uvvU+vmnpLZ2paivG-(cd*y3$hCIcsZcYOGh{$&)A6*XX&kXZd3G8m)G$Zz-LV z^GF3VAW^Mdv!)4OM8EgqRiz~*Cji;uzl2uC9^=8I84vNp;ltJ|q-*uQwGp2ma6cY7 z;`%`!9UXO@fr&Ebapfs34OmS9^u6$)bJxrucutf>`dKPKT%%*d3XlFVKunp9 zasduxjrjs>f8V=D|J=XNZp;_Zy^WgQ$9WDjgY=z@stwiEBm9u5*|34&1Na8BMjjgf3+SHcr`5~>oz1Y?SW^=K z^bTyO6>Gar#P_W2gEMwq)ot3; zREHn~U&Dp0l6YT0&k-wLwYjb?5zGK`W6S2v+K>AM(95m2C20L|3m~rN8dprPr@t)5lsk9Hu*W z?pS990s;Ez=+Rj{x7p``4>+c0G5^pYnB1^!TL=(?HLHZ+HicG{~4F1d^5Awl_2!1jICM-!9eoLhbbT^;yHcefyTAaqRcY zmuctDopPT!%k+}x%lZRKnzykr2}}XfG_ne?nRQO~?%hkzo;@RN{P6o`&mMUWBYMTe z6i8ChtjX&gXl`nvrU>jah)2iNM%JdjqoaeaU%yVn!^70x-flljp6Q5tK}5}&X8&&G zX3fpb3E(!rH=zVI_9Gjl45w@{(ITqngWFe7@9{mX;tO25Z_8 zQHEpI+FkTU#4xu>RkN>b3Tnc3UpWzPXWm#o55GKF09j^Mh~)K7{QqbO_~(@CVq! zS<8954|P8mXN2MRs86xZ&Q4EfM@JB94b=(YGuk)s&^jiSF=t3*oNK3`rD{H`yQ?d; ztE=laAUoZx5?RC8*WKOj`%LXEkgDd>&^Q4M^z`%u0rg-It=hLCVsq!Z%^6eB-OvOT zFZ28TN&cRmgU}Elrnk43)!>Z1FCPL2K$7}gwzIc48NX}#!A1BpJP?#v5wkNprhV** z?Cpalt1oH&{r!o3eSKc&ap)iz2BTn_VV`4>9M^b3;(YY}4>#ML6{~(4mH+?%07*qo IM6N<$f(jP3KmY&$ literal 0 HcmV?d00001 diff --git a/src/httpcore2/site-httpcore2/assets/javascripts/LICENSE b/src/httpcore2/site-httpcore2/assets/javascripts/LICENSE new file mode 100644 index 00000000..baab16bd --- /dev/null +++ b/src/httpcore2/site-httpcore2/assets/javascripts/LICENSE @@ -0,0 +1,29 @@ +------------------------------------------------------------------------------- +Third-Party licenses +------------------------------------------------------------------------------- + +Package: clipboard@2.0.11 +License: MIT +Copyright: Zeno Rocha + +------------------------------------------------------------------------------- + +Package: escape-html@1.0.3 +License: MIT +Copyright: 2012-2013 TJ Holowaychuk + 2015 Andreas Lubbe + 2015 Tiancheng "Timothy" Gu + +------------------------------------------------------------------------------- + +Package: focus-visible@5.2.1 +License: W3C +Copyright: WICG + +------------------------------------------------------------------------------- + +Package: rxjs@7.8.2 +License: Apache-2.0 +Copyright: 2015-2018 Google, Inc., + 2015-2018 Netflix, Inc., + 2015-2018 Microsoft Corp. and contributors diff --git a/src/httpcore2/site-httpcore2/assets/javascripts/bundle.dbc0afdc.min.js b/src/httpcore2/site-httpcore2/assets/javascripts/bundle.dbc0afdc.min.js new file mode 100644 index 00000000..c2eab7e1 --- /dev/null +++ b/src/httpcore2/site-httpcore2/assets/javascripts/bundle.dbc0afdc.min.js @@ -0,0 +1,3 @@ +"use strict";(()=>{var Oc=Object.create;var Hn=Object.defineProperty,Sc=Object.defineProperties,Lc=Object.getOwnPropertyDescriptor,Mc=Object.getOwnPropertyDescriptors,kc=Object.getOwnPropertyNames,Dr=Object.getOwnPropertySymbols,Ac=Object.getPrototypeOf,$n=Object.prototype.hasOwnProperty,Wo=Object.prototype.propertyIsEnumerable;var Do=(e,t,r)=>t in e?Hn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,M=(e,t)=>{for(var r in t||(t={}))$n.call(t,r)&&Do(e,r,t[r]);if(Dr)for(var r of Dr(t))Wo.call(t,r)&&Do(e,r,t[r]);return e},He=(e,t)=>Sc(e,Mc(t));var gr=(e,t)=>{var r={};for(var n in e)$n.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&Dr)for(var n of Dr(e))t.indexOf(n)<0&&Wo.call(e,n)&&(r[n]=e[n]);return r};var Pn=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Cc=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of kc(t))!$n.call(e,o)&&o!==r&&Hn(e,o,{get:()=>t[o],enumerable:!(n=Lc(t,o))||n.enumerable});return e};var _r=(e,t,r)=>(r=e!=null?Oc(Ac(e)):{},Cc(t||!e||!e.__esModule?Hn(r,"default",{value:e,enumerable:!0}):r,e));var Vo=(e,t,r)=>new Promise((n,o)=>{var i=c=>{try{s(r.next(c))}catch(l){o(l)}},a=c=>{try{s(r.throw(c))}catch(l){o(l)}},s=c=>c.done?n(c.value):Promise.resolve(c.value).then(i,a);s((r=r.apply(e,t)).next())});var qo=Pn((In,zo)=>{(function(e,t){typeof In=="object"&&typeof zo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(In,(function(){"use strict";function e(r){var n=!0,o=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(_){return!!(_&&_!==document&&_.nodeName!=="HTML"&&_.nodeName!=="BODY"&&"classList"in _&&"contains"in _.classList)}function c(_){var de=_.type,be=_.tagName;return!!(be==="INPUT"&&a[de]&&!_.readOnly||be==="TEXTAREA"&&!_.readOnly||_.isContentEditable)}function l(_){_.classList.contains("focus-visible")||(_.classList.add("focus-visible"),_.setAttribute("data-focus-visible-added",""))}function u(_){_.hasAttribute("data-focus-visible-added")&&(_.classList.remove("focus-visible"),_.removeAttribute("data-focus-visible-added"))}function p(_){_.metaKey||_.altKey||_.ctrlKey||(s(r.activeElement)&&l(r.activeElement),n=!0)}function d(_){n=!1}function m(_){s(_.target)&&(n||c(_.target))&&l(_.target)}function h(_){s(_.target)&&(_.target.classList.contains("focus-visible")||_.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(_.target))}function v(_){document.visibilityState==="hidden"&&(o&&(n=!0),y())}function y(){document.addEventListener("mousemove",T),document.addEventListener("mousedown",T),document.addEventListener("mouseup",T),document.addEventListener("pointermove",T),document.addEventListener("pointerdown",T),document.addEventListener("pointerup",T),document.addEventListener("touchmove",T),document.addEventListener("touchstart",T),document.addEventListener("touchend",T)}function E(){document.removeEventListener("mousemove",T),document.removeEventListener("mousedown",T),document.removeEventListener("mouseup",T),document.removeEventListener("pointermove",T),document.removeEventListener("pointerdown",T),document.removeEventListener("pointerup",T),document.removeEventListener("touchmove",T),document.removeEventListener("touchstart",T),document.removeEventListener("touchend",T)}function T(_){_.target.nodeName&&_.target.nodeName.toLowerCase()==="html"||(n=!1,E())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",d,!0),document.addEventListener("pointerdown",d,!0),document.addEventListener("touchstart",d,!0),document.addEventListener("visibilitychange",v,!0),y(),r.addEventListener("focus",m,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)}))});var Mo=Pn((W0,_s)=>{"use strict";var Qu=/["'&<>]/;_s.exports=ep;function ep(e){var t=""+e,r=Qu.exec(t);if(!r)return t;var n,o="",i=0,a=0;for(i=r.index;i{(function(t,r){typeof jr=="object"&&typeof Ao=="object"?Ao.exports=r():typeof define=="function"&&define.amd?define([],r):typeof jr=="object"?jr.ClipboardJS=r():t.ClipboardJS=r()})(jr,function(){return(function(){var e={686:(function(n,o,i){"use strict";i.d(o,{default:function(){return vr}});var a=i(279),s=i.n(a),c=i(370),l=i.n(c),u=i(817),p=i.n(u);function d(G){try{return document.execCommand(G)}catch(H){return!1}}var m=function(H){var C=p()(H);return d("cut"),C},h=m;function v(G){var H=document.documentElement.getAttribute("dir")==="rtl",C=document.createElement("textarea");C.style.fontSize="12pt",C.style.border="0",C.style.padding="0",C.style.margin="0",C.style.position="absolute",C.style[H?"right":"left"]="-9999px";var W=window.pageYOffset||document.documentElement.scrollTop;return C.style.top="".concat(W,"px"),C.setAttribute("readonly",""),C.value=G,C}var y=function(H,C){var W=v(H);C.container.appendChild(W);var V=p()(W);return d("copy"),W.remove(),V},E=function(H){var C=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},W="";return typeof H=="string"?W=y(H,C):H instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(H==null?void 0:H.type)?W=y(H.value,C):(W=p()(H),d("copy")),W},T=E;function _(G){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?_=function(C){return typeof C}:_=function(C){return C&&typeof Symbol=="function"&&C.constructor===Symbol&&C!==Symbol.prototype?"symbol":typeof C},_(G)}var de=function(){var H=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},C=H.action,W=C===void 0?"copy":C,V=H.container,Z=H.target,We=H.text;if(W!=="copy"&&W!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(Z!==void 0)if(Z&&_(Z)==="object"&&Z.nodeType===1){if(W==="copy"&&Z.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(W==="cut"&&(Z.hasAttribute("readonly")||Z.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(We)return T(We,{container:V});if(Z)return W==="cut"?h(Z):T(Z,{container:V})},be=de;function A(G){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?A=function(C){return typeof C}:A=function(C){return C&&typeof Symbol=="function"&&C.constructor===Symbol&&C!==Symbol.prototype?"symbol":typeof C},A(G)}function S(G,H){if(!(G instanceof H))throw new TypeError("Cannot call a class as a function")}function D(G,H){for(var C=0;C0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof V.action=="function"?V.action:this.defaultAction,this.target=typeof V.target=="function"?V.target:this.defaultTarget,this.text=typeof V.text=="function"?V.text:this.defaultText,this.container=A(V.container)==="object"?V.container:document.body}},{key:"listenClick",value:function(V){var Z=this;this.listener=l()(V,"click",function(We){return Z.onClick(We)})}},{key:"onClick",value:function(V){var Z=V.delegateTarget||V.currentTarget,We=this.action(Z)||"copy",Jt=be({action:We,container:this.container,target:this.target(Z),text:this.text(Z)});this.emit(Jt?"success":"error",{action:We,text:Jt,trigger:Z,clearSelection:function(){Z&&Z.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(V){return Yt("action",V)}},{key:"defaultTarget",value:function(V){var Z=Yt("target",V);if(Z)return document.querySelector(Z)}},{key:"defaultText",value:function(V){return Yt("text",V)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(V){var Z=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return T(V,Z)}},{key:"cut",value:function(V){return h(V)}},{key:"isSupported",value:function(){var V=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],Z=typeof V=="string"?[V]:V,We=!!document.queryCommandSupported;return Z.forEach(function(Jt){We=We&&!!document.queryCommandSupported(Jt)}),We}}]),C})(s()),vr=kt}),828:(function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,c){for(;s&&s.nodeType!==o;){if(typeof s.matches=="function"&&s.matches(c))return s;s=s.parentNode}}n.exports=a}),438:(function(n,o,i){var a=i(828);function s(u,p,d,m,h){var v=l.apply(this,arguments);return u.addEventListener(d,v,h),{destroy:function(){u.removeEventListener(d,v,h)}}}function c(u,p,d,m,h){return typeof u.addEventListener=="function"?s.apply(null,arguments):typeof d=="function"?s.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return s(v,p,d,m,h)}))}function l(u,p,d,m){return function(h){h.delegateTarget=a(h.target,p),h.delegateTarget&&m.call(u,h)}}n.exports=c}),879:(function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}}),370:(function(n,o,i){var a=i(879),s=i(438);function c(d,m,h){if(!d&&!m&&!h)throw new Error("Missing required arguments");if(!a.string(m))throw new TypeError("Second argument must be a String");if(!a.fn(h))throw new TypeError("Third argument must be a Function");if(a.node(d))return l(d,m,h);if(a.nodeList(d))return u(d,m,h);if(a.string(d))return p(d,m,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function l(d,m,h){return d.addEventListener(m,h),{destroy:function(){d.removeEventListener(m,h)}}}function u(d,m,h){return Array.prototype.forEach.call(d,function(v){v.addEventListener(m,h)}),{destroy:function(){Array.prototype.forEach.call(d,function(v){v.removeEventListener(m,h)})}}}function p(d,m,h){return s(document.body,d,m,h)}n.exports=c}),817:(function(n){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),l=document.createRange();l.selectNodeContents(i),c.removeAllRanges(),c.addRange(l),a=c.toString()}return a}n.exports=o}),279:(function(n){function o(){}o.prototype={on:function(i,a,s){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var c=this;function l(){c.off(i,l),a.apply(s,arguments)}return l._=a,this.on(i,l,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),c=0,l=s.length;for(c;c0&&i[i.length-1])&&(l[0]===6||l[0]===2)){r=0;continue}if(l[0]===3&&(!i||l[1]>i[0]&&l[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function te(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],a;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(a)throw a.error}}return i}function ne(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||c(m,v)})},h&&(o[m]=h(o[m])))}function c(m,h){try{l(n[m](h))}catch(v){d(i[0][3],v)}}function l(m){m.value instanceof At?Promise.resolve(m.value.v).then(u,p):d(i[0][2],m)}function u(m){c("next",m)}function p(m){c("throw",m)}function d(m,h){m(h),i.shift(),i.length&&c(i[0][0],i[0][1])}}function Go(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof $e=="function"?$e(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(a){return new Promise(function(s,c){a=e[i](a),o(s,c,a.done,a.value)})}}function o(i,a,s,c){Promise.resolve(c).then(function(l){i({value:l,done:s})},a)}}function U(e){return typeof e=="function"}function Xt(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Vr=Xt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function ut(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var rt=(function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=$e(a),c=s.next();!c.done;c=s.next()){var l=c.value;l.remove(this)}}catch(v){t={error:v}}finally{try{c&&!c.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var u=this.initialTeardown;if(U(u))try{u()}catch(v){i=v instanceof Vr?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var d=$e(p),m=d.next();!m.done;m=d.next()){var h=m.value;try{Yo(h)}catch(v){i=i!=null?i:[],v instanceof Vr?i=ne(ne([],te(i)),te(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{m&&!m.done&&(o=d.return)&&o.call(d)}finally{if(n)throw n.error}}}if(i)throw new Vr(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)Yo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&ut(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&ut(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=(function(){var t=new e;return t.closed=!0,t})(),e})();var jn=rt.EMPTY;function zr(e){return e instanceof rt||e&&"closed"in e&&U(e.remove)&&U(e.add)&&U(e.unsubscribe)}function Yo(e){U(e)?e():e.unsubscribe()}var Je={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var Zt={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,a=o.isStopped,s=o.observers;return i||a?jn:(this.currentObservers=null,s.push(r),new rt(function(){n.currentObservers=null,ut(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,a=n.isStopped;o?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,n){return new ni(r,n)},t})(F);var ni=(function(e){ue(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:jn},t})(I);var Wn=(function(e){ue(t,e);function t(r){var n=e.call(this)||this;return n._value=r,n}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var n=e.prototype._subscribe.call(this,r);return!n.closed&&r.next(this._value),n},t.prototype.getValue=function(){var r=this,n=r.hasError,o=r.thrownError,i=r._value;if(n)throw o;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t})(I);var xr={now:function(){return(xr.delegate||Date).now()},delegate:void 0};var wr=(function(e){ue(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=xr);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,a=n._infiniteTimeWindow,s=n._timestampProvider,c=n._windowTime;o||(i.push(r),!a&&i.push(s.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,a=o._buffer,s=a.slice(),c=0;c0?e.prototype.schedule.call(this,r,n):(this.delay=n,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,n){return n>0||this.closed?e.prototype.execute.call(this,r,n):this._execute(r,n)},t.prototype.requestAsyncId=function(r,n,o){return o===void 0&&(o=0),o!=null&&o>0||o==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,n,o):(r.flush(this),0)},t})(rr);var ai=(function(e){ue(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t})(nr);var qn=new ai(ii);var si=(function(e){ue(t,e);function t(r,n){var o=e.call(this,r,n)||this;return o.scheduler=r,o.work=n,o}return t.prototype.requestAsyncId=function(r,n,o){return o===void 0&&(o=0),o!==null&&o>0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=tr.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var a=r.actions;n!=null&&n===r._scheduled&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==n&&(tr.cancelAnimationFrame(n),r._scheduled=void 0)},t})(rr);var ci=(function(e){ue(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n;r?n=r.id:(n=this._scheduled,this._scheduled=void 0);var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t})(nr);var je=new ci(si);var x=new F(function(e){return e.complete()});function Br(e){return e&&U(e.schedule)}function Kn(e){return e[e.length-1]}function nt(e){return U(Kn(e))?e.pop():void 0}function qe(e){return Br(Kn(e))?e.pop():void 0}function Gr(e,t){return typeof Kn(e)=="number"?e.pop():t}var or=(function(e){return e&&typeof e.length=="number"&&typeof e!="function"});function Yr(e){return U(e==null?void 0:e.then)}function Jr(e){return U(e[er])}function Xr(e){return Symbol.asyncIterator&&U(e==null?void 0:e[Symbol.asyncIterator])}function Zr(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Nc(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Qr=Nc();function en(e){return U(e==null?void 0:e[Qr])}function tn(e){return Bo(this,arguments,function(){var r,n,o,i;return Wr(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,At(r.read())];case 3:return n=a.sent(),o=n.value,i=n.done,i?[4,At(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,At(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function rn(e){return U(e==null?void 0:e.getReader)}function N(e){if(e instanceof F)return e;if(e!=null){if(Jr(e))return Dc(e);if(or(e))return Wc(e);if(Yr(e))return Vc(e);if(Xr(e))return li(e);if(en(e))return zc(e);if(rn(e))return qc(e)}throw Zr(e)}function Dc(e){return new F(function(t){var r=e[er]();if(U(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Wc(e){return new F(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?L(function(o,i){return e(o,i,n)}):Le,Me(1),r?at(t):Ti(function(){return new an}))}}function Zn(e){return e<=0?function(){return x}:O(function(t,r){var n=[];t.subscribe(w(r,function(o){n.push(o),e=2,!0))}function xe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new I}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,c=s===void 0?!0:s;return function(l){var u,p,d,m=0,h=!1,v=!1,y=function(){p==null||p.unsubscribe(),p=void 0},E=function(){y(),u=d=void 0,h=v=!1},T=function(){var _=u;E(),_==null||_.unsubscribe()};return O(function(_,de){m++,!v&&!h&&y();var be=d=d!=null?d:r();de.add(function(){m--,m===0&&!v&&!h&&(p=Qn(T,c))}),be.subscribe(de),!u&&m>0&&(u=new Ht({next:function(A){return be.next(A)},error:function(A){v=!0,y(),p=Qn(E,o,A),be.error(A)},complete:function(){h=!0,y(),p=Qn(E,a),be.complete()}}),N(_).subscribe(u))})(l)}}function Qn(e,t){for(var r=[],n=2;ne.next(document)),e}function P(e,t=document){return Array.from(t.querySelectorAll(e))}function Y(e,t=document){let r=we(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function we(e,t=document){return t.querySelector(e)||void 0}function xt(){var e,t,r,n;return(n=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?n:void 0}var ll=R(b(document.body,"focusin"),b(document.body,"focusout")).pipe(Be(1),J(void 0),f(()=>xt()||document.body),ie(1));function ar(e){return ll.pipe(f(t=>e.contains(t)),ae())}function Ut(e,t){let{matches:r}=matchMedia("(hover)");return j(()=>(r?R(b(e,"mouseenter").pipe(f(()=>!0)),b(e,"mouseleave").pipe(f(()=>!1))):R(b(e,"touchstart").pipe(f(()=>!0)),b(e,"touchend").pipe(f(()=>!1)),b(e,"touchcancel").pipe(f(()=>!1)))).pipe(t?Tr(o=>Ve(+!o*t)):Le,J(!0,e.matches(":hover"))))}function Mi(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Mi(e,r)}function k(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)Mi(n,o);return n}function ki(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function wt(e){let t=k("script",{src:e});return j(()=>(document.head.appendChild(t),R(b(t,"load"),b(t,"error").pipe(g(()=>on(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(f(()=>{}),z(()=>document.head.removeChild(t)),Me(1))))}function Ai(e){let t=k("link",{rel:"stylesheet",href:e});return document.head.appendChild(t),R(b(t,"load"),b(t,"error").pipe(g(()=>on(()=>new ReferenceError(`Invalid styles: ${e}`))))).pipe(f(()=>{}),Me(1))}var Ci=new I,ul=j(()=>typeof ResizeObserver=="undefined"?wt("https://unpkg.com/resize-observer-polyfill"):K(void 0)).pipe(f(()=>new ResizeObserver(e=>e.forEach(t=>Ci.next(t)))),g(e=>R(Ke,K(e)).pipe(z(()=>e.disconnect()))),ie(1));function Ae(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Re(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return ul.pipe($(r=>r.observe(t)),g(r=>Ci.pipe(L(n=>n.target===t),z(()=>r.unobserve(t)))),f(()=>Ae(e)),J(Ae(e)))}function Mr(e){return{width:e.scrollWidth,height:e.scrollHeight}}function Hi(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function $i(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Et(e){return{x:e.offsetLeft,y:e.offsetTop}}function Pi(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function Ii(e){return R(b(window,"load"),b(window,"resize")).pipe(Xe(0,je),f(()=>Et(e)),J(Et(e)))}function fn(e){return{x:e.scrollLeft,y:e.scrollTop}}function Nt(e){return R(b(e,"scroll"),b(window,"scroll"),b(window,"resize")).pipe(Xe(0,je),f(()=>fn(e)),J(fn(e)))}var Ri=new I,pl=j(()=>K(new IntersectionObserver(e=>{for(let t of e)Ri.next(t)},{threshold:0}))).pipe(g(e=>R(Ke,K(e)).pipe(z(()=>e.disconnect()))),ie(1));function Tt(e){return pl.pipe($(t=>t.observe(e)),g(t=>Ri.pipe(L(({target:r})=>r===e),z(()=>t.unobserve(e)),f(({isIntersecting:r})=>r))))}var fl=Object.create,fa=Object.defineProperty,ml=Object.getOwnPropertyDescriptor,dl=Object.getOwnPropertyNames,hl=Object.getPrototypeOf,vl=Object.prototype.hasOwnProperty,bl=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),gl=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of dl(t))!vl.call(e,o)&&o!==r&&fa(e,o,{get:()=>t[o],enumerable:!(n=ml(t,o))||n.enumerable});return e},_l=(e,t,r)=>(r=e!=null?fl(hl(e)):{},gl(t||!e||!e.__esModule?fa(r,"default",{value:e,enumerable:!0}):r,e)),yl=bl((e,t)=>{var r="Expected a function",n=NaN,o="[object Symbol]",i=/^\s+|\s+$/g,a=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,c=/^0o[0-7]+$/i,l=parseInt,u=typeof global=="object"&&global&&global.Object===Object&&global,p=typeof self=="object"&&self&&self.Object===Object&&self,d=u||p||Function("return this")(),m=Object.prototype,h=m.toString,v=Math.max,y=Math.min,E=function(){return d.Date.now()};function T(S,D,ee){var le,ce,Ne,_t,De,lt,tt=0,Yt=!1,kt=!1,vr=!0;if(typeof S!="function")throw new TypeError(r);D=A(D)||0,_(ee)&&(Yt=!!ee.leading,kt="maxWait"in ee,Ne=kt?v(A(ee.maxWait)||0,D):Ne,vr="trailing"in ee?!!ee.trailing:vr);function G(Oe){var yt=le,br=ce;return le=ce=void 0,tt=Oe,_t=S.apply(br,yt),_t}function H(Oe){return tt=Oe,De=setTimeout(V,D),Yt?G(Oe):_t}function C(Oe){var yt=Oe-lt,br=Oe-tt,No=D-yt;return kt?y(No,Ne-br):No}function W(Oe){var yt=Oe-lt,br=Oe-tt;return lt===void 0||yt>=D||yt<0||kt&&br>=Ne}function V(){var Oe=E();if(W(Oe))return Z(Oe);De=setTimeout(V,C(Oe))}function Z(Oe){return De=void 0,vr&&le?G(Oe):(le=ce=void 0,_t)}function We(){De!==void 0&&clearTimeout(De),tt=0,le=lt=ce=De=void 0}function Jt(){return De===void 0?_t:Z(E())}function Nr(){var Oe=E(),yt=W(Oe);if(le=arguments,ce=this,lt=Oe,yt){if(De===void 0)return H(lt);if(kt)return De=setTimeout(V,D),G(lt)}return De===void 0&&(De=setTimeout(V,D)),_t}return Nr.cancel=We,Nr.flush=Jt,Nr}function _(S){var D=typeof S;return!!S&&(D=="object"||D=="function")}function de(S){return!!S&&typeof S=="object"}function be(S){return typeof S=="symbol"||de(S)&&h.call(S)==o}function A(S){if(typeof S=="number")return S;if(be(S))return n;if(_(S)){var D=typeof S.valueOf=="function"?S.valueOf():S;S=_(D)?D+"":D}if(typeof S!="string")return S===0?S:+S;S=S.replace(i,"");var ee=s.test(S);return ee||c.test(S)?l(S.slice(2),ee?2:8):a.test(S)?n:+S}t.exports=T}),En,B,ma,da,Dt,ji,ha,va,ba,fo,oo,io,xl,Ar={},ga=[],wl=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,Pr=Array.isArray;function mt(e,t){for(var r in t)e[r]=t[r];return e}function mo(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function Vt(e,t,r){var n,o,i,a={};for(i in t)i=="key"?n=t[i]:i=="ref"?o=t[i]:a[i]=t[i];if(arguments.length>2&&(a.children=arguments.length>3?En.call(arguments,2):r),typeof e=="function"&&e.defaultProps!=null)for(i in e.defaultProps)a[i]===void 0&&(a[i]=e.defaultProps[i]);return hn(e,a,n,o,null)}function hn(e,t,r,n,o){var i={type:e,props:t,key:r,ref:n,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o!=null?o:++ma,__i:-1,__u:0};return o==null&&B.vnode!=null&&B.vnode(i),i}function dt(e){return e.children}function ct(e,t){this.props=e,this.context=t}function cr(e,t){if(t==null)return e.__?cr(e.__,e.__i+1):null;for(var r;ts&&Dt.sort(va),e=Dt.shift(),s=Dt.length,e.__d&&(r=void 0,n=void 0,o=(n=(t=e).__v).__e,i=[],a=[],t.__P&&((r=mt({},n)).__v=n.__v+1,B.vnode&&B.vnode(r),ho(t.__P,r,n,t.__n,t.__P.namespaceURI,32&n.__u?[o]:null,i,o!=null?o:cr(n),!!(32&n.__u),a),r.__v=n.__v,r.__.__k[r.__i]=r,wa(i,r,a),n.__e=n.__=null,r.__e!=o&&_a(r)));_n.__r=0}function ya(e,t,r,n,o,i,a,s,c,l,u){var p,d,m,h,v,y,E,T=n&&n.__k||ga,_=t.length;for(c=El(r,t,T,c,_),p=0;p<_;p++)(m=r.__k[p])!=null&&(d=m.__i==-1?Ar:T[m.__i]||Ar,m.__i=p,y=ho(e,m,d,o,i,a,s,c,l,u),h=m.__e,m.ref&&d.ref!=m.ref&&(d.ref&&vo(d.ref,null,m),u.push(m.ref,m.__c||h,m)),v==null&&h!=null&&(v=h),(E=!!(4&m.__u))||d.__k===m.__k?c=xa(m,c,e,E):typeof m.type=="function"&&y!==void 0?c=y:h&&(c=h.nextSibling),m.__u&=-7);return r.__e=v,c}function El(e,t,r,n,o){var i,a,s,c,l,u=r.length,p=u,d=0;for(e.__k=new Array(o),i=0;i0?hn(a.type,a.props,a.key,a.ref?a.ref:null,a.__v):a).__=e,a.__b=e.__b+1,s=null,(l=a.__i=Tl(a,r,c,p))!=-1&&(p--,(s=r[l])&&(s.__u|=2)),s==null||s.__v==null?(l==-1&&(o>u?d--:oc?d--:d++,a.__u|=4))):e.__k[i]=null;if(p)for(i=0;i(u?1:0)){for(o=r-1,i=r+1;o>=0||i=0?o--:i++])!=null&&!(2&l.__u)&&s==l.key&&c==l.type)return a}return-1}function Ui(e,t,r){t[0]=="-"?e.setProperty(t,r!=null?r:""):e[t]=r==null?"":typeof r!="number"||wl.test(t)?r:r+"px"}function mn(e,t,r,n,o){var i,a;e:if(t=="style")if(typeof r=="string")e.style.cssText=r;else{if(typeof n=="string"&&(e.style.cssText=n=""),n)for(t in n)r&&t in r||Ui(e.style,t,"");if(r)for(t in r)n&&r[t]==n[t]||Ui(e.style,t,r[t])}else if(t[0]=="o"&&t[1]=="n")i=t!=(t=t.replace(ba,"$1")),a=t.toLowerCase(),t=a in e||t=="onFocusOut"||t=="onFocusIn"?a.slice(2):t.slice(2),e.l||(e.l={}),e.l[t+i]=r,r?n?r.u=n.u:(r.u=fo,e.addEventListener(t,i?io:oo,i)):e.removeEventListener(t,i?io:oo,i);else{if(o=="http://www.w3.org/2000/svg")t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(t!="width"&&t!="height"&&t!="href"&&t!="list"&&t!="form"&&t!="tabIndex"&&t!="download"&&t!="rowSpan"&&t!="colSpan"&&t!="role"&&t!="popover"&&t in e)try{e[t]=r!=null?r:"";break e}catch(s){}typeof r=="function"||(r==null||r===!1&&t[4]!="-"?e.removeAttribute(t):e.setAttribute(t,t=="popover"&&r==1?"":r))}}function Ni(e){return function(t){if(this.l){var r=this.l[t.type+e];if(t.t==null)t.t=fo++;else if(t.t0?e:Pr(e)?e.map(Ea):mt({},e)}function Ol(e,t,r,n,o,i,a,s,c){var l,u,p,d,m,h,v,y=r.props,E=t.props,T=t.type;if(T=="svg"?o="http://www.w3.org/2000/svg":T=="math"?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),i!=null){for(l=0;l=r.__.length&&r.__.push({}),r.__[e]}function yn(e){return $r=1,Ml(La,e)}function Ml(e,t,r){var n=bo(Hr++,2);if(n.t=e,!n.__c&&(n.__=[r?r(t):La(void 0,t),function(s){var c=n.__N?n.__N[0]:n.__[0],l=n.t(c,s);c!==l&&(n.__N=[l,n.__[1]],n.__c.setState({}))}],n.__c=ve,!ve.__f)){var o=function(s,c,l){if(!n.__c.__H)return!0;var u=n.__c.__H.__.filter(function(d){return!!d.__c});if(u.every(function(d){return!d.__N}))return!i||i.call(this,s,c,l);var p=n.__c.props!==s;return u.forEach(function(d){if(d.__N){var m=d.__[0];d.__=d.__N,d.__N=void 0,m!==d.__[0]&&(p=!0)}}),i&&i.call(this,s,c,l)||p};ve.__f=!0;var i=ve.shouldComponentUpdate,a=ve.componentWillUpdate;ve.componentWillUpdate=function(s,c,l){if(this.__e){var u=i;i=void 0,o(s,c,l),i=u}a&&a.call(this,s,c,l)},ve.shouldComponentUpdate=o}return n.__N||n.__}function ht(e,t){var r=bo(Hr++,3);!Ee.__s&&Sa(r.__H,t)&&(r.__=e,r.u=t,ve.__H.__h.push(r))}function zt(e){return $r=5,ur(function(){return{current:e}},[])}function ur(e,t){var r=bo(Hr++,7);return Sa(r.__H,t)&&(r.__=e(),r.__H=t,r.__h=e),r.__}function kl(e,t){return $r=8,ur(function(){return e},t)}function Al(){for(var e;e=Oa.shift();)if(e.__P&&e.__H)try{e.__H.__h.forEach(vn),e.__H.__h.forEach(so),e.__H.__h=[]}catch(t){e.__H.__h=[],Ee.__e(t,e.__v)}}Ee.__b=function(e){ve=null,Wi&&Wi(e)},Ee.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),Bi&&Bi(e,t)},Ee.__r=function(e){Vi&&Vi(e),Hr=0;var t=(ve=e.__c).__H;t&&(to===ve?(t.__h=[],ve.__h=[],t.__.forEach(function(r){r.__N&&(r.__=r.__N),r.u=r.__N=void 0})):(t.__h.forEach(vn),t.__h.forEach(so),t.__h=[],Hr=0)),to=ve},Ee.diffed=function(e){zi&&zi(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(Oa.push(t)!==1&&Di===Ee.requestAnimationFrame||((Di=Ee.requestAnimationFrame)||Cl)(Al)),t.__H.__.forEach(function(r){r.u&&(r.__H=r.u),r.u=void 0})),to=ve=null},Ee.__c=function(e,t){t.some(function(r){try{r.__h.forEach(vn),r.__h=r.__h.filter(function(n){return!n.__||so(n)})}catch(n){t.some(function(o){o.__h&&(o.__h=[])}),t=[],Ee.__e(n,r.__v)}}),qi&&qi(e,t)},Ee.unmount=function(e){Ki&&Ki(e);var t,r=e.__c;r&&r.__H&&(r.__H.__.forEach(function(n){try{vn(n)}catch(o){t=o}}),r.__H=void 0,t&&Ee.__e(t,r.__v))};var Gi=typeof requestAnimationFrame=="function";function Cl(e){var t,r=function(){clearTimeout(n),Gi&&cancelAnimationFrame(t),setTimeout(e)},n=setTimeout(r,35);Gi&&(t=requestAnimationFrame(r))}function vn(e){var t=ve,r=e.__c;typeof r=="function"&&(e.__c=void 0,r()),ve=t}function so(e){var t=ve;e.__c=e.__(),ve=t}function Sa(e,t){return!e||e.length!==t.length||t.some(function(r,n){return r!==e[n]})}function La(e,t){return typeof t=="function"?t(e):t}function Hl(e,t){for(var r in t)e[r]=t[r];return e}function Yi(e,t){for(var r in e)if(r!=="__source"&&!(r in t))return!0;for(var n in t)if(n!=="__source"&&e[n]!==t[n])return!0;return!1}function Ji(e,t){this.props=e,this.context=t}(Ji.prototype=new ct).isPureReactComponent=!0,Ji.prototype.shouldComponentUpdate=function(e,t){return Yi(this.props,e)||Yi(this.state,t)};var Xi=B.__b;B.__b=function(e){e.type&&e.type.__f&&e.ref&&(e.props.ref=e.ref,e.ref=null),Xi&&Xi(e)};var cw=typeof Symbol<"u"&&Symbol.for&&Symbol.for("react.forward_ref")||3911,$l=B.__e;B.__e=function(e,t,r,n){if(e.then){for(var o,i=t;i=i.__;)if((o=i.__c)&&o.__c)return t.__e==null&&(t.__e=r.__e,t.__k=r.__k),o.__c(e,t)}$l(e,t,r,n)};var Zi=B.unmount;function Ma(e,t,r){return e&&(e.__c&&e.__c.__H&&(e.__c.__H.__.forEach(function(n){typeof n.__c=="function"&&n.__c()}),e.__c.__H=null),(e=Hl({},e)).__c!=null&&(e.__c.__P===r&&(e.__c.__P=t),e.__c.__e=!0,e.__c=null),e.__k=e.__k&&e.__k.map(function(n){return Ma(n,t,r)})),e}function ka(e,t,r){return e&&r&&(e.__v=null,e.__k=e.__k&&e.__k.map(function(n){return ka(n,t,r)}),e.__c&&e.__c.__P===t&&(e.__e&&r.appendChild(e.__e),e.__c.__e=!0,e.__c.__P=r)),e}function ro(){this.__u=0,this.o=null,this.__b=null}function Aa(e){var t=e.__.__c;return t&&t.__a&&t.__a(e)}function dn(){this.i=null,this.l=null}B.unmount=function(e){var t=e.__c;t&&t.__R&&t.__R(),t&&32&e.__u&&(e.type=null),Zi&&Zi(e)},(ro.prototype=new ct).__c=function(e,t){var r=t.__c,n=this;n.o==null&&(n.o=[]),n.o.push(r);var o=Aa(n.__v),i=!1,a=function(){i||(i=!0,r.__R=null,o?o(s):s())};r.__R=a;var s=function(){if(!--n.__u){if(n.state.__a){var c=n.state.__a;n.__v.__k[0]=ka(c,c.__c.__P,c.__c.__O)}var l;for(n.setState({__a:n.__b=null});l=n.o.pop();)l.forceUpdate()}};n.__u++||32&t.__u||n.setState({__a:n.__b=n.__v.__k[0]}),e.then(a,a)},ro.prototype.componentWillUnmount=function(){this.o=[]},ro.prototype.render=function(e,t){if(this.__b){if(this.__v.__k){var r=document.createElement("div"),n=this.__v.__k[0].__c;this.__v.__k[0]=Ma(this.__b,r,n.__O=n.__P)}this.__b=null}var o=t.__a&&Vt(dt,null,e.fallback);return o&&(o.__u&=-33),[Vt(dt,null,t.__a?null:e.children),o]};var Qi=function(e,t,r){if(++r[1]===r[0]&&e.l.delete(t),e.props.revealOrder&&(e.props.revealOrder[0]!=="t"||!e.l.size))for(r=e.i;r;){for(;r.length>3;)r.pop()();if(r[1]Object.freeze({get current(){return t.current}}),[])}var zl=typeof globalThis<"u"&&typeof navigator<"u"&&typeof document<"u";function ql(e,...t){var r;(r=e==null?void 0:e.addEventListener)==null||r.call(e,...t)}function Kl(e,...t){var r;(r=e==null?void 0:e.removeEventListener)==null||r.call(e,...t)}var Bl=(e,t)=>Object.hasOwn(e,t),Gl=()=>!0,Yl=()=>!1;function Jl(e=!1){let t=zt(e),r=kl(()=>t.current,[]);return ht(()=>(t.current=!0,()=>{t.current=!1}),[]),r}function Xl(e,...t){let r=Jl(),n=Ha(t[1]),o=ur(()=>function(...i){r()&&(typeof n.current=="function"?n.current.apply(this,i):typeof n.current.handleEvent=="function"&&n.current.handleEvent.apply(this,i))},[]);ht(()=>{let i=Zl(e)?e.current:e;if(!i)return;let a=t.slice(2);return ql(i,t[0],o,...a),()=>{Kl(i,t[0],o,...a)}},[e,t[0]])}function Zl(e){return e!==null&&typeof e=="object"&&Bl(e,"current")}var Ql=e=>typeof e=="function"?e:typeof e=="string"?t=>t.key===e:e?Gl:Yl,eu=zl?globalThis:null;function $a(e,t,r=[],n={}){let{event:o="keydown",target:i=eu,eventOptions:a}=n,s=Ha(t),c=ur(()=>{let l=Ql(e);return function(u){l(u)&&s.current.call(this,u)}},r);Xl(i,o,c,a)}function Pa(e){var t,r,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var o=e.length;for(t=0;t1)St--;else{for(var e,t=!1;kr!==void 0;){var r=kr;for(kr=void 0,co++;r!==void 0;){var n=r.o;if(r.o=void 0,r.f&=-3,!(8&r.f)&&ja(r))try{r.c()}catch(o){t||(e=o,t=!0)}r=n}}if(co=0,St--,t)throw e}}function nu(e){if(St>0)return e();St++;try{return e()}finally{Tn()}}var se=void 0;function Ia(e){var t=se;se=void 0;try{return e()}finally{se=t}}var kr=void 0,St=0,co=0,xn=0;function Ra(e){if(se!==void 0){var t=e.n;if(t===void 0||t.t!==se)return t={i:0,S:e,p:se.s,n:void 0,t:se,e:void 0,x:void 0,r:t},se.s!==void 0&&(se.s.n=t),se.s=t,e.n=t,32&se.f&&e.S(t),t;if(t.i===-1)return t.i=0,t.n!==void 0&&(t.n.p=t.p,t.p!==void 0&&(t.p.n=t.n),t.p=se.s,t.n=void 0,se.s.n=t,se.s=t),t}}function Ce(e,t){this.v=e,this.i=0,this.n=void 0,this.t=void 0,this.W=t==null?void 0:t.watched,this.Z=t==null?void 0:t.unwatched,this.name=t==null?void 0:t.name}Ce.prototype.brand=ru;Ce.prototype.h=function(){return!0};Ce.prototype.S=function(e){var t=this,r=this.t;r!==e&&e.e===void 0&&(e.x=r,this.t=e,r!==void 0?r.e=e:Ia(function(){var n;(n=t.W)==null||n.call(t)}))};Ce.prototype.U=function(e){var t=this;if(this.t!==void 0){var r=e.e,n=e.x;r!==void 0&&(r.x=n,e.e=void 0),n!==void 0&&(n.e=r,e.x=void 0),e===this.t&&(this.t=n,n===void 0&&Ia(function(){var o;(o=t.Z)==null||o.call(t)}))}};Ce.prototype.subscribe=function(e){var t=this;return Kt(function(){var r=t.value,n=se;se=void 0;try{e(r)}finally{se=n}},{name:"sub"})};Ce.prototype.valueOf=function(){return this.value};Ce.prototype.toString=function(){return this.value+""};Ce.prototype.toJSON=function(){return this.value};Ce.prototype.peek=function(){var e=se;se=void 0;try{return this.value}finally{se=e}};Object.defineProperty(Ce.prototype,"value",{get:function(){var e=Ra(this);return e!==void 0&&(e.i=this.i),this.v},set:function(e){if(e!==this.v){if(co>100)throw new Error("Cycle detected");this.v=e,this.i++,xn++,St++;try{for(var t=this.t;t!==void 0;t=t.x)t.t.N()}finally{Tn()}}}});function Lt(e,t){return new Ce(e,t)}function ja(e){for(var t=e.s;t!==void 0;t=t.n)if(t.S.i!==t.i||!t.S.h()||t.S.i!==t.i)return!0;return!1}function Fa(e){for(var t=e.s;t!==void 0;t=t.n){var r=t.S.n;if(r!==void 0&&(t.r=r),t.S.n=t,t.i=-1,t.n===void 0){e.s=t;break}}}function Ua(e){for(var t=e.s,r=void 0;t!==void 0;){var n=t.p;t.i===-1?(t.S.U(t),n!==void 0&&(n.n=t.n),t.n!==void 0&&(t.n.p=n)):r=t,t.S.n=t.r,t.r!==void 0&&(t.r=void 0),t=n}e.s=r}function Bt(e,t){Ce.call(this,void 0),this.x=e,this.s=void 0,this.g=xn-1,this.f=4,this.W=t==null?void 0:t.watched,this.Z=t==null?void 0:t.unwatched,this.name=t==null?void 0:t.name}Bt.prototype=new Ce;Bt.prototype.h=function(){if(this.f&=-3,1&this.f)return!1;if((36&this.f)==32||(this.f&=-5,this.g===xn))return!0;if(this.g=xn,this.f|=1,this.i>0&&!ja(this))return this.f&=-2,!0;var e=se;try{Fa(this),se=this;var t=this.x();(16&this.f||this.v!==t||this.i===0)&&(this.v=t,this.f&=-17,this.i++)}catch(r){this.v=r,this.f|=16,this.i++}return se=e,Ua(this),this.f&=-2,!0};Bt.prototype.S=function(e){if(this.t===void 0){this.f|=36;for(var t=this.s;t!==void 0;t=t.n)t.S.S(t)}Ce.prototype.S.call(this,e)};Bt.prototype.U=function(e){if(this.t!==void 0&&(Ce.prototype.U.call(this,e),this.t===void 0)){this.f&=-33;for(var t=this.s;t!==void 0;t=t.n)t.S.U(t)}};Bt.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var e=this.t;e!==void 0;e=e.x)e.t.N()}};Object.defineProperty(Bt.prototype,"value",{get:function(){if(1&this.f)throw new Error("Cycle detected");var e=Ra(this);if(this.h(),e!==void 0&&(e.i=this.i),16&this.f)throw this.v;return this.v}});function oa(e,t){return new Bt(e,t)}function Na(e){var t=e.u;if(e.u=void 0,typeof t=="function"){St++;var r=se;se=void 0;try{t()}catch(n){throw e.f&=-2,e.f|=8,go(e),n}finally{se=r,Tn()}}}function go(e){for(var t=e.s;t!==void 0;t=t.n)t.S.U(t);e.x=void 0,e.s=void 0,Na(e)}function ou(e){if(se!==this)throw new Error("Out-of-order effect");Ua(this),se=e,this.f&=-2,8&this.f&&go(this),Tn()}function pr(e,t){this.x=e,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32,this.name=t==null?void 0:t.name}pr.prototype.c=function(){var e=this.S();try{if(8&this.f||this.x===void 0)return;var t=this.x();typeof t=="function"&&(this.u=t)}finally{e()}};pr.prototype.S=function(){if(1&this.f)throw new Error("Cycle detected");this.f|=1,this.f&=-9,Na(this),Fa(this),St++;var e=se;return se=this,ou.bind(this,e)};pr.prototype.N=function(){2&this.f||(this.f|=2,this.o=kr,kr=this)};pr.prototype.d=function(){this.f|=8,1&this.f||go(this)};pr.prototype.dispose=function(){this.d()};function Kt(e,t){var r=new pr(e,t);try{r.c()}catch(o){throw r.d(),o}var n=r.d.bind(r);return n[Symbol.dispose]=n,n}var Da,_o,no,Wa=[];Kt(function(){Da=this.N})();function fr(e,t){B[e]=t.bind(null,B[e]||function(){})}function wn(e){no&&no(),no=e&&e.S()}function Va(e){var t=this,r=e.data,n=au(r);n.value=r;var o=ur(function(){for(var s=t,c=t.__v;c=c.__;)if(c.__c){c.__c.__$f|=4;break}var l=oa(function(){var m=n.value.value;return m===0?0:m===!0?"":m||""}),u=oa(function(){return!Array.isArray(l.value)&&!da(l.value)}),p=Kt(function(){if(this.N=za,u.value){var m=l.value;s.__v&&s.__v.__e&&s.__v.__e.nodeType===3&&(s.__v.__e.data=m)}}),d=t.__$u.d;return t.__$u.d=function(){p(),d.call(this)},[u,l]},[]),i=o[0],a=o[1];return i.value?a.peek():a.value}Va.displayName="ReactiveTextNode";Object.defineProperties(Ce.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:Va},props:{configurable:!0,get:function(){return{data:this}}},__b:{configurable:!0,value:1}});fr("__b",function(e,t){if(typeof t.type=="function"&&typeof window<"u"&&window.__PREACT_SIGNALS_DEVTOOLS__&&window.__PREACT_SIGNALS_DEVTOOLS__.exitComponent(),typeof t.type=="string"){var r,n=t.props;for(var o in n)if(o!=="children"){var i=n[o];i instanceof Ce&&(r||(t.__np=r={}),r[o]=i,n[o]=i.peek())}}e(t)});fr("__r",function(e,t){if(typeof t.type=="function"&&typeof window<"u"&&window.__PREACT_SIGNALS_DEVTOOLS__&&window.__PREACT_SIGNALS_DEVTOOLS__.enterComponent(t),t.type!==dt){wn();var r,n=t.__c;n&&(n.__$f&=-2,(r=n.__$u)===void 0&&(n.__$u=r=(function(o){var i;return Kt(function(){i=this}),i.c=function(){n.__$f|=1,n.setState({})},i})())),_o=n,wn(r)}e(t)});fr("__e",function(e,t,r,n){typeof window<"u"&&window.__PREACT_SIGNALS_DEVTOOLS__&&window.__PREACT_SIGNALS_DEVTOOLS__.exitComponent(),wn(),_o=void 0,e(t,r,n)});fr("diffed",function(e,t){typeof t.type=="function"&&typeof window<"u"&&window.__PREACT_SIGNALS_DEVTOOLS__&&window.__PREACT_SIGNALS_DEVTOOLS__.exitComponent(),wn(),_o=void 0;var r;if(typeof t.type=="string"&&(r=t.__e)){var n=t.__np,o=t.props;if(n){var i=r.U;if(i)for(var a in i){var s=i[a];s!==void 0&&!(a in n)&&(s.d(),i[a]=void 0)}else i={},r.U=i;for(var c in n){var l=i[c],u=n[c];l===void 0?(l=iu(r,c,u,o),i[c]=l):l.o(u,o)}}}e(t)});function iu(e,t,r,n){var o=t in e&&e.ownerSVGElement===void 0,i=Lt(r);return{o:function(a,s){i.value=a,n=s},d:Kt(function(){this.N=za;var a=i.value.value;n[t]!==a&&(n[t]=a,o?e[t]=a:a?e.setAttribute(t,a):e.removeAttribute(t))})}}fr("unmount",function(e,t){if(typeof t.type=="string"){var r=t.__e;if(r){var n=r.U;if(n){r.U=void 0;for(var o in n){var i=n[o];i&&i.d()}}}}else{var a=t.__c;if(a){var s=a.__$u;s&&(a.__$u=void 0,s.d())}}e(t)});fr("__h",function(e,t,r,n){(n<3||n===9)&&(t.__$f|=2),e(t,r,n)});ct.prototype.shouldComponentUpdate=function(e,t){var r=this.__$u,n=r&&r.s!==void 0;for(var o in t)return!0;if(this.__f||typeof this.u=="boolean"&&this.u===!0){var i=2&this.__$f;if(!(n||i||4&this.__$f)||1&this.__$f)return!0}else if(!(n||4&this.__$f)||3&this.__$f)return!0;for(var a in e)if(a!=="__source"&&e[a]!==this.props[a])return!0;for(var s in this.props)if(!(s in e))return!0;return!1};function au(e,t){return yn(function(){return Lt(e,t)})[0]}var su=function(e){queueMicrotask(function(){queueMicrotask(e)})};function cu(){nu(function(){for(var e;e=Wa.shift();)Da.call(e)})}function za(){Wa.push(this)===1&&(B.requestAnimationFrame||su)(cu)}var lo=[0];for(let e=0;e<32;e++)lo.push(lo[e]|1<>>5]>>>e&1}set(e){this.data[e>>>5]|=1<<(e&31)}forEach(e){let t=this.size&31;for(let r=0;r{var r;return(r=t.tags)==null?void 0:r.length})&&(matchMedia("(max-width: 768px)").matches||qa())}function Wt(){Qe.value=He(M({},Qe.value),{hideSearch:!Qe.value.hideSearch})}function qa(){Qe.value=He(M({},Qe.value),{hideFilters:!Qe.value.hideFilters})}function bn(){return Qe.value.selectedItem}function uo(e){Qe.value=He(M({},Qe.value),{selectedItem:e})}function pu(){var e,t;return(t=(e=lr.value)==null?void 0:e.items)!=null?t:[]}function On(){return typeof Se.value.input=="string"?Se.value.input:""}function Ka(e){let t=Ba();e.length&&!t.length?Se.value=He(M({},Se.value),{page:void 0,input:e}):!e.length&&t.length?Se.value=He(M({},Se.value),{page:void 0,input:{type:"operator",data:{operator:"not",operands:[]}}}):Se.value=He(M({},Se.value),{page:void 0,input:e})}function fu(){typeof st.value.pagination.next<"u"&&(Se.value=He(M({},Se.value),{page:st.value.pagination.next}))}function mu(e){let t=Se.value.filter.input;if("type"in t&&t.type==="operator"){for(let r of t.data.operands)if("type"in r&&r.type==="value"&&typeof r.data.value=="string"&&r.data.value===e)return!0}return!1}function Ba(){let e=Se.value.filter.input,t=[];if("type"in e&&e.type==="operator")for(let r of e.data.operands)"type"in r&&r.type==="value"&&typeof r.data.value=="string"&&t.push(r.data.value);return t}function du(e){let t=Se.value.filter.input,r=[];if("type"in t&&t.type==="operator")for(let n of t.data.operands)"type"in n&&n.type==="value"&&typeof n.data.value=="string"&&r.push(n.data.value);if(r.includes(e)){let n=r.indexOf(e);n>-1&&r.splice(n,1)}else r.push(e);Se.value=He(M({},Se.value),{page:void 0,filter:He(M({},Se.value.filter),{input:{type:"operator",data:{operator:"and",operands:r.map(n=>({type:"value",data:{field:"tags",value:n}}))}}})}),Ka(On())}function hu(){return st.value.items}function vu(){return st.value.total}function bu(){var e;for(let t of(e=st.value.aggregations)!=null?e:[])if(t.type==="term")return t.data.value;return[]}function sr(){return Qe.value.hideSearch}function gu(){return Qe.value.hideFilters}function Ga(){var e;return(e=Ya.value.highlight)!=null?e:!1}var Qe=Lt({hideSearch:!0,hideFilters:!0,selectedItem:0}),Ya=Lt({}),lr=Lt(),aa=Lt(),Se=Lt({input:"",filter:{input:{type:"operator",data:{operator:"and",operands:[]}},aggregation:{input:[{type:"term",data:{field:"tags"}}]}}}),st=Lt({items:[],query:{select:{documents:new ia(0),terms:new ia(0)},values:[]},pagination:{total:0}});function _u(e,t,r){for(let n=0;tr&&t(0,o,r,r=i);continue;case 62:e.charCodeAt(r+1)===47?t(2,--o,r,r=i+1):_u(e,r,n)?t(3,o,r,r=i+1):t(1,o++,r,r=i+1)}i>r&&t(0,o,r,i)}function xu(e,t=0,r=e.length){let n=++t;e:for(let l=0;n{let i=[],a=[],{onElement:s,onText:c=wu}=typeof r=="function"?{onElement:r}:r,l=0,u=0;return e(t,(p,d,m,h)=>{if(p===0)i[l++]=c(t,m,h),a[u++]={value:null,depth:d};else if(p&1&&(a[u++]={value:xu(t,m,h),depth:d}),p&2)for(let v=0;u>=0;v++){let{value:y,depth:E}=a[--u];if(E>d)continue;let T=i.slice(l-=v,l+v);i[l++]=s(y,T),u++;break}},n,o),i.slice(0,l)}}function Tu(e){return e.replace(/[&<>]/g,t=>{switch(t.charCodeAt(0)){case 38:return"&";case 60:return"<";case 62:return">"}})}function gn(e){return e.replace(/&(amp|[lg]t);/g,t=>{switch(t.charCodeAt(1)){case 97:return"&";case 108:return"<";case 103:return">"}})}function Ou(e,t){return{start:e.start+t,end:e.end+t,value:e.value}}function Su(e,t,r){return e.slice(t,r)}function Lu(e){let{onHighlight:t,onText:r=Su}=typeof e=="function"?{onHighlight:e}:e;return(n,o,i=0,a=n.length)=>{var l;let s=[],c=(l=o==null?void 0:o.ranges)!=null?l:[];for(let u=0,p=i;ua)break;let m=c[u].end;if(mi&&s.push(r(n,i,d));let{value:h}=c[u];s.push(t(n,{start:d,end:i=m,value:h}))}return i{let o=n.data;switch(o.type){case 1:aa.value=!0;break;case 3:typeof o.data.pagination.prev<"u"?st.value=He(M({},st.value),{pagination:o.data.pagination,items:[...st.value.items,...o.data.items]}):(st.value=o.data,uo(0));break}},Kt(()=>{lr.value&&r.postMessage({type:0,data:lr.value})}),Kt(()=>{aa.value&&r.postMessage({type:2,data:Se.value})})}var sa={container:"p",hidden:"m"};function $u(e){return q("div",{class:qt(sa.container,{[sa.hidden]:e.hidden}),onClick:()=>Wt()})}var ca={container:"r",disabled:"c"};function po(e){return q("button",{class:qt(ca.container,{[ca.disabled]:!e.onClick}),onClick:e.onClick,children:e.children})}var la=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),Pu=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(t,r,n)=>n?n.toUpperCase():r.toLowerCase()),ua=e=>{let t=Pu(e);return t.charAt(0).toUpperCase()+t.slice(1)},Iu=(...e)=>e.filter((t,r,n)=>!!t&&t.trim()!==""&&n.indexOf(t)===r).join(" ").trim(),Ru={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},ju=c=>{var l=c,{color:e="currentColor",size:t=24,strokeWidth:r=2,absoluteStrokeWidth:n,children:o,iconNode:i,class:a=""}=l,s=gr(l,["color","size","strokeWidth","absoluteStrokeWidth","children","iconNode","class"]);return Vt("svg",M(He(M({},Ru),{width:String(t),height:t,stroke:e,"stroke-width":n?Number(r)*24/Number(t):r,class:["lucide",a].join(" ")}),s),[...i.map(([u,p])=>Vt(u,p)),...Cr(o)])},yo=(e,t)=>{let r=a=>{var s=a,{class:n="",children:o}=s,i=gr(s,["class","children"]);return Vt(ju,He(M({},i),{iconNode:t,class:Iu(`lucide-${la(ua(e))}`,`lucide-${la(e)}`,n)}),o)};return r.displayName=ua(e),r},Fu=yo("corner-down-left",[["path",{d:"M20 4v7a4 4 0 0 1-4 4H4",key:"6o5b7l"}],["path",{d:"m9 10-5 5 5 5",key:"1kshq7"}]]),Uu=yo("list-filter",[["path",{d:"M2 5h20",key:"1fs1ex"}],["path",{d:"M6 12h12",key:"8npq4p"}],["path",{d:"M9 19h6",key:"456am0"}]]),Nu=yo("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]),lw=_l(yl(),1);function Du({threshold:e=0,root:t=null,rootMargin:r="0%",freezeOnceVisible:n=!1,initialIsIntersecting:o=!1,onChange:i}={}){var a;let[s,c]=yn(null),[l,u]=yn(()=>({isIntersecting:o,entry:void 0})),p=zt();p.current=i;let d=((a=l.entry)==null?void 0:a.isIntersecting)&&n;ht(()=>{if(!s||!("IntersectionObserver"in window)||d)return;let v,y=new IntersectionObserver(E=>{let T=Array.isArray(y.thresholds)?y.thresholds:[y.thresholds];E.forEach(_=>{let de=_.isIntersecting&&T.some(be=>_.intersectionRatio>=be);u({isIntersecting:de,entry:_}),p.current&&p.current(de,_),de&&n&&v&&(v(),v=void 0)})},{threshold:e,root:t,rootMargin:r});return y.observe(s),()=>{y.disconnect()}},[s,JSON.stringify(e),t,r,d,n]);let m=zt(null);ht(()=>{var v;!s&&(v=l.entry)!=null&&v.target&&!n&&!d&&m.current!==l.entry.target&&(m.current=l.entry.target,u({isIntersecting:o,entry:void 0}))},[s,l.entry,n,d,o]);let h=[c,!!l.isIntersecting,l.entry];return h.ref=h[0],h.isIntersecting=h[1],h.entry=h[2],h}var pt={container:"n",hidden:"l",content:"u",pop:"d",badge:"y",sidebar:"i",controls:"w",results:"k",loadmore:"z"};function Wu(e){let{isIntersecting:t,ref:r}=Du({threshold:0});ht(()=>{t&&fu()},[t]);let n=zt(null);ht(()=>{n.current&&typeof Se.value.page>"u"&&n.current.scrollTo({top:0,behavior:"smooth"})},[Se.value]);let o=Ba();return q("div",{class:qt(pt.container,{[pt.hidden]:e.hidden}),children:[q("div",{class:pt.content,children:[q("div",{class:pt.controls,children:[q(po,{onClick:Wt,children:q(Nu,{})}),q(zu,{focus:!e.hidden}),q(po,{onClick:qa,children:[q(Uu,{}),o.length>0&&q("span",{class:pt.badge,children:o.length})]})]}),q("div",{class:pt.results,ref:n,children:[q(qu,{keyboard:!e.hidden}),q("div",{class:pt.loadmore,ref:r})]})]}),q("div",{class:qt(pt.sidebar,{[pt.hidden]:gu()}),children:q(Vu,{})})]})}var Ot={container:"X",list:"j",heading:"F",title:"I",item:"o",active:"g",value:"R",count:"q"};function Vu(e){let t=bu();return t.sort((r,n)=>n.node.count-r.node.count),q("div",{class:Ot.container,children:[q("h3",{class:Ot.heading,children:"Filters"}),q("h4",{class:Ot.title,children:"Tags"}),q("ol",{class:Ot.list,children:t.map(r=>q("li",{class:qt(Ot.item,{[Ot.active]:mu(r.node.value)}),onClick:()=>du(r.node.value),children:[q("span",{class:Ot.value,children:r.node.value}),q("span",{class:Ot.count,children:r.node.count})]}))})]})}var pa={container:"f"};function zu(e){let t=zt(null);return ht(()=>{var r,n;e.focus?(r=t.current)==null||r.focus():(n=t.current)==null||n.blur()},[e.focus]),q("div",{class:pa.container,children:q("input",{ref:t,type:"text",class:pa.content,value:gn(On()),onInput:r=>Ka(Tu(r.currentTarget.value)),autocapitalize:"off",autocomplete:"off",autocorrect:"off",placeholder:"Search",spellcheck:!1,role:"combobox"})})}var ft={container:"b",heading:"A",item:"a",active:"h",wrapper:"B",actions:"s",title:"x",path:"t"};function Za(){let[e,t]=yn(!1);return ht(()=>{let r=()=>t(!0),n=()=>t(!1);return document.addEventListener("compositionstart",r),document.addEventListener("compositionend",n),()=>{document.removeEventListener("compositionstart",r),document.removeEventListener("compositionend",n)}},[]),e}function qu(e){var s;let t=pu(),r=hu(),n=bn(),o=zt([]),i=Za();ht(()=>{let c=o.current[n];c&&c.scrollIntoView({block:"center",behavior:"smooth"})},[n]),$a(e.keyboard,c=>{if(i)return;let l=bn();c.key==="ArrowDown"?(c.preventDefault(),uo(Math.min(l+1,r.length-1))):c.key==="ArrowUp"&&(c.preventDefault(),uo(Math.max(l-1,0)))},[e.keyboard,i]);let a=(s=vu())!=null?s:0;return q(dt,{children:[r.length>0&&q("h3",{class:ft.heading,children:[q("span",{class:ft.bubble,children:new Intl.NumberFormat("en-US").format(a)})," ","results"]}),q("ol",{class:ft.container,children:r.map((c,l)=>{var m;let u=Ja(t[c.id].title,c.matches.find(({field:h})=>h==="title")),p=Hu((m=t[c.id].path)!=null?m:[],c.matches.find(({field:h})=>h==="path")),d=t[c.id].location;if(Ga()){let h=encodeURIComponent(On()),[v,y]=d.split("#",2);d=`${v}?h=${h.replace(/%20/g,"+")}`,typeof y<"u"&&(d+=`#${y}`)}return q("li",{children:q("a",{ref:h=>{o.current[l]=h},href:d,onClick:()=>Wt(),class:qt(ft.item,{[ft.active]:l===bn()}),children:[q("div",{class:ft.wrapper,children:[q("h2",{class:ft.title,children:u}),q("menu",{class:ft.path,children:p.map(h=>q("li",{children:h}))})]}),q("nav",{class:ft.actions,children:q(po,{children:q(Fu,{})})})]})})})})]})}var Ku={container:"e"};function Bu(e){let t=Za();return $a(!0,r=>{var n,o,i,a,s;if(!t)if((r.metaKey||r.ctrlKey)&&r.key==="k")r.preventDefault(),Wt();else if((r.metaKey||r.ctrlKey)&&r.key==="j")document.body.classList.toggle("dark");else if(r.key==="Enter"&&!sr()){r.preventDefault();let c=bn(),l=(o=(n=st.value)==null?void 0:n.items[c])==null?void 0:o.id;if((a=(i=lr.value)==null?void 0:i.items[l])!=null&&a.location){Wt();let u=(s=lr.value)==null?void 0:s.items[l].location;if(Ga()){let p=encodeURIComponent(On()),[d,m]=u.split("#",2);u=`${d}?h=${p.replace(/%20/g,"+")}`,typeof m<"u"&&(u+=`#${m}`)}window.location.href=u}}else r.key==="Escape"&&!sr()&&(r.preventDefault(),Wt())},[t]),q("div",{class:Ku.container,children:[q($u,{hidden:sr()}),q(Wu,{hidden:sr()})]})}function Qa(e,t){uu(e),Ll(q(Bu,{}),t)}function xo(){Wt()}function Gu(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Yu(){return R(b(window,"compositionstart").pipe(f(()=>!0)),b(window,"compositionend").pipe(f(()=>!1))).pipe(J(!1))}function es(){let e=b(window,"keydown").pipe(f(t=>({mode:sr()?"global":"search",type:t.key,meta:t.ctrlKey||t.metaKey,claim(){t.preventDefault(),t.stopPropagation()}})),L(({mode:t,type:r})=>{if(t==="global"){let n=xt();if(typeof n!="undefined")return!Gu(n,r)}return!0}),xe());return Yu().pipe(g(t=>t?x:e))}function Ge(){return new URL(location.href)}function vt(e,t=!1){if(X("navigation.instant")&&!t){let r=k("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function ts(){return new I}function rs(){return location.hash.slice(1)}function ns(e){let t=k("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function wo(e){return R(b(window,"hashchange"),e).pipe(f(rs),J(rs()),L(t=>t.length>0),f(decodeURIComponent),ie(1))}function os(e){return wo(e).pipe(f(t=>we(`[id="${t}"]`)),L(t=>typeof t!="undefined"))}function Ir(e){let t=matchMedia(e);return ln(r=>t.addListener(()=>r(t.matches))).pipe(J(t.matches))}function is(){let e=matchMedia("print");return R(b(window,"beforeprint").pipe(f(()=>!0)),b(window,"afterprint").pipe(f(()=>!1))).pipe(J(e.matches))}function Eo(e,t){return e.pipe(g(r=>r?t():x))}function To(e,t){return new F(r=>{let n=new XMLHttpRequest;return n.open("GET",`${e}`),n.responseType="blob",n.addEventListener("load",()=>{n.status>=200&&n.status<300?(r.next(n.response),r.complete()):r.error(new Error(n.statusText))}),n.addEventListener("error",()=>{r.error(new Error("Network error"))}),n.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(n.addEventListener("progress",o=>{var i;if(o.lengthComputable)t.progress$.next(o.loaded/o.total*100);else{let a=(i=n.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(o.loaded/+a*100)}}),t.progress$.next(5)),n.send(),()=>n.abort()})}function et(e,t){return To(e,t).pipe(g(r=>r.text()),f(r=>JSON.parse(r)),ie(1))}function Sn(e,t){let r=new DOMParser;return To(e,t).pipe(g(n=>n.text()),f(n=>r.parseFromString(n,"text/html")),ie(1))}function as(e,t){let r=new DOMParser;return To(e,t).pipe(g(n=>n.text()),f(n=>r.parseFromString(n,"text/xml")),ie(1))}var Oo={drawer:Y("[data-md-toggle=drawer]"),search:Y("[data-md-toggle=search]")};function So(e,t){Oo[e].checked!==t&&Oo[e].click()}function Ln(e){let t=Oo[e];return b(t,"change").pipe(f(()=>t.checked),J(t.checked))}function ss(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function cs(){return R(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(f(ss),J(ss()))}function ls(){return{width:innerWidth,height:innerHeight}}function us(){return b(window,"resize",{passive:!0}).pipe(f(ls),J(ls()))}function ps(){return re([cs(),us()]).pipe(f(([e,t])=>({offset:e,size:t})),ie(1))}function Mn(e,{viewport$:t,header$:r}){let n=t.pipe(fe("size")),o=re([n,r]).pipe(f(()=>Et(e)));return re([r,t,o]).pipe(f(([{height:i},{offset:a,size:s},{x:c,y:l}])=>({offset:{x:a.x-c,y:a.y-l+i},size:s})))}var Ju=Y("#__config"),mr=JSON.parse(Ju.textContent);mr.base=`${new URL(mr.base,Ge())}`;function Ue(){return mr}function X(e){return mr.features.includes(e)}function Gt(e,t){return typeof t!="undefined"?mr.translations[e].replace("#",t.toString()):mr.translations[e]}function bt(e,t=document){return Y(`[data-md-component=${e}]`,t)}function Te(e,t=document){return P(`[data-md-component=${e}]`,t)}function Xu(e){let t=Y(".md-typeset > :first-child",e);return b(t,"click",{once:!0}).pipe(f(()=>Y(".md-typeset",e)),f(r=>({hash:__md_hash(r.innerHTML)})))}function fs(e){if(!X("announce.dismiss")||!e.childElementCount)return x;if(!e.hidden){let t=Y(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return j(()=>{let t=new I;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),Xu(e).pipe($(r=>t.next(r)),z(()=>t.complete()),f(r=>M({ref:e},r)))})}function Zu(e,{target$:t}){return t.pipe(f(r=>({hidden:r!==e})))}function ms(e,t){let r=new I;return r.subscribe(({hidden:n})=>{e.hidden=n}),Zu(e,t).pipe($(n=>r.next(n)),z(()=>r.complete()),f(n=>M({ref:e},n)))}function Lo(e,t){return t==="inline"?k("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},k("div",{class:"md-tooltip__inner md-typeset"})):k("div",{class:"md-tooltip",id:e,role:"tooltip"},k("div",{class:"md-tooltip__inner md-typeset"}))}function kn(...e){return k("div",{class:"md-tooltip2",role:"dialog"},k("div",{class:"md-tooltip2__inner md-typeset"},e))}function ds(...e){return k("div",{class:"md-tooltip2",role:"tooltip"},k("div",{class:"md-tooltip2__inner md-typeset"},e))}function hs(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return k("aside",{class:"md-annotation",tabIndex:0},Lo(t),k("a",{href:r,class:"md-annotation__index",tabIndex:-1},k("span",{"data-md-annotation-id":e})))}else return k("aside",{class:"md-annotation",tabIndex:0},Lo(t),k("span",{class:"md-annotation__index",tabIndex:-1},k("span",{"data-md-annotation-id":e})))}function vs(e){return k("button",{class:"md-code__button",title:Gt("clipboard.copy"),"data-clipboard-target":`#${e} > code`,"data-md-type":"copy"})}function bs(){return k("button",{class:"md-code__button",title:"Toggle line selection","data-md-type":"select"})}function gs(){return k("nav",{class:"md-code__nav"})}var tp=_r(Mo());function ys(e){return k("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>k("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?ki(r):r)))}function ko(e){let t=`tabbed-control tabbed-control--${e}`;return k("div",{class:t,hidden:!0},k("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function xs(e){return k("div",{class:"md-typeset__scrollwrap"},k("div",{class:"md-typeset__table"},e))}function rp(e){var n;let t=Ue(),r=new URL(`../${e.version}/`,t.base);return k("li",{class:"md-version__item"},k("a",{href:`${r}`,class:"md-version__link"},e.title,((n=t.version)==null?void 0:n.alias)&&e.aliases.length>0&&k("span",{class:"md-version__alias"},e.aliases[0])))}function ws(e,t){var n;let r=Ue();return e=e.filter(o=>{var i;return!((i=o.properties)!=null&&i.hidden)}),k("div",{class:"md-version"},k("button",{class:"md-version__current","aria-label":Gt("select.version")},t.title,((n=r.version)==null?void 0:n.alias)&&t.aliases.length>0&&k("span",{class:"md-version__alias"},t.aliases[0])),k("ul",{class:"md-version__list"},e.map(rp)))}var np=0;function op(e,t=250){let r=re([ar(e),Ut(e,t)]).pipe(f(([o,i])=>o||i),ae()),n=j(()=>$i(e)).pipe(oe(Nt),Lr(1),Ze(r),f(()=>Pi(e)));return r.pipe(Or(o=>o),g(()=>re([r,n])),f(([o,i])=>({active:o,offset:i})),xe())}function Rr(e,t,r=250){let{content$:n,viewport$:o}=t,i=`__tooltip2_${np++}`;return j(()=>{let a=new I,s=new Wn(!1);a.pipe(he(),ye(!1)).subscribe(s);let c=s.pipe(Tr(u=>Ve(+!u*250,qn)),ae(),g(u=>u?n:x),$(u=>u.id=i),xe());re([a.pipe(f(({active:u})=>u)),c.pipe(g(u=>Ut(u,250)),J(!1))]).pipe(f(u=>u.some(p=>p))).subscribe(s);let l=s.pipe(L(u=>u),pe(c,o),f(([u,p,{size:d}])=>{let m=e.getBoundingClientRect(),h=m.width/2;if(p.role==="tooltip")return{x:h,y:8+m.height};if(m.y>=d.height/2){let{height:v}=Ae(p);return{x:h,y:-16-v}}else return{x:h,y:16+m.height}}));return re([c,a,l]).subscribe(([u,{offset:p},d])=>{u.style.setProperty("--md-tooltip-host-x",`${p.x}px`),u.style.setProperty("--md-tooltip-host-y",`${p.y}px`),u.style.setProperty("--md-tooltip-x",`${d.x}px`),u.style.setProperty("--md-tooltip-y",`${d.y}px`),u.classList.toggle("md-tooltip2--top",d.y<0),u.classList.toggle("md-tooltip2--bottom",d.y>=0)}),s.pipe(L(u=>u),pe(c,(u,p)=>p),L(u=>u.role==="tooltip")).subscribe(u=>{let p=Ae(Y(":scope > *",u));u.style.setProperty("--md-tooltip-width",`${p.width}px`),u.style.setProperty("--md-tooltip-tail","0px")}),s.pipe(ae(),Ie(je),pe(c)).subscribe(([u,p])=>{p.classList.toggle("md-tooltip2--active",u)}),re([s.pipe(L(u=>u)),c]).subscribe(([u,p])=>{p.role==="dialog"?(e.setAttribute("aria-controls",i),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",i)}),s.pipe(L(u=>!u)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),op(e,r).pipe($(u=>a.next(u)),z(()=>a.complete()),f(u=>M({ref:e},u)))})}function Ye(e,{viewport$:t},r=document.body){return Rr(e,{content$:new F(n=>{let o=e.title,i=ds(o);return n.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",o)}}),viewport$:t},0)}function ip(e,t){let r=j(()=>re([Ii(e),Nt(t)])).pipe(f(([{x:n,y:o},i])=>{let{width:a,height:s}=Ae(e);return{x:n-i.x+a/2,y:o-i.y+s/2}}));return ar(e).pipe(g(n=>r.pipe(f(o=>({active:n,offset:o})),Me(+!n||1/0))))}function Es(e,t,{target$:r}){let[n,o]=Array.from(e.children);return j(()=>{let i=new I,a=i.pipe(he(),ye(!0));return i.subscribe({next({offset:s}){e.style.setProperty("--md-tooltip-x",`${s.x}px`),e.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),Tt(e).pipe(Q(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),R(i.pipe(L(({active:s})=>s)),i.pipe(Be(250),L(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(n):n.remove()},complete(){e.prepend(n)}}),i.pipe(Xe(16,je)).subscribe(({active:s})=>{n.classList.toggle("md-tooltip--active",s)}),i.pipe(Lr(125,je),L(()=>!!e.offsetParent),f(()=>e.offsetParent.getBoundingClientRect()),f(({x:s})=>s)).subscribe({next(s){s?e.style.setProperty("--md-tooltip-0",`${-s}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),b(o,"click").pipe(Q(a),L(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),b(o,"mousedown").pipe(Q(a),pe(i)).subscribe(([s,{active:c}])=>{var l;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(c){s.preventDefault();let u=e.parentElement.closest(".md-annotation");u instanceof HTMLElement?u.focus():(l=xt())==null||l.blur()}}),r.pipe(Q(a),L(s=>s===n),Rt(125)).subscribe(()=>e.focus()),ip(e,t).pipe($(s=>i.next(s)),z(()=>i.complete()),f(s=>M({ref:e},s)))})}function ap(e){let t=Ue();if(e.tagName!=="CODE")return[e];let r=[".c",".c1",".cm"];if(t.annotate){let n=e.closest("[class|=language]");if(n)for(let o of Array.from(n.classList)){if(!o.startsWith("language-"))continue;let[,i]=o.split("-");i in t.annotate&&r.push(...t.annotate[i])}}return P(r.join(", "),e)}function sp(e){let t=[];for(let r of ap(e)){let n=[],o=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=o.nextNode();i;i=o.nextNode())n.push(i);for(let i of n){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,c]=a;if(typeof c=="undefined"){let l=i.splitText(a.index);i=l.splitText(s.length),t.push(l)}else{i.textContent=s,t.push(i);break}}}}return t}function Ts(e,t){t.append(...Array.from(e.childNodes))}function An(e,t,{target$:r,print$:n}){let o=t.closest("[id]"),i=o==null?void 0:o.id,a=new Map;for(let s of sp(t)){let[,c]=s.textContent.match(/\((\d+)\)/);we(`:scope > li:nth-child(${c})`,e)&&(a.set(c,hs(c,i)),s.replaceWith(a.get(c)))}return a.size===0?x:j(()=>{let s=new I,c=s.pipe(he(),ye(!0)),l=[];for(let[u,p]of a)l.push([Y(".md-typeset",p),Y(`:scope > li:nth-child(${u})`,e)]);return n.pipe(Q(c)).subscribe(u=>{e.hidden=!u,e.classList.toggle("md-annotation-list",u);for(let[p,d]of l)u?Ts(p,d):Ts(d,p)}),R(...[...a].map(([,u])=>Es(u,t,{target$:r}))).pipe(z(()=>s.complete()),xe())})}function Os(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Os(t)}}function Ss(e,t){return j(()=>{let r=Os(e);return typeof r!="undefined"?An(r,e,t):x})}var Ms=_r(Co());var cp=0,Ls=R(b(window,"keydown").pipe(f(()=>!0)),R(b(window,"keyup"),b(window,"contextmenu")).pipe(f(()=>!1))).pipe(J(!1),ie(1));function ks(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return ks(t)}}function lp(e){return Re(e).pipe(f(({width:t})=>({scrollable:Mr(e).width>t})),fe("scrollable"))}function As(e,t){let{matches:r}=matchMedia("(hover)"),n=j(()=>{let o=new I,i=o.pipe(Zn(1));o.subscribe(({scrollable:m})=>{m&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=[],s=e.closest("pre"),c=s.closest("[id]"),l=c?c.id:cp++;s.id=`__code_${l}`;let u=[],p=e.closest(".highlight");if(p instanceof HTMLElement){let m=ks(p);if(typeof m!="undefined"&&(p.classList.contains("annotate")||X("content.code.annotate"))){let h=An(m,e,t);u.push(Re(p).pipe(Q(i),f(({width:v,height:y})=>v&&y),ae(),g(v=>v?h:x)))}}let d=P(":scope > span[id]",e);if(d.length&&(e.classList.add("md-code__content"),e.closest(".select")||X("content.code.select")&&!e.closest(".no-select"))){let m=+d[0].id.split("-").pop(),h=bs();a.push(h),X("content.tooltips")&&u.push(Ye(h,{viewport$}));let v=b(h,"click").pipe(Sr(A=>!A,!1),$(()=>h.blur()),xe());v.subscribe(A=>{h.classList.toggle("md-code__button--active",A)});let y=me(d).pipe(oe(A=>Ut(A).pipe(f(S=>[A,S]))));v.pipe(g(A=>A?y:x)).subscribe(([A,S])=>{let D=we(".hll.select",A);if(D&&!S)D.replaceWith(...Array.from(D.childNodes));else if(!D&&S){let ee=document.createElement("span");ee.className="hll select",ee.append(...Array.from(A.childNodes).slice(1)),A.append(ee)}});let E=me(d).pipe(oe(A=>b(A,"mousedown").pipe($(S=>S.preventDefault()),f(()=>A)))),T=v.pipe(g(A=>A?E:x),pe(Ls),f(([A,S])=>{var ee;let D=d.indexOf(A)+m;if(S===!1)return[D,D];{let le=P(".hll",e).map(ce=>d.indexOf(ce.parentElement)+m);return(ee=window.getSelection())==null||ee.removeAllRanges(),[Math.min(D,...le),Math.max(D,...le)]}})),_=wo(x).pipe(L(A=>A.startsWith(`__codelineno-${l}-`)));_.subscribe(A=>{let[,,S]=A.split("-"),D=S.split(":").map(le=>+le-m+1);D.length===1&&D.push(D[0]);for(let le of P(".hll:not(.select)",e))le.replaceWith(...Array.from(le.childNodes));let ee=d.slice(D[0]-1,D[1]);for(let le of ee){let ce=document.createElement("span");ce.className="hll",ce.append(...Array.from(le.childNodes).slice(1)),le.append(ce)}}),_.pipe(Me(1),Ie(ge)).subscribe(A=>{if(A.includes(":")){let S=document.getElementById(A.split(":")[0]);S&&setTimeout(()=>{let D=S,ee=-64;for(;D!==document.body;)ee+=D.offsetTop,D=D.offsetParent;window.scrollTo({top:ee})},1)}});let be=me(P('a[href^="#__codelineno"]',p)).pipe(oe(A=>b(A,"click").pipe($(S=>S.preventDefault()),f(()=>A)))).pipe(Q(i),pe(Ls),f(([A,S])=>{let ee=+Y(`[id="${A.hash.slice(1)}"]`).parentElement.id.split("-").pop();if(S===!1)return[ee,ee];{let le=P(".hll",e).map(ce=>+ce.parentElement.id.split("-").pop());return[Math.min(ee,...le),Math.max(ee,...le)]}}));R(T,be).subscribe(A=>{let S=`#__codelineno-${l}-`;A[0]===A[1]?S+=A[0]:S+=`${A[0]}:${A[1]}`,history.replaceState({},"",S),window.dispatchEvent(new HashChangeEvent("hashchange",{newURL:window.location.origin+window.location.pathname+S,oldURL:window.location.href}))})}if(Ms.default.isSupported()&&(e.closest(".copy")||X("content.code.copy")&&!e.closest(".no-copy"))){let m=vs(s.id);a.push(m),X("content.tooltips")&&u.push(Ye(m,{viewport$}))}if(a.length){let m=gs();m.append(...a),s.insertBefore(m,e)}return lp(e).pipe($(m=>o.next(m)),z(()=>o.complete()),f(m=>M({ref:e},m)),jt(R(...u).pipe(Q(i))))});return X("content.lazy")?Tt(e).pipe(L(o=>o),Me(1),g(()=>n)):n}function up(e,{target$:t,print$:r}){let n=!0;return R(t.pipe(f(o=>o.closest("details:not([open])")),L(o=>e===o),f(()=>({action:"open",reveal:!0}))),r.pipe(L(o=>o||!n),$(()=>n=e.open),f(o=>({action:o?"open":"close"}))))}function Cs(e,t){return j(()=>{let r=new I;return r.subscribe(({action:n,reveal:o})=>{e.toggleAttribute("open",n==="open"),o&&e.scrollIntoView()}),up(e,t).pipe($(n=>r.next(n)),z(()=>r.complete()),f(n=>M({ref:e},n)))})}var Ho;function pp(){return typeof GLightbox=="undefined"||GLightbox instanceof Element?Gn([wt("https://unpkg.com/glightbox@3/dist/js/glightbox.min.js"),Ai("https://unpkg.com/glightbox@3/dist/css/glightbox.min.css")]).pipe(f(()=>{})):K(void 0)}function Hs(e){return Ho||(Ho=pp().pipe(f(()=>new GLightbox(M({touchNavigation:!0,loop:!1,zoomable:!0,draggable:!0,openEffect:"zoom",closeEffect:"zoom",slideEffect:"slide",onOpen:()=>{document.activeElement instanceof HTMLElement&&document.activeElement.blur()}},typeof GLightboxOptions!="undefined"?GLightboxOptions:{}))),ie(1))),Ho.pipe($(t=>t.setElements(e))),Ho.pipe(g(()=>e.map(t=>({ref:t}))))}var $s=0,Ps=new Map;function fp(e){let t=document.createElement("h3");t.innerHTML=e.innerHTML;let r=[t],n=e.nextElementSibling;for(;n&&!(n instanceof HTMLHeadingElement);)r.push(n.cloneNode(!0)),n=n.nextElementSibling;return r}function mp(e,t){for(let r of P("[href], [src]",e))for(let n of["href","src"]){let o=r.getAttribute(n);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){r[n]=new URL(r.getAttribute(n),t).toString();break}}for(let r of P("[name^=__], [for]",e))for(let n of["id","for","name"]){let o=r.getAttribute(n);o&&r.setAttribute(n,`${o}$preview_${$s}`)}return $s++,K(e)}function dp(e){let t=Ps.get(e.toString());return t?K(t):Sn(e).pipe(g(r=>mp(r,e)),f(r=>(Ps.set(e.toString(),r),r)))}function Is(e,t){let{sitemap$:r}=t;if(!(e instanceof HTMLAnchorElement))return x;if(!(X("navigation.instant.preview")||e.hasAttribute("data-preview")))return x;e.removeAttribute("title");let n=re([ar(e),Ut(e).pipe(ke(1))]).pipe(f(([i,a])=>i||a),ae(),L(i=>i));return Pt([r,n]).pipe(g(([i])=>{let a=new URL(e.href);return a.search=a.hash="",i.has(`${a}`)?K(a):x}),g(i=>dp(i)),g(i=>{let a=e.hash?`article [id="${decodeURIComponent(e.hash.slice(1))}"]`:"article h1",s=we(a,i);return typeof s=="undefined"?x:K(fp(s))})).pipe(g(i=>{let a=new F(s=>{let c=kn(...i);return s.next(c),document.body.append(c),()=>c.remove()});return Rr(e,M({content$:a},t))}))}var Rs=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.flowchartTitleText{fill:var(--md-mermaid-label-fg-color)}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel p,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel p{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color)}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}.classDiagramTitleText{fill:var(--md-mermaid-label-fg-color)}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs marker.marker.composition.class path,defs marker.marker.dependency.class path,defs marker.marker.extension.class path{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs marker.marker.aggregation.class path{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}.statediagramTitleText{fill:var(--md-mermaid-label-fg-color)}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}[id^=entity] path,[id^=entity] rect{fill:var(--md-default-bg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs .marker.oneOrMore.er *,defs .marker.onlyOne.er *,defs .marker.zeroOrMore.er *,defs .marker.zeroOrOne.er *{stroke:var(--md-mermaid-edge-color)!important}text:not([class]):last-child{fill:var(--md-mermaid-label-fg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}.actor-line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}[id$=-arrowhead] path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var $o,vp=0;function bp(){return typeof mermaid=="undefined"||mermaid instanceof Element?wt("https://unpkg.com/mermaid@11/dist/mermaid.min.js"):K(void 0)}function js(e){return e.classList.remove("mermaid"),$o||($o=bp().pipe($(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Rs,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),f(()=>{}),ie(1))),$o.subscribe(()=>Vo(null,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${vp++}`,r=k("div",{class:"mermaid"}),n=e.textContent,{svg:o,fn:i}=yield mermaid.render(t,n),a=r.attachShadow({mode:"closed"});a.innerHTML=o,e.replaceWith(r),i==null||i(a)})),$o.pipe(f(()=>({ref:e})))}var Fs=k("table");function Us(e){return e.replaceWith(Fs),Fs.replaceWith(xs(e)),K({ref:e})}function gp(e){let t=e.find(r=>r.checked)||e[0];return R(...e.map(r=>b(r,"change").pipe(f(()=>Y(`label[for="${r.id}"]`))))).pipe(J(Y(`label[for="${t.id}"]`)),f(r=>({active:r})))}function Ns(e,{viewport$:t,target$:r}){let n=Y(".tabbed-labels",e),o=P(":scope > input",e),i=ko("prev");e.append(i);let a=ko("next");return e.append(a),j(()=>{let s=new I,c=s.pipe(he(),ye(!0));re([s,Re(e),Tt(e)]).pipe(Q(c),Xe(1,je)).subscribe({next([{active:l},u]){let p=Et(l),{width:d}=Ae(l);e.style.setProperty("--md-indicator-x",`${p.x}px`),e.style.setProperty("--md-indicator-width",`${d}px`);let m=fn(n);(p.xm.x+u.width)&&n.scrollTo({left:Math.max(0,p.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),re([Nt(n),Re(n)]).pipe(Q(c)).subscribe(([l,u])=>{let p=Mr(n);i.hidden=l.x<16,a.hidden=l.x>p.width-u.width-16}),R(b(i,"click").pipe(f(()=>-1)),b(a,"click").pipe(f(()=>1))).pipe(Q(c)).subscribe(l=>{let{width:u}=Ae(n);n.scrollBy({left:u*l,behavior:"smooth"})}),r.pipe(Q(c),L(l=>o.includes(l))).subscribe(l=>l.click()),n.classList.add("tabbed-labels--linked");for(let l of o){let u=Y(`label[for="${l.id}"]`);u.replaceChildren(k("a",{href:`#${u.htmlFor}`,tabIndex:-1},...Array.from(u.childNodes))),b(u.firstElementChild,"click").pipe(Q(c),L(p=>!(p.metaKey||p.ctrlKey)),$(p=>{p.preventDefault(),p.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${u.htmlFor}`),u.click()})}return X("content.tabs.link")&&s.pipe(ke(1),pe(t)).subscribe(([{active:l},{offset:u}])=>{let p=l.innerText.trim();if(l.hasAttribute("data-md-switching"))l.removeAttribute("data-md-switching");else{let d=e.offsetTop-u.y;for(let h of P("[data-tabs]"))for(let v of P(":scope > input",h)){let y=Y(`label[for="${v.id}"]`);if(y!==l&&y.innerText.trim()===p){y.setAttribute("data-md-switching",""),v.click();break}}window.scrollTo({top:e.offsetTop-d});let m=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([p,...m])])}}),s.pipe(Q(c)).subscribe(()=>{for(let l of P("audio, video",e))l.offsetWidth&&l.autoplay?l.play().catch(()=>{}):l.pause()}),gp(o).pipe($(l=>s.next(l)),z(()=>s.complete()),f(l=>M({ref:e},l)))}).pipe($t(ge))}function Ds(e,t){let{viewport$:r,target$:n,print$:o}=t;return R(...P(".annotate:not(.highlight)",e).map(i=>Ss(i,{target$:n,print$:o})),...P("pre:not(.mermaid) > code",e).map(i=>As(i,{target$:n,print$:o})),...P("a",e).map(i=>Is(i,t)),...P("pre.mermaid",e).map(i=>js(i)),Hs(P(".glightbox",e)),...P("table:not([class])",e).map(i=>Us(i)),...P("details",e).map(i=>Cs(i,{target$:n,print$:o})),...P("[data-tabs]",e).map(i=>Ns(i,{viewport$:r,target$:n})),...P("[title]:not([data-preview])",e).filter(()=>X("content.tooltips")).map(i=>Ye(i,{viewport$:r})),...P(".footnote-ref",e).filter(()=>X("content.footnote.tooltips")).map(i=>Rr(i,{content$:new F(a=>{let s=new URL(i.href).hash.slice(1),c=Array.from(document.getElementById(s).cloneNode(!0).children),l=kn(...c);return a.next(l),document.body.append(l),()=>l.remove()}),viewport$:r})))}function _p(e,{alert$:t}){return t.pipe(g(r=>R(K(!0),K(!1).pipe(Rt(2e3))).pipe(f(n=>({message:r,active:n})))))}function Ws(e,t){let r=Y(".md-typeset",e);return j(()=>{let n=new I;return n.subscribe(({message:o,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=o}),_p(e,t).pipe($(o=>n.next(o)),z(()=>n.complete()),f(o=>M({ref:e},o)))})}function yp({viewport$:e}){if(!X("header.autohide"))return K(!1);let t=e.pipe(f(({offset:{y:o}})=>o),It(2,1),f(([o,i])=>[oMath.abs(i-o.y)>100),f(([,[o]])=>o),ae()),n=Ln("search");return re([e,n]).pipe(f(([{offset:o},i])=>o.y>400&&!i),ae(),g(o=>o?r:K(!1)),J(!1))}function Vs(e,t){return j(()=>re([Re(e),yp(t)])).pipe(f(([{height:r},n])=>({height:r,hidden:n})),ae((r,n)=>r.height===n.height&&r.hidden===n.hidden),ie(1))}function zs(e,{viewport$:t,header$:r,main$:n}){return j(()=>{let o=new I,i=o.pipe(he(),ye(!0));o.pipe(fe("active"),Ze(r)).subscribe(([{active:s},{hidden:c}])=>{e.classList.toggle("md-header--shadow",s&&!c),e.hidden=c});let a=me(P("[title]",e)).pipe(L(()=>X("content.tooltips")),oe(s=>Ye(s,{viewport$:t})));return n.subscribe(o),r.pipe(Q(i),f(s=>M({ref:e},s)),jt(a.pipe(Q(i))))})}function xp(e,{viewport$:t,header$:r}){return Mn(e,{viewport$:t,header$:r}).pipe(f(({offset:{y:n}})=>{let{height:o}=Ae(e);return{active:o>0&&n>=o}}),fe("active"))}function qs(e,t){return j(()=>{let r=new I;r.subscribe({next({active:o}){e.classList.toggle("md-header__title--active",o)},complete(){e.classList.remove("md-header__title--active")}});let n=we(".md-content h1");return typeof n=="undefined"?x:xp(n,t).pipe($(o=>r.next(o)),z(()=>r.complete()),f(o=>M({ref:e},o)))})}function Ks(e,{viewport$:t,header$:r}){let n=r.pipe(f(({height:i})=>i),ae()),o=n.pipe(g(()=>Re(e).pipe(f(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),fe("bottom"))));return re([n,o,t]).pipe(f(([i,{top:a,bottom:s},{offset:{y:c},size:{height:l}}])=>(l=Math.max(0,l-Math.max(0,a-c,i)-Math.max(0,l+c-s)),{offset:a-i,height:l,active:a-i<=c})),ae((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function wp(e){let t=__md_get("__palette")||{index:e.findIndex(n=>matchMedia(n.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return K(...e).pipe(oe(n=>b(n,"change").pipe(f(()=>n))),J(e[r]),f(n=>({index:e.indexOf(n),color:{media:n.getAttribute("data-md-color-media"),scheme:n.getAttribute("data-md-color-scheme"),primary:n.getAttribute("data-md-color-primary"),accent:n.getAttribute("data-md-color-accent")}})),ie(1))}function Bs(e){let t=P("input",e),r=k("meta",{name:"theme-color"});document.head.appendChild(r);let n=k("meta",{name:"color-scheme"});document.head.appendChild(n);let o=Ir("(prefers-color-scheme: light)");return j(()=>{let i=new I;return i.subscribe(a=>{if(document.body.setAttribute("data-md-color-switching",""),a.color.media==="(prefers-color-scheme)"){let s=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(s.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");a.color.scheme=c.getAttribute("data-md-color-scheme"),a.color.primary=c.getAttribute("data-md-color-primary"),a.color.accent=c.getAttribute("data-md-color-accent")}for(let[s,c]of Object.entries(a.color))document.body.setAttribute(`data-md-color-${s}`,c);for(let s=0;sa.key==="Enter"),pe(i,(a,s)=>s)).subscribe(({index:a})=>{a=(a+1)%t.length,t[a].click(),t[a].focus()}),i.pipe(f(()=>{let a=bt("header"),s=window.getComputedStyle(a);return n.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(a=>r.content=`#${a}`),i.pipe(Ie(ge)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),wp(t).pipe(Q(o.pipe(ke(1))),Ft(),$(a=>i.next(a)),z(()=>i.complete()),f(a=>M({ref:e},a)))})}function Gs(e,{progress$:t}){return j(()=>{let r=new I;return r.subscribe(({value:n})=>{e.style.setProperty("--md-progress-value",`${n}`)}),t.pipe($(n=>r.next({value:n})),z(()=>r.complete()),f(n=>({ref:e,value:n})))})}var Ys='.v u{text-decoration:underline!important;text-decoration-style:wavy!important;text-decoration-thickness:1px!important}.p{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background-color:rgba(var(--color-backdrop)/var(--alpha-lighter));cursor:pointer;height:100%;pointer-events:auto;position:absolute;transition:opacity .25s;width:100%}.p.m{opacity:0;pointer-events:none;transition:opacity .35s}.r{align-items:center;background-color:initial;border:none;border-radius:var(--space-2);cursor:pointer;display:flex;flex-shrink:0;font-family:var(--font-family);height:36px;justify-content:center;outline:none;padding:0;position:relative;transition:background-color .25s,color .25s;width:36px;z-index:1}.r svg{stroke:rgb(var(--color-foreground));height:18px;opacity:.5;width:18px}.r:before{background-color:rgb(var(--color-background-subtle));border-radius:var(--border-radius-2);content:"";inset:0;opacity:0;position:absolute;transform:scale(.75);transition:transform 125ms,opacity 125ms;z-index:0}.r:hover:before{opacity:1;transform:scale(1)}.r.c{cursor:auto}.r.c:before{display:none}.n{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background-color:rgba(var(--color-background)/var(--alpha-light));border-radius:var(--space-3);box-shadow:0 0 60px #0000000d;display:flex;height:480px;overflow:hidden;pointer-events:auto;position:absolute;transition:transform .25s cubic-bezier(.16,1,.3,1),opacity .25s;width:640px}.n.l{opacity:0;pointer-events:none;transform:scale(1.1);transition:transform .25s .15s,opacity .15s}@media (max-width:680px){.n{border-radius:0;height:100%;width:100%}}.u{display:flex;flex-basis:min-content;flex-direction:column;flex-grow:1;flex-shrink:0}@keyframes d{0%{transform:scale(0)}50%{transform:scale(1.2)}to{transform:scale(1)}}.y{animation:d .25s ease-in-out;background:var(--color-highlight);border-radius:100%;color:#fff;font-size:8px;font-weight:700;height:12px;padding-top:1px;position:absolute;right:4px;top:4px;width:12px}.i{background-color:rgb(var(--color-background-subtle)/var(--alpha-lighter));flex-shrink:0;overflow:scroll;position:relative;transition:width .35s cubic-bezier(.16,1,.3,1),opacity .25s;width:200px}.i>*{transform:translate(0);transition:transform .25s cubic-bezier(.16,1,.3,1)}.i.l{opacity:0;width:0}.i.l>*{transform:translate(-48px)}@media (max-width:680px){.i{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background-color:rgba(var(--color-background-subtle)/var(--alpha-light));box-shadow:0 0 60px #00000026;height:100%;position:absolute;right:0;top:0}}.w{border-bottom:1px solid rgb(var(--color-foreground)/var(--alpha-lightest));display:flex;gap:var(--space-1);padding:var(--space-2)}.k{-webkit-overflow-scrolling:touch;overflow:auto;overscroll-behavior:contain}.z{padding:8px 10px}.X{color:rgb(var(--color-foreground)/var(--alpha-light));padding:var(--space-2);position:absolute;width:200px}.X,.j{display:flex;flex-direction:column}.j{gap:2px;list-style:none;padding:0}.F,.j{margin:0}.F{font-size:16px;font-weight:400}.F,.I{padding:8px}.I{font-size:14px;margin:4px 0 0;opacity:.5}.I,.o{font-size:12px}.o{cursor:pointer;display:flex;padding:4px 8px;position:relative}.o:before{background-color:var(--color-highlight-transparent);border-radius:var(--space-1);content:"";inset:0;opacity:0;position:absolute;transform:scale(.75);transition:transform 125ms,opacity 125ms;z-index:0}.o.g:before,.o:hover:before{opacity:1;transform:scale(1)}.o.g,.o:hover{color:var(--color-highlight)}.R{flex-grow:1}.R,.q{position:relative}.q{font-weight:700}.f{flex-grow:1}.f input{background:#0000;border:none;color:rgb(var(--color-foreground));font-family:var(--font-family);font-size:16px;height:100%;letter-spacing:-.25px;outline:none;width:100%}.b{color:rgb(var(--color-foreground)/var(--alpha-light));display:flex;flex-direction:column;gap:2px;line-height:1.3;list-style:none;margin:var(--space-2);margin-top:0;padding:0}.A,.b li{margin:0}.A{color:rgb(var(--color-foreground)/var(--alpha-lighter));font-size:12px;margin-top:var(--space-2);padding:0 18px}.a{border-radius:var(--space-2);color:inherit;cursor:pointer;display:flex;flex-direction:row;flex-grow:1;padding:8px 10px;position:relative;text-decoration:none}.a:before{background-color:rgb(var(--color-background-subtle));border-radius:var(--border-radius-2);content:"";display:block;inset:0;opacity:0;position:absolute;transform:scale(.9);transition:transform 125ms,opacity 125ms;z-index:0}@media (pointer:fine){.a.h:before,.a:hover:before{opacity:1;transform:scale(1)}}.a mark{background:#0000;color:var(--color-highlight)}.a u{background-color:var(--color-highlight-transparent);border-radius:2px;box-shadow:0 0 0 1px var(--color-highlight-transparent);text-decoration:none}.B{flex-grow:1}.s{margin-right:-8px;opacity:0;position:relative;transform:translate(-2px);transition:transform 125ms,opacity 125ms;z-index:0}@media (pointer:fine){.h>.s,:hover>.s{opacity:1;transform:none}}.x{font-size:14px;margin:0;position:relative}.x code{background:rgb(var(--color-background-subtle));border-radius:var(--space-1);font-size:13px;padding:2px 4px}.t{color:rgb(var(--color-foreground)/var(--alpha-lighter));display:inline-flex;flex-wrap:wrap;font-size:12px;gap:var(--space-1);list-style:none;margin:0;padding:0;position:relative}.t li{white-space:nowrap}.t li:after{content:"/";display:inline;margin-left:var(--space-1)}.t li:last-child:after{content:"";display:none}.e{--space-1:4px;--space-2:calc(var(--space-1)*2);--space-3:calc(var(--space-2)*2);--space-4:calc(var(--space-3)*2);--space-5:calc(var(--space-4)*2);--alpha-light:.7;--alpha-lighter:.54;--alpha-lightest:.1;--color-highlight:var(--md-accent-fg-color,#526cfe);--color-highlight-transparent:var(--md-accent-fg-color--transparent,#526cfe1a);--border-radius-1:var(--space-1);--border-radius-2:var(--space-2);--border-radius-3:calc(var(--space-1) + var(--space-2));--font-family:var(--md-text-font-family,Inter,Roboto Flex,system-ui,sans-serif);--font-size:16px;--line-height:1.5;--letter-spacing:-.5px;-webkit-font-smoothing:antialiased;align-items:center;display:flex;font-family:var(--font-family);font-size:var(--font-size);height:100vh;justify-content:center;letter-spacing:var(--letter-spacing);line-height:var(--line-height);pointer-events:none;position:absolute;width:100vw}@media (pointer:coarse){.e{height:-webkit-fill-available}}.e *,.e :after,.e :before{box-sizing:border-box}';function Js(e,{index$:t}){let r=Ue(),n=document.createElement("div");document.body.appendChild(n),n.style.position="fixed",n.style.height="100%",n.style.top="0",n.style.zIndex="4";let o=n.attachShadow({mode:"open"});o.appendChild(k("style",{},Ys.toString()));try{Xa(r.search,{highlight:r.features.includes("search.highlight")}),me(t).subscribe(i=>{for(let a of i.items)a.location=new URL(`./${a.location}`,r.base).toString();Qa(i,o)}),b(e,"click").subscribe(()=>{xo()}),Ln("search").pipe(ke(1)).subscribe(()=>xo())}catch(i){e.hidden=!0;let a=Y("label[for=__search]");a.hidden=!0}return Ke}var Xs=_r(Mo());function Zs(e,{index$:t,location$:r}){return re([t,r.pipe(J(Ge()),L(n=>!!n.searchParams.get("h")))]).pipe(f(([n,o])=>Tp(n.config)(o.searchParams.get("h"))),f(n=>{var a;let o=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let c=s.textContent,l=n(c);l.length>c.length&&o.set(s,l)}for(let[s,c]of o){let{childNodes:l}=k("span",null,c);s.replaceWith(...Array.from(l))}return{ref:e,nodes:o}}))}function Tp(e){let t=e.separator.split("|").map(o=>o.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":o).join("|"),r=new RegExp(t,"img"),n=(o,i,a)=>`${i}${a}`;return o=>{o=o.replace(/\s+/g," ").replace(/&/g,"&").trim();let i=new RegExp(`(^|${e.separator}|)(${o.split(r).map(a=>a.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&")).filter(a=>a.length>0).join("|")})`,"img");return a=>(0,Xs.default)(a).replace(i,n).replace(/<\/mark>(\s+)]*>/img,"$1")}}function Op(e,{viewport$:t,main$:r}){let n=e.closest(".md-grid"),o=n.offsetTop-n.parentElement.offsetTop;return re([r,t]).pipe(f(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(o,Math.max(0,s-i))-o,{height:a,locked:s>=i+o})),ae((i,a)=>i.height===a.height&&i.locked===a.locked))}function Po(e,n){var o=n,{header$:t}=o,r=gr(o,["header$"]);let i=Y(".md-sidebar__scrollwrap",e),{y:a}=Et(i);return j(()=>{let s=new I,c=s.pipe(he(),ye(!0)),l=s.pipe(Xe(0,je));return l.pipe(pe(t)).subscribe({next([{height:u},{height:p}]){i.style.height=`${u-2*a}px`,e.style.top=`${p}px`},complete(){i.style.height="",e.style.top=""}}),l.pipe(Or()).subscribe(()=>{for(let u of P(".md-nav__link--active[href]",e)){if(!u.clientHeight)continue;let p=u.closest(".md-sidebar__scrollwrap");if(typeof p!="undefined"){let d=u.offsetTop-p.offsetTop,{height:m}=Ae(p);p.scrollTo({top:d-m/2})}}}),me(P("label[tabindex]",e)).pipe(oe(u=>b(u,"click").pipe(Ie(ge),f(()=>u),Q(c)))).subscribe(u=>{let p=Y(`[id="${u.htmlFor}"]`);Y(`[aria-labelledby="${u.id}"]`).setAttribute("aria-expanded",`${p.checked}`)}),X("content.tooltips")&&me(P("abbr[title]",e)).pipe(oe(u=>Ye(u,{viewport$})),Q(c)).subscribe(),Op(e,r).pipe($(u=>s.next(u)),z(()=>s.complete()),f(u=>M({ref:e},u)))})}function Qs(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return Pt(et(`${r}/releases/latest`).pipe(_e(()=>x),f(n=>({version:n.tag_name})),at({})),et(r).pipe(_e(()=>x),f(n=>({stars:n.stargazers_count,forks:n.forks_count})),at({}))).pipe(f(([n,o])=>M(M({},n),o)))}else{let r=`https://api.github.com/users/${e}`;return et(r).pipe(f(n=>({repositories:n.public_repos})),at({}))}}function ec(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Pt(et(`${r}/releases/permalink/latest`).pipe(_e(()=>x),f(({tag_name:n})=>({version:n})),at({})),et(r).pipe(_e(()=>x),f(({star_count:n,forks_count:o})=>({stars:n,forks:o})),at({}))).pipe(f(([n,o])=>M(M({},n),o)))}function tc(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,n]=t;return Qs(r,n)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,n]=t;return ec(r,n)}return x}var Sp;function Lp(e){return Sp||(Sp=j(()=>{let t=__md_get("__source",sessionStorage);if(t)return K(t);if(Te("consent").length){let n=__md_get("__consent");if(!(n&&n.github))return x}return tc(e.href).pipe($(n=>__md_set("__source",n,sessionStorage)))}).pipe(_e(()=>x),L(t=>Object.keys(t).length>0),f(t=>({facts:t})),ie(1)))}function rc(e){let t=Y(":scope > :last-child",e);return j(()=>{let r=new I;return r.subscribe(({facts:n})=>{t.appendChild(ys(n)),t.classList.add("md-source__repository--active")}),Lp(e).pipe($(n=>r.next(n)),z(()=>r.complete()),f(n=>M({ref:e},n)))})}function Mp(e,{viewport$:t,header$:r}){return Re(document.body).pipe(g(()=>Mn(e,{header$:r,viewport$:t})),f(({offset:{y:n}})=>({hidden:n>=10})),fe("hidden"))}function nc(e,t){return j(()=>{let r=new I;return r.subscribe({next({hidden:n}){e.hidden=n},complete(){e.hidden=!1}}),(X("navigation.tabs.sticky")?K({hidden:!1}):Mp(e,t)).pipe($(n=>r.next(n)),z(()=>r.complete()),f(n=>M({ref:e},n)))})}function kp(e,{viewport$:t,header$:r}){let n=new Map,o=P(".md-nav__link",e);for(let s of o){let c=decodeURIComponent(s.hash.substring(1)),l=we(`[id="${c}"]`);typeof l!="undefined"&&n.set(s,l)}let i=r.pipe(fe("height"),f(({height:s})=>{let c=bt("main"),l=Y(":scope > :first-child",c);return s+.9*(l.offsetTop-c.offsetTop)}),xe());return Re(document.body).pipe(fe("height"),g(s=>j(()=>{let c=[];return K([...n].reduce((l,[u,p])=>{for(;c.length&&n.get(c[c.length-1]).tagName>=p.tagName;)c.pop();let d=p.offsetTop;for(;!d&&p.parentElement;)p=p.parentElement,d=p.offsetTop;let m=p.offsetParent;for(;m;m=m.offsetParent)d+=m.offsetTop;return l.set([...c=[...c,u]].reverse(),d)},new Map))}).pipe(f(c=>new Map([...c].sort(([,l],[,u])=>l-u))),Ze(i),g(([c,l])=>t.pipe(Sr(([u,p],{offset:{y:d},size:m})=>{let h=d+m.height>=Math.floor(s.height);for(;p.length;){let[,v]=p[0];if(v-l=d&&!h)p=[u.pop(),...p];else break}return[u,p]},[[],[...c]]),ae((u,p)=>u[0]===p[0]&&u[1]===p[1])))))).pipe(f(([s,c])=>({prev:s.map(([l])=>l),next:c.map(([l])=>l)})),J({prev:[],next:[]}),It(2,1),f(([s,c])=>s.prev.length{let i=new I,a=i.pipe(he(),ye(!0));i.subscribe(({prev:c,next:l})=>{for(let[u]of l)u.classList.remove("md-nav__link--passed"),u.classList.remove("md-nav__link--active");for(let[u,[p]]of c.entries())p.classList.add("md-nav__link--passed"),p.classList.toggle("md-nav__link--active",u===c.length-1)});let s=we(".md-sidebar--secondary");if(typeof s!="undefined"&&b(document.body,"click").subscribe(c=>{let l=c.target;if(!s.contains(l)){let u=we(".md-nav__toggle",s);typeof u!="undefined"&&(u.checked=!1)}}),X("toc.follow")){let c=R(t.pipe(Be(1),f(()=>{})),t.pipe(Be(250),f(()=>"smooth")));i.pipe(L(({prev:l})=>l.length>0),Ze(n.pipe(Ie(ge))),pe(c)).subscribe(([[{prev:l}],u])=>{let[p]=l[l.length-1];if(p.offsetHeight){let d=Hi(p);if(typeof d!="undefined"){let m=p.offsetTop-d.offsetTop,{height:h}=Ae(d);d.scrollTo({top:m-h/2,behavior:u})}}})}return X("navigation.tracking")&&t.pipe(Q(a),fe("offset"),Be(250),ke(1),Q(o.pipe(ke(1))),Ft({delay:250}),pe(i)).subscribe(([,{prev:c}])=>{let l=Ge(),u=c[c.length-1];if(u&&u.length){let[p]=u,{hash:d}=new URL(p.href);l.hash!==d&&(l.hash=d,history.replaceState({},"",`${l}`))}else l.hash="",history.replaceState({},"",`${l}`)}),kp(e,{viewport$:t,header$:r}).pipe($(c=>i.next(c)),z(()=>i.complete()),f(c=>M({ref:e},c)))})}function Ap(e,{viewport$:t,main$:r,target$:n}){let o=t.pipe(f(({offset:{y:a}})=>a),It(2,1),f(([a,s])=>a>s&&s>0),ae()),i=r.pipe(f(({active:a})=>a));return re([i,o]).pipe(f(([a,s])=>!(a&&s)),ae(),Q(n.pipe(ke(1))),ye(!0),Ft({delay:250}),f(a=>({hidden:a})))}function ic(e,{viewport$:t,header$:r,main$:n,target$:o}){let i=new I,a=i.pipe(he(),ye(!0));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(Q(a),fe("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),b(e,"click").subscribe(s=>{s.preventDefault(),window.scrollTo({top:0})}),Ap(e,{viewport$:t,main$:n,target$:o}).pipe($(s=>i.next(s)),z(()=>i.complete()),f(s=>M({ref:e},s)))}function ac(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,t.port&&(e.port=t.port),e}function Cp(e,t){let r=new Map;for(let n of P("url",e)){let o=Y("loc",n),i=[ac(new URL(o.textContent),t)];r.set(`${i[0]}`,i);for(let a of P("[rel=alternate]",n)){let s=a.getAttribute("href");s!=null&&i.push(ac(new URL(s),t))}}return r}function dr(e){return as(new URL("sitemap.xml",e)).pipe(f(t=>Cp(t,new URL(e))),_e(()=>K(new Map)),xe())}function sc({document$:e}){let t=new Map;e.pipe(g(()=>P("link[rel=alternate]")),f(r=>new URL(r.href)),L(r=>!t.has(r.toString())),oe(r=>dr(r).pipe(f(n=>[r,n]),_e(()=>x)))).subscribe(([r,n])=>{t.set(r.toString().replace(/\/$/,""),n)}),b(document.body,"click").pipe(L(r=>!r.metaKey&&!r.ctrlKey),g(r=>{if(r.target instanceof Element){let n=r.target.closest("a");if(n&&!n.target){let o=[...t].find(([p])=>n.href.startsWith(`${p}/`));if(typeof o=="undefined")return x;let[i,a]=o,s=Ge();if(s.href.startsWith(i))return x;let c=Ue(),l=s.href.replace(c.base,"");l=`${i}/${l}`;let u=a.has(l.split("#")[0])?new URL(l,c.base):new URL(i);return r.preventDefault(),K(u)}}return x})).subscribe(r=>vt(r,!0))}var Io=_r(Co());function Hp(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function cc({alert$:e}){Io.default.isSupported()&&new F(t=>{new Io.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Hp(Y(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe($(t=>{t.trigger.focus()}),f(()=>Gt("clipboard.copied"))).subscribe(e)}function lc(e,t){if(!(e.target instanceof Element))return x;let r=e.target.closest("a");if(r===null)return x;if(r.target||e.metaKey||e.ctrlKey)return x;let n=new URL(r.href);return n.search=n.hash="",t.has(`${n}`)?(e.preventDefault(),K(r)):x}function uc(e){let t=new Map;for(let r of P(":scope > *",e.head))t.set(r.outerHTML,r);return t}function pc(e){for(let t of P("[href], [src]",e))for(let r of["href","src"]){let n=t.getAttribute(r);if(n&&!/^(?:[a-z]+:)?\/\//i.test(n)){t[r]=t[r];break}}return K(e)}function $p(e){for(let n of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...X("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let o=we(n),i=we(n,e);typeof o!="undefined"&&typeof i!="undefined"&&o.replaceWith(i)}let t=uc(document);for(let[n,o]of uc(e))t.has(n)?t.delete(n):document.head.appendChild(o);for(let n of t.values()){let o=n.getAttribute("name");o!=="theme-color"&&o!=="color-scheme"&&n.remove()}let r=bt("container");return it(P("script",r)).pipe(g(n=>{let o=e.createElement("script");if(n.src){for(let i of n.getAttributeNames())o.setAttribute(i,n.getAttribute(i));return n.replaceWith(o),new F(i=>{o.onload=()=>i.complete()})}else return o.textContent=n.textContent,n.replaceWith(o),x}),he(),ye(document))}function fc({sitemap$:e,location$:t,viewport$:r,progress$:n}){if(location.protocol==="file:")return Ke;K(document).subscribe(pc);let o=b(document.body,"click").pipe(Ze(e),g(([s,c])=>lc(s,c)),f(({href:s})=>new URL(s)),xe()),i=b(window,"popstate").pipe(f(Ge),xe());o.pipe(pe(r)).subscribe(([s,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",s)}),R(o,i).subscribe(t);let a=t.pipe(fe("pathname"),g(s=>Sn(s,{progress$:n}).pipe(_e(()=>(vt(s,!0),x)))),g(pc),g($p),xe());return R(a.pipe(pe(t,(s,c)=>c)),a.pipe(g(()=>t),fe("hash")),t.pipe(ae((s,c)=>s.pathname===c.pathname&&s.hash===c.hash),g(()=>o),$(()=>history.back()))).subscribe(s=>{var c,l;history.state!==null||!s.hash?window.scrollTo(0,(l=(c=history.state)==null?void 0:c.y)!=null?l:0):(history.scrollRestoration="auto",ns(s.hash),history.scrollRestoration="manual")}),t.subscribe(()=>{history.scrollRestoration="manual"}),b(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),r.pipe(fe("offset"),Be(100)).subscribe(({offset:s})=>{history.replaceState(s,"")}),X("navigation.instant.prefetch")&&R(b(document.body,"mousemove"),b(document.body,"focusin")).pipe(Ze(e),g(([s,c])=>lc(s,c)),Be(25),Xn(({href:s})=>s),pn(s=>{let c=document.createElement("link");return c.rel="prefetch",c.href=s.toString(),document.head.appendChild(c),b(c,"load").pipe(f(()=>c),Me(1))})).subscribe(s=>s.remove()),a}function mc(e){var u;let{selectedVersionSitemap:t,selectedVersionBaseURL:r,currentLocation:n,currentBaseURL:o}=e,i=(u=Ro(o))==null?void 0:u.pathname;if(i===void 0)return;let a=Pp(n.pathname,i);if(a===void 0)return;let s=Rp(t.keys());if(!t.has(s))return;let c=Ro(a,s);if(!c||!t.has(c.href))return;let l=Ro(a,r);if(l)return l.hash=n.hash,l.search=n.search,l}function Ro(e,t){try{return new URL(e,t)}catch(r){return}}function Pp(e,t){if(e.startsWith(t))return e.slice(t.length)}function Ip(e,t){let r=Math.min(e.length,t.length),n;for(n=0;nx)),n=r.pipe(f(o=>{let[,i]=t.base.match(/([^/]+)\/?$/);return o.find(({version:a,aliases:s})=>a===i||s.includes(i))||o[0]}));r.pipe(f(o=>new Map(o.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),g(o=>b(document.body,"click").pipe(L(i=>!i.metaKey&&!i.ctrlKey),pe(n),g(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&o.has(s.href)){let c=s.href;return!i.target.closest(".md-version")&&o.get(c)===a?x:(i.preventDefault(),K(new URL(c)))}}return x}),g(i=>dr(i).pipe(f(a=>{var s;return(s=mc({selectedVersionSitemap:a,selectedVersionBaseURL:i,currentLocation:Ge(),currentBaseURL:t.base}))!=null?s:i})))))).subscribe(o=>vt(o,!0)),re([r,n]).subscribe(([o,i])=>{Y(".md-header__topic").appendChild(ws(o,i))}),e.pipe(g(()=>n)).subscribe(o=>{var s;let i=new URL(t.base),a=__md_get("__outdated",sessionStorage,i);if(a===null){a=!0;let c=((s=t.version)==null?void 0:s.default)||"latest";Array.isArray(c)||(c=[c]);e:for(let l of c)for(let u of o.aliases.concat(o.version))if(new RegExp(l,"i").test(u)){a=!1;break e}__md_set("__outdated",a,sessionStorage,i)}if(a)for(let c of Te("outdated"))c.hidden=!1})}function hc({document$:e,viewport$:t}){e.pipe(g(()=>P(".md-ellipsis")),oe(r=>Tt(r).pipe(Q(e.pipe(ke(1))),L(n=>n),f(()=>r),Me(1))),L(r=>r.offsetWidth{let n=r.innerText,o=r.closest("a")||r;return o.title=n,X("content.tooltips")?Ye(o,{viewport$:t}).pipe(Q(e.pipe(ke(1))),z(()=>o.removeAttribute("title"))):x})).subscribe(),X("content.tooltips")&&e.pipe(g(()=>P(".md-status")),oe(r=>Ye(r,{viewport$:t}))).subscribe()}function vc({document$:e,tablet$:t}){e.pipe(g(()=>P(".md-toggle--indeterminate")),$(r=>{r.indeterminate=!0,r.checked=!1}),oe(r=>b(r,"change").pipe(eo(()=>r.classList.contains("md-toggle--indeterminate")),f(()=>r))),pe(t)).subscribe(([r,n])=>{r.classList.remove("md-toggle--indeterminate"),n&&(r.checked=!1)})}function jp(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function bc({document$:e}){e.pipe(g(()=>P("[data-md-scrollfix]")),$(t=>t.removeAttribute("data-md-scrollfix")),L(jp),oe(t=>b(t,"touchstart").pipe(f(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let n=e[r];typeof n=="string"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?t.insertBefore(this.previousSibling,n):t.replaceChild(n,this)}}}));function Fp(){return location.protocol==="file:"?wt(`${new URL("search.js",Cn.base)}`).pipe(f(()=>__index),_e(()=>Ke),ie(1)):et(new URL("search.json",Cn.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var gt=Li(),Ur=ts(),hr=os(Ur),_c=es(),ze=ps(),jo=Ir("(min-width: 60em)"),yc=Ir("(min-width: 76.25em)"),xc=is(),Cn=Ue(),wc=we(".md-search")?Fp():Ke,Fo=new I;cc({alert$:Fo});sc({document$:gt});var Uo=new I,Ec=dr(Cn.base);X("navigation.instant")&&fc({sitemap$:Ec,location$:Ur,viewport$:ze,progress$:Uo}).subscribe(gt);var gc;((gc=Cn.version)==null?void 0:gc.provider)==="mike"&&dc({document$:gt});R(Ur,hr).pipe(Rt(125)).subscribe(()=>{So("drawer",!1),So("search",!1)});_c.pipe(L(({mode:e,meta:t})=>e==="global"&&!t)).subscribe(e=>{switch(e.type){case",":case"p":let t=document.querySelector("link[rel=prev]");t instanceof HTMLLinkElement&&vt(t);break;case".":case"n":let r=document.querySelector("link[rel=next]");r instanceof HTMLLinkElement&&vt(r);break;case"/":let n=document.querySelector("[data-md-component=search] button");n instanceof HTMLButtonElement&&n.click();break;case"Enter":let o=xt();o instanceof HTMLLabelElement&&o.click()}});hc({viewport$:ze,document$:gt});vc({document$:gt,tablet$:jo});bc({document$:gt});var Mt=Vs(bt("header"),{viewport$:ze}),Fr=gt.pipe(f(()=>bt("main")),g(e=>Ks(e,{viewport$:ze,header$:Mt})),ie(1)),Up=R(...Te("consent").map(e=>ms(e,{target$:hr})),...Te("dialog").map(e=>Ws(e,{alert$:Fo})),...Te("palette").map(e=>Bs(e)),...Te("progress").map(e=>Gs(e,{progress$:Uo})),...Te("search").map(e=>Js(e,{index$:wc})),...Te("source").map(e=>rc(e))),Np=j(()=>R(...Te("announce").map(e=>fs(e)),...Te("content").map(e=>Ds(e,{sitemap$:Ec,viewport$:ze,target$:hr,print$:xc})),...Te("content").map(e=>X("search.highlight")?Zs(e,{index$:wc,location$:Ur}):x),...Te("header").map(e=>zs(e,{viewport$:ze,header$:Mt,main$:Fr})),...Te("header-title").map(e=>qs(e,{viewport$:ze,header$:Mt})),...Te("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Eo(yc,()=>Po(e,{viewport$:ze,header$:Mt,main$:Fr})):Eo(jo,()=>Po(e,{viewport$:ze,header$:Mt,main$:Fr}))),...Te("tabs").map(e=>nc(e,{viewport$:ze,header$:Mt})),...Te("toc").map(e=>oc(e,{viewport$:ze,header$:Mt,main$:Fr,target$:hr})),...Te("top").map(e=>ic(e,{viewport$:ze,header$:Mt,main$:Fr,target$:hr})))),Tc=gt.pipe(g(()=>Np),jt(Up),ie(1));Tc.subscribe();window.document$=gt;window.location$=Ur;window.target$=hr;window.keyboard$=_c;window.viewport$=ze;window.tablet$=jo;window.screen$=yc;window.print$=xc;window.alert$=Fo;window.progress$=Uo;window.component$=Tc;})(); diff --git a/src/httpcore2/site-httpcore2/assets/javascripts/workers/search.e2d2d235.min.js b/src/httpcore2/site-httpcore2/assets/javascripts/workers/search.e2d2d235.min.js new file mode 100644 index 00000000..a56d589a --- /dev/null +++ b/src/httpcore2/site-httpcore2/assets/javascripts/workers/search.e2d2d235.min.js @@ -0,0 +1 @@ +"use strict";(()=>{var vt=Object.create;var K=Object.defineProperty,wt=Object.defineProperties,bt=Object.getOwnPropertyDescriptor,Tt=Object.getOwnPropertyDescriptors,Mt=Object.getOwnPropertyNames,W=Object.getOwnPropertySymbols,kt=Object.getPrototypeOf,Y=Object.prototype.hasOwnProperty,Et=Object.prototype.propertyIsEnumerable;var B=(t,e,n)=>e in t?K(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,R=(t,e)=>{for(var n in e||(e={}))Y.call(e,n)&&B(t,n,e[n]);if(W)for(var n of W(e))Et.call(e,n)&&B(t,n,e[n]);return t},Q=(t,e)=>wt(t,Tt(e));var Ft=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Rt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of Mt(e))!Y.call(t,l)&&l!==n&&K(t,l,{get:()=>e[l],enumerable:!(r=bt(e,l))||r.enumerable});return t};var qt=(t,e,n)=>(n=t!=null?vt(kt(t)):{},Rt(e||!t||!t.__esModule?K(n,"default",{value:t,enumerable:!0}):n,t));var L=(t,e,n)=>B(t,typeof e!="symbol"?e+"":e,n);var E=(t,e,n)=>new Promise((r,l)=>{var o=u=>{try{s(n.next(u))}catch(i){l(i)}},a=u=>{try{s(n.throw(u))}catch(i){l(i)}},s=u=>u.done?r(u.value):Promise.resolve(u.value).then(o,a);s((n=n.apply(t,e)).next())});var xt=Ft(mt=>{"use strict";function C(t,e,n={}){return{name:t,from:e,meta:n}}function H(t,e){let n=[{value:t,depth:0}];for(let r=0,l=-1,o=0;r>=0;){let{value:a,depth:s}=n[r];if(l<=s&&a.type==="operator"&&a.data.operands.length>0)for(let u=a.data.operands.length;u>0;)n[++r]={value:a.data.operands[--u],depth:s+1};else{let u=e(a,o++,s);if(typeof u<"u")return u;--r}l=s}}var P=class extends Error{constructor(t,e){super(e),this.code=t}};function $(t,e){let n=zt(t);for(let r=0;r{let{matches:r}=n;for(let l=0;l{let l=e.get(n);return typeof l>"u"&&e.set(n,l=t(n,...r)),l}}function D(t,e){return Object.defineProperty(e,"name",{value:t}),e}function tt(t){return E(this,null,function*(){let e=[];if(typeof t.plugins<"u")for(let n=0;n32)throw new RangeError("Bit format exceeds 32 bits");return t}function nt(t,e,n){let r=N(t),l=N(e),o=typeof n<"u"?N(n):32-r-l;return St({d:r,f:l,x:o})}var T=[0];for(let t=0;t<32;t++)T.push(T[t]|1<=n&&t{e+=r*r}),Math.sqrt(e)}function Pt(t,e){t instanceof J?t.data.forEach((n,r)=>{e(n,r)}):t.forEach((n,r)=>{e({start:n,end:n+1,value:1},r)})}var O=class{constructor(t,e=jt(Math.ceil(t/32))){this.size=t,this.data=e}get(t){return this.data[t>>>5]>>>t&1}set(t){this.data[t>>>5]|=1<<(t&31)}forEach(t){let e=this.size&31;for(let n=0;n>>0;for(let n=0;n0;l++){let{value:o,depth:a}=n[--r],s=e(o,l,a);if(typeof s<"u")return s;for(let u=o.children.length;u>0;)n[r++]={value:o.children[--u],depth:a+1}}}function Vt(t,e){return E(this,null,function*(){let{fields:n,plugins:r=[]}=e,l=nt(t.length,n.length),o=[];for(let u=0;u"u")continue;let f=u<{var m;return(m=g.onFilterInput)==null?void 0:m.call(g,p,f,l)},d);let c=o[i],h=k();d=Array.isArray(d)?d:[d];for(let p=0;p{let v=c.index.get(m.node);typeof v>"u"&&c.index.set(m.node,v=k());let w=c.terms.length;for(let b=0;b{var i;return(i=u.onFilterStore)==null?void 0:i.call(u,s,e,t)}),s})}function Ut(t,e,n,r={}){let l=[];if(e<0||e>=t.count.fields)return l;let o=t.shards[e],a=new Map,{count:s=1/0,depth:u=1/0}=r;for(let i=0;iu)continue;let p=a.get(d);typeof p>"u"&&a.set(d,p={node:f,children:[]});let g=l;h>0&&(g=a.get(o.terms[c]).children),g.length=t.count.fields)return{documents:r,terms:l};let o=t.shards[n];return e.forEach(a=>{let{occurrences:s}=o.terms[a];for(let u=0;u>>t.space.x>>>t.space.f;r.set(i)}l[n].set(a)}),{documents:r,terms:l}}function Bt(t){let{documents:e,terms:n}=U(t);A(e,1);for(let r=0;rnew O(e.length))}}function Kt(t,e,n){let{compiler:r,fields:l,plugins:o=[]}=n,{input:a,scope:s,abort:u=!1}=z(o,(f,c)=>{var h;return(h=c.onFilterQuery)==null?void 0:h.call(c,f,t,n)},e),i={items:[],query:{select:U(t),values:[]}},d=new Map;if(u===!1){let f=r(n),{select:c,values:h}=f(a,t);typeof s<"u"&&V(c.documents,s);let p=new Map;i.query={select:c,values:h},c.terms.forEach((g,m)=>{g.forEach(y=>{let x=t.shards[m],{occurrences:v}=x.terms[y];for(let w=0;w>>t.space.x,F=b>>>t.space.f;if(!c.documents.get(F))continue;let S=p.get(b);typeof S>"u"&&p.set(b,S=new j(k()));let yt=M&T[t.space.x];S.add(yt,y)}})}),c.documents.forEach(g=>{let m={id:g,matches:[]};i.items.push(m),d.set(g,m)}),p.forEach((g,m)=>{let y=m>>>t.space.f,x=m&T[t.space.f];d.get(y).matches.push({id:m,field:l[x].name,value:{filter:g},score:0})})}return z(o,(f,c)=>{var h;return(h=c.onFilterResult)==null?void 0:h.call(c,f,t,n)},i)}function st(t){let{fields:e}=t;return(n,r)=>{if(It(n))return n;let l=[Bt(r)],o=[],a=0;return H(n,({type:s,data:u})=>{switch(s){case"value":let i=e.findIndex(({name:c})=>c===u.field);if(i===-1){l[a++]=U(r);break}let d=u.value;if(typeof d!="object"){let c=new j(k()),h=r.shards[i],p=h.index.get(d);if(typeof p<"u")for(let g=0;gf+1&&a--;){I(l[f].documents,l[a].documents);for(let c=0;cf+1&&a--;){V(l[f].documents,l[a].documents);for(let c=0;cf+1&&a--;)lt(l[f].documents,l[a].documents)}}}),{select:l[0],values:o}}}function Lt(t){return{name:t.name,data:t.data,onFilterOptions:t.onFilterOptions,onFilterInput:t.onFilterInput,onFilterStore:t.onFilterStore,onFilterQuery:t.onFilterQuery,onFilterResult:t.onFilterResult}}function ot(t){return typeof t=="object"&&t!==null&&"type"in t&&"data"in t}function Nt(t){return typeof t=="object"&&t!==null&&"select"in t&&"values"in t}function Gt(t){return t.normalize("NFKD").toLowerCase()}function Ht(t,e){let n=Math.min(t.length,e.length);for(let r=0;r65535)){let o=e(l=t.codePointAt(n),n);if(typeof o<"u")return o}}function ut(t,e,n=0,r=t.length){let l=k();return Jt(t,o=>{l.push(o);let a=e(String.fromCodePoint(...l),l.length);if(typeof a<"u")return a},n,r)}function Wt(t,e,n=0,r=t.length){let l=n;for(let o=0;ln&&e(n,n=l);continue;case 62:n=l+1}l>n&&e(n,l)}function it(t,e,n,r=0){return Wt(t,(l,o)=>e(t,(a,s)=>{r=n({value:t.slice(a,s),index:r,start:a,end:s})},l,o)),r}function Yt(t,e,n,r=0){for(let l=0,o=0;l(a.start+=o,a.end+=o,n(a)),r);return r}function Zt(t){let e=new RegExp(t,"gu");return(n,r,l=0,o=n.length)=>{var u;e.lastIndex=l;let a,s=0;do{a=e.exec(n);let i=(u=a==null?void 0:a.index)!=null?u:o;l"u")continue;let p=f<{var y;return(y=m.onTextInput)==null?void 0:y.call(m,g,p,a)},h),h=Array.isArray(h)?h:[h],Yt(h,n,g=>{let m=z(o,(y,x)=>{var v;return(v=x.onTextTokens)==null?void 0:v.call(x,y)},[g]);for(let y=0;y"u"?s.set(x,[p<{var c;return(c=f.onTextStore)==null?void 0:c.call(f,i,e,t)}),i})}function Xt(t,e,n){let{documents:r,terms:l}=_(t);return n<0||n>=t.count.fields?{documents:r,terms:l}:(e.forEach(o=>{let{occurrences:a}=t.terms[o];for(let s=0;s>>t.space.x;if((u&T[t.space.f])!==n)continue;let i=u>>>t.space.f;r.set(i)}l.set(o)}),{documents:r,terms:l})}function te(t,e){let{documents:n,terms:r}=_(t),l=t.space.f+t.space.x;return e.forEach(o=>{let{occurrences:a}=t.terms[o];for(let s=0;s>>l);r.set(o)}),{documents:n,terms:r}}function _(t){return{documents:new O(t.count.documents),terms:new O(t.terms.length)}}function ee(t,e,n){let{compiler:r,fields:l,plugins:o=[]}=n,{input:a,scope:s,abort:u=!1}=z(o,(f,c)=>{var h;return(h=c.onTextQuery)==null?void 0:h.call(c,f,t,n)},e),i={items:[],query:{select:_(t),values:[]}},d=new Map;if(u===!1){let f=r(n),{select:c,values:h}=f(a,t);typeof s<"u"&&V(c.documents,s);let p=new O(l.length),g=new Map;i.query={select:c,values:h},c.terms.forEach(m=>{A(p,0);for(let x=0;x>>t.space.x,M=w>>>t.space.f;if(!c.documents.get(M))continue;let b=w&T[t.space.f];if(!p.get(b))continue;let F=g.get(w);typeof F>"u"&&g.set(w,F=new j(k()));let S=v&T[t.space.x];F.add(S,m)}}),c.documents.forEach(m=>{let y={id:m,matches:[]};i.items.push(y),d.set(m,y)}),g.forEach((m,y)=>{let x=y>>>t.space.f,v=y&T[t.space.f];d.get(x).matches.push({id:y,field:l[v].name,value:{text:m},score:0})})}return z(o,(f,c)=>{var h;return(h=c.onTextResult)==null?void 0:h.call(c,f,t,n)},i)}function ne(t,e=10){return t.length>1?1+t[t.length-1]-t[0]:e}function re(t,e,n,r=10){let l=[];t.value.text.forEach((s,u)=>{for(let i=0;is.index-u.index);let o=l.slice(0,1),a=0;for(let s=0;sr||i.value===u.value)d=o.map(({index:f})=>f),o=[l[s+1]];else{for(let f=0;fi.index-u.index){let h=o.splice(f+1);d=o.map(({index:p})=>p),o=[...h,l[s+1]]}else d=o.map(({index:h})=>h),o=[l[s+1]];break}}typeof d>"u"&&o.push(l[s+1])}if(typeof d<"u"){let f=n(d,a++);if(typeof f<"u")return f}}if(o.length)return n(o.map(({index:s})=>s),a)}function le(t){let{transform:e,parser:n,fields:r}=t,l=n(t);return(o,a)=>{if(Nt(o))return o;typeof o=="string"&&(o=l(o));let s=[_(a)],u=[],i=0;return H(o,({type:d,data:f})=>{switch(d){case"value":let c=f.value;if(typeof c=="string"){let p=new j(k()),g=a.index.get(e(c));typeof g<"u"&&p.add(g,1),c=p}if(f.field==="*")s[i++]=te(a,c);else{let p=r.findIndex(({name:g})=>g===f.field);s[i++]=Xt(a,c,p)}u.push(Q(R({},f),{value:c}));break;case"operator":let h=i-f.operands.length;switch(f.operator){case"or":for(;i>h+1&&i--;)I(s[h].documents,s[i].documents),I(s[h].terms,s[i].terms);break;case"and":for(;i>h+1&&i--;)V(s[h].documents,s[i].documents),I(s[h].terms,s[i].terms);break;case"not":for(at(s[h].documents),A(s[h].terms,0);i>h+1&&i--;)lt(s[h].documents,s[i].documents)}}}),{select:s[0],values:u}}}function ft(t,e){return H(t,(n,r,l)=>{if(n.type!=="value")return;let o=e(n.data,r,l);if(typeof o<"u")return o})}function ct(t){if(t.length===0)return[];let e=[],n=[];for(let o=0;oo.index-a.index);let r=new Set([n[0].value]),l=n[0].index;for(let o=1;o{t[i].start>l||t[i].end{e.push({start:l,end:o,value:n})})}return new J(ct(e))}function ae(t,e="or",n){let{separator:r}=t;return n!=null||(n=l=>({field:"*",value:l.value})),l=>{let o=[];return it(l,r,a=>{let s=n(a);typeof s<"u"&&o.push({type:"value",data:s})}),{type:"operator",data:{operator:e,operands:o}}}}function se(t,e){return E(this,null,function*(){let n=yield tt(e),r=yield At(n,(o,a)=>{var s;return(s=a.onTextOptions)==null?void 0:s.call(a,o,t)},Q(R({},e),{plugins:n})),l=yield $t(t,r);return D("text",o=>{if(o.type!=="text")throw new P("unsupported");return{type:o.type,data:ee(l,o.data,r)}})})}function q(t){return{name:t.name,data:t.data,onTextOptions:t.onTextOptions,onTextInput:t.onTextInput,onTextTokens:t.onTextTokens,onTextStore:t.onTextStore,onTextQuery:t.onTextQuery,onTextResult:t.onTextResult}}function oe(t){let{handlers:e}=t,n,r=new Map;return Lt({name:"aggregation",onFilterStore(l,o){for(let a=0;a"u")continue;let u=!0;o.documents.forEach(i=>{u=!1}),u&&A(o.documents,1),l.aggregations.push(s(a,o))}}})}function ue(t={}){let{empty:e=!1,limit:n}=t;return(r,{fields:l})=>{let o=r.space.f+r.space.x;return D("term",({type:a,data:s},{documents:u})=>{if(a!=="term")throw new P("unsupported");let i=l.findIndex(({name:f})=>f===s.field),d=Ut(r,i,f=>{let c=0,{occurrences:h}=f;for(let p=0;p>>o)&&c++;if(!(e===!1&&c===0))return{value:f.value,count:c}},R(R({},n),s.limit));return{type:a,data:{field:s.field,value:d}}})}}function ie(t,e="prefix"){return{type:e,data:t}}function fe(t){return typeof t=="object"&&"type"in t&&typeof t.type=="string"&&"data"in t&&typeof t.data=="string"}function ce(t,e={}){var u;let{prefix:n=2,filter:r=[]}=e,l=t.terms,o=new Map,a=Ot(l.length),s=k();for(let i=0;i{var p;return o.set(c,(p=o.get(c))!=null?p:i),h===n||void 0});let f=i?l[i-1]:"";a[i]=Ht(f,d)}for(let i=0;ii-d),{terms:l,index:o,cover:a,exact:s}}function de(t,e){let n="",r=-1,l=-1;if(ut(e,s=>{let u=t.index.get(s);if(typeof u>"u")return!0;n=s,r=u}),r!==-1)for(let s=n.length;ss>r&&sa),index:e.index},{prefix:t.prefix,filter:(l=t.filter)==null?void 0:l.map(r)}))},onTextQuery(e,n,r){let{transform:l,parser:o}=r;if(typeof e.input=="string")e.input=o(r)(e.input);else if(!ot(e.input))return;ft(e.input,a=>{var u;let s=a.value;if(fe(s))s=l(s.data);else return;a.value=(u=de(this.data,s))!=null?u:s})}})}function pe(t){let e=Q(R({},t),{plugins:[]}),n,r,l;return q({name:"filter",onTextOptions(a,s){return E(this,null,function*(){e.plugins=yield tt(t),l=yield Vt(s,e)})},onTextQuery(a){typeof a.filter<"u"&&(n=a.filter,r!=null||(r=st(e)),n.input=r(n.input,l),a.scope=n.input.select.documents)},onTextResult(a){if(typeof n<"u"){let s=!0;a.query.select.documents.forEach(i=>{s=!1}),s||(n.scope=a.query.select.documents);let u=Kt(l,n,e);a.aggregations=u.aggregations,n=void 0}}})}function ht(t,e){let n=[],r=t/e>>>0,l=t%e,o=0;if(r)for(let a=0;as);r.sort((a,s)=>t.terms[a].length-t.terms[s].length||t.terms[a].localeCompare(t.terms[s]));let l=0;for(let a=0;al&&(l=t.terms[a].length);let o=[];for(let a=0;a"u"?u[d].set(f,[r[a]]):c.push(r[a])}}return{index:o,terms:t.terms,idxmp:r}}var ye=[["id","di","rr"],["dr","rd"],["dd"]];function pt(t,e,n=2){if(t.lengthn)return;let a,s,u,i=n+1;for(let d of ye[o]){for(u=a=s=0;an)break;switch(d[u-1]){case"d":a++;break;case"i":s++;break;case"r":a++,s++;break}}else a++,s++;u+=r-a+(l-s),u"u")continue;let a=me(e,o,2);for(let s=0;s"u"))for(let c of f){let h=t.terms[c].length,p=n(t.terms[c],e);typeof p<"u"&&r.add(c,(h-p)/h)}}}}if(r.data.length)return r}function we(t={}){return q({name:"fuzzy",onTextStore(e){var n;(n=this.data)!=null||(this.data=xe({terms:e.terms.map(({value:r})=>r)},t))},onTextQuery(e,n,r){let{transform:l,parser:o}=r;if(typeof e.input=="string")e.input=o(r)(e.input);else if(!ot(e.input))return;ft(e.input,a=>{var u;let s=a.value;if(typeof s=="string")s=l(s);else return;n.index.get(s)||(a.value=(u=ve(this.data,s))!=null?u:s)})}})}function be(){return{tables:new Map}}function Te(t,e={}){let{count:n}=e;return D("term",r=>{let l=dt(r);return(o,a)=>{let s=[];return o.value.text.forEach((u,i)=>{let d=a[u]>>>10,f=a[u]&T[10];for(let p=0;pu.start-i.start),{ranges:ct(s).slice(0,n)}}})}function Me(t){let e,n;return q({name:"highlight",data:be(),onTextInput(r,l){let{tables:o}=this.data;o.set(l,n=k())},onTextTokens(r){for(let l=0;l{let s=l.get(a.id);if(a.value.highlight)return;let u=o(a,s);a.value=Q(R({},a.value),{highlight:u})})}})}function ke(){return{directives:[]}}function gt(...t){return(e,n)=>{for(let r=0;r{if(r!=="match")throw new P("unsupported");let o=Fe(t),a=gt(...e.map(s=>s(n)));return $(n,({matches:s})=>{s.sort(o)}),(s,u)=>{let i=Math.min(s.matches.length,u.matches.length);for(let d=0,f=0;dr*(l.get(a.field)-l.get(s.field))}function Re(t,e={}){let n=dt(t.query),r=G(re),l=G(ne);return(o,a)=>{let s=r(o,n,f=>f),u=r(a,n,f=>f);if(s.length!==u.length)return u.length-s.length;let i=l(s),d=l(u);return i!==d?i-d:s[0]!==u[0]?s[0]-u[0]:0}}function qe(t){let e=new Map;return q({name:"order",data:ke(),onTextOptions(r,l){return E(this,null,function*(){for(let o=0;o"u")throw new P("unknown");o.push(u(r,s))}r.items.sort(gt(...o))}})}function ze(t){let e=t.handler();return q({name:"pagination",onTextQuery(n){return e.onQuery(n,t)},onTextResult(n){return e.onResult(n,t)}})}function Ae(t){let{id:e,size:n=10,from:r=0}=t;if(r-n>=0)return{id:e,size:n,from:r-n}}function Qe(t,e){let{id:n,size:r=10,from:l=0}=t;if(l+rE(null,null,function*(){let e=t.data;switch(e.type){case 0:Z=yield se(e.data.items,{separator:Zt(e.data.config.separator),transform:G(Gt),parser:r=>ae(r,"and",l=>({field:"*",value:ie(l.value),range:{start:l.start,end:l.end,value:l.index}})),compiler:le,fields:[C("title",r=>r.title,{weight:3}),C("text",r=>r.text),C("path",r=>r.path,{weight:2})],plugins:[he(),we(),pe({compiler:st,fields:[C("tags",r=>r.tags)],plugins:[oe({handlers:[ue()]})]}),qe({handlers:[r=>Ee({fields:r.fields,comparators:[Re]})],defaults:{order:[{type:"match",data:{field:"*"}}]}}),()=>q({onTextResult(r){r.total=r.items.length}}),ze({handler:Se,size:10}),Me({handler:r=>Te(r)}),()=>q({onTextResult(r){let{query:l}=r,o=l.values.map(({range:a,value:s})=>{var i,d;let u=!1;return s.forEach((f,c)=>{!u&&c<1&&(u=!0)}),u?-1:((i=a==null?void 0:a.end)!=null?i:0)-((d=a==null?void 0:a.start)!=null?d:0)});X(r,a=>{var s;(s=a.value.highlight)==null||s.ranges.forEach(u=>{u.value=o[u.value]})})}})]}),self.postMessage({type:1});break;case 2:let n=Z({type:"text",data:e.data});self.postMessage({type:3,data:n.data});break}})});var _e=qt(xt());})(); diff --git a/src/httpcore2/site-httpcore2/assets/stylesheets/classic/main.a2001754.min.css b/src/httpcore2/site-httpcore2/assets/stylesheets/classic/main.a2001754.min.css new file mode 100644 index 00000000..48839e8b --- /dev/null +++ b/src/httpcore2/site-httpcore2/assets/stylesheets/classic/main.a2001754.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-scheme=default]{color-scheme:light}[data-md-color-scheme=default] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=default] img[src$="#only-dark"]{display:none}:root,[data-md-color-scheme=default]{--md-hue:225deg;--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008a;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#00000012;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-bg-color--light:#f5f5f5b3;--md-code-bg-color--lighter:#f5f5f54d;--md-code-hl-color:#4287ff;--md-code-hl-color--light:#4287ff1a;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-mark-color:#ffff0080;--md-typeset-table-color:#0000001f;--md-typeset-table-color--light:rgba(0,0,0,.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-warning-fg-color:#000000de;--md-warning-bg-color:#ff9;--md-footer-fg-color:#fff;--md-footer-fg-color--light:#ffffffb3;--md-footer-fg-color--lighter:#ffffff73;--md-footer-bg-color:#000000de;--md-footer-bg-color--dark:#00000052;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059;--color-foreground:0 0 0;--color-background:255 255 255;--color-background-subtle:240 240 240;--color-backdrop:255 255 255}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}.md-icon svg.lucide{fill:#0000;stroke:currentcolor}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6;overflow-wrap:break-word}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset h5 code{text-transform:none}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset a code{color:var(--md-typeset-a-color)}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none;transition:background-color 125ms}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;transition:color 125ms,background-color 125ms;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{cursor:help;text-decoration:none}.md-typeset [data-preview],.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light)}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}.md-typeset ul[type]{list-style-type:revert-layer}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}.md-typeset ol ol ol ol,.md-typeset ul ol ol ol{list-style-type:upper-alpha}.md-typeset ol ol ol ol ol,.md-typeset ul ol ol ol ol{list-style-type:upper-roman}.md-typeset ol[type],.md-typeset ul[type]{list-style-type:revert-layer}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}[dir=ltr] .md-typeset ol li ol,[dir=ltr] .md-typeset ol li ul,[dir=ltr] .md-typeset ul li ol,[dir=ltr] .md-typeset ul li ul{margin-left:.625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:fit-content}.md-typeset figure img{display:block;margin:0 auto}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td>:first-child,.md-typeset table:not([class]) th>:first-child{margin-top:0}.md-typeset table:not([class]) td>:last-child,.md-typeset table:not([class]) th>:last-child{margin-bottom:0}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:var(--md-typeset-table-color--light);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.984375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-typeset .md-author{border-radius:100%;display:block;flex-shrink:0;height:1.6rem;overflow:hidden;position:relative;transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .md-author img{display:block}.md-typeset .md-author--more{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .md-author--long{height:2.4rem;width:2.4rem}.md-typeset a.md-author{transform:scale(1)}.md-typeset a.md-author img{border-radius:100%;filter:grayscale(100%) opacity(75%);transition:filter 125ms}.md-typeset a.md-author:focus,.md-typeset a.md-author:hover{transform:scale(1.1);z-index:1}.md-typeset a.md-author:focus img,.md-typeset a.md-author:hover img{filter:grayscale(0)}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background-color:var(--md-warning-bg-color);color:var(--md-warning-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.no-js .md-banner__button{display:none}.md-banner__button:hover{opacity:.7}html{scrollbar-gutter:stable;font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.984375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:focus,.md-clipboard:hover{color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:focus code,.md-clipboard--inline:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}:root{--md-code-select-icon:url('data:image/svg+xml;charset=utf-8,');--md-code-copy-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-code__content{display:grid}.md-code__nav{background-color:var(--md-code-bg-color--lighter);border-radius:.1rem;display:flex;gap:.2rem;padding:.2rem;position:absolute;right:.25em;top:.25em;transition:background-color .25s;z-index:1}:hover>.md-code__nav{background-color:var(--md-code-bg-color--light)}.md-code__button{color:var(--md-default-fg-color--lightest);cursor:pointer;display:block;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em}:hover>*>.md-code__button{color:var(--md-default-fg-color--light)}.md-code__button.focus-visible,.md-code__button:hover{color:var(--md-accent-fg-color)}.md-code__button--active{color:var(--md-default-fg-color)!important}.md-code__button:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-code__button[data-md-type=select]:after{-webkit-mask-image:var(--md-code-select-icon);mask-image:var(--md-code-select-icon)}.md-code__button[data-md-type=copy]:after{-webkit-mask-image:var(--md-code-copy-icon);mask-image:var(--md-code-copy-icon)}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:#0000008a;height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.984375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}.md-content__button svg.lucide{fill:#0000;stroke:currentcolor}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{display:flex;flex-wrap:wrap;place-content:baseline center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}@media print{.md-feedback{display:none}}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{align-items:end;display:flex;flex-grow:0.01;margin-bottom:.4rem;margin-top:1rem;max-width:100%;outline-color:var(--md-accent-fg-color);overflow:hidden;transition:opacity .25s}.md-footer__link:focus,.md-footer__link:hover{opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.984375em){.md-footer__link--prev{flex-shrink:0}.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;margin-bottom:.7rem;max-width:calc(100% - 2.4rem);padding:0 1rem;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;opacity:.7}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:focus,html .md-footer-meta.md-typeset a:hover{color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{display:inline-flex;gap:.2rem;margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-social__link svg.lucide{fill:#0000;stroke:currentcolor}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:focus,.md-typeset .md-button:hover{background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:focus,.md-typeset .md-input:hover{border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem #0000,0 .2rem .4rem #0000;color:var(--md-primary-bg-color);display:block;left:0;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.234375em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo img,.md-header__button.md-logo svg{fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-left:1rem;margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem;margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;white-space:nowrap}.md-header__option>input{bottom:0}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}.md-meta{color:var(--md-default-fg-color--light);font-size:.7rem;line-height:1.3}.md-meta__list{display:inline-flex;flex-wrap:wrap;list-style:none;margin:0;padding:0}.md-meta__item:not(:last-child):after{content:"·";margin-left:.2rem;margin-right:.2rem}.md-meta__link{color:var(--md-typeset-a-color)}.md-meta__link:focus,.md-meta__link:hover{color:var(--md-accent-fg-color)}.md-draft{background-color:#ff1744;border-radius:.125em;color:#fff;display:inline-block;font-weight:700;padding-left:.5714285714em;padding-right:.5714285714em}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{color:var(--md-default-fg-color--light);display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo img,.md-nav__title .md-nav__button.md-logo svg{fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__link{align-items:flex-start;display:flex;gap:.4rem;margin-top:.625em;scroll-snap-align:start;transition:color 125ms}.md-nav__link--passed,.md-nav__link--passed code{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active,.md-nav__item .md-nav__link--active code{color:var(--md-typeset-a-color)}.md-nav__link .md-ellipsis{position:relative}.md-nav__link .md-ellipsis code{word-break:normal}[dir=ltr] .md-nav__link .md-icon:last-child{margin-left:auto}[dir=rtl] .md-nav__link .md-icon:last-child{margin-right:auto}.md-nav__link .md-typeset{font-size:.7rem;line-height:1.3}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em;position:relative;width:1.3em}.md-nav__link svg.lucide{fill:#0000;stroke:currentcolor}.md-nav__link[for]:focus,.md-nav__link[for]:hover,.md-nav__link[href]:focus,.md-nav__link[href]:hover{color:var(--md-accent-fg-color);cursor:pointer}.md-nav__link[for]:focus code,.md-nav__link[for]:hover code,.md-nav__link[href]:focus code,.md-nav__link[href]:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__container>.md-nav__link{margin-top:0}.md-nav__container>.md-nav__link:first-child{flex-grow:1;min-width:0}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.234375em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary .md-nav__item,.md-nav--primary .md-nav__title{font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;overscroll-behavior-y:contain;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest)}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:focus,.md-nav--primary .md-nav__item--active>.md-nav__link:hover{color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link svg{margin-top:.1em}.md-nav--primary .md-nav__link>.md-nav__link{padding:0}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{backface-visibility:hidden}}@media screen and (max-width:59.984375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.234375em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav{margin-bottom:-.4rem}.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--secondary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--secondary .md-nav__list{padding-right:.6rem}.md-nav--secondary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--secondary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--secondary .md-nav__item>.md-nav__link{margin-left:.4rem}}@media screen and (min-width:76.25em){.md-nav{margin-bottom:-.4rem;transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon{display:none}[dir=ltr] .md-nav--primary .md-nav__list{padding-left:.6rem}[dir=rtl] .md-nav--primary .md-nav__list{padding-right:.6rem}.md-nav--primary .md-nav__list{padding-bottom:.4rem}[dir=ltr] .md-nav--primary .md-nav__item>.md-nav__link{margin-right:.4rem}[dir=rtl] .md-nav--primary .md-nav__item>.md-nav__link{margin-left:.4rem}.md-nav__toggle~.md-nav{display:grid;grid-template-rows:minmax(.4rem,0fr);opacity:0;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .25s,visibility 0ms .25s;visibility:collapse}.md-nav__toggle~.md-nav>.md-nav__list{overflow:hidden}.md-nav__toggle.md-toggle--indeterminate~.md-nav,.md-nav__toggle:checked~.md-nav{grid-template-rows:minmax(.4rem,1fr);opacity:1;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .15s .1s,visibility 0ms;visibility:visible}.md-nav__toggle.md-toggle--indeterminate~.md-nav{transition:none}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link[for]{color:var(--md-default-fg-color--light)}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav__link .md-icon,.md-nav__item--section>.md-nav__link>[for]{display:none}[dir=ltr] .md-nav__item--section>.md-nav{margin-left:-.6rem}[dir=rtl] .md-nav__item--section>.md-nav{margin-right:-.6rem}.md-nav__item--section>.md-nav{display:block;opacity:1;visibility:visible}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s;width:.9rem}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;border-radius:100%;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;vertical-align:-.1rem;width:100%}[dir=rtl] .md-nav__icon:after{transform:rotate(180deg)}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon:after,.md-nav__item--nested .md-toggle--indeterminate~.md-nav__link .md-nav__icon:after{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);margin-top:0;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active.md-nav__item--section{margin:0}[dir=ltr] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-left:-.6rem}[dir=rtl] .md-nav--lifted>.md-nav__list>.md-nav__item>.md-nav:not(.md-nav--secondary){margin-right:-.6rem}.md-nav--lifted>.md-nav__list>.md-nav__item>[for]{color:var(--md-default-fg-color--light)}.md-nav--lifted .md-nav[data-md-level="1"]{grid-template-rows:minmax(.4rem,1fr);opacity:1;visibility:visible}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__list{overflow:visible;padding-bottom:0}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}.md-pagination{font-size:.8rem;font-weight:700;gap:.4rem}.md-pagination,.md-pagination>*{align-items:center;display:flex;justify-content:center}.md-pagination>*{border-radius:.2rem;height:1.8rem;min-width:1.8rem;text-align:center}.md-pagination__current{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light)}.md-pagination__link{transition:color 125ms,background-color 125ms}.md-pagination__link:focus,.md-pagination__link:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-pagination__link:focus svg,.md-pagination__link:hover svg{color:var(--md-accent-fg-color)}.md-pagination__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-pagination__link svg{fill:currentcolor;color:var(--md-default-fg-color--lighter);display:block;max-height:100%;width:1.2rem}:root{--md-path-icon:url('data:image/svg+xml;charset=utf-8,')}.md-path{font-size:.7rem;margin:0 .8rem;overflow:auto;padding-top:1.2rem}.md-path:not([hidden]){display:block}@media screen and (min-width:76.25em){.md-path{margin:0 1.2rem}}.md-path__list{align-items:center;display:flex;gap:.2rem;list-style:none;margin:0;padding:0}.md-path__item:not(:first-child){display:inline-flex;gap:.2rem;white-space:nowrap}.md-path__item:not(:first-child):before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline;height:.8rem;-webkit-mask-image:var(--md-path-icon);mask-image:var(--md-path-icon);width:.8rem}.md-path__link{align-items:center;color:var(--md-default-fg-color--light);display:flex}.md-path__link:focus,.md-path__link:hover{color:var(--md-accent-fg-color)}:root{--md-post-pin-icon:url('data:image/svg+xml;charset=utf-8,')}.md-post__back{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin-bottom:1.2rem;padding-bottom:1.2rem}@media screen and (max-width:76.234375em){.md-post__back{display:none}}[dir=rtl] .md-post__back svg{transform:scaleX(-1)}.md-post__authors{display:flex;flex-direction:column;gap:.6rem;margin:0 .6rem 1.2rem}.md-post .md-post__meta a{transition:color 125ms}.md-post .md-post__meta a:focus,.md-post .md-post__meta a:hover{color:var(--md-accent-fg-color)}.md-post__title{color:var(--md-default-fg-color--light);font-weight:700}.md-post--excerpt{margin-bottom:3.2rem}.md-post--excerpt .md-post__header{align-items:center;display:flex;gap:.6rem;min-height:1.6rem}.md-post--excerpt .md-post__authors{align-items:center;display:inline-flex;flex-direction:row;gap:.2rem;margin:0;min-height:2.4rem}[dir=ltr] .md-post--excerpt .md-post__meta .md-meta__list{margin-right:.4rem}[dir=rtl] .md-post--excerpt .md-post__meta .md-meta__list{margin-left:.4rem}.md-post--excerpt .md-post__content>:first-child{--md-scroll-margin:6rem;margin-top:0}.md-post>.md-nav--secondary{margin:1em 0}.md-pin{background:var(--md-default-fg-color--lightest);border-radius:1rem;margin-top:-.05rem;padding:.2rem}.md-pin:after{background-color:currentcolor;content:"";display:block;height:.6rem;margin:0 auto;-webkit-mask-image:var(--md-post-pin-icon);mask-image:var(--md-post-pin-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.6rem}.md-profile{align-items:center;display:flex;font-size:.7rem;gap:.6rem;line-height:1.4;width:100%}.md-profile__description{flex-grow:1}.md-content--post{display:flex}@media screen and (max-width:76.234375em){.md-content--post{flex-flow:column-reverse}}.md-content--post>.md-content__inner{flex-grow:1;min-width:0}@media screen and (min-width:76.25em){[dir=ltr] .md-content--post>.md-content__inner{margin-left:1.2rem}[dir=rtl] .md-content--post>.md-content__inner{margin-right:1.2rem}}@media screen and (max-width:76.234375em){.md-sidebar.md-sidebar--post{padding:0;position:static;width:100%}.md-sidebar.md-sidebar--post .md-sidebar__scrollwrap{overflow:visible}.md-sidebar.md-sidebar--post .md-sidebar__inner{padding:0}.md-sidebar.md-sidebar--post .md-post__meta{margin-left:.6rem;margin-right:.6rem}.md-sidebar.md-sidebar--post .md-nav__item{border:none;display:inline}.md-sidebar.md-sidebar--post .md-nav__list{display:inline-flex;flex-wrap:wrap;gap:.6rem;padding-bottom:.6rem;padding-top:.6rem}.md-sidebar.md-sidebar--post .md-nav__link{padding:0}.md-sidebar.md-sidebar--post .md-nav{height:auto;margin-bottom:0;position:static}}:root{--md-progress-value:0;--md-progress-delay:400ms}.md-progress{background:var(--md-primary-bg-color);height:.075rem;opacity:min(clamp(0,var(--md-progress-value),1),clamp(0,100 - var(--md-progress-value),1));position:fixed;top:0;transform:scaleX(calc(var(--md-progress-value)*1%));transform-origin:left;transition:transform .5s cubic-bezier(.19,1,.22,1),opacity .25s var(--md-progress-delay);width:100%;z-index:4}:root{--md-search-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}@media screen and (max-width:59.984375em){.md-search{display:none}}.no-js .md-search{display:none}[dir=ltr] .md-search__button{padding-left:1.9rem;padding-right:2.2rem}[dir=rtl] .md-search__button{padding-left:2.2rem;padding-right:1.9rem}.md-search__button{background:var(--md-primary-fg-color);color:var(--md-primary-bg-color);cursor:pointer;font-size:.7rem;position:relative;text-align:left}@media screen and (min-width:45em){.md-search__button{background-color:#00000042;border-radius:.2rem;height:1.6rem;transition:background-color .4s,color .4s;width:8.9rem}.md-search__button:focus,.md-search__button:hover{background-color:#ffffff1f;color:var(--md-primary-bg-color)}}[dir=ltr] .md-search__button:before{left:0}[dir=rtl] .md-search__button:before{right:0}.md-search__button:before{background-color:var(--md-primary-bg-color);content:"";height:1rem;margin-left:.5rem;-webkit-mask-image:var(--md-search-icon);mask-image:var(--md-search-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.3rem;width:1rem}.md-search__button:after{background:#00000042;border-radius:.1rem;content:"Ctrl+K";display:block;font-size:.6rem;padding:.1rem .2rem;position:absolute;right:.6rem;top:.35rem}[data-platform^=Mac] .md-search__button:after{content:"⌘K"}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}@media screen and (max-width:59.984375em){.md-select__inner{left:100%;transform:translate3d(-100%,.3rem,0)}}.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{max-height:min(75vh,28rem);opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}@media screen and (max-width:59.984375em){.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{transform:translate3d(-100%,0,0)}}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";filter:drop-shadow(0 -1px 0 var(--md-default-fg-color--lightest));height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}@media screen and (max-width:59.984375em){.md-select__inner:after{left:auto;right:1rem}}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:focus,.md-select__link:hover{color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.234375em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;overscroll-behavior-y:contain;position:absolute;right:0;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000}@media screen and (min-width:60em){.md-sidebar__scrollwrap{scrollbar-gutter:stable;scrollbar-width:thin}}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap:focus-within,.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}}@media screen and (max-width:76.234375em){.md-overlay{background-color:#0000008a;height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-source-file{margin:1em 0}[dir=ltr] .md-source-file__fact{margin-right:.6rem}[dir=rtl] .md-source-file__fact{margin-left:.6rem}.md-source-file__fact{align-items:center;color:var(--md-default-fg-color--light);display:inline-flex;font-size:.68rem;gap:.3rem}.md-source-file__fact .md-icon{flex-shrink:0;margin-bottom:.05rem}[dir=ltr] .md-source-file__fact .md-author{float:left}[dir=rtl] .md-source-file__fact .md-author{float:right}.md-source-file__fact .md-author{margin-right:.2rem}.md-source-file__fact svg{width:.9rem}:root{--md-status:url('data:image/svg+xml;charset=utf-8,');--md-status--new:url('data:image/svg+xml;charset=utf-8,');--md-status--deprecated:url('data:image/svg+xml;charset=utf-8,');--md-status--encrypted:url('data:image/svg+xml;charset=utf-8,')}.md-status:after{background-color:var(--md-default-fg-color--light);content:"";display:inline-block;height:1.125em;-webkit-mask-image:var(--md-status);mask-image:var(--md-status);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.125em}.md-status:hover:after{background-color:currentcolor}.md-status--new:after{-webkit-mask-image:var(--md-status--new);mask-image:var(--md-status--new)}.md-status--deprecated:after{-webkit-mask-image:var(--md-status--deprecated);mask-image:var(--md-status--deprecated)}.md-status--encrypted:after{-webkit-mask-image:var(--md-status--encrypted);mask-image:var(--md-status--encrypted)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.234375em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;display:flex;list-style:none;margin:0;overflow:auto;padding:0;scrollbar-width:none;white-space:nowrap}.md-tabs__list::-webkit-scrollbar{display:none}.md-tabs__item{height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__item--active .md-tabs__link{color:inherit;opacity:1}.md-tabs__link{backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link:focus,.md-tabs__link:hover{color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags:not([hidden]){display:inline-flex;flex-wrap:wrap;gap:.5em;margin-bottom:.75em;margin-top:-.125em}.md-typeset .md-tag{align-items:center;background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-flex;font-size:.64rem;font-size:min(.8em,.64rem);font-weight:700;gap:.5em;letter-spacing:normal;line-height:1.6;padding:.3125em .78125em}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-shadow{opacity:.5}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon[href]:focus:before,.md-typeset .md-tag-icon[href]:hover:before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{transform:scale(.95)}75%{transform:scale(1)}to{transform:scale(.95)}}:root{--md-annotation-bg-icon:url('data:image/svg+xml;charset=utf-8,');--md-annotation-icon:url('data:image/svg+xml;charset=utf-8,')}.md-tooltip{backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:700;-webkit-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.5rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}.focus-visible>.md-tooltip,.md-tooltip:target{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-style:normal;font-weight:400;outline:none;text-align:initial;vertical-align:text-bottom;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}code .md-annotation{font-family:var(--md-code-font-family);font-size:inherit}.md-annotation:not([hidden]){display:inline-block;line-height:1.25}.md-annotation__index{border-radius:.01px;cursor:pointer;display:inline-block;margin-left:.4ch;margin-right:.4ch;outline:none;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none;vertical-align:text-top;z-index:0}.md-annotation .md-annotation__index{transition:z-index .25s}@media screen{.md-annotation__index{width:2.2ch}[data-md-visible]>.md-annotation__index{animation:pulse 2s infinite}.md-annotation__index:before{background:var(--md-default-bg-color);-webkit-mask-image:var(--md-annotation-bg-icon);mask-image:var(--md-annotation-bg-icon)}.md-annotation__index:after,.md-annotation__index:before{content:"";height:2.2ch;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:-.1ch;width:2.2ch;z-index:-1}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);-webkit-mask-image:var(--md-annotation-icon);mask-image:var(--md-annotation-icon);transform:scale(1.0001);transition:background-color .25s,transform .25s}.md-tooltip--active+.md-annotation__index:after{transform:rotate(45deg)}.md-tooltip--active+.md-annotation__index:after,:hover>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}}.md-tooltip--active+.md-annotation__index{animation-play-state:paused;transition-duration:0ms;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block}@media print{.md-annotation__index [data-md-annotation-id]{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);font-weight:700;padding:0 .6ch;white-space:nowrap}.md-annotation__index [data-md-annotation-id]:after{content:attr(data-md-annotation-id)}}.md-typeset .md-annotation-list{counter-reset:annotation;list-style:none!important}.md-typeset .md-annotation-list li{position:relative}[dir=ltr] .md-typeset .md-annotation-list li:before{left:-2.125em}[dir=rtl] .md-typeset .md-annotation-list li:before{right:-2.125em}.md-typeset .md-annotation-list li:before{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);content:counter(annotation);counter-increment:annotation;font-size:.8875em;font-weight:700;height:2ch;line-height:1.25;min-width:2ch;padding:0 .6ch;position:absolute;text-align:center;top:.25em}:root{--md-tooltip-width:20rem;--md-tooltip-tail:0.3rem}.md-tooltip2{backface-visibility:hidden;color:var(--md-default-fg-color);font-family:var(--md-text-font-family);opacity:0;pointer-events:none;position:absolute;top:calc(var(--md-tooltip-host-y) + var(--md-tooltip-y));transform:translateY(-.4rem);transform-origin:calc(var(--md-tooltip-host-x) + var(--md-tooltip-x)) 0;transition:transform 0ms .25s,opacity .25s,z-index .25s;width:100%;z-index:0}.md-tooltip2:before{border-left:var(--md-tooltip-tail) solid #0000;border-right:var(--md-tooltip-tail) solid #0000;content:"";display:block;left:clamp(1.5 * .8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-tail),100vw - 2 * var(--md-tooltip-tail) - 1.5 * .8rem);position:absolute;z-index:1}.md-tooltip2--top:before{border-top:var(--md-tooltip-tail) solid var(--md-default-bg-color);bottom:calc(var(--md-tooltip-tail)*-1 + .025rem);filter:drop-shadow(0 1px 0 hsla(0,0%,0%,.05))}.md-tooltip2--bottom:before{border-bottom:var(--md-tooltip-tail) solid var(--md-default-bg-color);filter:drop-shadow(0 -1px 0 hsla(0,0%,0%,.05));top:calc(var(--md-tooltip-tail)*-1 + .025rem)}.md-tooltip2--active{opacity:1;transform:translateY(0);transition:transform .4s cubic-bezier(0,1,.5,1),opacity .25s,z-index 0ms;z-index:4}.md-tooltip2__inner{scrollbar-gutter:stable;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);left:clamp(.8rem,var(--md-tooltip-host-x) - .8rem,100vw - var(--md-tooltip-width) - .8rem);max-height:40vh;max-width:calc(100vw - 1.6rem);position:relative;scrollbar-width:thin}.md-tooltip2__inner::-webkit-scrollbar{height:.2rem;width:.2rem}.md-tooltip2__inner::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-tooltip2__inner::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}[role=dialog]>.md-tooltip2__inner{font-size:.64rem;overflow:auto;padding:0 .8rem;pointer-events:auto;width:var(--md-tooltip-width)}[role=dialog]>.md-tooltip2__inner:after,[role=dialog]>.md-tooltip2__inner:before{content:"";display:block;height:.8rem;position:sticky;width:100%;z-index:10}[role=dialog]>.md-tooltip2__inner:before{background:linear-gradient(var(--md-default-bg-color),#0000 75%);top:0}[role=dialog]>.md-tooltip2__inner:after{background:linear-gradient(#0000,var(--md-default-bg-color) 75%);bottom:0}[role=tooltip]>.md-tooltip2__inner{font-size:.5rem;font-weight:700;left:clamp(.8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-width)/2,100vw - var(--md-tooltip-width) - .8rem);max-width:min(100vw - 2 * .8rem,400px);padding:.2rem .4rem;-webkit-user-select:none;user-select:none;width:fit-content}.md-tooltip2__inner.md-typeset>:first-child{margin-top:0}.md-tooltip2__inner.md-typeset>:last-child{margin-bottom:0}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:focus,.md-top:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}.md-top.lucide{fill:#0000;stroke:currentcolor}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__alias{margin-left:.3rem;opacity:.7}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:focus-within .md-version__list,.md-version:hover .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (hover:none),(pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:focus,.md-version__link:hover{color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}html.glightbox-open{height:100%;overflow:initial}html .gslide .gslide-description{background:var(--md-default-bg-color);-webkit-user-select:text;user-select:text}html .gslide .gslide-title{color:var(--md-default-fg-color);font-size:.8rem;margin-bottom:.4rem;margin-top:0}html .gslide .gslide-desc{color:var(--md-default-fg-color--light);font-size:.7rem}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:var(--md-admonition-bg-color);border:.075rem solid #448aff;border-radius:.2rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid;transition:box-shadow 125ms}@media print{.md-typeset .admonition,.md-typeset details{box-shadow:none}}.md-typeset .admonition:focus-within,.md-typeset details:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:2rem;padding-right:.6rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.6rem;padding-right:2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-left-width:.2rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-right-width:.2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset .admonition-title,.md-typeset summary{background-color:#448aff1a;border:none;font-weight:700;margin:0 -.6rem;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset .admonition-title:last-child,html .md-typeset summary:last-child{margin-bottom:0}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:.6rem}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:.6rem}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset .admonition-title code,.md-typeset summary code{box-shadow:0 0 0 .05rem var(--md-default-fg-color--lightest)}.md-typeset .admonition.note,.md-typeset details.note{border-color:#448aff}.md-typeset .admonition.note:focus-within,.md-typeset details.note:focus-within{box-shadow:0 0 0 .2rem #448aff1a}.md-typeset .note>.admonition-title,.md-typeset .note>summary{background-color:#448aff1a}.md-typeset .note>.admonition-title:before,.md-typeset .note>summary:before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset .note>.admonition-title:after,.md-typeset .note>summary:after{color:#448aff}.md-typeset .admonition.abstract,.md-typeset details.abstract{border-color:#00b0ff}.md-typeset .admonition.abstract:focus-within,.md-typeset details.abstract:focus-within{box-shadow:0 0 0 .2rem #00b0ff1a}.md-typeset .abstract>.admonition-title,.md-typeset .abstract>summary{background-color:#00b0ff1a}.md-typeset .abstract>.admonition-title:before,.md-typeset .abstract>summary:before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset .abstract>.admonition-title:after,.md-typeset .abstract>summary:after{color:#00b0ff}.md-typeset .admonition.info,.md-typeset details.info{border-color:#00b8d4}.md-typeset .admonition.info:focus-within,.md-typeset details.info:focus-within{box-shadow:0 0 0 .2rem #00b8d41a}.md-typeset .info>.admonition-title,.md-typeset .info>summary{background-color:#00b8d41a}.md-typeset .info>.admonition-title:before,.md-typeset .info>summary:before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset .info>.admonition-title:after,.md-typeset .info>summary:after{color:#00b8d4}.md-typeset .admonition.tip,.md-typeset details.tip{border-color:#00bfa5}.md-typeset .admonition.tip:focus-within,.md-typeset details.tip:focus-within{box-shadow:0 0 0 .2rem #00bfa51a}.md-typeset .tip>.admonition-title,.md-typeset .tip>summary{background-color:#00bfa51a}.md-typeset .tip>.admonition-title:before,.md-typeset .tip>summary:before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset .tip>.admonition-title:after,.md-typeset .tip>summary:after{color:#00bfa5}.md-typeset .admonition.success,.md-typeset details.success{border-color:#00c853}.md-typeset .admonition.success:focus-within,.md-typeset details.success:focus-within{box-shadow:0 0 0 .2rem #00c8531a}.md-typeset .success>.admonition-title,.md-typeset .success>summary{background-color:#00c8531a}.md-typeset .success>.admonition-title:before,.md-typeset .success>summary:before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset .success>.admonition-title:after,.md-typeset .success>summary:after{color:#00c853}.md-typeset .admonition.question,.md-typeset details.question{border-color:#64dd17}.md-typeset .admonition.question:focus-within,.md-typeset details.question:focus-within{box-shadow:0 0 0 .2rem #64dd171a}.md-typeset .question>.admonition-title,.md-typeset .question>summary{background-color:#64dd171a}.md-typeset .question>.admonition-title:before,.md-typeset .question>summary:before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset .question>.admonition-title:after,.md-typeset .question>summary:after{color:#64dd17}.md-typeset .admonition.warning,.md-typeset details.warning{border-color:#ff9100}.md-typeset .admonition.warning:focus-within,.md-typeset details.warning:focus-within{box-shadow:0 0 0 .2rem #ff91001a}.md-typeset .warning>.admonition-title,.md-typeset .warning>summary{background-color:#ff91001a}.md-typeset .warning>.admonition-title:before,.md-typeset .warning>summary:before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset .warning>.admonition-title:after,.md-typeset .warning>summary:after{color:#ff9100}.md-typeset .admonition.failure,.md-typeset details.failure{border-color:#ff5252}.md-typeset .admonition.failure:focus-within,.md-typeset details.failure:focus-within{box-shadow:0 0 0 .2rem #ff52521a}.md-typeset .failure>.admonition-title,.md-typeset .failure>summary{background-color:#ff52521a}.md-typeset .failure>.admonition-title:before,.md-typeset .failure>summary:before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset .failure>.admonition-title:after,.md-typeset .failure>summary:after{color:#ff5252}.md-typeset .admonition.danger,.md-typeset details.danger{border-color:#ff1744}.md-typeset .admonition.danger:focus-within,.md-typeset details.danger:focus-within{box-shadow:0 0 0 .2rem #ff17441a}.md-typeset .danger>.admonition-title,.md-typeset .danger>summary{background-color:#ff17441a}.md-typeset .danger>.admonition-title:before,.md-typeset .danger>summary:before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset .danger>.admonition-title:after,.md-typeset .danger>summary:after{color:#ff1744}.md-typeset .admonition.bug,.md-typeset details.bug{border-color:#f50057}.md-typeset .admonition.bug:focus-within,.md-typeset details.bug:focus-within{box-shadow:0 0 0 .2rem #f500571a}.md-typeset .bug>.admonition-title,.md-typeset .bug>summary{background-color:#f500571a}.md-typeset .bug>.admonition-title:before,.md-typeset .bug>summary:before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset .bug>.admonition-title:after,.md-typeset .bug>summary:after{color:#f50057}.md-typeset .admonition.example,.md-typeset details.example{border-color:#7c4dff}.md-typeset .admonition.example:focus-within,.md-typeset details.example:focus-within{box-shadow:0 0 0 .2rem #7c4dff1a}.md-typeset .example>.admonition-title,.md-typeset .example>summary{background-color:#7c4dff1a}.md-typeset .example>.admonition-title:before,.md-typeset .example>summary:before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset .example>.admonition-title:after,.md-typeset .example>summary:after{color:#7c4dff}.md-typeset .admonition.quote,.md-typeset details.quote{border-color:#9e9e9e}.md-typeset .admonition.quote:focus-within,.md-typeset details.quote:focus-within{box-shadow:0 0 0 .2rem #9e9e9e1a}.md-typeset .quote>.admonition-title,.md-typeset .quote>summary{background-color:#9e9e9e1a}.md-typeset .quote>.admonition-title:before,.md-typeset .quote>summary:before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset .quote>.admonition-title:after,.md-typeset .quote>summary:after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:hover .footnote-backref,.md-typeset .footnote>ol>li:target .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :hover>.headerlink,.md-typeset :target>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset .headerlink:hover,.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset h1:target,.md-typeset h2:target,.md-typeset h3:target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.doc-contents td code{word-break:normal!important}.doc-md-description,.doc-md-description>p:first-child{display:inline}.md-typeset h5 .doc-object-name{text-transform:none}.doc .md-typeset__table,.doc .md-typeset__table table{display:table!important;width:100%}.doc .md-typeset__table tr{display:table-row}.doc-param-default,.doc-type_param-default{float:right}.doc-heading-parameter,.doc-heading-type_parameter{display:inline}.md-typeset .doc-heading-parameter{font-size:inherit}.doc-heading-parameter .headerlink,.doc-heading-type_parameter .headerlink{margin-left:0!important;margin-right:.2rem}.doc-section-title{font-weight:700}.doc-signature .autorefs{color:inherit;text-decoration-style:dotted}:host,:root,[data-md-color-scheme=default]{--doc-symbol-parameter-fg-color:#829bd1;--doc-symbol-type_parameter-fg-color:#829bd1;--doc-symbol-attribute-fg-color:#953800;--doc-symbol-function-fg-color:#8250df;--doc-symbol-method-fg-color:#8250df;--doc-symbol-class-fg-color:#0550ae;--doc-symbol-type_alias-fg-color:#0550ae;--doc-symbol-module-fg-color:#5cad0f;--doc-symbol-parameter-bg-color:#829bd11a;--doc-symbol-type_parameter-bg-color:#829bd11a;--doc-symbol-attribute-bg-color:#9538001a;--doc-symbol-function-bg-color:#8250df1a;--doc-symbol-method-bg-color:#8250df1a;--doc-symbol-class-bg-color:#0550ae1a;--doc-symbol-type_alias-bg-color:#0550ae1a;--doc-symbol-module-bg-color:#5cad0f1a}[data-md-color-scheme=slate]{--doc-symbol-parameter-fg-color:#829bd1;--doc-symbol-type_parameter-fg-color:#829bd1;--doc-symbol-attribute-fg-color:#ffa657;--doc-symbol-function-fg-color:#d2a8ff;--doc-symbol-method-fg-color:#d2a8ff;--doc-symbol-class-fg-color:#79c0ff;--doc-symbol-type_alias-fg-color:#79c0ff;--doc-symbol-module-fg-color:#baff79;--doc-symbol-parameter-bg-color:#829bd11a;--doc-symbol-type_parameter-bg-color:#829bd11a;--doc-symbol-attribute-bg-color:#ffa6571a;--doc-symbol-function-bg-color:#d2a8ff1a;--doc-symbol-method-bg-color:#d2a8ff1a;--doc-symbol-class-bg-color:#79c0ff1a;--doc-symbol-type_alias-bg-color:#79c0ff1a;--doc-symbol-module-bg-color:#baff791a}code.doc-symbol{border-radius:.1rem;font-size:.85em;font-weight:700;padding:0 .3em}a code.doc-symbol-parameter,code.doc-symbol-parameter{background-color:var(--doc-symbol-parameter-bg-color);color:var(--doc-symbol-parameter-fg-color)}code.doc-symbol-parameter:after{content:"param"}a code.doc-symbol-type_parameter,code.doc-symbol-type_parameter{background-color:var(--doc-symbol-type_parameter-bg-color);color:var(--doc-symbol-type_parameter-fg-color)}code.doc-symbol-type_parameter:after{content:"type-param"}a code.doc-symbol-attribute,code.doc-symbol-attribute{background-color:var(--doc-symbol-attribute-bg-color);color:var(--doc-symbol-attribute-fg-color)}code.doc-symbol-attribute:after{content:"attr"}a code.doc-symbol-function,code.doc-symbol-function{background-color:var(--doc-symbol-function-bg-color);color:var(--doc-symbol-function-fg-color)}code.doc-symbol-function:after{content:"func"}a code.doc-symbol-method,code.doc-symbol-method{background-color:var(--doc-symbol-method-bg-color);color:var(--doc-symbol-method-fg-color)}code.doc-symbol-method:after{content:"meth"}a code.doc-symbol-class,code.doc-symbol-class{background-color:var(--doc-symbol-class-bg-color);color:var(--doc-symbol-class-fg-color)}code.doc-symbol-class:after{content:"class"}a code.doc-symbol-type_alias,code.doc-symbol-type_alias{background-color:var(--doc-symbol-type_alias-bg-color);color:var(--doc-symbol-type_alias-fg-color)}code.doc-symbol-type_alias:after{content:"type"}a code.doc-symbol-module,code.doc-symbol-module{background-color:var(--doc-symbol-module-bg-color);color:var(--doc-symbol-module-fg-color)}code.doc-symbol-module:after{content:"mod"}:root{--md-admonition-icon--mkdocstrings-source:url('data:image/svg+xml;charset=utf-8,') }.md-typeset .admonition.mkdocstrings-source,.md-typeset details.mkdocstrings-source{border:none;padding:0}.md-typeset .admonition.mkdocstrings-source:focus-within,.md-typeset details.mkdocstrings-source:focus-within{box-shadow:none}.md-typeset .mkdocstrings-source>.admonition-title,.md-typeset .mkdocstrings-source>summary{background-color:inherit}.md-typeset .mkdocstrings-source>.admonition-title:before,.md-typeset .mkdocstrings-source>summary:before{background-color:var(--md-default-fg-color);-webkit-mask-image:var(--md-admonition-icon--mkdocstrings-source);mask-image:var(--md-admonition-icon--mkdocstrings-source)}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.984375em){.md-typeset div.arithmatex{margin:0 -.8rem}.md-typeset div.arithmatex>*{width:min-content}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset div.arithmatex mjx-assistive-mml{height:0}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset del.critic,.md-typeset ins.critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem;overflow:hidden}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset .emojione,.md-typeset .gemoji,.md-typeset .twemoji{--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset .emojione svg,.md-typeset .gemoji svg,.md-typeset .twemoji svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset .emojione svg.lucide,.md-typeset .gemoji svg.lucide,.md-typeset .twemoji svg.lucide{fill:#0000;stroke:currentcolor}.md-typeset .lg,.md-typeset .xl,.md-typeset .xxl,.md-typeset .xxxl{vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight .o,.highlight .ow{color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight .cpf,.highlight .l,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .si,.highlight .ss{color:var(--md-code-hl-string-color)}.highlight .cp,.highlight .se,.highlight .sh,.highlight .sr,.highlight .sx{color:var(--md-code-hl-special-color)}.highlight .il,.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--md-code-hl-number-color)}.highlight .k,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:var(--md-code-hl-keyword-color)}.highlight .kc,.highlight .n{color:var(--md-code-hl-name-color)}.highlight .bp,.highlight .nb,.highlight .no{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight .ne,.highlight .nf,.highlight .nn{color:var(--md-code-hl-function-color)}.highlight .nd,.highlight .ni,.highlight .nl,.highlight .nt{color:var(--md-code-hl-keyword-color)}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm,.highlight .cs,.highlight .sd{color:var(--md-code-hl-comment-color)}.highlight .na,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--md-code-hl-variable-color)}.highlight .ge,.highlight .gh,.highlight .go,.highlight .gp,.highlight .gr,.highlight .gs,.highlight .gt,.highlight .gu{color:var(--md-code-hl-generic-color)}.highlight .gd,.highlight .gi{border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color--light);box-shadow:2px 0 0 0 var(--md-code-hl-color) inset;display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:sticky;-webkit-user-select:none;user-select:none;z-index:3}.highlight code>span[id^=__span]>:last-child .md-annotation{margin-right:2.4rem}.highlight code[data-md-copying]{display:initial}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable tbody,.highlighttable td{display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .linenodiv span[class]{padding-right:.5882352941em}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.984375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:after,.md-typeset .keys kbd:before{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-set>input.focus-visible~.tabbed-labels:before{background-color:var(--md-accent-fg-color)}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-default-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,background-color .25s,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-default-fg-color)}.md-typeset .tabbed-labels>label>[href]:first-child{color:inherit}.md-typeset .tabbed-labels--linked>label{padding:0}.md-typeset .tabbed-labels--linked>label>a{display:block;padding:.78125em 1.25em .625em}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,#0000);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,#0000);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.984375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-default-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.md-typeset [role=dialog] .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset [role=dialog] .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset [role=dialog] .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset [role=dialog] .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset [role=dialog] .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset [role=dialog] .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset [role=dialog] .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset [role=dialog] .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset [role=dialog] .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset [role=dialog] .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset [role=dialog] .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset [role=dialog] .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset [role=dialog] .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset [role=dialog] .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset [role=dialog] .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset [role=dialog] .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset [role=dialog] .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset [role=dialog] .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset [role=dialog] .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset [role=dialog] .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),[role=dialog] .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,[role=dialog] .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),[role=dialog] .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),[role=dialog] .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),[role=dialog] .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),[role=dialog] .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),[role=dialog] .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),[role=dialog] .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),[role=dialog] .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),[role=dialog] .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),[role=dialog] .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),[role=dialog] .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),[role=dialog] .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),[role=dialog] .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),[role=dialog] .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),[role=dialog] .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),[role=dialog] .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),[role=dialog] .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),[role=dialog] .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),[role=dialog] .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-default-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}@media print{.giscus,[id=__comments]{display:none}}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color);--md-mermaid-sequence-actor-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actor-fg-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-actor-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-actor-line-color:var(--md-default-fg-color--lighter);--md-mermaid-sequence-actorman-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actorman-line-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-box-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-box-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-label-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-label-fg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-loop-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-loop-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-loop-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-message-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-message-line-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-note-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-border-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-number-bg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-number-fg-color:var(--md-accent-bg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr));margin:1em 0}.md-typeset .grid.cards>ol,.md-typeset .grid.cards>ul{display:contents}.md-typeset .grid.cards>ol>li,.md-typeset .grid.cards>ul>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.1rem;display:block;margin:0;padding:.8rem;transition:border .25s,box-shadow .25s}.md-typeset .grid.cards>ol>li:focus-within,.md-typeset .grid.cards>ol>li:hover,.md-typeset .grid.cards>ul>li:focus-within,.md-typeset .grid.cards>ul>li:hover,.md-typeset .grid>.card:focus-within,.md-typeset .grid>.card:hover{border-color:#0000;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>ol>li>hr,.md-typeset .grid.cards>ul>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>ol>li>:first-child,.md-typeset .grid.cards>ul>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>ol>li>:last-child,.md-typeset .grid.cards>ul>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*,.md-typeset .grid>.admonition,.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>.md-typeset details,.md-typeset .grid>details,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/assets/stylesheets/classic/palette.7dc9a0ad.min.css b/src/httpcore2/site-httpcore2/assets/stylesheets/classic/palette.7dc9a0ad.min.css new file mode 100644 index 00000000..2d838197 --- /dev/null +++ b/src/httpcore2/site-httpcore2/assets/stylesheets/classic/palette.7dc9a0ad.min.css @@ -0,0 +1 @@ +@media screen{[data-md-color-scheme=slate]{--md-default-fg-color:hsla(var(--md-hue),15%,90%,0.82);--md-default-fg-color--light:hsla(var(--md-hue),15%,90%,0.56);--md-default-fg-color--lighter:hsla(var(--md-hue),15%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),15%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,14%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,14%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,14%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,14%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,0.82);--md-code-bg-color:hsla(var(--md-hue),15%,18%,1);--md-code-bg-color--light:hsla(var(--md-hue),15%,18%,0.9);--md-code-bg-color--lighter:hsla(var(--md-hue),15%,18%,0.54);--md-code-hl-color:#2977ff;--md-code-hl-color--light:#2977ff1a;--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-kbd-color:hsla(var(--md-hue),15%,90%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,90%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-mark-color:#4287ff4d;--md-typeset-table-color:hsla(var(--md-hue),15%,95%,0.12);--md-typeset-table-color--light:hsla(var(--md-hue),15%,95%,0.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-bg-color:hsla(var(--md-hue),15%,10%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,8%,1);--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #00000040,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0006,0 0 0.05rem #00000059;color-scheme:dark}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate]{--color-foreground:255 255 255;--color-background:22 23 26;--color-background-subtle:33 34 38;--color-backdrop:11 12 15}[data-md-color-scheme=slate][data-md-color-primary=pink]{--md-typeset-a-color:#ed5487}[data-md-color-scheme=slate][data-md-color-primary=purple]{--md-typeset-a-color:#c46fd3}[data-md-color-scheme=slate][data-md-color-primary=deep-purple]{--md-typeset-a-color:#a47bea}[data-md-color-scheme=slate][data-md-color-primary=indigo]{--md-typeset-a-color:#5488e8}[data-md-color-scheme=slate][data-md-color-primary=teal]{--md-typeset-a-color:#00ccb8}[data-md-color-scheme=slate][data-md-color-primary=green]{--md-typeset-a-color:#71c174}[data-md-color-scheme=slate][data-md-color-primary=deep-orange]{--md-typeset-a-color:#ff764d}[data-md-color-scheme=slate][data-md-color-primary=brown]{--md-typeset-a-color:#c1775c}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=blue-grey],[data-md-color-scheme=slate][data-md-color-primary=grey],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#5e8bde}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}}[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:#ff19471a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:#f500561a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:#df41fb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:#7c4dff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:#4287ff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:#0091eb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:#00bad61a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:#00bda41a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:#00c7531a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:#63de171a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:#b0eb001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:#ffd5001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:#ffaa001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:#ff91001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:#ff6e421a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=light-green]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#72ad2e}[data-md-color-primary=lime]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#8b990a}[data-md-color-primary=yellow]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#b8a500}[data-md-color-primary=amber]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#d19d00}[data-md-color-primary=orange]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#e68a00}[data-md-color-primary=white]{--md-primary-fg-color:hsla(var(--md-hue),0%,100%,1);--md-primary-fg-color--light:hsla(var(--md-hue),0%,100%,0.7);--md-primary-fg-color--dark:hsla(var(--md-hue),0%,0%,0.07);--md-primary-bg-color:hsla(var(--md-hue),0%,0%,0.87);--md-primary-bg-color--light:hsla(var(--md-hue),0%,0%,0.54);--md-typeset-a-color:#4051b5}[data-md-color-primary=white] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=white] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:hsla(var(--md-hue),0%,0%,.07)}[data-md-color-primary=white] .md-search__form:hover{background-color:hsla(var(--md-hue),0%,0%,.32)}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:hsla(var(--md-hue),0%,0%,.87)}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid #00000012}}[data-md-color-primary=black]{--md-primary-fg-color:hsla(var(--md-hue),15%,9%,1);--md-primary-fg-color--light:hsla(var(--md-hue),15%,9%,0.54);--md-primary-fg-color--dark:hsla(var(--md-hue),15%,9%,1);--md-primary-bg-color:hsla(var(--md-hue),15%,100%,1);--md-primary-bg-color--light:hsla(var(--md-hue),15%,100%,0.7);--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=black] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:hsla(var(--md-hue),0%,100%,1)}[data-md-color-primary=black] .md-header{background-color:hsla(var(--md-hue),15%,9%,1)}@media screen and (max-width:59.984375em){[data-md-color-primary=black] .md-nav__source{background-color:hsla(var(--md-hue),15%,11%,.87)}}@media screen and (max-width:76.234375em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:hsla(var(--md-hue),15%,9%,1)}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:hsla(var(--md-hue),15%,9%,1)}} \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/assets/stylesheets/modern/main.fba56155.min.css b/src/httpcore2/site-httpcore2/assets/stylesheets/modern/main.fba56155.min.css new file mode 100644 index 00000000..9e1db826 --- /dev/null +++ b/src/httpcore2/site-httpcore2/assets/stylesheets/modern/main.fba56155.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-scheme=default]{color-scheme:light}[data-md-color-scheme=default] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=default] img[src$="#only-dark"]{display:none}:root,[data-md-color-scheme=default]{--md-hue:225deg;--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008c;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#0000000d;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-bg-color--light:#f5f5f5b3;--md-code-bg-color--lighter:#f5f5f54d;--md-code-hl-color:#4287ff;--md-code-hl-color--light:#4287ff1a;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-mark-color:#ffff0080;--md-typeset-table-color:#0000001f;--md-typeset-table-color--light:rgba(0,0,0,.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-warning-fg-color:#000000de;--md-warning-bg-color:#ff9;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059;--color-foreground:0 0 0;--color-background:255 255 255;--color-background-subtle:240 240 240;--color-backdrop:255 255 255}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}.md-icon svg.lucide{fill:#0000;stroke:currentcolor}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}aside,body,input{font-feature-settings:"kern","liga";color:var(--md-typeset-color);font-family:var(--md-text-font-family)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-preview-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.75rem;letter-spacing:-.01em;line-height:1.8;overflow-wrap:break-word}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color);font-size:1.875em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:700;letter-spacing:-.025em}.md-typeset h2{font-size:1.5em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:700;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset h5 code{text-transform:none}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);text-decoration:underline;word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset a code{color:var(--md-typeset-a-color)}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none;transition:background-color 125ms}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.2rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:.25em .4em;transition:color 125ms,background-color 125ms;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{border-radius:.4rem;-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{border-radius:.2rem;box-shadow:0 0 0 .05rem var(--md-typeset-kbd-border-color),0 .15rem 0 var(--md-typeset-kbd-border-color);color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}.md-typeset [data-preview]{position:relative}[dir=ltr] .md-typeset [data-preview]:after{margin-left:.125em}[dir=rtl] .md-typeset [data-preview]:after{margin-right:.125em}.md-typeset [data-preview]:after{background-color:currentcolor;content:"";display:inline-block;height:.8em;-webkit-mask-image:var(--md-typeset-preview-icon);mask-image:var(--md-typeset-preview-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-top;width:.8em}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}.md-typeset ul[type]{list-style-type:revert-layer}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}.md-typeset ol ol ol ol,.md-typeset ul ol ol ol{list-style-type:upper-alpha}.md-typeset ol ol ol ol ol,.md-typeset ul ol ol ol ol{list-style-type:upper-roman}.md-typeset ol[type],.md-typeset ul[type]{list-style-type:revert-layer}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}[dir=ltr] .md-typeset ol li ol,[dir=ltr] .md-typeset ol li ul,[dir=ltr] .md-typeset ul li ol,[dir=ltr] .md-typeset ul li ul{margin-left:.625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:fit-content}.md-typeset figure img{display:block;margin:0 auto}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td>:first-child,.md-typeset table:not([class]) th>:first-child{margin-top:0}.md-typeset table:not([class]) td>:last-child,.md-typeset table:not([class]) th>:last-child{margin-bottom:0}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:var(--md-typeset-table-color--light);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.984375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-banner{background-color:var(--md-accent-fg-color--transparent);color:var(--md-default-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background-color:var(--md-warning-bg-color);color:var(--md-warning-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.no-js .md-banner__button{display:none}.md-banner__button:hover{opacity:.7}html{scrollbar-gutter:stable;font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.984375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:focus,.md-clipboard:hover{color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:focus code,.md-clipboard--inline:hover code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}:root{--md-code-select-icon:url('data:image/svg+xml;charset=utf-8,');--md-code-copy-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-code__content{display:grid}.md-code__nav{background-color:var(--md-code-bg-color--lighter);border-radius:.1rem;display:flex;gap:.2rem;padding:.2rem;position:absolute;right:.25em;top:.25em;transition:background-color .25s;z-index:1}:hover>.md-code__nav{background-color:var(--md-code-bg-color--light)}.md-code__button{color:var(--md-default-fg-color--lightest);cursor:pointer;display:block;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;transition:color .25s;width:1.5em}:hover>*>.md-code__button{color:var(--md-default-fg-color--light)}.md-code__button.focus-visible,.md-code__button:hover{color:var(--md-accent-fg-color)}.md-code__button--active{color:var(--md-default-fg-color)!important}.md-code__button:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-code__button[data-md-type=select]:after{-webkit-mask-image:var(--md-code-select-icon);mask-image:var(--md-code-select-icon)}.md-code__button[data-md-type=copy]:after{-webkit-mask-image:var(--md-code-copy-icon);mask-image:var(--md-code-copy-icon)}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .35s both;-webkit-backdrop-filter:blur(.2rem);backdrop-filter:blur(.2rem);background-color:var(--md-default-bg-color--light);height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{bottom:0;display:flex;justify-content:center;max-height:100%;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.8rem;box-shadow:var(--md-shadow-z3);margin:.4rem;overflow:auto;padding-left:1.2rem;padding-right:1.2rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{line-height:1.2;margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.984375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.7rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{background-color:var(--md-default-fg-color--lightest);border-radius:.4rem;display:flex;margin-top:.2rem;padding:.3rem}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color);transition:color .25s,background-color .25s}.md-typeset .md-content__button svg{opacity:.5;transition:opacity .25s}.md-typeset .md-content__button:focus,.md-typeset .md-content__button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .md-content__button:focus svg,.md-typeset .md-content__button:hover svg{opacity:1}.md-content__button svg{height:.9rem;width:.9rem}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}.md-content__button svg.lucide{fill:#0000;stroke:currentcolor}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-accent-fg-color);border-radius:1.2rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem 1.2rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{display:flex;flex-wrap:wrap;place-content:baseline center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}@media print{.md-feedback{display:none}}.md-footer{background-color:var(--md-default-bg-color);border-top:.05rem solid var(--md-default-fg-color--lightest);color:var(--md-default-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{align-items:end;display:flex;flex-grow:0.01;margin-bottom:.4rem;margin-top:1rem;max-width:100%;outline-color:var(--md-accent-fg-color);overflow:hidden;transition:opacity .25s}.md-footer__link:focus,.md-footer__link:hover{opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.984375em){.md-footer__link--prev{flex-shrink:0}.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.8rem;margin-bottom:.7rem;max-width:calc(100% - 2.4rem);padding:0 1rem;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.6rem;opacity:.7}.md-footer-meta{background-color:var(--md-default-fg-color--lightest)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a:not(:focus,:hover){color:var(--md-default-fg-color)}.md-copyright{color:var(--md-default-fg-color--light);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-default-fg-color)}.md-social{display:inline-flex;gap:.2rem;margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-social__link svg.lucide{fill:#0000;stroke:currentcolor}.md-typeset .md-button{background-color:var(--md-default-fg-color--lightest);border-radius:1.2rem;color:var(--md-default-fg-color--light);cursor:pointer;display:inline-block;font-size:.875em;font-weight:700;padding:.625em 2em;text-decoration:none;transition:color 125ms,background-color 125ms,opacity 125ms}.md-typeset .md-button.focus-visible{outline-offset:0}.md-typeset .md-button:focus,.md-typeset .md-button:hover{color:var(--md-default-fg-color--light);opacity:.8}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button--primary:focus,.md-typeset .md-button--primary:hover{color:var(--md-primary-bg-color);opacity:.8}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:focus,.md-typeset .md-input:hover{border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{-webkit-backdrop-filter:blur(.4rem);backdrop-filter:blur(.4rem);background-color:var(--md-default-bg-color--light);color:var(--md-default-fg-color);display:block;left:0;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1)}.md-header--shadow{box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest);transition:transform .25s cubic-bezier(.1,.7,.1,1)}.md-header__inner{align-items:center;display:flex;padding:0 .4rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.234375em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo img,.md-header__button.md-logo svg{fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo img.lucide,.md-header__button.md-logo svg.lucide{fill:#0000;stroke:currentcolor}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;letter-spacing:-.025em;line-height:2.4rem;margin-left:.4rem;margin-right:.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;white-space:nowrap}.md-header__option>input{bottom:0}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.5rem;width:11.5rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}.md-header .md-icon svg{height:1rem;width:1rem}:root{--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3;transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav .md-nav__title{display:none}.md-nav__list{display:flex;flex-direction:column;gap:.2rem;list-style:none;margin:0;padding:0}[dir=ltr] .md-nav__list .md-nav__list{margin-left:.6rem}[dir=rtl] .md-nav__list .md-nav__list{margin-right:.6rem}.md-nav__item--nested .md-nav__list:after,.md-nav__item--nested .md-nav__list:before{content:" ";display:block;height:0}.md-nav__link{align-items:flex-start;border-radius:.4rem;cursor:pointer;display:flex;gap:.6rem;margin-left:.2rem;margin-right:.2rem;padding:.35rem .8rem;transition:color .25s,background-color .25s}.md-nav__link .md-nav__link{margin:0}.md-nav__link--passed,.md-nav__link--passed code{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active{font-weight:500}.md-nav--primary .md-nav__item .md-nav__link--active{background:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-nav__item .md-nav__link--active,.md-nav__item .md-nav__link--active code{color:var(--md-typeset-a-color)}.md-nav__item .md-nav__link--active code svg,.md-nav__item .md-nav__link--active svg{opacity:1}[dir=ltr] .md-nav__item--nested>.md-nav__link:not(.md-nav__container){padding-right:.35rem}[dir=rtl] .md-nav__item--nested>.md-nav__link:not(.md-nav__container){padding-left:.35rem}.md-nav__link .md-ellipsis{flex-grow:1;position:relative}.md-nav__link .md-ellipsis code{word-break:normal}.md-nav__link .md-typeset{font-size:.7rem;line-height:1.3}.md-nav__link svg{fill:currentcolor;flex-shrink:0;height:1.3em;opacity:.5;position:relative;width:1.3em}.md-nav__link svg.lucide{fill:#0000;stroke:currentcolor}.md-nav--primary .md-nav__link[for]:focus:not(.md-nav__link--active),.md-nav--primary .md-nav__link[for]:hover:not(.md-nav__link--active),.md-nav--primary .md-nav__link[href]:focus:not(.md-nav__link--active),.md-nav--primary .md-nav__link[href]:hover:not(.md-nav__link--active){background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color)}.md-nav--secondary .md-nav__link{margin-left:.2rem;margin-right:.2rem;overflow-wrap:normal;padding:.35rem .8rem}.md-nav--secondary .md-nav__link[for]:focus,.md-nav--secondary .md-nav__link[for]:hover,.md-nav--secondary .md-nav__link[href]:focus,.md-nav--secondary .md-nav__link[href]:hover{background-color:initial;color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link[for=__toc],.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__icon{font-size:.9rem;height:.9rem;width:.9rem}[dir=rtl] .md-nav__icon:after{transform:rotate(180deg)}.md-nav__item--nested .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;width:100%}@media screen and (min-width:76.25em){.md-nav__item--nested.md-nav__item--section>.md-nav__link .md-nav__icon:after{display:none}}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon:after,.md-nav__item--nested .md-toggle--indeterminate~.md-nav__link .md-nav__icon:after{transform:rotate(90deg)}.md-nav__container{background:#0000;gap:.2rem;padding:0}.md-nav__container>:first-child{flex-grow:1;min-width:0}.md-nav__container>:nth-child(2){padding:.35rem}@media screen and (min-width:76.25em){.md-nav__item--section>.md-nav__container>:nth-child(2){display:none}}.md-nav__container__icon{flex-shrink:0}.md-nav__toggle~.md-nav{display:grid;grid-template-rows:minmax(.005rem,0fr);opacity:0;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .25s,visibility 0ms .25s;visibility:collapse}.md-nav__toggle~.md-nav>.md-nav__list{overflow:hidden}.md-nav__toggle.md-toggle--indeterminate~.md-nav,.md-nav__toggle:checked~.md-nav{grid-template-rows:minmax(.4rem,1fr);opacity:1;transition:grid-template-rows .25s cubic-bezier(.86,0,.07,1),opacity .15s .1s,visibility 0ms;visibility:visible}.md-nav__toggle.md-toggle--indeterminate~.md-nav{transition:none}.md-nav--secondary{margin-bottom:.1rem;margin-top:.1rem}.md-nav--secondary .md-nav{margin-top:.2rem}.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);display:flex;font-weight:700;margin-left:.2rem;margin-right:.2rem;padding:.35rem .6rem;position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}.md-nav--secondary .md-nav__link{padding:.2rem .6rem}@media screen and (max-width:76.234375em){.md-nav--primary{margin-bottom:.4rem;margin-left:.2rem;margin-right:.2rem}.md-nav .md-nav__title[for=__drawer]{align-items:center;border-bottom:.05rem solid var(--md-default-fg-color-lightest);display:flex;font-size:.8rem;font-weight:700;gap:.4rem;padding:.8rem}.md-nav .md-nav__title[for=__drawer] .md-logo{height:1.6rem;width:1.6rem}.md-nav .md-nav__title[for=__drawer] .md-logo img,.md-nav .md-nav__title[for=__drawer] .md-logo svg{fill:currentcolor;display:block;height:100%;max-width:100%;object-fit:contain;width:auto}.md-nav .md-nav__title[for=__drawer] .md-logo img.lucide,.md-nav .md-nav__title[for=__drawer] .md-logo svg.lucide{fill:#0000;stroke:currentcolor}}.md-nav__source{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.4rem;margin:.2rem .2rem .6rem;transition:background-color .25s,border-color .25s}.md-nav__source:focus,.md-nav__source:hover{background-color:var(--md-default-fg-color--lightest);border-color:#0000}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{margin-left:1.1rem}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{margin-right:1.1rem}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-default-fg-color--lightest)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-default-fg-color--lightest)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:.5em;margin-top:.5em;opacity:1;visibility:visible}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary .md-nav__link{background:#0000}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary .md-nav__link--active{font-weight:500}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary .md-nav__link:focus,.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary .md-nav__link:hover{color:var(--md-accent-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__list{margin-left:0;overflow:visible;padding-bottom:0}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}@media screen and (min-width:76.25em){.md-nav--primary{margin-bottom:.1rem;margin-top:.1rem}.md-nav__source{display:none}[dir=ltr] .md-nav__list .md-nav__item--section>.md-nav>.md-nav__list{margin-left:0}[dir=rtl] .md-nav__list .md-nav__item--section>.md-nav>.md-nav__list{margin-right:0}.md-nav__item--section>.md-nav__link--active,.md-nav__item--section>.md-nav__link>.md-nav__link--active{font-weight:700}.md-nav__item--section{margin-top:.4rem}.md-nav__item--section:first-child{margin-top:0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700}.md-nav__item--section>.md-nav__link:not(.md-nav__container){pointer-events:none}.md-nav__item--section>.md-nav{display:block;opacity:1;visibility:visible}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav--lifted{margin-top:0}.md-nav--lifted>.md-nav__list>.md-nav__item{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav{margin-top:.1rem}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav>.md-nav__list:before,.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active.md-nav__item--section{margin:0}.md-nav--lifted .md-nav[data-md-level="1"]{grid-template-rows:minmax(.4rem,1fr);opacity:1;visibility:visible}}:root{--md-path-icon:url('data:image/svg+xml;charset=utf-8,')}.md-path{font-size:.7rem;margin:.4rem .8rem 0;overflow:auto;padding-top:1.2rem}.md-path:not([hidden]){display:block}@media screen and (min-width:76.25em){.md-path{margin:.4rem 1.2rem 0}}.md-path__list{align-items:center;display:flex;gap:.2rem;list-style:none;margin:0;padding:0}.md-path__item:not(:first-child){align-items:center;display:inline-flex;gap:.2rem;white-space:nowrap}.md-path__item:not(:first-child):before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline;height:.6rem;-webkit-mask-image:var(--md-path-icon);mask-image:var(--md-path-icon);width:.6rem}.md-path__link{align-items:center;color:var(--md-default-fg-color--light);display:flex;transition:color .25s}.md-path__link:focus,.md-path__link:hover{color:var(--md-accent-fg-color)}:root{--md-progress-value:0;--md-progress-delay:400ms}.md-progress{background:var(--md-primary-bg-color);height:.075rem;opacity:min(clamp(0,var(--md-progress-value),1),clamp(0,100 - var(--md-progress-value),1));position:fixed;top:0;transform:scaleX(calc(var(--md-progress-value)*1%));transform-origin:left;transition:transform .5s cubic-bezier(.19,1,.22,1),opacity .25s var(--md-progress-delay);width:100%;z-index:4}:root{--md-search-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:45em){.md-search{padding:.2rem 0}}@media screen and (max-width:59.984375em){.md-search{display:none}}.no-js .md-search{display:none}[dir=ltr] .md-search__button{padding-left:1.9rem;padding-right:2.2rem}[dir=rtl] .md-search__button{padding-left:2.2rem;padding-right:1.9rem}.md-search__button{background:var(--md-default-bg-color);color:var(--md-default-fg-color);cursor:pointer;font-size:.7rem;position:relative;text-align:left}@media screen and (min-width:45em){.md-search__button{background-color:var(--md-default-fg-color--lightest);border-radius:.4rem;height:1.6rem;transition:background-color .4s,color .4s;width:8.9rem}.md-search__button:focus,.md-search__button:hover{background-color:var(--md-default-fg-color--lighter);color:var(--md-default-fg-color)}}[dir=ltr] .md-search__button:before{left:0}[dir=rtl] .md-search__button:before{right:0}.md-search__button:before{background-color:var(--md-default-fg-color);content:"";height:1rem;margin-left:.5rem;-webkit-mask-image:var(--md-search-icon);mask-image:var(--md-search-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.3rem;width:1rem}.md-search__button:after{background:var(--md-default-bg-color--light);border-radius:.2rem;content:"Ctrl+K";display:block;font-size:.6rem;padding:.1rem .2rem;position:absolute;right:.6rem;top:.35rem}[data-platform^=Mac] .md-search__button:after{content:"⌘K"}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.4rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}@media screen and (max-width:59.984375em){.md-select__inner{left:100%;transform:translate3d(-100%,.3rem,0)}}.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{max-height:min(75vh,28rem);opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}@media screen and (max-width:59.984375em){.md-select:focus-within .md-select__inner,.md-select:hover .md-select__inner{transform:translate3d(-100%,0,0)}}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";filter:drop-shadow(0 -1px 0 var(--md-default-fg-color--lightest));height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}@media screen and (max-width:59.984375em){.md-select__inner:after{left:auto;right:1rem}}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:focus,.md-select__link:hover{color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.1rem 0;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.234375em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{-webkit-backdrop-filter:blur(.4rem);backdrop-filter:blur(.4rem);background-color:var(--md-default-bg-color--light);border-radius:.8rem;display:block;height:calc(100% - .8rem);position:fixed;top:.4rem;transform:translateX(0);transition:transform .2s cubic-bezier(.5,0,.5,0),box-shadow .2s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.5rem);transition:transform .25s cubic-bezier(.7,.7,.1,1),box-shadow .25s}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.5rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overscroll-behavior-y:contain;position:absolute;right:0;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{order:2}@media screen and (max-width:59.984375em){.md-sidebar--secondary{bottom:1.6rem;padding:0;position:fixed;right:.8rem;top:auto;width:auto;z-index:2}.md-sidebar--secondary .md-nav--secondary{margin-top:0}.md-sidebar--secondary .md-nav__title{padding:.55rem .6rem .35rem}.md-sidebar--secondary .md-sidebar__scrollwrap{display:flex;flex-direction:column-reverse;overflow-y:visible;position:relative}.md-sidebar--secondary .md-sidebar__inner{background-color:var(--md-default-bg-color);border-radius:.4rem;bottom:2.7rem;box-shadow:var(--md-shadow-z2);max-height:50vh;opacity:0;overflow-y:auto;padding-bottom:.4rem;pointer-events:none;position:absolute;right:0;transform:translateY(.4rem);transition:transform 0ms .25s,opacity .25s;width:11.7rem}.md-sidebar--secondary [type=checkbox]:checked~.md-sidebar__inner{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(0,1,.35,1),opacity .25s,z-index 0ms}.md-sidebar--secondary .md-sidebar-button{-webkit-backdrop-filter:blur(.4rem);backdrop-filter:blur(.4rem);background-color:var(--md-default-bg-color--light);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:inline-flex;font-size:.7rem;gap:.4rem;outline:none;padding:.5rem;transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms}.md-sidebar--secondary .md-sidebar-button:after{background-color:currentcolor;content:"";display:block;height:.9rem;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:transform .25s;width:.9rem}.md-sidebar--secondary .md-sidebar-button:focus,.md-sidebar--secondary .md-sidebar-button:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-sidebar--secondary .md-sidebar-button__wrapper{text-align:right}}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.md-sidebar--secondary .md-sidebar-button{display:none}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{backface-visibility:hidden;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000}@media screen and (min-width:60em){.md-sidebar__scrollwrap{scrollbar-gutter:stable;scrollbar-width:thin}}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap:focus-within,.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap:focus-within::-webkit-scrollbar-thumb:hover,.md-sidebar__scrollwrap:hover::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}@media screen and (max-width:76.234375em){[dir=ltr] .md-sidebar__inner{padding-right:0}[dir=rtl] .md-sidebar__inner{padding-left:0}}}@media screen and (max-width:76.234375em){.md-overlay{-webkit-backdrop-filter:blur(.2rem);backdrop-filter:blur(.2rem);background-color:var(--md-default-bg-color--light);height:0;opacity:0;position:fixed;top:0;transition:width 0ms .5s,height 0ms .5s,opacity .25s 125ms;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{backface-visibility:hidden;display:block;font-size:.55rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}.md-header .md-source__icon svg{height:1.2rem;width:1.2rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts 0ms ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact 0ms ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-source-file{margin:1em 0}[dir=ltr] .md-source-file__fact{margin-right:.6rem}[dir=rtl] .md-source-file__fact{margin-left:.6rem}.md-source-file__fact{align-items:center;color:var(--md-default-fg-color--light);display:inline-flex;font-size:.68rem;gap:.3rem}.md-source-file__fact .md-icon{flex-shrink:0;margin-bottom:.05rem}[dir=ltr] .md-source-file__fact .md-author{float:left}[dir=rtl] .md-source-file__fact .md-author{float:right}.md-source-file__fact .md-author{margin-right:.2rem}.md-source-file__fact svg{width:.9rem}:root{--md-status:url('data:image/svg+xml;charset=utf-8,');--md-status--new:url('data:image/svg+xml;charset=utf-8,');--md-status--deprecated:url('data:image/svg+xml;charset=utf-8,')}.md-status:after{background-color:var(--md-default-fg-color--light);content:"";display:inline-block;height:1.125em;-webkit-mask-image:var(--md-status);mask-image:var(--md-status);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-bottom;width:1.125em}.md-status:hover:after{background-color:currentcolor}.md-status--new:after{-webkit-mask-image:var(--md-status--new);mask-image:var(--md-status--new)}.md-status--deprecated:after{-webkit-mask-image:var(--md-status--deprecated);mask-image:var(--md-status--deprecated)}.md-tabs{box-shadow:0 -.05rem 0 inset var(--md-default-fg-color--lightest);color:var(--md-default-fg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:2}@media print{.md-tabs{display:none}}@media screen and (max-width:76.234375em){.md-tabs{display:none}}.md-header--lifted .md-tabs{box-shadow:none;margin-bottom:-.05rem}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.4rem}[dir=rtl] .md-tabs__list{margin-right:.4rem}.md-tabs__list{contain:content;display:flex;list-style:none;margin:0;overflow:auto;padding:0;scrollbar-width:none;white-space:nowrap}.md-tabs__list::-webkit-scrollbar{display:none}.md-tabs__item{height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__item--active{border-bottom:.05rem solid var(--md-default-fg-color);font-weight:500;position:relative;transition:border-bottom .25s}.md-tabs[hidden] .md-tabs__item--active{border-bottom:.05rem solid #0000}.md-tabs__item--active .md-tabs__link{color:inherit;opacity:1}.md-tabs__link{backface-visibility:hidden;display:flex;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link:focus,.md-tabs__link:hover{color:inherit;opacity:1}[dir=ltr] .md-tabs__link svg{margin-right:.4rem}[dir=rtl] .md-tabs__link svg{margin-left:.4rem}.md-tabs__link svg{fill:currentcolor;height:1.3em}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags:not([hidden]){display:flex;flex-wrap:wrap;gap:.5em;margin-bottom:1.2rem;margin-top:.8rem;padding-top:1.2rem}.md-typeset .md-tag{align-items:center;background:var(--md-default-fg-color--lightest);border-radius:.4rem;display:inline-flex;font-size:.64rem;font-size:min(.8em,.64rem);font-weight:700;gap:.5em;letter-spacing:normal;line-height:1.6;padding:.3125em .78125em}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-shadow{opacity:.5}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon[href]:focus:before,.md-typeset .md-tag-icon[href]:hover:before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{transform:scale(.95)}75%{transform:scale(1)}to{transform:scale(.95)}}:root{--md-annotation-bg-icon:url('data:image/svg+xml;charset=utf-8,');--md-annotation-icon:url('data:image/svg+xml;charset=utf-8,')}.md-tooltip{backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.4rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x) - .1rem,100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:calc(var(--md-tooltip-y) - .1rem);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}.md-tooltip--inline{font-weight:400;-webkit-user-select:none;user-select:none;width:auto}.md-tooltip--inline:not(.md-tooltip--active){transform:translateY(.2rem) scale(.9)}.md-tooltip--inline .md-tooltip__inner{font-size:.55rem;padding:.2rem .4rem}[hidden]+.md-tooltip--inline{display:none}.focus-visible>.md-tooltip,.md-tooltip:target{outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-style:normal;font-weight:400;outline:none;text-align:initial;vertical-align:text-bottom;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}code .md-annotation{font-family:var(--md-code-font-family);font-size:inherit}.md-annotation:not([hidden]){display:inline-block;line-height:1.25}.md-annotation__index{border-radius:.01px;cursor:pointer;display:inline-block;margin-left:.4ch;margin-right:.4ch;outline:none;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none;vertical-align:text-top;z-index:0}.md-annotation .md-annotation__index{transition:z-index .25s}@media screen{.md-annotation__index{width:2.2ch}[data-md-visible]>.md-annotation__index{animation:pulse 2s infinite}.md-annotation__index:before{background:var(--md-default-bg-color);-webkit-mask-image:var(--md-annotation-bg-icon);mask-image:var(--md-annotation-bg-icon)}.md-annotation__index:after,.md-annotation__index:before{content:"";height:2.2ch;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:-.1ch;width:2.2ch;z-index:-1}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);-webkit-mask-image:var(--md-annotation-icon);mask-image:var(--md-annotation-icon);transform:scale(1.0001);transition:background-color .25s,transform .25s}.md-tooltip--active+.md-annotation__index:after{transform:rotate(45deg)}.md-tooltip--active+.md-annotation__index:after,:hover>.md-annotation__index:after{background-color:var(--md-accent-fg-color)}}.md-tooltip--active+.md-annotation__index{animation-play-state:paused;transition-duration:0ms;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block}@media print{.md-annotation__index [data-md-annotation-id]{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);font-weight:700;padding:0 .6ch;white-space:nowrap}.md-annotation__index [data-md-annotation-id]:after{content:attr(data-md-annotation-id)}}.md-typeset .md-annotation-list{counter-reset:annotation;list-style:none!important}.md-typeset .md-annotation-list li{position:relative}[dir=ltr] .md-typeset .md-annotation-list li:before{left:-2.125em}[dir=rtl] .md-typeset .md-annotation-list li:before{right:-2.125em}.md-typeset .md-annotation-list li:before{background:var(--md-default-fg-color--lighter);border-radius:2ch;color:var(--md-default-bg-color);content:counter(annotation);counter-increment:annotation;font-size:.8875em;font-weight:700;height:2ch;line-height:1.25;min-width:2ch;padding:0 .6ch;position:absolute;text-align:center;top:.25em}:root{--md-tooltip-width:20rem;--md-tooltip-tail:0.3rem}.md-tooltip2{backface-visibility:hidden;color:var(--md-default-fg-color);font-family:var(--md-text-font-family);opacity:0;pointer-events:none;position:absolute;top:calc(var(--md-tooltip-host-y) + var(--md-tooltip-y));transform:translateY(.4rem);transform-origin:calc(var(--md-tooltip-host-x) + var(--md-tooltip-x)) 0;transition:transform 0ms .25s,opacity .25s,z-index .25s;width:100%;z-index:0}.md-tooltip2:before{border-left:var(--md-tooltip-tail) solid #0000;border-right:var(--md-tooltip-tail) solid #0000;content:"";display:block;left:clamp(1.5 * .8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-tail),100vw - 2 * var(--md-tooltip-tail) - 1.5 * .8rem);position:absolute;z-index:1}.md-tooltip2--top:before{border-top:var(--md-tooltip-tail) solid var(--md-default-bg-color);bottom:calc(var(--md-tooltip-tail)*-1 + .025rem);filter:drop-shadow(0 1px 0 var(--md-default-fg-color--lightest))}.md-tooltip2--bottom:before{border-bottom:var(--md-tooltip-tail) solid var(--md-default-bg-color);filter:drop-shadow(0 -1px 0 var(--md-default-fg-color--lightest));top:calc(var(--md-tooltip-tail)*-1 + .025rem)}.md-tooltip2--active{opacity:1;transform:translateY(0);transition:transform .4s cubic-bezier(0,1,.35,1),opacity .25s,z-index 0ms;z-index:4}.md-tooltip2__inner{scrollbar-gutter:stable;background-color:var(--md-default-bg-color);border-radius:.4rem;box-shadow:var(--md-shadow-z2);left:clamp(.8rem,var(--md-tooltip-host-x) - .8rem,100vw - var(--md-tooltip-width) - .8rem);max-height:40vh;max-width:calc(100vw - 1.6rem);position:relative;scrollbar-width:thin}.md-tooltip2__inner::-webkit-scrollbar{height:.2rem;width:.2rem}.md-tooltip2__inner::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-tooltip2__inner::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}[role=dialog]>.md-tooltip2__inner{font-size:.64rem;overflow:auto;padding:0 .8rem;pointer-events:auto;width:var(--md-tooltip-width)}[role=dialog]>.md-tooltip2__inner:after,[role=dialog]>.md-tooltip2__inner:before{content:"";display:block;height:.8rem;position:sticky;width:100%;z-index:10}[role=dialog]>.md-tooltip2__inner:before{background:linear-gradient(var(--md-default-bg-color),#0000 75%);top:0}[role=dialog]>.md-tooltip2__inner:after{background:linear-gradient(#0000,var(--md-default-bg-color) 75%);bottom:0}[role=tooltip]>.md-tooltip2__inner{font-size:.55rem;font-weight:400;left:clamp(.8rem,var(--md-tooltip-host-x) + var(--md-tooltip-x) - var(--md-tooltip-width)/2,100vw - var(--md-tooltip-width) - .8rem);max-width:min(100vw - 2 * .8rem,400px);padding:.2rem .4rem;-webkit-user-select:none;user-select:none;width:fit-content}.md-tooltip2__inner.md-typeset>:first-child{margin-top:0}.md-tooltip2__inner.md-typeset>:last-child{margin-bottom:0}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{-webkit-backdrop-filter:blur(.4rem);backdrop-filter:blur(.4rem);background-color:var(--md-default-bg-color--light);border-radius:1.6rem;bottom:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:flex;font-size:.7rem;gap:.4rem;outline:none;padding:.5rem .9rem .5rem .7rem;position:fixed;top:auto!important;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:focus,.md-top:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;height:.9rem;vertical-align:-.5em;width:.9rem}.md-top svg.lucide{fill:#0000;stroke:currentcolor}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__alias{margin-left:.3rem;opacity:.7}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:focus-within .md-version__list,.md-version:hover .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (hover:none),(pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:focus,.md-version__link:hover{color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}html.glightbox-open{height:100%;overflow:initial}html .gslide .gslide-description,html .gslide .gslide-image img{background:var(--md-default-bg-color)}html .gslide .gslide-description{-webkit-user-select:text;user-select:text}html .gslide .gslide-title{color:var(--md-default-fg-color);font-size:.8rem;margin-bottom:.4rem;margin-top:0}html .gslide .gslide-desc{color:var(--md-default-fg-color--light);font-size:.7rem}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:#448aff1a;border-radius:.4rem;color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .8rem;page-break-inside:avoid}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:1.6rem;padding-right:.8rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.8rem;padding-right:1.6rem}.md-typeset .admonition-title,.md-typeset summary{font-weight:700;margin-bottom:1em;margin-top:.6rem;position:relative}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:0}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:0}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.125em;width:1rem}.md-typeset .admonition.note,.md-typeset details.note{background-color:#448aff1a}.md-typeset .note>.admonition-title:before,.md-typeset .note>summary:before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset .note>.admonition-title:after,.md-typeset .note>summary:after{color:#448aff}.md-typeset .admonition.abstract,.md-typeset details.abstract{background-color:#00b0ff1a}.md-typeset .abstract>.admonition-title:before,.md-typeset .abstract>summary:before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset .abstract>.admonition-title:after,.md-typeset .abstract>summary:after{color:#00b0ff}.md-typeset .admonition.info,.md-typeset details.info{background-color:#00b8d41a}.md-typeset .info>.admonition-title:before,.md-typeset .info>summary:before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset .info>.admonition-title:after,.md-typeset .info>summary:after{color:#00b8d4}.md-typeset .admonition.tip,.md-typeset details.tip{background-color:#00bfa51a}.md-typeset .tip>.admonition-title:before,.md-typeset .tip>summary:before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset .tip>.admonition-title:after,.md-typeset .tip>summary:after{color:#00bfa5}.md-typeset .admonition.success,.md-typeset details.success{background-color:#00c8531a}.md-typeset .success>.admonition-title:before,.md-typeset .success>summary:before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset .success>.admonition-title:after,.md-typeset .success>summary:after{color:#00c853}.md-typeset .admonition.question,.md-typeset details.question{background-color:#64dd171a}.md-typeset .question>.admonition-title:before,.md-typeset .question>summary:before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset .question>.admonition-title:after,.md-typeset .question>summary:after{color:#64dd17}.md-typeset .admonition.warning,.md-typeset details.warning{background-color:#ff91001a}.md-typeset .warning>.admonition-title:before,.md-typeset .warning>summary:before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset .warning>.admonition-title:after,.md-typeset .warning>summary:after{color:#ff9100}.md-typeset .admonition.failure,.md-typeset details.failure{background-color:#ff52521a}.md-typeset .failure>.admonition-title:before,.md-typeset .failure>summary:before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset .failure>.admonition-title:after,.md-typeset .failure>summary:after{color:#ff5252}.md-typeset .admonition.danger,.md-typeset details.danger{background-color:#ff17441a}.md-typeset .danger>.admonition-title:before,.md-typeset .danger>summary:before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset .danger>.admonition-title:after,.md-typeset .danger>summary:after{color:#ff1744}.md-typeset .admonition.bug,.md-typeset details.bug{background-color:#f500571a}.md-typeset .bug>.admonition-title:before,.md-typeset .bug>summary:before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset .bug>.admonition-title:after,.md-typeset .bug>summary:after{color:#f50057}.md-typeset .admonition.example,.md-typeset details.example{background-color:#7c4dff1a}.md-typeset .example>.admonition-title:before,.md-typeset .example>summary:before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset .example>.admonition-title:after,.md-typeset .example>summary:after{color:#7c4dff}.md-typeset .admonition.quote,.md-typeset details.quote{background-color:#9e9e9e1a}.md-typeset .quote>.admonition-title:before,.md-typeset .quote>summary:before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset .quote>.admonition-title:after,.md-typeset .quote>summary:after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateY(0);transition:none}.md-typeset .footnote>ol>li:hover .footnote-backref,.md-typeset .footnote>ol>li:target .footnote-backref{opacity:1;transform:translateY(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700;text-decoration:none}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateY(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateY(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateY(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;text-decoration:none;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :hover>.headerlink,.md-typeset :target>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset .headerlink:hover,.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset h1:target{--md-scroll-offset:0.1rem}.md-typeset h3:target,.md-typeset h4:target{--md-scroll-offset:-0.1rem}:root{--md-admonition-icon--mkdocstrings:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--mkdocstrings-open:url('data:image/svg+xml;charset=utf-8,')}.doc-object-name{font-family:var(--md-code-font-family)}code.doc-symbol-heading{margin-right:.4rem;padding:0}[dir=ltr] .doc-labels{margin-left:.4rem}[dir=rtl] .doc-labels{margin-right:.4rem}.doc-label code{background:#0000;border:1px solid var(--md-default-fg-color--lightest);border-radius:.5rem;color:var(--md-default-fg-color--light);font-weight:400;padding-left:.3rem;padding-right:.3rem;vertical-align:text-bottom}.doc-contents td code{word-break:normal!important}.doc-md-description,.doc-md-description>p:first-child{display:inline}.md-typeset h5 .doc-object-name{text-transform:none}.doc .md-typeset__table,.doc .md-typeset__table table{display:table!important;width:100%}.doc .md-typeset__table tr{display:table-row}.doc-param-default,.doc-type_param-default{float:right}.doc-heading-parameter,.doc-heading-type_parameter{display:inline}.md-typeset .doc-heading-parameter{font-size:inherit}.doc-heading-parameter .headerlink,.doc-heading-type_parameter .headerlink{margin-left:0!important;margin-right:.2rem}.doc-section-title{font-weight:700}.doc-signature .autorefs{color:inherit;text-decoration-style:dotted}div.doc-contents:not(.first){border-left:.05rem solid var(--md-code-bg-color);margin-left:.4rem;padding-left:.8rem}:host,:root,[data-md-color-scheme=default]{--doc-symbol-parameter-fg-color:#829bd1;--doc-symbol-type_parameter-fg-color:#829bd1;--doc-symbol-attribute-fg-color:#953800;--doc-symbol-function-fg-color:#8250df;--doc-symbol-method-fg-color:#8250df;--doc-symbol-class-fg-color:#0550ae;--doc-symbol-type_alias-fg-color:#0550ae;--doc-symbol-module-fg-color:#5cad0f}[data-md-color-scheme=slate]{--doc-symbol-parameter-fg-color:#829bd1;--doc-symbol-type_parameter-fg-color:#829bd1;--doc-symbol-attribute-fg-color:#ffa657;--doc-symbol-function-fg-color:#d2a8ff;--doc-symbol-method-fg-color:#d2a8ff;--doc-symbol-class-fg-color:#79c0ff;--doc-symbol-type_alias-fg-color:#79c0ff;--doc-symbol-module-fg-color:#baff79}.md-ellipsis:has(.doc-symbol){font-family:var(--md-code-font-family);font-size:.95em}code.doc-symbol{background-color:initial;border-radius:.1rem;font-size:1em;font-weight:400}a code.doc-symbol-parameter,code.doc-symbol-parameter{color:var(--doc-symbol-parameter-fg-color)}.md-content code.doc-symbol-parameter:after{content:"param"}.md-sidebar code.doc-symbol-parameter:after{content:"p"}a code.doc-symbol-type_parameter,code.doc-symbol-type_parameter{color:var(--doc-symbol-type_parameter-fg-color)}.md-content code.doc-symbol-type_parameter:after{content:"type-param"}.md-sidebar code.doc-symbol-type_parameter:after{content:"t"}a code.doc-symbol-attribute,code.doc-symbol-attribute{color:var(--doc-symbol-attribute-fg-color)}.md-content code.doc-symbol-attribute:after{content:"attribute"}.md-sidebar code.doc-symbol-attribute:after{content:"a"}a code.doc-symbol-function,code.doc-symbol-function{color:var(--doc-symbol-function-fg-color)}.md-content code.doc-symbol-function:after{content:"function"}.md-sidebar code.doc-symbol-function:after{content:"f"}a code.doc-symbol-method,code.doc-symbol-method{color:var(--doc-symbol-method-fg-color)}.md-content code.doc-symbol-method:after{content:"method"}.md-sidebar code.doc-symbol-method:after{content:"m"}a code.doc-symbol-class,code.doc-symbol-class{color:var(--doc-symbol-class-fg-color)}.md-content code.doc-symbol-class:after{content:"class"}.md-sidebar code.doc-symbol-class:after{content:"c"}a code.doc-symbol-type_alias,code.doc-symbol-type_alias{color:var(--doc-symbol-type_alias-fg-color)}.md-content code.doc-symbol-type_alias:after{content:"type"}.md-sidebar code.doc-symbol-type_alias:after{content:"t"}a code.doc-symbol-module,code.doc-symbol-module{color:var(--doc-symbol-module-fg-color)}.md-content code.doc-symbol-module:after{content:"module"}.md-sidebar code.doc-symbol-module:after{content:"mod"}.md-typeset details.mkdocstrings-source{background:#0000;border:.05rem solid var(--md-code-bg-color)}.md-typeset details.mkdocstrings-source>summary:before{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-admonition-icon--mkdocstrings);mask-image:var(--md-admonition-icon--mkdocstrings)}.md-typeset details.mkdocstrings-source[open]>summary:before{-webkit-mask-image:var(--md-admonition-icon--mkdocstrings-open);mask-image:var(--md-admonition-icon--mkdocstrings-open)}.md-typeset details.mkdocstrings-source>summary:after{background-color:var(--md-default-fg-color--light)}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.984375em){.md-typeset div.arithmatex{margin:0 -.8rem}.md-typeset div.arithmatex>*{width:min-content}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset div.arithmatex mjx-assistive-mml{height:0}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset del.critic,.md-typeset ins.critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem;margin-bottom:.6rem}[dir=ltr] .md-typeset summary{padding-right:1.6rem}[dir=rtl] .md-typeset summary{padding-left:1.6rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem;overflow:hidden}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:0}[dir=rtl] .md-typeset summary:after{left:0}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.125em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset .emojione,.md-typeset .gemoji,.md-typeset .twemoji{--md-icon-size:1.125em;display:inline-flex;height:var(--md-icon-size);vertical-align:text-top}.md-typeset .emojione svg,.md-typeset .gemoji svg,.md-typeset .twemoji svg{fill:currentcolor;max-height:100%;width:var(--md-icon-size)}.md-typeset .emojione svg.lucide,.md-typeset .gemoji svg.lucide,.md-typeset .twemoji svg.lucide{fill:#0000;stroke:currentcolor}.md-typeset .lg,.md-typeset .xl,.md-typeset .xxl,.md-typeset .xxxl{vertical-align:text-bottom}.md-typeset .middle{vertical-align:middle}.md-typeset .lg{--md-icon-size:1.5em}.md-typeset .xl{--md-icon-size:2.25em}.md-typeset .xxl{--md-icon-size:3em}.md-typeset .xxxl{--md-icon-size:4em}.highlight .o,.highlight .ow{color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight .cpf,.highlight .l,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .si,.highlight .ss{color:var(--md-code-hl-string-color)}.highlight .cp,.highlight .se,.highlight .sh,.highlight .sr,.highlight .sx{color:var(--md-code-hl-special-color)}.highlight .il,.highlight .m,.highlight .mb,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--md-code-hl-number-color)}.highlight .k,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:var(--md-code-hl-keyword-color)}.highlight .kc,.highlight .n{color:var(--md-code-hl-name-color)}.highlight .bp,.highlight .nb,.highlight .no{color:var(--md-code-hl-constant-color)}.highlight .nc,.highlight .ne,.highlight .nf,.highlight .nn{color:var(--md-code-hl-function-color)}.highlight .nd,.highlight .ni,.highlight .nl,.highlight .nt{color:var(--md-code-hl-keyword-color)}.highlight .c,.highlight .c1,.highlight .ch,.highlight .cm,.highlight .cs,.highlight .sd{color:var(--md-code-hl-comment-color)}.highlight .na,.highlight .nv,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--md-code-hl-variable-color)}.highlight .ge,.highlight .gh,.highlight .go,.highlight .gp,.highlight .gr,.highlight .gs,.highlight .gt,.highlight .gu{color:var(--md-code-hl-generic-color)}.highlight .gd,.highlight .gi{border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color--light);box-shadow:2px 0 0 0 var(--md-code-hl-color) inset;display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.4rem;border-top-right-radius:.4rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:sticky;-webkit-user-select:none;user-select:none;z-index:3}.highlight code>span[id^=__span]>:last-child .md-annotation{margin-right:2.4rem}.highlight code[data-md-copying]{display:initial}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable tbody,.highlighttable td{display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.4rem;border-top-left-radius:.4rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .linenodiv span[class]{padding-right:.5882352941em}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit;text-decoration:none}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.4rem;border-bottom-right-radius:.4rem;border-top-width:.4rem;margin-top:-1.5em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.984375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:after,.md-typeset .keys kbd:before{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.075rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-set>input.focus-visible~.tabbed-labels:before{background-color:var(--md-accent-fg-color)}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-default-fg-color);bottom:0;content:"";display:block;height:1.5px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,background-color .25s,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.7rem;font-weight:400;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-default-fg-color)}.md-typeset .tabbed-labels>label>[href]:first-child{color:inherit;text-decoration:none}.md-typeset .tabbed-labels--linked>label{padding:0}.md-typeset .tabbed-labels--linked>label>a{display:block;padding:.78125em 1.25em .625em}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;-webkit-backdrop-filter:blur(.4rem);backdrop-filter:blur(.4rem);background-color:var(--md-default-bg-color--light);border-radius:100%;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.4rem;pointer-events:auto;transition:transform 125ms;width:.9rem}.md-typeset .tabbed-button:hover{transform:scale(1.125)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.984375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-default-fg-color);font-weight:500}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.md-typeset [role=dialog] .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset [role=dialog] .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset [role=dialog] .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset [role=dialog] .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset [role=dialog] .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset [role=dialog] .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset [role=dialog] .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset [role=dialog] .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset [role=dialog] .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset [role=dialog] .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset [role=dialog] .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset [role=dialog] .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset [role=dialog] .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset [role=dialog] .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset [role=dialog] .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset [role=dialog] .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset [role=dialog] .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset [role=dialog] .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset [role=dialog] .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset [role=dialog] .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),[role=dialog] .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,[role=dialog] .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),[role=dialog] .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),[role=dialog] .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),[role=dialog] .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),[role=dialog] .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),[role=dialog] .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),[role=dialog] .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),[role=dialog] .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),[role=dialog] .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),[role=dialog] .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),[role=dialog] .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),[role=dialog] .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),[role=dialog] .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),[role=dialog] .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),[role=dialog] .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),[role=dialog] .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),[role=dialog] .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),[role=dialog] .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),[role=dialog] .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-default-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lighter);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.25em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}@media print{.giscus,[id=__comments]{display:none}}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color);--md-mermaid-sequence-actor-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actor-fg-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-actor-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-actor-line-color:var(--md-default-fg-color--lighter);--md-mermaid-sequence-actorman-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-actorman-line-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-box-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-box-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-label-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-label-fg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-loop-bg-color:var(--md-mermaid-node-bg-color);--md-mermaid-sequence-loop-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-loop-border-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-message-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-message-line-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-bg-color:var(--md-mermaid-label-bg-color);--md-mermaid-sequence-note-fg-color:var(--md-mermaid-edge-color);--md-mermaid-sequence-note-border-color:var(--md-mermaid-label-fg-color);--md-mermaid-sequence-number-bg-color:var(--md-mermaid-node-fg-color);--md-mermaid-sequence-number-fg-color:var(--md-accent-bg-color)}.mermaid{line-height:normal;margin:1em 0}.md-typeset .grid{grid-gap:.4rem;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr));margin:1em 0}.md-typeset .grid.cards>ol,.md-typeset .grid.cards>ul{display:contents}.md-typeset .grid.cards>ol>li,.md-typeset .grid.cards>ul>li,.md-typeset .grid>.card{border:.05rem solid var(--md-default-fg-color--lightest);border-radius:.4rem;display:block;margin:0;padding:.8rem;transition:background-color .25s,border .25s,box-shadow .25s}.md-typeset .grid.cards>ol>li:focus-within,.md-typeset .grid.cards>ol>li:hover,.md-typeset .grid.cards>ul>li:focus-within,.md-typeset .grid.cards>ul>li:hover,.md-typeset .grid>.card:focus-within,.md-typeset .grid>.card:hover{border-color:#0000;box-shadow:var(--md-shadow-z2)}.md-typeset .grid.cards>ol>li>hr,.md-typeset .grid.cards>ul>li>hr,.md-typeset .grid>.card>hr{margin-bottom:1em;margin-top:1em}.md-typeset .grid.cards>ol>li>:first-child,.md-typeset .grid.cards>ul>li>:first-child,.md-typeset .grid>.card>:first-child{margin-top:0}.md-typeset .grid.cards>ol>li>:last-child,.md-typeset .grid.cards>ul>li>:last-child,.md-typeset .grid>.card>:last-child{margin-bottom:0}.md-typeset .grid>*,.md-typeset .grid>.admonition,.md-typeset .grid>.highlight>*,.md-typeset .grid>.highlighttable,.md-typeset .grid>.md-typeset details,.md-typeset .grid>details,.md-typeset .grid>pre{margin-bottom:0;margin-top:0}.md-typeset .grid>.highlight>pre:only-child,.md-typeset .grid>.highlight>pre>code,.md-typeset .grid>.highlighttable,.md-typeset .grid>.highlighttable>tbody,.md-typeset .grid>.highlighttable>tbody>tr,.md-typeset .grid>.highlighttable>tbody>tr>.code,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre,.md-typeset .grid>.highlighttable>tbody>tr>.code>.highlight>pre>code{height:100%}.md-typeset .grid>.tabbed-set{margin-bottom:0;margin-top:0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/assets/stylesheets/modern/palette.dfe2e883.min.css b/src/httpcore2/site-httpcore2/assets/stylesheets/modern/palette.dfe2e883.min.css new file mode 100644 index 00000000..d58a561e --- /dev/null +++ b/src/httpcore2/site-httpcore2/assets/stylesheets/modern/palette.dfe2e883.min.css @@ -0,0 +1 @@ +@media screen{[data-md-color-scheme=slate]{--md-default-fg-color:hsla(var(--md-hue),15%,90%,0.82);--md-default-fg-color--light:hsla(var(--md-hue),15%,90%,0.56);--md-default-fg-color--lighter:hsla(var(--md-hue),15%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),15%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,5%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,5%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,5%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,5%,0.07);--md-code-fg-color:hsla(var(--md-hue),20%,80%,1);--md-code-bg-color:hsla(var(--md-hue),20%,10%,1);--md-code-bg-color--light:hsla(var(--md-hue),20%,10%,0.9);--md-code-bg-color--lighter:hsla(var(--md-hue),20%,10%,0.54);--md-code-hl-color:#2977ff;--md-code-hl-color--light:#2977ff1a;--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-kbd-color:hsla(var(--md-hue),15%,90%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,90%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-mark-color:#4287ff4d;--md-typeset-table-color:hsla(var(--md-hue),15%,95%,0.12);--md-typeset-table-color--light:hsla(var(--md-hue),15%,95%,0.035);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-bg-color:hsla(var(--md-hue),15%,10%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,8%,1);--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #ffffff1a;--md-shadow-z2:0 0.2rem 0.5rem #00000040,0 0 0.05rem #ffffff59;--md-shadow-z3:0 0.5rem 2rem #0006,0 0 0.05rem #00000059;color-scheme:dark}[data-md-color-scheme=slate] .md-header__title,[data-md-color-scheme=slate] h1,[data-md-color-scheme=slate] h2,[data-md-color-scheme=slate] h3,[data-md-color-scheme=slate] h4,[data-md-color-scheme=slate] h5,[data-md-color-scheme=slate] h6{color:hsla(var(--md-hue),0%,100%,1)}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate]{--color-foreground:255 255 255;--color-background:22 23 26;--color-background-subtle:33 34 38;--color-backdrop:11 12 15}[data-md-color-scheme=slate][data-md-color-primary=pink]{--md-typeset-a-color:#ed5487}[data-md-color-scheme=slate][data-md-color-primary=purple]{--md-typeset-a-color:#c46fd3}[data-md-color-scheme=slate][data-md-color-primary=deep-purple]{--md-typeset-a-color:#a47bea}[data-md-color-scheme=slate][data-md-color-primary=indigo]{--md-typeset-a-color:#5488e8}[data-md-color-scheme=slate][data-md-color-primary=teal]{--md-typeset-a-color:#00ccb8}[data-md-color-scheme=slate][data-md-color-primary=green]{--md-typeset-a-color:#71c174}[data-md-color-scheme=slate][data-md-color-primary=deep-orange]{--md-typeset-a-color:#ff764d}[data-md-color-scheme=slate][data-md-color-primary=brown]{--md-typeset-a-color:#c1775c}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=blue-grey],[data-md-color-scheme=slate][data-md-color-primary=grey],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#5e8bde}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}}[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:#ff19471a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:#f500561a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:#df41fb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:#7c4dff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:#4287ff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:#0091eb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:#00bad61a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:#00bda41a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:#00c7531a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:#63de171a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:#b0eb001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:#ffd5001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:#ffaa001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:#ff91001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:#ff6e421a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=light-green]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#72ad2e}[data-md-color-primary=lime]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#8b990a}[data-md-color-primary=yellow]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#b8a500}[data-md-color-primary=amber]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#d19d00}[data-md-color-primary=orange]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#e68a00} \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/async/index.html b/src/httpcore2/site-httpcore2/async/index.html new file mode 100644 index 00000000..2a4181b5 --- /dev/null +++ b/src/httpcore2/site-httpcore2/async/index.html @@ -0,0 +1,1429 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Async Support - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + + +
+ +
+ + + +
+
+ + + +
+ +
+ + + + + + +

Async Support

+

HTTPX offers a standard synchronous API by default, but also gives you the option of an async client if you need it.

+

Async is a concurrency model that is far more efficient than multi-threading, and can provide significant performance benefits and enable the use of long-lived network connections such as WebSockets.

+

If you're working with an async web framework then you'll also want to use an async client for sending outgoing HTTP requests.

+

Launching concurrent async tasks is far more resource efficient than spawning multiple threads. The Python interpreter should be able to comfortably handle switching between over 1000 concurrent tasks, while a sensible number of threads in a thread pool might be to enable around 10 or 20 concurrent threads.

+

Enabling Async support

+

If you're using async with Python's stdlib asyncio support, install the optional dependencies using:

+
pip install 'httpcore2[asyncio]'
+
+

Alternatively, if you're working with the Python trio package:

+
pip install 'httpcore2[trio]'
+
+

We highly recommend trio for async support. The trio project pioneered the principles of structured concurrency, and has a more carefully constrained API against which to work from.

+

API differences

+

When using async support, you need make sure to use an async connection pool class:

+
# The async variation of `httpcore2.ConnectionPool`
+async with httpcore2.AsyncConnectionPool() as http:
+    ...
+
+

Sending requests

+

Sending requests with the async version of httpcore2 requires the await keyword:

+
import asyncio
+import httpcore2
+
+async def main():
+    async with httpcore2.AsyncConnectionPool() as http:
+        response = await http.request("GET", "https://www.example.com/")
+
+
+asyncio.run(main())
+
+

When including content in the request, the content must either be bytes or an async iterable yielding bytes.

+

Streaming responses

+

Streaming responses also require a slightly different interface to the sync version:

+
    +
  • with <pool>.stream(...) as responseasync with <pool>.stream() as response.
  • +
  • for chunk in response.iter_stream()async for chunk in response.aiter_stream().
  • +
  • response.read()await response.aread().
  • +
  • response.close()await response.aclose()
  • +
+

For example:

+
import asyncio
+import httpcore2
+
+
+async def main():
+    async with httpcore2.AsyncConnectionPool() as http:
+        async with http.stream("GET", "https://www.example.com/") as response:
+            async for chunk in response.aiter_stream():
+                print(f"Downloaded: {chunk}")
+
+
+asyncio.run(main())
+
+

Pool lifespans

+

When using httpcore2 in an async environment it is strongly recommended that you instantiate and use connection pools using the context managed style:

+
async with httpcore2.AsyncConnectionPool() as http:
+    ...
+
+

To benefit from connection pooling it is recommended that you instantiate a single connection pool in this style, and pass it around throughout your application.

+

If you do want to use a connection pool without this style then you'll need to ensure that you explicitly close the pool once it is no longer required:

+
try:
+    http = httpcore2.AsyncConnectionPool()
+    ...
+finally:
+    await http.aclose()
+
+

This is a little different to the threaded context, where it's okay to simply instantiate a globally available connection pool, and then allow Python's garbage collection to deal with closing any connections in the pool, once the __del__ method is called.

+

The reason for this difference is that asynchronous code is not able to run within the context of the synchronous __del__ method, so there is no way for connections to be automatically closed at the point of garbage collection. This can lead to unterminated TCP connections still remaining after the Python interpreter quits.

+

Supported environments

+

HTTPX supports either asyncio or trio as an async environment.

+

It will auto-detect which of those two to use as the backend for socket operations and concurrency primitives.

+

AsyncIO

+

AsyncIO is Python's built-in library for writing concurrent code with the async/await syntax.

+

Let's take a look at sending several outgoing HTTP requests concurrently, using asyncio:

+
import asyncio
+import httpcore2
+import time
+
+
+async def download(http, year):
+    await http.request("GET", f"https://en.wikipedia.org/wiki/{year}")
+
+
+async def main():
+    async with httpcore2.AsyncConnectionPool() as http:
+        started = time.time()
+        # Here we use `asyncio.gather()` in order to run several tasks concurrently...
+        tasks = [download(http, year) for year in range(2000, 2020)]
+        await asyncio.gather(*tasks)
+        complete = time.time()
+
+        for connection in http.connections:
+            print(connection)
+        print("Complete in %.3f seconds" % (complete - started))
+
+
+asyncio.run(main())
+
+

Trio

+

Trio is an alternative async library, designed around the the principles of structured concurrency.

+
import httpcore2
+import trio
+import time
+
+
+async def download(http, year):
+    await http.request("GET", f"https://en.wikipedia.org/wiki/{year}")
+
+
+async def main():
+    async with httpcore2.AsyncConnectionPool() as http:
+        started = time.time()
+        async with trio.open_nursery() as nursery:
+            for year in range(2000, 2020):
+                nursery.start_soon(download, http, year)
+        complete = time.time()
+
+        for connection in http.connections:
+            print(connection)
+        print("Complete in %.3f seconds" % (complete - started))
+
+
+trio.run(main)
+
+

AnyIO

+

AnyIO is an asynchronous networking and concurrency library that works on top of either asyncio or trio. It blends in with native libraries of your chosen backend (defaults to asyncio).

+

The anyio library is designed around the the principles of structured concurrency, and brings many of the same correctness and usability benefits that Trio provides, while interoperating with existing asyncio libraries.

+
import httpcore2
+import anyio
+import time
+
+
+async def download(http, year):
+    await http.request("GET", f"https://en.wikipedia.org/wiki/{year}")
+
+
+async def main():
+    async with httpcore2.AsyncConnectionPool() as http:
+        started = time.time()
+        async with anyio.create_task_group() as task_group:
+            for year in range(2000, 2020):
+                task_group.start_soon(download, http, year)
+        complete = time.time()
+
+        for connection in http.connections:
+            print(connection)
+        print("Complete in %.3f seconds" % (complete - started))
+
+
+anyio.run(main)
+
+
+

Reference

+

httpcore2.AsyncConnectionPool

+ + +
+ + + +

+ httpcore2.AsyncConnectionPool + + +

+ + +
+

+ Bases: AsyncRequestInterface

+ + + +

A connection pool for making HTTP requests.

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

+ connections + + + + property + + +

+
connections: list[AsyncConnectionInterface]
+
+ +
+ +

Return a list of the connections currently in the pool.

+

For example:

+
>>> pool.connections
+[
+    <AsyncHTTPConnection ['https://example.com:443', HTTP/1.1, ACTIVE, Request Count: 6]>,
+    <AsyncHTTPConnection ['https://example.com:443', HTTP/1.1, IDLE, Request Count: 9]> ,
+    <AsyncHTTPConnection ['http://example.com:80', HTTP/1.1, IDLE, Request Count: 1]>,
+]
+
+ +
+ +
+ + + + +
+ + +

+ __init__ + + +

+
__init__(
+    ssl_context: SSLContext | None = None,
+    proxy: Proxy | None = None,
+    max_connections: int | None = 10,
+    max_keepalive_connections: int | None = None,
+    keepalive_expiry: float | None = None,
+    http1: bool = True,
+    http2: bool = False,
+    retries: int = 0,
+    local_address: str | None = None,
+    uds: str | None = None,
+    network_backend: AsyncNetworkBackend | None = None,
+    socket_options: Iterable[SOCKET_OPTION] | None = None,
+) -> None
+
+ +
+ +

A connection pool for making HTTP requests.

+ + +

Parameters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionDefault
+ ssl_context + + SSLContext | None + +
+

An SSL context to use for verifying connections. +If not specified, the default httpcore2.default_ssl_context() +will be used.

+
+
+ None +
+ max_connections + + int | None + +
+

The maximum number of concurrent HTTP connections that +the pool should allow. Any attempt to send a request on a pool that +would exceed this amount will block until a connection is available.

+
+
+ 10 +
+ max_keepalive_connections + + int | None + +
+

The maximum number of idle HTTP connections +that will be maintained in the pool.

+
+
+ None +
+ keepalive_expiry + + float | None + +
+

The duration in seconds that an idle HTTP connection +may be maintained for before being expired from the pool.

+
+
+ None +
+ http1 + + bool + +
+

A boolean indicating if HTTP/1.1 requests should be supported +by the connection pool. Defaults to True.

+
+
+ True +
+ http2 + + bool + +
+

A boolean indicating if HTTP/2 requests should be supported by +the connection pool. Defaults to False.

+
+
+ False +
+ retries + + int + +
+

The maximum number of retries when trying to establish a +connection.

+
+
+ 0 +
+ local_address + + str | None + +
+

Local address to connect from. Can also be used to connect +using a particular address family. Using local_address="0.0.0.0" +will connect using an AF_INET address (IPv4), while using +local_address="::" will connect using an AF_INET6 address (IPv6).

+
+
+ None +
+ uds + + str | None + +
+

Path to a Unix Domain Socket to use instead of TCP sockets.

+
+
+ None +
+ network_backend + + AsyncNetworkBackend | None + +
+

A backend instance to use for handling network I/O.

+
+
+ None +
+ socket_options + + Iterable[SOCKET_OPTION] | None + +
+

Socket options that have to be included +in the TCP socket when the connection was established.

+
+
+ None +
+ + +
+ +
+ +
+ + +

+ handle_async_request + + + + async + + +

+
handle_async_request(request: Request) -> Response
+
+ +
+ +

Send an HTTP request, and return an HTTP response.

+

This is the core implementation that is called into by .request() or .stream().

+ + +
+ +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/connection-pools/index.html b/src/httpcore2/site-httpcore2/connection-pools/index.html new file mode 100644 index 00000000..15500b02 --- /dev/null +++ b/src/httpcore2/site-httpcore2/connection-pools/index.html @@ -0,0 +1,1309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Connection Pools - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + + +
+ +
+ + + +
+
+ + + +
+ +
+ + + + + + +

Connection Pools

+

While the top-level API provides convenience functions for working with httpcore2, +in practice you'll almost always want to take advantage of the connection pooling +functionality that it provides.

+

To do so, instantiate a pool instance, and use it to send requests:

+
import httpcore2
+
+http = httpcore2.ConnectionPool()
+r = http.request("GET", "https://www.example.com/")
+
+print(r)
+# <Response [200]>
+
+

Connection pools support the same .request() and .stream() APIs as described in the Quickstart.

+

We can observe the benefits of connection pooling with a simple script like so:

+
import httpcore2
+import time
+
+
+http = httpcore2.ConnectionPool()
+for counter in range(5):
+    started = time.time()
+    response = http.request("GET", "https://www.example.com/")
+    complete = time.time()
+    print(response, "in %.3f seconds" % (complete - started))
+
+

The output should demonstrate the initial request as being substantially slower than the subsequent requests:

+
<Response [200]> in {0.529} seconds
+<Response [200]> in {0.096} seconds
+<Response [200]> in {0.097} seconds
+<Response [200]> in {0.095} seconds
+<Response [200]> in {0.098} seconds
+
+

This is to be expected. Once we've established a connection to "www.example.com" we're able to reuse it for following requests.

+

Configuration

+

The connection pool instance is also the main point of configuration. Let's take a look at the various options that it provides:

+

SSL configuration

+
    +
  • ssl_context: An SSL context to use for verifying connections. + If not specified, the default httpcore2.default_ssl_context() + will be used.
  • +
+

Pooling configuration

+
    +
  • max_connections: The maximum number of concurrent HTTP connections that the pool + should allow. Any attempt to send a request on a pool that would + exceed this amount will block until a connection is available.
  • +
  • max_keepalive_connections: The maximum number of idle HTTP connections that will + be maintained in the pool.
  • +
  • keepalive_expiry: The duration in seconds that an idle HTTP connection may be + maintained for before being expired from the pool.
  • +
+

HTTP version support

+
    +
  • http1: A boolean indicating if HTTP/1.1 requests should be supported by the connection + pool. Defaults to True.
  • +
  • http2: A boolean indicating if HTTP/2 requests should be supported by the connection + pool. Defaults to False.
  • +
+

Other options

+
    +
  • retries: The maximum number of retries when trying to establish a connection.
  • +
  • local_address: Local address to connect from. Can also be used to connect using + a particular address family. Using local_address="0.0.0.0" will + connect using an AF_INET address (IPv4), while using local_address="::" + will connect using an AF_INET6 address (IPv6).
  • +
  • uds: Path to a Unix Domain Socket to use instead of TCP sockets.
  • +
  • network_backend: A backend instance to use for handling network I/O.
  • +
  • socket_options: Socket options that have to be included in the TCP socket when the connection was established.
  • +
+

Pool lifespans

+

Because connection pools hold onto network resources, careful developers may want to ensure that instances are properly closed once they are no longer required.

+

Working with a single global instance isn't a bad idea for many use case, since the connection pool will automatically be closed when the __del__ method is called on it:

+
# This is perfectly fine for most purposes.
+# The connection pool will automatically be closed when it is garbage collected,
+# or when the Python interpreter exits.
+http = httpcore2.ConnectionPool()
+
+

However, to be more explicit around the resource usage, we can use the connection pool within a context manager:

+
with httpcore2.ConnectionPool() as http:
+    ...
+
+

Or else close the pool explicitly:

+
http = httpcore2.ConnectionPool()
+try:
+    ...
+finally:
+    http.close()
+
+

Thread and task safety

+

Connection pools are designed to be thread-safe. Similarly, when using httpcore2 in an async context connection pools are task-safe.

+

This means that you can have a single connection pool instance shared by multiple threads.

+
+

Reference

+

httpcore2.ConnectionPool

+ + +
+ + + +

+ httpcore2.ConnectionPool + + +

+ + +
+

+ Bases: RequestInterface

+ + + +

A connection pool for making HTTP requests.

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

+ connections + + + + property + + +

+
connections: list[ConnectionInterface]
+
+ +
+ +

Return a list of the connections currently in the pool.

+

For example:

+
>>> pool.connections
+[
+    <HTTPConnection ['https://example.com:443', HTTP/1.1, ACTIVE, Request Count: 6]>,
+    <HTTPConnection ['https://example.com:443', HTTP/1.1, IDLE, Request Count: 9]> ,
+    <HTTPConnection ['http://example.com:80', HTTP/1.1, IDLE, Request Count: 1]>,
+]
+
+ +
+ +
+ + + + +
+ + +

+ __init__ + + +

+
__init__(
+    ssl_context: SSLContext | None = None,
+    proxy: Proxy | None = None,
+    max_connections: int | None = 10,
+    max_keepalive_connections: int | None = None,
+    keepalive_expiry: float | None = None,
+    http1: bool = True,
+    http2: bool = False,
+    retries: int = 0,
+    local_address: str | None = None,
+    uds: str | None = None,
+    network_backend: NetworkBackend | None = None,
+    socket_options: Iterable[SOCKET_OPTION] | None = None,
+) -> None
+
+ +
+ +

A connection pool for making HTTP requests.

+ + +

Parameters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionDefault
+ ssl_context + + SSLContext | None + +
+

An SSL context to use for verifying connections. +If not specified, the default httpcore2.default_ssl_context() +will be used.

+
+
+ None +
+ max_connections + + int | None + +
+

The maximum number of concurrent HTTP connections that +the pool should allow. Any attempt to send a request on a pool that +would exceed this amount will block until a connection is available.

+
+
+ 10 +
+ max_keepalive_connections + + int | None + +
+

The maximum number of idle HTTP connections +that will be maintained in the pool.

+
+
+ None +
+ keepalive_expiry + + float | None + +
+

The duration in seconds that an idle HTTP connection +may be maintained for before being expired from the pool.

+
+
+ None +
+ http1 + + bool + +
+

A boolean indicating if HTTP/1.1 requests should be supported +by the connection pool. Defaults to True.

+
+
+ True +
+ http2 + + bool + +
+

A boolean indicating if HTTP/2 requests should be supported by +the connection pool. Defaults to False.

+
+
+ False +
+ retries + + int + +
+

The maximum number of retries when trying to establish a +connection.

+
+
+ 0 +
+ local_address + + str | None + +
+

Local address to connect from. Can also be used to connect +using a particular address family. Using local_address="0.0.0.0" +will connect using an AF_INET address (IPv4), while using +local_address="::" will connect using an AF_INET6 address (IPv6).

+
+
+ None +
+ uds + + str | None + +
+

Path to a Unix Domain Socket to use instead of TCP sockets.

+
+
+ None +
+ network_backend + + NetworkBackend | None + +
+

A backend instance to use for handling network I/O.

+
+
+ None +
+ socket_options + + Iterable[SOCKET_OPTION] | None + +
+

Socket options that have to be included +in the TCP socket when the connection was established.

+
+
+ None +
+ + +
+ +
+ +
+ + +

+ handle_request + + +

+
handle_request(request: Request) -> Response
+
+ +
+ +

Send an HTTP request, and return an HTTP response.

+

This is the core implementation that is called into by .request() or .stream().

+ + +
+ +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/connections/index.html b/src/httpcore2/site-httpcore2/connections/index.html new file mode 100644 index 00000000..336cad84 --- /dev/null +++ b/src/httpcore2/site-httpcore2/connections/index.html @@ -0,0 +1,803 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Connections - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + + + + + +
+
+ + + + + + + + +
+ + + + +
+
+
+ + + +
+ +
+ + + + + + +

Connections

+

TODO

+
+

Reference

+

httpcore2.HTTPConnection

+ + +
+ + + +

+ httpcore2.HTTPConnection + + +

+ + +
+

+ Bases: ConnectionInterface

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

httpcore2.HTTP11Connection

+ + +
+ + + +

+ httpcore2.HTTP11Connection + + +

+ + +
+

+ Bases: ConnectionInterface

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

httpcore2.HTTP2Connection

+ + +
+ + + +

+ httpcore2.HTTP2Connection + + +

+ + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/exceptions/index.html b/src/httpcore2/site-httpcore2/exceptions/index.html new file mode 100644 index 00000000..52088073 --- /dev/null +++ b/src/httpcore2/site-httpcore2/exceptions/index.html @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Exceptions - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + + + + + +
+
+ + + + + + + + +
+ + + + +
+
+
+ + + +
+ +
+ + + + + + +

Exceptions

+

The following exceptions may be raised when sending a request:

+
    +
  • httpcore2.TimeoutException
      +
    • httpcore2.PoolTimeout
    • +
    • httpcore2.ConnectTimeout
    • +
    • httpcore2.ReadTimeout
    • +
    • httpcore2.WriteTimeout
    • +
    +
  • +
  • httpcore2.NetworkError
      +
    • httpcore2.ConnectError
    • +
    • httpcore2.ReadError
    • +
    • httpcore2.WriteError
    • +
    +
  • +
  • httpcore2.ProtocolError
      +
    • httpcore2.RemoteProtocolError
    • +
    • httpcore2.LocalProtocolError
    • +
    +
  • +
  • httpcore2.ProxyError
  • +
  • httpcore2.UnsupportedProtocol
  • +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/extensions/index.html b/src/httpcore2/site-httpcore2/extensions/index.html new file mode 100644 index 00000000..c09df5d6 --- /dev/null +++ b/src/httpcore2/site-httpcore2/extensions/index.html @@ -0,0 +1,1284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Extensions - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+ +
+ + + + + + +

Extensions

+

The request/response API used by httpcore2 is kept deliberately simple and explicit.

+

The Request and Response models are pretty slim wrappers around this core API:

+
# Pseudo-code expressing the essentials of the request/response model.
+(
+    status_code: int,
+    headers: List[Tuple(bytes, bytes)],
+    stream: Iterable[bytes]
+) = handle_request(
+    method: bytes,
+    url: URL,
+    headers: List[Tuple(bytes, bytes)],
+    stream: Iterable[bytes]
+)
+
+

This is everything that's needed in order to represent an HTTP exchange.

+

Well... almost.

+

There is a maxim in Computer Science that "All non-trivial abstractions, to some degree, are leaky". When an expression is leaky, it's important that it ought to at least leak only in well-defined places.

+

In order to handle cases that don't otherwise fit inside this core abstraction, httpcore2 requests and responses have 'extensions'. These are a dictionary of optional additional information.

+

Let's expand on our request/response abstraction...

+
# Pseudo-code expressing the essentials of the request/response model,
+# plus extensions allowing for additional API that does not fit into
+# this abstraction.
+(
+    status_code: int,
+    headers: List[Tuple(bytes, bytes)],
+    stream: Iterable[bytes],
+    extensions: dict
+) = handle_request(
+    method: bytes,
+    url: URL,
+    headers: List[Tuple(bytes, bytes)],
+    stream: Iterable[bytes],
+    extensions: dict
+)
+
+

Several extensions are supported both on the request:

+
r = httpcore2.request(
+    "GET",
+    "https://www.example.com",
+    extensions={"timeout": {"connect": 5.0}}
+)
+
+

And on the response:

+
r = httpcore2.request("GET", "https://www.example.com")
+
+print(r.extensions["http_version"])
+# When using HTTP/1.1 on the client side, the server HTTP response
+# could feasibly be one of b"HTTP/0.9", b"HTTP/1.0", or b"HTTP/1.1".
+
+

Request Extensions

+

"timeout"

+

A dictionary of str: Optional[float] timeout values.

+

May include values for 'connect', 'read', 'write', or 'pool'.

+

For example:

+
# Timeout if a connection takes more than 5 seconds to established, or if
+# we are blocked waiting on the connection pool for more than 10 seconds.
+r = httpcore2.request(
+    "GET",
+    "https://www.example.com",
+    extensions={"timeout": {"connect": 5.0, "pool": 10.0}}
+)
+
+

"trace"

+

The trace extension allows a callback handler to be installed to monitor the internal +flow of events within httpcore2. The simplest way to explain this is with an example:

+
import httpcore2
+
+def log(event_name, info):
+    print(event_name, info)
+
+r = httpcore2.request("GET", "https://www.example.com/", extensions={"trace": log})
+# connection.connect_tcp.started {'host': 'www.example.com', 'port': 443, 'local_address': None, 'timeout': None}
+# connection.connect_tcp.complete {'return_value': <httpcore2._backends.sync.SyncStream object at 0x1093f94d0>}
+# connection.start_tls.started {'ssl_context': <ssl.SSLContext object at 0x1093ee750>, 'server_hostname': b'www.example.com', 'timeout': None}
+# connection.start_tls.complete {'return_value': <httpcore2._backends.sync.SyncStream object at 0x1093f9450>}
+# http11.send_request_headers.started {'request': <Request [b'GET']>}
+# http11.send_request_headers.complete {'return_value': None}
+# http11.send_request_body.started {'request': <Request [b'GET']>}
+# http11.send_request_body.complete {'return_value': None}
+# http11.receive_response_headers.started {'request': <Request [b'GET']>}
+# http11.receive_response_headers.complete {'return_value': (b'HTTP/1.1', 200, b'OK', [(b'Age', b'553715'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Thu, 21 Oct 2021 17:08:42 GMT'), (b'Etag', b'"3147526947+ident"'), (b'Expires', b'Thu, 28 Oct 2021 17:08:42 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1DCD)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')])}
+# http11.receive_response_body.started {'request': <Request [b'GET']>}
+# http11.receive_response_body.complete {'return_value': None}
+# http11.response_closed.started {}
+# http11.response_closed.complete {'return_value': None}
+
+

The event_name and info arguments here will be one of the following:

+
    +
  • {event_type}.{event_name}.started, <dictionary of keyword arguments>
  • +
  • {event_type}.{event_name}.complete, {"return_value": <...>}
  • +
  • {event_type}.{event_name}.failed, {"exception": <...>}
  • +
+

Note that when using the async variant of httpcore2 the handler function passed to "trace" must be an async def ... function.

+

The following event types are currently exposed...

+

Establishing the connection

+
    +
  • "connection.connect_tcp"
  • +
  • "connection.connect_unix_socket"
  • +
  • "connection.start_tls"
  • +
+

HTTP/1.1 events

+
    +
  • "http11.send_request_headers"
  • +
  • "http11.send_request_body"
  • +
  • "http11.receive_response"
  • +
  • "http11.receive_response_body"
  • +
  • "http11.response_closed"
  • +
+

HTTP/2 events

+
    +
  • "http2.send_connection_init"
  • +
  • "http2.send_request_headers"
  • +
  • "http2.send_request_body"
  • +
  • "http2.receive_response_headers"
  • +
  • "http2.receive_response_body"
  • +
  • "http2.response_closed"
  • +
+

The exact set of trace events may be subject to change across different versions of httpcore2. If you need to rely on a particular set of events it is recommended that you pin installation of the package to a fixed version.

+

"sni_hostname"

+

The server's hostname, which is used to confirm the hostname supplied by the SSL certificate.

+

For example:

+
headers = {"Host": "www.encode.io"}
+extensions = {"sni_hostname": "www.encode.io"}
+response = httpcore2.request(
+    "GET",
+    "https://185.199.108.153",
+    headers=headers,
+    extensions=extensions
+)
+
+

"target"

+

The target that is used as the HTTP target instead of the URL path.

+

This enables support constructing requests that would otherwise be unsupported. In particular...

+
    +
  • Forward proxy requests using an absolute URI.
  • +
  • Tunneling proxy requests using CONNECT with hostname as the target.
  • +
  • Server-wide OPTIONS * requests.
  • +
+

For example:

+
extensions = {"target": b"www.encode.io:443"}
+response = httpcore2.request(
+    "CONNECT",
+    "http://your-tunnel-proxy.com",
+    headers=headers,
+    extensions=extensions
+)
+
+

Response Extensions

+

"http_version"

+

The HTTP version, as bytes. Eg. b"HTTP/1.1".

+

When using HTTP/1.1 the response line includes an explicit version, and the value of this key could feasibly be one of b"HTTP/0.9", b"HTTP/1.0", or b"HTTP/1.1".

+

When using HTTP/2 there is no further response versioning included in the protocol, and the value of this key will always be b"HTTP/2".

+

"reason_phrase"

+

The reason-phrase of the HTTP response, as bytes. For example b"OK". Some servers may include a custom reason phrase, although this is not recommended.

+

HTTP/2 onwards does not include a reason phrase on the wire.

+

When no key is included, a default based on the status code may be used.

+

"stream_id"

+

When HTTP/2 is being used the "stream_id" response extension can be accessed to determine the ID of the data stream that the response was sent on.

+

"network_stream"

+

The "network_stream" extension allows developers to handle HTTP CONNECT and Upgrade requests, by providing an API that steps outside the standard request/response model, and can directly read or write to the network.

+

The interface provided by the network stream:

+
    +
  • read(max_bytes, timeout = None) -> bytes
  • +
  • write(buffer, timeout = None)
  • +
  • close()
  • +
  • start_tls(ssl_context, server_hostname = None, timeout = None) -> NetworkStream
  • +
  • get_extra_info(info) -> Any
  • +
+

This API can be used as the foundation for working with HTTP proxies, WebSocket upgrades, and other advanced use-cases.

+

See the network backends documentation for more information on working directly with network streams.

+
CONNECT requests
+

A proxy CONNECT request using the network stream:

+
# Formulate a CONNECT request...
+#
+# This will establish a connection to 127.0.0.1:8080, and then send the following...
+#
+# CONNECT http://www.example.com HTTP/1.1
+url = "http://127.0.0.1:8080"
+extensions = {"target: "http://www.example.com"}
+with httpcore2.stream("CONNECT", url, extensions=extensions) as response:
+    network_stream = response.extensions["network_stream"]
+
+    # Upgrade to an SSL stream...
+    network_stream = network_stream.start_tls(
+        ssl_context=httpcore2.default_ssl_context(),
+        hostname=b"www.example.com",
+    )
+
+    # Manually send an HTTP request over the network stream, and read the response...
+    #
+    # For a more complete example see the httpcore2 `TunnelHTTPConnection` implementation.
+    network_stream.write(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
+    data = network_stream.read()
+    print(data)
+
+
Upgrade requests
+

Using the wsproto package to handle a websockets session:

+
import httpcore2
+import wsproto
+import os
+import base64
+
+
+url = "http://127.0.0.1:8000/"
+headers = {
+    b"Connection": b"Upgrade",
+    b"Upgrade": b"WebSocket",
+    b"Sec-WebSocket-Key": base64.b64encode(os.urandom(16)),
+    b"Sec-WebSocket-Version": b"13"
+}
+with httpcore2.stream("GET", url, headers=headers) as response:
+    if response.status != 101:
+        raise Exception("Failed to upgrade to websockets", response)
+
+    # Get the raw network stream.
+    network_steam = response.extensions["network_stream"]
+
+    # Write a WebSocket text frame to the stream.
+    ws_connection = wsproto.Connection(wsproto.ConnectionType.CLIENT)
+    message = wsproto.events.TextMessage("hello, world!")
+    outgoing_data = ws_connection.send(message)
+    network_steam.write(outgoing_data)
+
+    # Wait for a response.
+    incoming_data = network_steam.read(max_bytes=4096)
+    ws_connection.receive_data(incoming_data)
+    for event in ws_connection.events():
+        if isinstance(event, wsproto.events.TextMessage):
+            print("Got data:", event.data)
+
+    # Write a WebSocket close to the stream.
+    message = wsproto.events.CloseConnection(code=1000)
+    outgoing_data = ws_connection.send(message)
+    network_steam.write(outgoing_data)
+
+
Extra network information
+

The network stream abstraction also allows access to various low-level information that may be exposed by the underlying socket:

+
response = httpcore2.request("GET", "https://www.example.com")
+network_stream = response.extensions["network_stream"]
+
+client_addr = network_stream.get_extra_info("client_addr")
+server_addr = network_stream.get_extra_info("server_addr")
+print("Client address", client_addr)
+print("Server address", server_addr)
+
+

The socket SSL information is also available through this interface, although you need to ensure that the underlying connection is still open, in order to access it...

+
with httpcore2.stream("GET", "https://www.example.com") as response:
+    network_stream = response.extensions["network_stream"]
+
+    ssl_object = network_stream.get_extra_info("ssl_object")
+    print("TLS version", ssl_object.version())
+
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/http2/index.html b/src/httpcore2/site-httpcore2/http2/index.html new file mode 100644 index 00000000..c03e6e7f --- /dev/null +++ b/src/httpcore2/site-httpcore2/http2/index.html @@ -0,0 +1,1028 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HTTP/2 - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + + + + + + + + + +
+ +
+ + + + + + +

HTTP/2

+

HTTP/2 is a major new iteration of the HTTP protocol, that provides a more efficient transport, with potential performance benefits. HTTP/2 does not change the core semantics of the request or response, but alters the way that data is sent to and from the server.

+

Rather than the text format that HTTP/1.1 uses, HTTP/2 is a binary format. The binary format provides full request and response multiplexing, and efficient compression of HTTP headers. The stream multiplexing means that where HTTP/1.1 requires one TCP stream for each concurrent request, HTTP/2 allows a single TCP stream to handle multiple concurrent requests.

+

HTTP/2 also provides support for functionality such as response prioritization, and server push.

+

For a comprehensive guide to HTTP/2 you may want to check out "HTTP2 Explained".

+

Enabling HTTP/2

+

When using the httpcore2 client, HTTP/2 support is not enabled by default, because HTTP/1.1 is a mature, battle-hardened transport layer, and our HTTP/1.1 implementation may be considered the more robust option at this point in time. It is possible that a future version of httpcore2 may enable HTTP/2 support by default.

+

If you're issuing highly concurrent requests you might want to consider trying out our HTTP/2 support. You can do so by first making sure to install the optional HTTP/2 dependencies...

+
pip install 'httpcore2[http2]'
+
+

And then instantiating a connection pool with HTTP/2 support enabled:

+
import httpcore2
+
+pool = httpcore2.ConnectionPool(http2=True)
+
+

We can take a look at the difference in behaviour by issuing several outgoing requests in parallel.

+

Start out by using a standard HTTP/1.1 connection pool:

+
import httpcore2
+import concurrent.futures
+import time
+
+
+def download(http, year):
+    http.request("GET", f"https://en.wikipedia.org/wiki/{year}")
+
+
+def main():
+    with httpcore2.ConnectionPool() as http:
+        started = time.time()
+        with concurrent.futures.ThreadPoolExecutor(max_workers=10) as threads:
+            for year in range(2000, 2020):
+                threads.submit(download, http, year)
+        complete = time.time()
+
+        for connection in http.connections:
+            print(connection)
+        print("Complete in %.3f seconds" % (complete - started))
+
+
+main()
+
+

If you run this with an HTTP/1.1 connection pool, you ought to see output similar to the following:

+
<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 2]>,
+<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 3]>,
+<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 6]>,
+<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 5]>,
+<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 1]>,
+<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 1]>,
+<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 1]>,
+<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 1]>
+Complete in 0.586 seconds
+
+

We can see that the connection pool required a number of connections in order to handle the parallel requests.

+

If we now upgrade our connection pool to support HTTP/2:

+
with httpcore2.ConnectionPool(http2=True) as http:
+    ...
+
+

And run the same script again, we should end up with something like this:

+
<HTTPConnection ['https://en.wikipedia.org:443', HTTP/2, IDLE, Request Count: 20]>
+Complete in 0.573 seconds
+
+

All of our requests have been handled over a single connection.

+

Switching to HTTP/2 should not necessarily be considered an "upgrade". It is more complex, and requires more computational power, and so particularly in an interpreted language like Python it could be slower in some instances. Moreover, utilising multiple connections may end up connecting to multiple hosts, and could sometimes appear faster to the client, at the cost of requiring more server resources. Enabling HTTP/2 is most likely to be beneficial if you are sending requests in high concurrency, and may often be more well suited to an async context, rather than multi-threading.

+

Inspecting the HTTP version

+

Enabling HTTP/2 support on the client does not necessarily mean that your requests and responses will be transported over HTTP/2, since both the client and the server need to support HTTP/2. If you connect to a server that only supports HTTP/1.1 the client will use a standard HTTP/1.1 connection instead.

+

You can determine which version of the HTTP protocol was used by examining the "http_version" response extension.

+
import httpcore2
+
+pool = httpcore2.ConnectionPool(http2=True)
+response = pool.request("GET", "https://www.example.com/")
+
+# Should be one of b"HTTP/2", b"HTTP/1.1", b"HTTP/1.0", or b"HTTP/0.9".
+print(response.extensions["http_version"])
+
+

See the extensions documentation for more details.

+

HTTP/2 negotiation

+

Robust servers need to support both HTTP/2 and HTTP/1.1 capable clients, and so need some way to "negotiate" with the client which protocol version will be used.

+

HTTP/2 over HTTPS

+

Generally the method used is for the server to advertise if it has HTTP/2 support during the part of the SSL connection handshake. This is known as ALPN - "Application Layer Protocol Negotiation".

+

Most browsers only provide HTTP/2 support over HTTPS connections, and this is also the default behaviour that httpcore2 provides. If you enable HTTP/2 support you should still expect to see HTTP/1.1 connections for any http:// URLs.

+

HTTP/2 over HTTP

+

Servers can optionally also support HTTP/2 over HTTP by supporting the Upgrade: h2c header.

+

This mechanism is not supported by httpcore2. It requires an additional round-trip between the client and server, and also requires any request body to be sent twice.

+

Prior Knowledge

+

If you know in advance that the server you are communicating with will support HTTP/2, then you can enforce that the client uses HTTP/2, without requiring either ALPN support or an HTTP Upgrade: h2c header.

+

This is managed by disabling HTTP/1.1 support on the connection pool:

+
pool = httpcore2.ConnectionPool(http1=False, http2=True)
+
+

Request & response headers

+

Because HTTP/2 frames the requests and responses somewhat differently to HTTP/1.1, there is a difference in some of the headers that are used.

+

In order for the httpcore2 library to support both HTTP/1.1 and HTTP/2 transparently, the HTTP/1.1 style is always used throughout the API. Any differences in header styles are only mapped onto HTTP/2 at the internal network layer.

+

Request headers

+

The following pseudo-headers are used by HTTP/2 in the request:

+
    +
  • :method - The request method.
  • +
  • :path - Taken from the URL of the request.
  • +
  • :authority - Equivalent to the Host header in HTTP/1.1. In httpcore2 this is represented using the request Host header, which is automatically populated from the request URL if no Host header is explicitly included.
  • +
  • :scheme - Taken from the URL of the request.
  • +
+

These pseudo-headers are included in httpcore2 as part of the request.method and request.url attributes, and through the request.headers["Host"] header. They are not exposed directly by their psuedo-header names.

+

The one other difference to be aware of is the Transfer-Encoding: chunked header.

+

In HTTP/2 this header is never used, since streaming data is framed using a different mechanism.

+

In httpcore2 the Transfer-Encoding: chunked header is always used to represent the presence of a streaming body on the request, and is automatically populated if required. However the header is only sent if the underlying connection ends up being HTTP/1.1, and is omitted if the underlying connection ends up being HTTP/2.

+

Response headers

+

The following pseudo-header is used by HTTP/2 in the response:

+
    +
  • :status - The response status code.
  • +
+

In httpcore2 this is represented by the response.status attribute, rather than being exposed as a psuedo-header.

+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/index.html b/src/httpcore2/site-httpcore2/index.html new file mode 100644 index 00000000..33fe5767 --- /dev/null +++ b/src/httpcore2/site-httpcore2/index.html @@ -0,0 +1,800 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + HTTPCore - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + + +
+ +
+ + +
+ + + + +
+
+
+ + + +
+ +
+ + + + + + +

HTTPCore

+

Test Suite +Package version

+
+

Do one thing, and do it well.

+
+

The HTTP Core package provides a minimal low-level HTTP client, which does +one thing only. Sending HTTP requests.

+

It does not provide any high level model abstractions over the API, +does not handle redirects, multipart uploads, building authentication headers, +transparent HTTP caching, URL parsing, session cookie handling, +content or charset decoding, handling JSON, environment based configuration +defaults, or any of that Jazz.

+

Some things HTTP Core does do:

+
    +
  • Sending HTTP requests.
  • +
  • Thread-safe / task-safe connection pooling.
  • +
  • HTTP(S) proxy & SOCKS proxy support.
  • +
  • Supports HTTP/1.1 and HTTP/2.
  • +
  • Provides both sync and async interfaces.
  • +
  • Async backend support for asyncio and trio.
  • +
+

Installation

+

For HTTP/1.1 only support, install with:

+
pip install httpcore2
+
+

For HTTP/1.1 and HTTP/2 support, install with:

+
pip install httpcore2[http2]
+
+

For SOCKS proxy support, install with:

+
pip install httpcore2[socks]
+
+

Example

+

Let's check we're able to send HTTP requests:

+
import httpcore2
+
+response = httpcore2.request("GET", "https://www.example.com/")
+
+print(response)
+# <Response [200]>
+print(response.status)
+# 200
+print(response.headers)
+# [(b'Accept-Ranges', b'bytes'), (b'Age', b'557328'), (b'Cache-Control', b'max-age=604800'), ...]
+print(response.content)
+# b'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>\n\n<meta charset="utf-8"/>\n ...'
+
+

Ready to get going?

+

Head over to the quickstart documentation.

+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/logging/index.html b/src/httpcore2/site-httpcore2/logging/index.html new file mode 100644 index 00000000..829df1c5 --- /dev/null +++ b/src/httpcore2/site-httpcore2/logging/index.html @@ -0,0 +1,692 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Logging - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + + + + + +
+
+ + + + + + + + +
+ + + + +
+
+
+ + + +
+ +
+ + + + + + +

Logging

+

If you need to inspect the internal behaviour of httpcore2, you can use Python's standard logging to output debug level information.

+

For example, the following configuration...

+
import logging
+import httpcore2
+
+logging.basicConfig(
+    format="%(levelname)s [%(asctime)s] %(name)s - %(message)s",
+    datefmt="%Y-%m-%d %H:%M:%S",
+    level=logging.DEBUG
+)
+
+httpcore2.request('GET', 'https://www.example.com')
+
+

Will send debug level output to the console, or wherever stdout is directed too...

+
DEBUG [2023-01-09 14:44:00] httpcore2.connection - connect_tcp.started host='www.example.com' port=443 local_address=None timeout=None
+DEBUG [2023-01-09 14:44:00] httpcore2.connection - connect_tcp.complete return_value=<httpcore2._backends.sync.SyncStream object at 0x109ba6610>
+DEBUG [2023-01-09 14:44:00] httpcore2.connection - start_tls.started ssl_context=<ssl.SSLContext object at 0x109e427b0> server_hostname='www.example.com' timeout=None
+DEBUG [2023-01-09 14:44:00] httpcore2.connection - start_tls.complete return_value=<httpcore2._backends.sync.SyncStream object at 0x109e8b050>
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_headers.started request=<Request [b'GET']>
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_headers.complete
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_body.started request=<Request [b'GET']>
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_body.complete
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_headers.started request=<Request [b'GET']>
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Age', b'572646'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Mon, 09 Jan 2023 14:44:00 GMT'), (b'Etag', b'"3147526947+ident"'), (b'Expires', b'Mon, 16 Jan 2023 14:44:00 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1D18)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')])
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_body.started request=<Request [b'GET']>
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_body.complete
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - response_closed.started
+DEBUG [2023-01-09 14:44:00] httpcore2.http11 - response_closed.complete
+DEBUG [2023-01-09 14:44:00] httpcore2.connection - close.started
+DEBUG [2023-01-09 14:44:00] httpcore2.connection - close.complete
+
+

The exact formatting of the debug logging may be subject to change across different versions of httpcore2. If you need to rely on a particular format it is recommended that you pin installation of the package to a fixed version.

+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/network-backends/index.html b/src/httpcore2/site-httpcore2/network-backends/index.html new file mode 100644 index 00000000..95cbe892 --- /dev/null +++ b/src/httpcore2/site-httpcore2/network-backends/index.html @@ -0,0 +1,1172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Network Backends - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + + + + + + + + + +
+ +
+ + + + + + +

Network Backends

+

The API layer at which httpcore2 interacts with the network is described as the network backend. Various backend implementations are provided, allowing httpcore2 to handle networking in different runtime contexts.

+

Working with network backends

+

The default network backend

+

Typically you won't need to specify a network backend, as a default will automatically be selected. However, understanding how the network backends fit in may be useful if you want to better understand the underlying architecture. Let's start by seeing how we can explicitly select the network backend.

+

First we're making a standard HTTP request, using a connection pool:

+
import httpcore2
+
+with httpcore2.ConnectionPool() as http:
+    response = http.request('GET', 'https://www.example.com')
+    print(response)
+
+

We can also have the same behavior, but be explicit with our selection of the network backend:

+
import httpcore2
+
+network_backend = httpcore2.SyncBackend()
+with httpcore2.ConnectionPool(network_backend=network_backend) as http:
+    response = http.request('GET', 'https://www.example.com')
+    print(response)
+
+

The httpcore2.SyncBackend() implementation handles the opening of TCP connections, and operations on the socket stream, such as reading, writing, and closing the connection.

+

We can get a better understanding of this by using a network backend to send a basic HTTP/1.1 request directly:

+
import httpcore2
+
+# Create an SSL context using 'certifi' for the certificates.
+ssl_context = httpcore2.default_ssl_context()
+
+# A basic HTTP/1.1 request as a plain bytestring.
+request = b'\r\n'.join([
+    b'GET / HTTP/1.1',
+    b'Host: www.example.com',
+    b'Accept: */*',
+    b'Connection: close',
+    b''
+])
+
+# Open a TCP stream and upgrade it to SSL.
+network_backend = httpcore2.SyncBackend()
+network_stream = network_backend.connect_tcp("www.example.com", 443)
+network_stream = network_stream.start_tls(ssl_context, server_hostname="www.example.com")
+
+# Send the HTTP request.
+network_stream.write(request)
+
+# Read the HTTP response.
+while True:
+    response = network_stream.read(max_bytes=4096)
+    if response == b'':
+        break
+    print(response)
+
+# The output should look something like this:
+#
+# b'HTTP/1.1 200 OK\r\nAge: 600005\r\n [...] Content-Length: 1256\r\nConnection: close\r\n\r\n'
+# b'<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title> [...] </html>\n'
+
+

Async network backends

+

If we're working with an async codebase, then we need to select a different backend.

+

The httpcore2.AnyIOBackend is suitable for usage if you're running under asyncio. This is a networking backend implemented using the anyio package.

+
import httpcore2
+import asyncio
+
+async def main():
+    network_backend = httpcore2.AnyIOBackend()
+    async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as http:
+        response = await http.request('GET', 'https://www.example.com')
+        print(response)
+
+asyncio.run(main())
+
+

The AnyIOBackend will work when running under either asyncio or trio. However, if you're working with async using the trio framework, then we recommend using the httpcore2.TrioBackend.

+

This will give you the same kind of networking behavior you'd have using AnyIOBackend, but there will be a little less indirection so it will be marginally more efficient and will present cleaner tracebacks in error cases.

+
import httpcore2
+import trio
+
+async def main():
+    network_backend = httpcore2.TrioBackend()
+    async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as http:
+        response = await http.request('GET', 'https://www.example.com')
+        print(response)
+
+trio.run(main)
+
+

Mock network backends

+

There are also mock network backends available that can be useful for testing purposes. +These backends accept a list of bytes, and return network stream interfaces that return those byte streams.

+

Here's an example of mocking a simple HTTP/1.1 response...

+
import httpcore2
+
+network_backend = httpcore2.MockBackend([
+    b"HTTP/1.1 200 OK\r\n",
+    b"Content-Type: plain/text\r\n",
+    b"Content-Length: 13\r\n",
+    b"\r\n",
+    b"Hello, world!",
+])
+with httpcore2.ConnectionPool(network_backend=network_backend) as http:
+    response = http.request("GET", "https://example.com/")
+    print(response.extensions['http_version'])
+    print(response.status)
+    print(response.content)
+
+

Mocking a HTTP/2 response is more complex, since it uses a binary format...

+
import hpack
+import hyperframe.frame
+import httpcore2
+
+content = [
+    hyperframe.frame.SettingsFrame().serialize(),
+    hyperframe.frame.HeadersFrame(
+        stream_id=1,
+        data=hpack.Encoder().encode(
+            [
+                (b":status", b"200"),
+                (b"content-type", b"plain/text"),
+            ]
+        ),
+        flags=["END_HEADERS"],
+    ).serialize(),
+    hyperframe.frame.DataFrame(
+        stream_id=1, data=b"Hello, world!", flags=["END_STREAM"]
+    ).serialize(),
+]
+# Note that we instantiate the mock backend with an `http2=True` argument.
+# This ensures that the mock network stream acts as if the `h2` ALPN flag has been set,
+# and causes the connection pool to interact with the connection using HTTP/2.
+network_backend = httpcore2.MockBackend(content, http2=True)
+with httpcore2.ConnectionPool(network_backend=network_backend) as http:
+    response = http.request("GET", "https://example.com/")
+    print(response.extensions['http_version'])
+    print(response.status)
+    print(response.content)
+
+

Custom network backends

+

The base interface for network backends is provided as public API, allowing you to implement custom networking behavior.

+

You can use this to provide advanced networking functionality such as:

+
    +
  • Network recording / replay.
  • +
  • In-depth debug tooling.
  • +
  • Handling non-standard SSL or DNS requirements.
  • +
+

Here's an example that records the network response to a file on disk:

+
import httpcore2
+
+
+class RecordingNetworkStream(httpcore2.NetworkStream):
+    def __init__(self, record_file, stream):
+        self.record_file = record_file
+        self.stream = stream
+
+    def read(self, max_bytes, timeout=None):
+        data = self.stream.read(max_bytes, timeout=timeout)
+        self.record_file.write(data)
+        return data
+
+    def write(self, buffer, timeout=None):
+        self.stream.write(buffer, timeout=timeout)
+
+    def close(self) -> None:
+        self.stream.close()
+
+    def start_tls(
+        self,
+        ssl_context,
+        server_hostname=None,
+        timeout=None,
+    ):
+        self.stream = self.stream.start_tls(
+            ssl_context, server_hostname=server_hostname, timeout=timeout
+        )
+        return self
+
+    def get_extra_info(self, info):
+        return self.stream.get_extra_info(info)
+
+
+class RecordingNetworkBackend(httpcore2.NetworkBackend):
+    """
+    A custom network backend that records network responses.
+    """
+    def __init__(self, record_file):
+        self.record_file = record_file
+        self.backend = httpcore2.SyncBackend()
+
+    def connect_tcp(
+        self,
+        host,
+        port,
+        timeout=None,
+        local_address=None,
+        socket_options=None,
+    ):
+        # Note that we're only using a single record file here,
+        # so even if multiple connections are opened the network
+        # traffic will all write to the same file.
+
+        # An alternative implementation might automatically use
+        # a new file for each opened connection.
+        stream = self.backend.connect_tcp(
+            host,
+            port,
+            timeout=timeout,
+            local_address=local_address,
+            socket_options=socket_options
+        )
+        return RecordingNetworkStream(self.record_file, stream)
+
+
+# Once you make the request, the raw HTTP/1.1 response will be available
+# in the 'network-recording' file.
+#
+# Try switching to `http2=True` to see the difference when recording HTTP/2 binary network traffic,
+# or add `headers={'Accept-Encoding': 'gzip'}` to see HTTP content compression.
+with open("network-recording", "wb") as record_file:
+    network_backend = RecordingNetworkBackend(record_file)
+    with httpcore2.ConnectionPool(network_backend=network_backend) as http:
+        response = http.request("GET", "https://www.example.com/")
+        print(response)
+
+
+

Reference

+

Networking Backends

+
    +
  • httpcore2.SyncBackend
  • +
  • httpcore2.AnyIOBackend
  • +
  • httpcore2.TrioBackend
  • +
+

Mock Backends

+
    +
  • httpcore2.MockBackend
  • +
  • httpcore2.MockStream
  • +
  • httpcore2.AsyncMockBackend
  • +
  • httpcore2.AsyncMockStream
  • +
+

Base Interface

+
    +
  • httpcore2.NetworkBackend
  • +
  • httpcore2.NetworkStream
  • +
  • httpcore2.AsyncNetworkBackend
  • +
  • httpcore2.AsyncNetworkStream
  • +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/objects.inv b/src/httpcore2/site-httpcore2/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..3f5926092f3b1d734ff4d2ce3c3545ea1c2ac2f2 GIT binary patch literal 568 zcmV-80>}L$AX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkNR8&wy zZ*pZa3L_v^WpZ8b#rNMXCQiPX<{x4c-qC5v2Md45Qg_Yg{5?LA~SZYx^(CeMd^%? zLlvtIIDn<*?Q0Sz1an}p8+Ej~|GP6jer~T+Q*uGk@>QN#`NkQerK&hvb6#i7>7}fR zlv$Axy}VjHXZh1Uq*-EIu}WdA#a}HuFQn+p+oRM7qLfIH?+M%06rbacSW z`>&DxmdIRC*>q?s^H$V8rSG3cQ!cBM3b?G!tl)F=F(G-Unwb}qrdmSnhq7Z^mETek zp;ikcxW+mVsRSj5C`KP@BlM9ETO7LjLeO6ztZ7lKPtrf8fqz$AN~4{a8?vm()c4Yf z*++dpvJ{YG)pX!HTFasPAmctmhl13OCn5ita-A$d^tC`d-O~uSG($6sWcRWVb5`v` z1eD0~!6>d)ct|s + + + + + + + + + + + + + + + + + + + + + + + + + + + + Proxies - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + + +
+ +
+ + +
+ + + + +
+
+
+ + + +
+ +
+ + + + + + +

Proxies

+

The httpcore2 package provides support for HTTP proxies, using either "HTTP Forwarding" or "HTTP Tunnelling". Forwarding is a proxy mechanism for sending requests to http URLs via an intermediate proxy. Tunnelling is a proxy mechanism for sending requests to https URLs via an intermediate proxy.

+

Sending requests via a proxy is very similar to sending requests using a standard connection pool:

+
import httpcore2
+
+proxy = httpcore2.Proxy("http://127.0.0.1:8080/")
+pool = httpcore2.ConnectionPool(proxy=proxy)
+r = proxy.request("GET", "https://www.example.com/")
+
+print(r)
+# <Response [200]>
+
+

You can test the httpcore2 proxy support, using the Python proxy.py tool:

+
pip install proxy.py
+proxy --hostname 127.0.0.1 --port 8080
+
+

Requests will automatically use either forwarding or tunnelling, depending on if the scheme is http or https.

+

Authentication

+

Proxy authentication can be included in the initial configuration:

+
import httpcore2
+
+# A `Proxy-Authorization` header will be included on the initial proxy connection.
+proxy = httpcore2.Proxy(
+    url="http://127.0.0.1:8080/",
+    auth=("<username>", "<password>")
+)
+pool = httpcore2.ConnectionPool(proxy=proxy)
+
+

Custom headers can also be included:

+
import httpcore2
+import base64
+
+# Construct and include a `Proxy-Authorization` header.
+auth = base64.b64encode(b"<username>:<password>")
+proxy = httpcore2.Proxy(
+    url="http://127.0.0.1:8080/",
+    headers={"Proxy-Authorization": b"Basic " + auth}
+)
+pool = httpcore2.ConnectionPool(proxy=proxy)
+
+

Proxy SSL

+

The httpcore2 package also supports HTTPS proxies for http and https destinations.

+

HTTPS proxies can be used in the same way that HTTP proxies are.

+
proxy = httpcore2.Proxy(url="https://127.0.0.1:8080/")
+
+

Also, when using HTTPS proxies, you may need to configure the SSL context, which you can do with the ssl_context argument.

+
import ssl
+import httpcore2
+
+proxy_ssl_context = ssl.create_default_context()
+proxy_ssl_context.check_hostname = False
+
+proxy = httpcore2.Proxy(
+    url='https://127.0.0.1:8080/',
+    ssl_context=proxy_ssl_context
+)
+pool = httpcore2.ConnectionPool(proxy=proxy)
+
+

HTTP Versions

+

If you use proxies, keep in mind that the httpcore2 package only supports proxies to HTTP/1.1 servers.

+

SOCKS proxy support

+

The httpcore2 package also supports proxies using the SOCKS5 protocol.

+

Make sure to install the optional dependency using pip install 'httpcore2[socks]'.

+

The SOCKSProxy class should be using instead of a standard connection pool:

+
import httpcore2
+
+# Note that the SOCKS port is 1080.
+proxy = httpcore2.Proxy(url="socks5://127.0.0.1:1080/")
+pool = httpcore2.ConnectionPool(proxy=proxy)
+r = pool.request("GET", "https://www.example.com/")
+
+

Authentication via SOCKS is also supported:

+
import httpcore2
+
+proxy = httpcore2.Proxy(
+    url="socks5://127.0.0.1:1080/",
+    auth=("<username>", "<password>"),
+)
+pool = httpcore2.ConnectionPool(proxy=proxy)
+r = pool.request("GET", "https://www.example.com/")
+
+
+

Reference

+

httpcore2.Proxy

+ + +
+ + + +

+ httpcore2.Proxy + + +

+ + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/quickstart/index.html b/src/httpcore2/site-httpcore2/quickstart/index.html new file mode 100644 index 00000000..9b3c6616 --- /dev/null +++ b/src/httpcore2/site-httpcore2/quickstart/index.html @@ -0,0 +1,1222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Quickstart - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + + +
+ +
+ + +
+ + + + +
+
+
+ + + +
+ +
+ + + + + + +

Quickstart

+

For convenience, the httpcore2 package provides a couple of top-level functions that you can use for sending HTTP requests. You probably don't want to integrate against functions if you're writing a library that uses httpcore2, but you might find them useful for testing httpcore2 from the command-line, or if you're writing a simple script that doesn't require any of the connection pooling or advanced configuration that httpcore2 offers.

+

Sending a request

+

We'll start off by sending a request...

+
import httpcore2
+
+response = httpcore2.request("GET", "https://www.example.com/")
+
+print(response)
+# <Response [200]>
+print(response.status)
+# 200
+print(response.headers)
+# [(b'Accept-Ranges', b'bytes'), (b'Age', b'557328'), (b'Cache-Control', b'max-age=604800'), ...]
+print(response.content)
+# b'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>\n\n<meta charset="utf-8"/>\n ...'
+
+

Request headers

+

Request headers may be included either in a dictionary style, or as a list of two-tuples.

+
import httpcore2
+import json
+
+headers = {'User-Agent': 'httpcore2'}
+r = httpcore2.request('GET', 'https://httpbin.org/headers', headers=headers)
+
+print(json.loads(r.content))
+# {
+#     'headers': {
+#         'Host': 'httpbin.org',
+#         'User-Agent': 'httpcore2',
+#         'X-Amzn-Trace-Id': 'Root=1-616ff5de-5ea1b7e12766f1cf3b8e3a33'
+#     }
+# }
+
+

The keys and values may either be provided as strings or as bytes. Where strings are provided they may only contain characters within the ASCII range chr(0) - chr(127). To include characters outside this range you must deal with any character encoding explicitly, and pass bytes as the header keys/values.

+

The Host header will always be automatically included in any outgoing request, as it is strictly required to be present by the HTTP protocol.

+

Note that the X-Amzn-Trace-Id header shown in the example above is not an outgoing request header, but has been added by a gateway server.

+

Request body

+

A request body can be included either as bytes...

+
import httpcore2
+import json
+
+r = httpcore2.request('POST', 'https://httpbin.org/post', content=b'Hello, world')
+
+print(json.loads(r.content))
+# {
+#     'args': {},
+#     'data': 'Hello, world',
+#     'files': {},
+#     'form': {},
+#     'headers': {
+#         'Host': 'httpbin.org',
+#         'Content-Length': '12',
+#         'X-Amzn-Trace-Id': 'Root=1-61700258-00e338a124ca55854bf8435f'
+#     },
+#     'json': None,
+#     'origin': '68.41.35.196',
+#     'url': 'https://httpbin.org/post'
+# }
+
+

Or as an iterable that returns bytes...

+
import httpcore2
+import json
+
+with open("hello-world.txt", "rb") as input_file:
+    r = httpcore2.request('POST', 'https://httpbin.org/post', content=input_file)
+
+print(json.loads(r.content))
+# {
+#     'args': {},
+#     'data': 'Hello, world',
+#     'files': {},
+#     'form': {},
+#     'headers': {
+#         'Host': 'httpbin.org',
+#         'Transfer-Encoding': 'chunked',
+#         'X-Amzn-Trace-Id': 'Root=1-61700258-00e338a124ca55854bf8435f'
+#     },
+#     'json': None,
+#     'origin': '68.41.35.196',
+#     'url': 'https://httpbin.org/post'
+# }
+
+

When a request body is included, either a Content-Length header or a Transfer-Encoding: chunked header will be automatically included.

+

The Content-Length header is used when passing bytes, and indicates an HTTP request with a body of a pre-determined length.

+

The Transfer-Encoding: chunked header is the mechanism that HTTP/1.1 uses for sending HTTP request bodies without a pre-determined length.

+

Streaming responses

+

When using the httpcore2.request() function, the response body will automatically be read to completion, and made available in the response.content attribute.

+

Sometimes you may be dealing with large responses and not want to read the entire response into memory. The httpcore2.stream() function provides a mechanism for sending a request and dealing with a streaming response:

+
import httpcore2
+
+with httpcore2.stream('GET', 'https://example.com') as response:
+    for chunk in response.iter_stream():
+        print(f"Downloaded: {chunk}")
+
+

Here's a more complete example that demonstrates downloading a response:

+
import httpcore2
+
+with httpcore2.stream('GET', 'https://speed.hetzner.de/100MB.bin') as response:
+    with open("download.bin", "wb") as output_file:
+        for chunk in response.iter_stream():
+            output_file.write(chunk)
+
+

The httpcore2.stream() API also allows you to conditionally read the response...

+
import httpcore2
+
+with httpcore2.stream('GET', 'https://example.com') as response:
+    content_length = [int(v) for k, v in response.headers if k.lower() == b'content-length'][0]
+    if content_length > 100_000_000:
+        raise Exception("Response too large.")
+    response.read()  # `response.content` is now available.
+
+
+

Reference

+

httpcore2.request()

+ + +
+ + +

+ httpcore2.request + + +

+
request(
+    method: bytes | str,
+    url: URL | bytes | str,
+    *,
+    headers: HeaderTypes = None,
+    content: bytes | Iterator[bytes] | None = None,
+    extensions: Extensions | None = None,
+) -> Response
+
+ +
+ +

Sends an HTTP request, returning the response.

+
response = httpcore2.request("GET", "https://www.example.com/")
+
+ + +

Parameters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionDefault
+ method + + bytes | str + +
+

The HTTP method for the request. Typically one of "GET", +"OPTIONS", "HEAD", "POST", "PUT", "PATCH", or "DELETE".

+
+
+ required +
+ url + + URL | bytes | str + +
+

The URL of the HTTP request. Either as an instance of httpcore2.URL, +or as str/bytes.

+
+
+ required +
+ headers + + HeaderTypes + +
+

The HTTP request headers. Either as a dictionary of str/bytes, +or as a list of two-tuples of str/bytes.

+
+
+ None +
+ content + + bytes | Iterator[bytes] | None + +
+

The content of the request body. Either as bytes, +or as a bytes iterator.

+
+
+ None +
+ extensions + + Extensions | None + +
+

A dictionary of optional extra information included on the request. +Possible keys include "timeout".

+
+
+ None +
+ + +

Returns:

+ + + + + + + + + + + + + +
TypeDescription
+ Response + +
+

An instance of httpcore2.Response.

+
+
+ + +
+ +

httpcore2.stream()

+ + +
+ + +

+ httpcore2.stream + + +

+
stream(
+    method: bytes | str,
+    url: URL | bytes | str,
+    *,
+    headers: HeaderTypes = None,
+    content: bytes | Iterator[bytes] | None = None,
+    extensions: Extensions | None = None,
+) -> typing.Iterator[Response]
+
+ +
+ +

Sends an HTTP request, returning the response within a content manager.

+
with httpcore2.stream("GET", "https://www.example.com/") as response:
+    ...
+
+

When using the stream() function, the body of the response will not be +automatically read. If you want to access the response body you should +either use content = response.read(), or for chunk in response.iter_content().

+ + +

Parameters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionDefault
+ method + + bytes | str + +
+

The HTTP method for the request. Typically one of "GET", +"OPTIONS", "HEAD", "POST", "PUT", "PATCH", or "DELETE".

+
+
+ required +
+ url + + URL | bytes | str + +
+

The URL of the HTTP request. Either as an instance of httpcore2.URL, +or as str/bytes.

+
+
+ required +
+ headers + + HeaderTypes + +
+

The HTTP request headers. Either as a dictionary of str/bytes, +or as a list of two-tuples of str/bytes.

+
+
+ None +
+ content + + bytes | Iterator[bytes] | None + +
+

The content of the request body. Either as bytes, +or as a bytes iterator.

+
+
+ None +
+ extensions + + Extensions | None + +
+

A dictionary of optional extra information included on the request. +Possible keys include "timeout".

+
+
+ None +
+ + +

Returns:

+ + + + + + + + + + + + + +
TypeDescription
+ Iterator[Response] + +
+

An instance of httpcore2.Response.

+
+
+ + +
+ +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/requests-responses-urls/index.html b/src/httpcore2/site-httpcore2/requests-responses-urls/index.html new file mode 100644 index 00000000..2af87f36 --- /dev/null +++ b/src/httpcore2/site-httpcore2/requests-responses-urls/index.html @@ -0,0 +1,1353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Requests, Responses, and URLs - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + + +
+ +
+ + +
+ + + + +
+
+
+ + + +
+ +
+ + + + + + +

Requests, Responses, and URLs

+

TODO

+

Requests

+

Request instances in httpcore2 are deliberately simple, and only include the essential information required to represent an HTTP request.

+

Properties on the request are plain byte-wise representations.

+
>>> request = httpcore2.Request("GET", "https://www.example.com/")
+>>> request.method
+b"GET"
+>>> request.url
+httpcore2.URL(scheme=b"https", host=b"www.example.com", port=None, target=b"/")
+>>> request.headers
+[(b'Host', b'www.example.com')]
+>>> request.stream
+<httpcore2.ByteStream [0 bytes]>
+
+

The interface is liberal in the types that it accepts, but specific in the properties that it uses to represent them. For example, headers may be specified as a dictionary of strings, but internally are represented as a list of (byte, byte) tuples.

+

```python

+
+
+
+

headers = {"User-Agent": "custom"} +request = httpcore2.Request("GET", "https://www.example.com/", headers=headers) +request.headers +[(b'Host', b'www.example.com'), (b"User-Agent", b"custom")]

+
+
+
+

Responses

+

...

+

URLs

+

...

+
+

Reference

+

httpcore2.Request

+ + +
+ + + +

+ httpcore2.Request + + +

+ + +
+ + + +

An HTTP request.

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

+ __init__ + + +

+
__init__(
+    method: bytes | str,
+    url: URL | bytes | str,
+    *,
+    headers: HeaderTypes = None,
+    content: bytes
+    | Iterable[bytes]
+    | AsyncIterable[bytes]
+    | None = None,
+    extensions: Extensions | None = None,
+) -> None
+
+ +
+ + + +

Parameters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionDefault
+ method + + bytes | str + +
+

The HTTP request method, either as a string or bytes. +For example: GET.

+
+
+ required +
+ url + + URL | bytes | str + +
+

The request URL, either as a URL instance, or as a string or bytes. +For example: "https://www.example.com".

+
+
+ required +
+ headers + + HeaderTypes + +
+

The HTTP request headers.

+
+
+ None +
+ content + + bytes | Iterable[bytes] | AsyncIterable[bytes] | None + +
+

The content of the request body.

+
+
+ None +
+ extensions + + Extensions | None + +
+

A dictionary of optional extra information included on +the request. Possible keys include "timeout", and "trace".

+
+
+ None +
+ + +
+ +
+ + + +
+ +
+ +

httpcore2.Response

+ + +
+ + + +

+ httpcore2.Response + + +

+ + +
+ + + +

An HTTP response.

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

+ __init__ + + +

+
__init__(
+    status: int,
+    *,
+    headers: HeaderTypes = None,
+    content: bytes
+    | Iterable[bytes]
+    | AsyncIterable[bytes]
+    | None = None,
+    extensions: Extensions | None = None,
+) -> None
+
+ +
+ + + +

Parameters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionDefault
+ status + + int + +
+

The HTTP status code of the response. For example 200.

+
+
+ required +
+ headers + + HeaderTypes + +
+

The HTTP response headers.

+
+
+ None +
+ content + + bytes | Iterable[bytes] | AsyncIterable[bytes] | None + +
+

The content of the response body.

+
+
+ None +
+ extensions + + Extensions | None + +
+

A dictionary of optional extra information included on +the responseself.Possible keys include "http_version", +"reason_phrase", and "network_stream".

+
+
+ None +
+ + +
+ +
+ + + +
+ +
+ +

httpcore2.URL

+ + +
+ + + +

+ httpcore2.URL + + +

+ + +
+ + + +

Represents the URL against which an HTTP request may be made.

+

The URL may either be specified as a plain string, for convenience:

+
url = httpcore2.URL("https://www.example.com/")
+
+

Or be constructed with explicitly pre-parsed components:

+
url = httpcore2.URL(scheme=b'https', host=b'www.example.com', port=None, target=b'/')
+
+

Using this second more explicit style allows integrations that are using +httpcore to pass through URLs that have already been parsed in order to use +libraries such as rfc-3986 rather than relying on the stdlib. It also ensures +that URL parsing is treated identically at both the networking level and at any +higher layers of abstraction.

+

The four components are important here, as they allow the URL to be precisely +specified in a pre-parsed format. They also allow certain types of request to +be created that could not otherwise be expressed.

+

For example, an HTTP request to http://www.example.com/ forwarded via a proxy +at http://localhost:8080...

+
# Constructs an HTTP request with a complete URL as the target:
+# GET https://www.example.com/ HTTP/1.1
+url = httpcore2.URL(
+    scheme=b'http',
+    host=b'localhost',
+    port=8080,
+    target=b'https://www.example.com/'
+)
+request = httpcore2.Request(
+    method="GET",
+    url=url
+)
+
+

Another example is constructing an OPTIONS * request...

+
# Constructs an 'OPTIONS *' HTTP request:
+# OPTIONS * HTTP/1.1
+url = httpcore2.URL(scheme=b'https', host=b'www.example.com', target=b'*')
+request = httpcore2.Request(method="OPTIONS", url=url)
+
+

This kind of request is not possible to formulate with a URL string, +because the / delimiter is always used to demark the target from the +host/port portion of the URL.

+

For convenience, string-like arguments may be specified either as strings or +as bytes. However, once a request is being issue over-the-wire, the URL +components are always ultimately required to be a bytewise representation.

+

In order to avoid any ambiguity over character encodings, when strings are used +as arguments, they must be strictly limited to the ASCII range chr(0)-chr(127). +If you require a bytewise representation that is outside this range you must +handle the character encoding directly, and pass a bytes instance.

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

+ __init__ + + +

+
__init__(
+    url: bytes | str = "",
+    *,
+    scheme: bytes | str = b"",
+    host: bytes | str = b"",
+    port: int | None = None,
+    target: bytes | str = b"",
+) -> None
+
+ +
+ + + +

Parameters:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionDefault
+ url + + bytes | str + +
+

The complete URL as a string or bytes.

+
+
+ '' +
+ scheme + + bytes | str + +
+

The URL scheme as a string or bytes. +Typically either "http" or "https".

+
+
+ b'' +
+ host + + bytes | str + +
+

The URL host as a string or bytes. Such as "www.example.com".

+
+
+ b'' +
+ port + + int | None + +
+

The port to connect to. Either an integer or None.

+
+
+ None +
+ target + + bytes | str + +
+

The target of the HTTP request. Such as "/items?search=red".

+
+
+ b'' +
+ + +
+ +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/search.json b/src/httpcore2/site-httpcore2/search.json new file mode 100644 index 00000000..6887c91c --- /dev/null +++ b/src/httpcore2/site-httpcore2/search.json @@ -0,0 +1 @@ +{"config":{"separator":"[\\s\\-_,:!=\\[\\]()\\\\\"`/]+|\\.(?!\\d)"},"items":[{"location":"","level":1,"title":"HTTPCore","text":"

Do one thing, and do it well.

The HTTP Core package provides a minimal low-level HTTP client, which does one thing only. Sending HTTP requests.

It does not provide any high level model abstractions over the API, does not handle redirects, multipart uploads, building authentication headers, transparent HTTP caching, URL parsing, session cookie handling, content or charset decoding, handling JSON, environment based configuration defaults, or any of that Jazz.

Some things HTTP Core does do:

  • Sending HTTP requests.
  • Thread-safe / task-safe connection pooling.
  • HTTP(S) proxy & SOCKS proxy support.
  • Supports HTTP/1.1 and HTTP/2.
  • Provides both sync and async interfaces.
  • Async backend support for asyncio and trio.
","path":["HTTPCore"],"tags":[]},{"location":"#installation","level":2,"title":"Installation","text":"

For HTTP/1.1 only support, install with:

pip install httpcore2\n

For HTTP/1.1 and HTTP/2 support, install with:

pip install httpcore2[http2]\n

For SOCKS proxy support, install with:

pip install httpcore2[socks]\n
","path":["HTTPCore"],"tags":[]},{"location":"#example","level":2,"title":"Example","text":"

Let's check we're able to send HTTP requests:

import httpcore2\n\nresponse = httpcore2.request(\"GET\", \"https://www.example.com/\")\n\nprint(response)\n# <Response [200]>\nprint(response.status)\n# 200\nprint(response.headers)\n# [(b'Accept-Ranges', b'bytes'), (b'Age', b'557328'), (b'Cache-Control', b'max-age=604800'), ...]\nprint(response.content)\n# b'<!doctype html>\\n<html>\\n<head>\\n<title>Example Domain</title>\\n\\n<meta charset=\"utf-8\"/>\\n ...'\n

Ready to get going?

Head over to the quickstart documentation.

","path":["HTTPCore"],"tags":[]},{"location":"async/","level":1,"title":"Async Support","text":"

HTTPX offers a standard synchronous API by default, but also gives you the option of an async client if you need it.

Async is a concurrency model that is far more efficient than multi-threading, and can provide significant performance benefits and enable the use of long-lived network connections such as WebSockets.

If you're working with an async web framework then you'll also want to use an async client for sending outgoing HTTP requests.

Launching concurrent async tasks is far more resource efficient than spawning multiple threads. The Python interpreter should be able to comfortably handle switching between over 1000 concurrent tasks, while a sensible number of threads in a thread pool might be to enable around 10 or 20 concurrent threads.

","path":["Async Support"],"tags":[]},{"location":"async/#enabling-async-support","level":2,"title":"Enabling Async support","text":"

If you're using async with Python's stdlib asyncio support, install the optional dependencies using:

pip install 'httpcore2[asyncio]'\n

Alternatively, if you're working with the Python trio package:

pip install 'httpcore2[trio]'\n

We highly recommend trio for async support. The trio project pioneered the principles of structured concurrency, and has a more carefully constrained API against which to work from.

","path":["Async Support"],"tags":[]},{"location":"async/#api-differences","level":2,"title":"API differences","text":"

When using async support, you need make sure to use an async connection pool class:

# The async variation of `httpcore2.ConnectionPool`\nasync with httpcore2.AsyncConnectionPool() as http:\n    ...\n
","path":["Async Support"],"tags":[]},{"location":"async/#sending-requests","level":3,"title":"Sending requests","text":"

Sending requests with the async version of httpcore2 requires the await keyword:

import asyncio\nimport httpcore2\n\nasync def main():\n    async with httpcore2.AsyncConnectionPool() as http:\n        response = await http.request(\"GET\", \"https://www.example.com/\")\n\n\nasyncio.run(main())\n

When including content in the request, the content must either be bytes or an async iterable yielding bytes.

","path":["Async Support"],"tags":[]},{"location":"async/#streaming-responses","level":3,"title":"Streaming responses","text":"

Streaming responses also require a slightly different interface to the sync version:

  • with <pool>.stream(...) as responseasync with <pool>.stream() as response.
  • for chunk in response.iter_stream()async for chunk in response.aiter_stream().
  • response.read()await response.aread().
  • response.close()await response.aclose()

For example:

import asyncio\nimport httpcore2\n\n\nasync def main():\n    async with httpcore2.AsyncConnectionPool() as http:\n        async with http.stream(\"GET\", \"https://www.example.com/\") as response:\n            async for chunk in response.aiter_stream():\n                print(f\"Downloaded: {chunk}\")\n\n\nasyncio.run(main())\n
","path":["Async Support"],"tags":[]},{"location":"async/#pool-lifespans","level":3,"title":"Pool lifespans","text":"

When using httpcore2 in an async environment it is strongly recommended that you instantiate and use connection pools using the context managed style:

async with httpcore2.AsyncConnectionPool() as http:\n    ...\n

To benefit from connection pooling it is recommended that you instantiate a single connection pool in this style, and pass it around throughout your application.

If you do want to use a connection pool without this style then you'll need to ensure that you explicitly close the pool once it is no longer required:

try:\n    http = httpcore2.AsyncConnectionPool()\n    ...\nfinally:\n    await http.aclose()\n

This is a little different to the threaded context, where it's okay to simply instantiate a globally available connection pool, and then allow Python's garbage collection to deal with closing any connections in the pool, once the __del__ method is called.

The reason for this difference is that asynchronous code is not able to run within the context of the synchronous __del__ method, so there is no way for connections to be automatically closed at the point of garbage collection. This can lead to unterminated TCP connections still remaining after the Python interpreter quits.

","path":["Async Support"],"tags":[]},{"location":"async/#supported-environments","level":2,"title":"Supported environments","text":"

HTTPX supports either asyncio or trio as an async environment.

It will auto-detect which of those two to use as the backend for socket operations and concurrency primitives.

","path":["Async Support"],"tags":[]},{"location":"async/#asyncio","level":3,"title":"AsyncIO","text":"

AsyncIO is Python's built-in library for writing concurrent code with the async/await syntax.

Let's take a look at sending several outgoing HTTP requests concurrently, using asyncio:

import asyncio\nimport httpcore2\nimport time\n\n\nasync def download(http, year):\n    await http.request(\"GET\", f\"https://en.wikipedia.org/wiki/{year}\")\n\n\nasync def main():\n    async with httpcore2.AsyncConnectionPool() as http:\n        started = time.time()\n        # Here we use `asyncio.gather()` in order to run several tasks concurrently...\n        tasks = [download(http, year) for year in range(2000, 2020)]\n        await asyncio.gather(*tasks)\n        complete = time.time()\n\n        for connection in http.connections:\n            print(connection)\n        print(\"Complete in %.3f seconds\" % (complete - started))\n\n\nasyncio.run(main())\n
","path":["Async Support"],"tags":[]},{"location":"async/#trio","level":3,"title":"Trio","text":"

Trio is an alternative async library, designed around the the principles of structured concurrency.

import httpcore2\nimport trio\nimport time\n\n\nasync def download(http, year):\n    await http.request(\"GET\", f\"https://en.wikipedia.org/wiki/{year}\")\n\n\nasync def main():\n    async with httpcore2.AsyncConnectionPool() as http:\n        started = time.time()\n        async with trio.open_nursery() as nursery:\n            for year in range(2000, 2020):\n                nursery.start_soon(download, http, year)\n        complete = time.time()\n\n        for connection in http.connections:\n            print(connection)\n        print(\"Complete in %.3f seconds\" % (complete - started))\n\n\ntrio.run(main)\n
","path":["Async Support"],"tags":[]},{"location":"async/#anyio","level":3,"title":"AnyIO","text":"

AnyIO is an asynchronous networking and concurrency library that works on top of either asyncio or trio. It blends in with native libraries of your chosen backend (defaults to asyncio).

The anyio library is designed around the the principles of structured concurrency, and brings many of the same correctness and usability benefits that Trio provides, while interoperating with existing asyncio libraries.

import httpcore2\nimport anyio\nimport time\n\n\nasync def download(http, year):\n    await http.request(\"GET\", f\"https://en.wikipedia.org/wiki/{year}\")\n\n\nasync def main():\n    async with httpcore2.AsyncConnectionPool() as http:\n        started = time.time()\n        async with anyio.create_task_group() as task_group:\n            for year in range(2000, 2020):\n                task_group.start_soon(download, http, year)\n        complete = time.time()\n\n        for connection in http.connections:\n            print(connection)\n        print(\"Complete in %.3f seconds\" % (complete - started))\n\n\nanyio.run(main)\n
","path":["Async Support"],"tags":[]},{"location":"async/#reference","level":1,"title":"Reference","text":"","path":["Async Support"],"tags":[]},{"location":"async/#httpcore2asyncconnectionpool","level":2,"title":"httpcore2.AsyncConnectionPool","text":"","path":["Async Support"],"tags":[]},{"location":"async/#httpcore2.AsyncConnectionPool","level":3,"title":"httpcore2.AsyncConnectionPool","text":"

Bases: AsyncRequestInterface

A connection pool for making HTTP requests.

","path":["Async Support"],"tags":[]},{"location":"async/#httpcore2.AsyncConnectionPool.connections","level":4,"title":"connections property","text":"
connections: list[AsyncConnectionInterface]\n

Return a list of the connections currently in the pool.

For example:

>>> pool.connections\n[\n    <AsyncHTTPConnection ['https://example.com:443', HTTP/1.1, ACTIVE, Request Count: 6]>,\n    <AsyncHTTPConnection ['https://example.com:443', HTTP/1.1, IDLE, Request Count: 9]> ,\n    <AsyncHTTPConnection ['http://example.com:80', HTTP/1.1, IDLE, Request Count: 1]>,\n]\n
","path":["Async Support"],"tags":[]},{"location":"async/#httpcore2.AsyncConnectionPool.__init__","level":4,"title":"__init__","text":"
__init__(\n    ssl_context: SSLContext | None = None,\n    proxy: Proxy | None = None,\n    max_connections: int | None = 10,\n    max_keepalive_connections: int | None = None,\n    keepalive_expiry: float | None = None,\n    http1: bool = True,\n    http2: bool = False,\n    retries: int = 0,\n    local_address: str | None = None,\n    uds: str | None = None,\n    network_backend: AsyncNetworkBackend | None = None,\n    socket_options: Iterable[SOCKET_OPTION] | None = None,\n) -> None\n

A connection pool for making HTTP requests.

Parameters:

Name Type Description Default ssl_context SSLContext | None

An SSL context to use for verifying connections. If not specified, the default httpcore2.default_ssl_context() will be used.

None max_connections int | None

The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available.

10 max_keepalive_connections int | None

The maximum number of idle HTTP connections that will be maintained in the pool.

None keepalive_expiry float | None

The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool.

None http1 bool

A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to True.

True http2 bool

A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False.

False retries int

The maximum number of retries when trying to establish a connection.

0 local_address str | None

Local address to connect from. Can also be used to connect using a particular address family. Using local_address=\"0.0.0.0\" will connect using an AF_INET address (IPv4), while using local_address=\"::\" will connect using an AF_INET6 address (IPv6).

None uds str | None

Path to a Unix Domain Socket to use instead of TCP sockets.

None network_backend AsyncNetworkBackend | None

A backend instance to use for handling network I/O.

None socket_options Iterable[SOCKET_OPTION] | None

Socket options that have to be included in the TCP socket when the connection was established.

None","path":["Async Support"],"tags":[]},{"location":"async/#httpcore2.AsyncConnectionPool.handle_async_request","level":4,"title":"handle_async_request async","text":"
handle_async_request(request: Request) -> Response\n

Send an HTTP request, and return an HTTP response.

This is the core implementation that is called into by .request() or .stream().

","path":["Async Support"],"tags":[]},{"location":"connection-pools/","level":1,"title":"Connection Pools","text":"

While the top-level API provides convenience functions for working with httpcore2, in practice you'll almost always want to take advantage of the connection pooling functionality that it provides.

To do so, instantiate a pool instance, and use it to send requests:

import httpcore2\n\nhttp = httpcore2.ConnectionPool()\nr = http.request(\"GET\", \"https://www.example.com/\")\n\nprint(r)\n# <Response [200]>\n

Connection pools support the same .request() and .stream() APIs as described in the Quickstart.

We can observe the benefits of connection pooling with a simple script like so:

import httpcore2\nimport time\n\n\nhttp = httpcore2.ConnectionPool()\nfor counter in range(5):\n    started = time.time()\n    response = http.request(\"GET\", \"https://www.example.com/\")\n    complete = time.time()\n    print(response, \"in %.3f seconds\" % (complete - started))\n

The output should demonstrate the initial request as being substantially slower than the subsequent requests:

<Response [200]> in {0.529} seconds\n<Response [200]> in {0.096} seconds\n<Response [200]> in {0.097} seconds\n<Response [200]> in {0.095} seconds\n<Response [200]> in {0.098} seconds\n

This is to be expected. Once we've established a connection to \"www.example.com\" we're able to reuse it for following requests.

","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#configuration","level":2,"title":"Configuration","text":"

The connection pool instance is also the main point of configuration. Let's take a look at the various options that it provides:

","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#ssl-configuration","level":3,"title":"SSL configuration","text":"
  • ssl_context: An SSL context to use for verifying connections. If not specified, the default httpcore2.default_ssl_context() will be used.
","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#pooling-configuration","level":3,"title":"Pooling configuration","text":"
  • max_connections: The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available.
  • max_keepalive_connections: The maximum number of idle HTTP connections that will be maintained in the pool.
  • keepalive_expiry: The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool.
","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#http-version-support","level":3,"title":"HTTP version support","text":"
  • http1: A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to True.
  • http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False.
","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#other-options","level":3,"title":"Other options","text":"
  • retries: The maximum number of retries when trying to establish a connection.
  • local_address: Local address to connect from. Can also be used to connect using a particular address family. Using local_address=\"0.0.0.0\" will connect using an AF_INET address (IPv4), while using local_address=\"::\" will connect using an AF_INET6 address (IPv6).
  • uds: Path to a Unix Domain Socket to use instead of TCP sockets.
  • network_backend: A backend instance to use for handling network I/O.
  • socket_options: Socket options that have to be included in the TCP socket when the connection was established.
","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#pool-lifespans","level":2,"title":"Pool lifespans","text":"

Because connection pools hold onto network resources, careful developers may want to ensure that instances are properly closed once they are no longer required.

Working with a single global instance isn't a bad idea for many use case, since the connection pool will automatically be closed when the __del__ method is called on it:

# This is perfectly fine for most purposes.\n# The connection pool will automatically be closed when it is garbage collected,\n# or when the Python interpreter exits.\nhttp = httpcore2.ConnectionPool()\n

However, to be more explicit around the resource usage, we can use the connection pool within a context manager:

with httpcore2.ConnectionPool() as http:\n    ...\n

Or else close the pool explicitly:

http = httpcore2.ConnectionPool()\ntry:\n    ...\nfinally:\n    http.close()\n
","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#thread-and-task-safety","level":2,"title":"Thread and task safety","text":"

Connection pools are designed to be thread-safe. Similarly, when using httpcore2 in an async context connection pools are task-safe.

This means that you can have a single connection pool instance shared by multiple threads.

","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#reference","level":1,"title":"Reference","text":"","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#httpcore2connectionpool","level":2,"title":"httpcore2.ConnectionPool","text":"","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#httpcore2.ConnectionPool","level":3,"title":"httpcore2.ConnectionPool","text":"

Bases: RequestInterface

A connection pool for making HTTP requests.

","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#httpcore2.ConnectionPool.connections","level":4,"title":"connections property","text":"
connections: list[ConnectionInterface]\n

Return a list of the connections currently in the pool.

For example:

>>> pool.connections\n[\n    <HTTPConnection ['https://example.com:443', HTTP/1.1, ACTIVE, Request Count: 6]>,\n    <HTTPConnection ['https://example.com:443', HTTP/1.1, IDLE, Request Count: 9]> ,\n    <HTTPConnection ['http://example.com:80', HTTP/1.1, IDLE, Request Count: 1]>,\n]\n
","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#httpcore2.ConnectionPool.__init__","level":4,"title":"__init__","text":"
__init__(\n    ssl_context: SSLContext | None = None,\n    proxy: Proxy | None = None,\n    max_connections: int | None = 10,\n    max_keepalive_connections: int | None = None,\n    keepalive_expiry: float | None = None,\n    http1: bool = True,\n    http2: bool = False,\n    retries: int = 0,\n    local_address: str | None = None,\n    uds: str | None = None,\n    network_backend: NetworkBackend | None = None,\n    socket_options: Iterable[SOCKET_OPTION] | None = None,\n) -> None\n

A connection pool for making HTTP requests.

Parameters:

Name Type Description Default ssl_context SSLContext | None

An SSL context to use for verifying connections. If not specified, the default httpcore2.default_ssl_context() will be used.

None max_connections int | None

The maximum number of concurrent HTTP connections that the pool should allow. Any attempt to send a request on a pool that would exceed this amount will block until a connection is available.

10 max_keepalive_connections int | None

The maximum number of idle HTTP connections that will be maintained in the pool.

None keepalive_expiry float | None

The duration in seconds that an idle HTTP connection may be maintained for before being expired from the pool.

None http1 bool

A boolean indicating if HTTP/1.1 requests should be supported by the connection pool. Defaults to True.

True http2 bool

A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False.

False retries int

The maximum number of retries when trying to establish a connection.

0 local_address str | None

Local address to connect from. Can also be used to connect using a particular address family. Using local_address=\"0.0.0.0\" will connect using an AF_INET address (IPv4), while using local_address=\"::\" will connect using an AF_INET6 address (IPv6).

None uds str | None

Path to a Unix Domain Socket to use instead of TCP sockets.

None network_backend NetworkBackend | None

A backend instance to use for handling network I/O.

None socket_options Iterable[SOCKET_OPTION] | None

Socket options that have to be included in the TCP socket when the connection was established.

None","path":["Connection Pools"],"tags":[]},{"location":"connection-pools/#httpcore2.ConnectionPool.handle_request","level":4,"title":"handle_request","text":"
handle_request(request: Request) -> Response\n

Send an HTTP request, and return an HTTP response.

This is the core implementation that is called into by .request() or .stream().

","path":["Connection Pools"],"tags":[]},{"location":"connections/","level":1,"title":"Connections","text":"

TODO

","path":["Connections"],"tags":[]},{"location":"connections/#reference","level":1,"title":"Reference","text":"","path":["Connections"],"tags":[]},{"location":"connections/#httpcore2httpconnection","level":2,"title":"httpcore2.HTTPConnection","text":"","path":["Connections"],"tags":[]},{"location":"connections/#httpcore2.HTTPConnection","level":3,"title":"httpcore2.HTTPConnection","text":"

Bases: ConnectionInterface

","path":["Connections"],"tags":[]},{"location":"connections/#httpcore2http11connection","level":2,"title":"httpcore2.HTTP11Connection","text":"","path":["Connections"],"tags":[]},{"location":"connections/#httpcore2.HTTP11Connection","level":3,"title":"httpcore2.HTTP11Connection","text":"

Bases: ConnectionInterface

","path":["Connections"],"tags":[]},{"location":"connections/#httpcore2http2connection","level":2,"title":"httpcore2.HTTP2Connection","text":"","path":["Connections"],"tags":[]},{"location":"connections/#httpcore2.HTTP2Connection","level":3,"title":"httpcore2.HTTP2Connection","text":"","path":["Connections"],"tags":[]},{"location":"exceptions/","level":1,"title":"Exceptions","text":"

The following exceptions may be raised when sending a request:

  • httpcore2.TimeoutException
    • httpcore2.PoolTimeout
    • httpcore2.ConnectTimeout
    • httpcore2.ReadTimeout
    • httpcore2.WriteTimeout
  • httpcore2.NetworkError
    • httpcore2.ConnectError
    • httpcore2.ReadError
    • httpcore2.WriteError
  • httpcore2.ProtocolError
    • httpcore2.RemoteProtocolError
    • httpcore2.LocalProtocolError
  • httpcore2.ProxyError
  • httpcore2.UnsupportedProtocol
","path":["Exceptions"],"tags":[]},{"location":"extensions/","level":1,"title":"Extensions","text":"

The request/response API used by httpcore2 is kept deliberately simple and explicit.

The Request and Response models are pretty slim wrappers around this core API:

# Pseudo-code expressing the essentials of the request/response model.\n(\n    status_code: int,\n    headers: List[Tuple(bytes, bytes)],\n    stream: Iterable[bytes]\n) = handle_request(\n    method: bytes,\n    url: URL,\n    headers: List[Tuple(bytes, bytes)],\n    stream: Iterable[bytes]\n)\n

This is everything that's needed in order to represent an HTTP exchange.

Well... almost.

There is a maxim in Computer Science that \"All non-trivial abstractions, to some degree, are leaky\". When an expression is leaky, it's important that it ought to at least leak only in well-defined places.

In order to handle cases that don't otherwise fit inside this core abstraction, httpcore2 requests and responses have 'extensions'. These are a dictionary of optional additional information.

Let's expand on our request/response abstraction...

# Pseudo-code expressing the essentials of the request/response model,\n# plus extensions allowing for additional API that does not fit into\n# this abstraction.\n(\n    status_code: int,\n    headers: List[Tuple(bytes, bytes)],\n    stream: Iterable[bytes],\n    extensions: dict\n) = handle_request(\n    method: bytes,\n    url: URL,\n    headers: List[Tuple(bytes, bytes)],\n    stream: Iterable[bytes],\n    extensions: dict\n)\n

Several extensions are supported both on the request:

r = httpcore2.request(\n    \"GET\",\n    \"https://www.example.com\",\n    extensions={\"timeout\": {\"connect\": 5.0}}\n)\n

And on the response:

r = httpcore2.request(\"GET\", \"https://www.example.com\")\n\nprint(r.extensions[\"http_version\"])\n# When using HTTP/1.1 on the client side, the server HTTP response\n# could feasibly be one of b\"HTTP/0.9\", b\"HTTP/1.0\", or b\"HTTP/1.1\".\n
","path":["Extensions"],"tags":[]},{"location":"extensions/#request-extensions","level":2,"title":"Request Extensions","text":"","path":["Extensions"],"tags":[]},{"location":"extensions/#timeout","level":3,"title":"\"timeout\"","text":"

A dictionary of str: Optional[float] timeout values.

May include values for 'connect', 'read', 'write', or 'pool'.

For example:

# Timeout if a connection takes more than 5 seconds to established, or if\n# we are blocked waiting on the connection pool for more than 10 seconds.\nr = httpcore2.request(\n    \"GET\",\n    \"https://www.example.com\",\n    extensions={\"timeout\": {\"connect\": 5.0, \"pool\": 10.0}}\n)\n
","path":["Extensions"],"tags":[]},{"location":"extensions/#trace","level":3,"title":"\"trace\"","text":"

The trace extension allows a callback handler to be installed to monitor the internal flow of events within httpcore2. The simplest way to explain this is with an example:

import httpcore2\n\ndef log(event_name, info):\n    print(event_name, info)\n\nr = httpcore2.request(\"GET\", \"https://www.example.com/\", extensions={\"trace\": log})\n# connection.connect_tcp.started {'host': 'www.example.com', 'port': 443, 'local_address': None, 'timeout': None}\n# connection.connect_tcp.complete {'return_value': <httpcore2._backends.sync.SyncStream object at 0x1093f94d0>}\n# connection.start_tls.started {'ssl_context': <ssl.SSLContext object at 0x1093ee750>, 'server_hostname': b'www.example.com', 'timeout': None}\n# connection.start_tls.complete {'return_value': <httpcore2._backends.sync.SyncStream object at 0x1093f9450>}\n# http11.send_request_headers.started {'request': <Request [b'GET']>}\n# http11.send_request_headers.complete {'return_value': None}\n# http11.send_request_body.started {'request': <Request [b'GET']>}\n# http11.send_request_body.complete {'return_value': None}\n# http11.receive_response_headers.started {'request': <Request [b'GET']>}\n# http11.receive_response_headers.complete {'return_value': (b'HTTP/1.1', 200, b'OK', [(b'Age', b'553715'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Thu, 21 Oct 2021 17:08:42 GMT'), (b'Etag', b'\"3147526947+ident\"'), (b'Expires', b'Thu, 28 Oct 2021 17:08:42 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1DCD)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')])}\n# http11.receive_response_body.started {'request': <Request [b'GET']>}\n# http11.receive_response_body.complete {'return_value': None}\n# http11.response_closed.started {}\n# http11.response_closed.complete {'return_value': None}\n

The event_name and info arguments here will be one of the following:

  • {event_type}.{event_name}.started, <dictionary of keyword arguments>
  • {event_type}.{event_name}.complete, {\"return_value\": <...>}
  • {event_type}.{event_name}.failed, {\"exception\": <...>}

Note that when using the async variant of httpcore2 the handler function passed to \"trace\" must be an async def ... function.

The following event types are currently exposed...

Establishing the connection

  • \"connection.connect_tcp\"
  • \"connection.connect_unix_socket\"
  • \"connection.start_tls\"

HTTP/1.1 events

  • \"http11.send_request_headers\"
  • \"http11.send_request_body\"
  • \"http11.receive_response\"
  • \"http11.receive_response_body\"
  • \"http11.response_closed\"

HTTP/2 events

  • \"http2.send_connection_init\"
  • \"http2.send_request_headers\"
  • \"http2.send_request_body\"
  • \"http2.receive_response_headers\"
  • \"http2.receive_response_body\"
  • \"http2.response_closed\"

The exact set of trace events may be subject to change across different versions of httpcore2. If you need to rely on a particular set of events it is recommended that you pin installation of the package to a fixed version.

","path":["Extensions"],"tags":[]},{"location":"extensions/#sni_hostname","level":3,"title":"\"sni_hostname\"","text":"

The server's hostname, which is used to confirm the hostname supplied by the SSL certificate.

For example:

headers = {\"Host\": \"www.encode.io\"}\nextensions = {\"sni_hostname\": \"www.encode.io\"}\nresponse = httpcore2.request(\n    \"GET\",\n    \"https://185.199.108.153\",\n    headers=headers,\n    extensions=extensions\n)\n
","path":["Extensions"],"tags":[]},{"location":"extensions/#target","level":3,"title":"\"target\"","text":"

The target that is used as the HTTP target instead of the URL path.

This enables support constructing requests that would otherwise be unsupported. In particular...

  • Forward proxy requests using an absolute URI.
  • Tunneling proxy requests using CONNECT with hostname as the target.
  • Server-wide OPTIONS * requests.

For example:

extensions = {\"target\": b\"www.encode.io:443\"}\nresponse = httpcore2.request(\n    \"CONNECT\",\n    \"http://your-tunnel-proxy.com\",\n    headers=headers,\n    extensions=extensions\n)\n
","path":["Extensions"],"tags":[]},{"location":"extensions/#response-extensions","level":2,"title":"Response Extensions","text":"","path":["Extensions"],"tags":[]},{"location":"extensions/#http_version","level":3,"title":"\"http_version\"","text":"

The HTTP version, as bytes. Eg. b\"HTTP/1.1\".

When using HTTP/1.1 the response line includes an explicit version, and the value of this key could feasibly be one of b\"HTTP/0.9\", b\"HTTP/1.0\", or b\"HTTP/1.1\".

When using HTTP/2 there is no further response versioning included in the protocol, and the value of this key will always be b\"HTTP/2\".

","path":["Extensions"],"tags":[]},{"location":"extensions/#reason_phrase","level":3,"title":"\"reason_phrase\"","text":"

The reason-phrase of the HTTP response, as bytes. For example b\"OK\". Some servers may include a custom reason phrase, although this is not recommended.

HTTP/2 onwards does not include a reason phrase on the wire.

When no key is included, a default based on the status code may be used.

","path":["Extensions"],"tags":[]},{"location":"extensions/#stream_id","level":3,"title":"\"stream_id\"","text":"

When HTTP/2 is being used the \"stream_id\" response extension can be accessed to determine the ID of the data stream that the response was sent on.

","path":["Extensions"],"tags":[]},{"location":"extensions/#network_stream","level":3,"title":"\"network_stream\"","text":"

The \"network_stream\" extension allows developers to handle HTTP CONNECT and Upgrade requests, by providing an API that steps outside the standard request/response model, and can directly read or write to the network.

The interface provided by the network stream:

  • read(max_bytes, timeout = None) -> bytes
  • write(buffer, timeout = None)
  • close()
  • start_tls(ssl_context, server_hostname = None, timeout = None) -> NetworkStream
  • get_extra_info(info) -> Any

This API can be used as the foundation for working with HTTP proxies, WebSocket upgrades, and other advanced use-cases.

See the network backends documentation for more information on working directly with network streams.

","path":["Extensions"],"tags":[]},{"location":"extensions/#connect-requests","level":5,"title":"CONNECT requests","text":"

A proxy CONNECT request using the network stream:

# Formulate a CONNECT request...\n#\n# This will establish a connection to 127.0.0.1:8080, and then send the following...\n#\n# CONNECT http://www.example.com HTTP/1.1\nurl = \"http://127.0.0.1:8080\"\nextensions = {\"target: \"http://www.example.com\"}\nwith httpcore2.stream(\"CONNECT\", url, extensions=extensions) as response:\n    network_stream = response.extensions[\"network_stream\"]\n\n    # Upgrade to an SSL stream...\n    network_stream = network_stream.start_tls(\n        ssl_context=httpcore2.default_ssl_context(),\n        hostname=b\"www.example.com\",\n    )\n\n    # Manually send an HTTP request over the network stream, and read the response...\n    #\n    # For a more complete example see the httpcore2 `TunnelHTTPConnection` implementation.\n    network_stream.write(b\"GET / HTTP/1.1\\r\\nHost: example.com\\r\\n\\r\\n\")\n    data = network_stream.read()\n    print(data)\n
","path":["Extensions"],"tags":[]},{"location":"extensions/#upgrade-requests","level":5,"title":"Upgrade requests","text":"

Using the wsproto package to handle a websockets session:

import httpcore2\nimport wsproto\nimport os\nimport base64\n\n\nurl = \"http://127.0.0.1:8000/\"\nheaders = {\n    b\"Connection\": b\"Upgrade\",\n    b\"Upgrade\": b\"WebSocket\",\n    b\"Sec-WebSocket-Key\": base64.b64encode(os.urandom(16)),\n    b\"Sec-WebSocket-Version\": b\"13\"\n}\nwith httpcore2.stream(\"GET\", url, headers=headers) as response:\n    if response.status != 101:\n        raise Exception(\"Failed to upgrade to websockets\", response)\n\n    # Get the raw network stream.\n    network_steam = response.extensions[\"network_stream\"]\n\n    # Write a WebSocket text frame to the stream.\n    ws_connection = wsproto.Connection(wsproto.ConnectionType.CLIENT)\n    message = wsproto.events.TextMessage(\"hello, world!\")\n    outgoing_data = ws_connection.send(message)\n    network_steam.write(outgoing_data)\n\n    # Wait for a response.\n    incoming_data = network_steam.read(max_bytes=4096)\n    ws_connection.receive_data(incoming_data)\n    for event in ws_connection.events():\n        if isinstance(event, wsproto.events.TextMessage):\n            print(\"Got data:\", event.data)\n\n    # Write a WebSocket close to the stream.\n    message = wsproto.events.CloseConnection(code=1000)\n    outgoing_data = ws_connection.send(message)\n    network_steam.write(outgoing_data)\n
","path":["Extensions"],"tags":[]},{"location":"extensions/#extra-network-information","level":5,"title":"Extra network information","text":"

The network stream abstraction also allows access to various low-level information that may be exposed by the underlying socket:

response = httpcore2.request(\"GET\", \"https://www.example.com\")\nnetwork_stream = response.extensions[\"network_stream\"]\n\nclient_addr = network_stream.get_extra_info(\"client_addr\")\nserver_addr = network_stream.get_extra_info(\"server_addr\")\nprint(\"Client address\", client_addr)\nprint(\"Server address\", server_addr)\n

The socket SSL information is also available through this interface, although you need to ensure that the underlying connection is still open, in order to access it...

with httpcore2.stream(\"GET\", \"https://www.example.com\") as response:\n    network_stream = response.extensions[\"network_stream\"]\n\n    ssl_object = network_stream.get_extra_info(\"ssl_object\")\n    print(\"TLS version\", ssl_object.version())\n
","path":["Extensions"],"tags":[]},{"location":"http2/","level":1,"title":"HTTP/2","text":"

HTTP/2 is a major new iteration of the HTTP protocol, that provides a more efficient transport, with potential performance benefits. HTTP/2 does not change the core semantics of the request or response, but alters the way that data is sent to and from the server.

Rather than the text format that HTTP/1.1 uses, HTTP/2 is a binary format. The binary format provides full request and response multiplexing, and efficient compression of HTTP headers. The stream multiplexing means that where HTTP/1.1 requires one TCP stream for each concurrent request, HTTP/2 allows a single TCP stream to handle multiple concurrent requests.

HTTP/2 also provides support for functionality such as response prioritization, and server push.

For a comprehensive guide to HTTP/2 you may want to check out \"HTTP2 Explained\".

","path":["HTTP/2"],"tags":[]},{"location":"http2/#enabling-http2","level":2,"title":"Enabling HTTP/2","text":"

When using the httpcore2 client, HTTP/2 support is not enabled by default, because HTTP/1.1 is a mature, battle-hardened transport layer, and our HTTP/1.1 implementation may be considered the more robust option at this point in time. It is possible that a future version of httpcore2 may enable HTTP/2 support by default.

If you're issuing highly concurrent requests you might want to consider trying out our HTTP/2 support. You can do so by first making sure to install the optional HTTP/2 dependencies...

pip install 'httpcore2[http2]'\n

And then instantiating a connection pool with HTTP/2 support enabled:

import httpcore2\n\npool = httpcore2.ConnectionPool(http2=True)\n

We can take a look at the difference in behaviour by issuing several outgoing requests in parallel.

Start out by using a standard HTTP/1.1 connection pool:

import httpcore2\nimport concurrent.futures\nimport time\n\n\ndef download(http, year):\n    http.request(\"GET\", f\"https://en.wikipedia.org/wiki/{year}\")\n\n\ndef main():\n    with httpcore2.ConnectionPool() as http:\n        started = time.time()\n        with concurrent.futures.ThreadPoolExecutor(max_workers=10) as threads:\n            for year in range(2000, 2020):\n                threads.submit(download, http, year)\n        complete = time.time()\n\n        for connection in http.connections:\n            print(connection)\n        print(\"Complete in %.3f seconds\" % (complete - started))\n\n\nmain()\n

If you run this with an HTTP/1.1 connection pool, you ought to see output similar to the following:

<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 2]>,\n<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 3]>,\n<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 6]>,\n<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 5]>,\n<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 1]>,\n<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 1]>,\n<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 1]>,\n<HTTPConnection ['https://en.wikipedia.org:443', HTTP/1.1, IDLE, Request Count: 1]>\nComplete in 0.586 seconds\n

We can see that the connection pool required a number of connections in order to handle the parallel requests.

If we now upgrade our connection pool to support HTTP/2:

with httpcore2.ConnectionPool(http2=True) as http:\n    ...\n

And run the same script again, we should end up with something like this:

<HTTPConnection ['https://en.wikipedia.org:443', HTTP/2, IDLE, Request Count: 20]>\nComplete in 0.573 seconds\n

All of our requests have been handled over a single connection.

Switching to HTTP/2 should not necessarily be considered an \"upgrade\". It is more complex, and requires more computational power, and so particularly in an interpreted language like Python it could be slower in some instances. Moreover, utilising multiple connections may end up connecting to multiple hosts, and could sometimes appear faster to the client, at the cost of requiring more server resources. Enabling HTTP/2 is most likely to be beneficial if you are sending requests in high concurrency, and may often be more well suited to an async context, rather than multi-threading.

","path":["HTTP/2"],"tags":[]},{"location":"http2/#inspecting-the-http-version","level":2,"title":"Inspecting the HTTP version","text":"

Enabling HTTP/2 support on the client does not necessarily mean that your requests and responses will be transported over HTTP/2, since both the client and the server need to support HTTP/2. If you connect to a server that only supports HTTP/1.1 the client will use a standard HTTP/1.1 connection instead.

You can determine which version of the HTTP protocol was used by examining the \"http_version\" response extension.

import httpcore2\n\npool = httpcore2.ConnectionPool(http2=True)\nresponse = pool.request(\"GET\", \"https://www.example.com/\")\n\n# Should be one of b\"HTTP/2\", b\"HTTP/1.1\", b\"HTTP/1.0\", or b\"HTTP/0.9\".\nprint(response.extensions[\"http_version\"])\n

See the extensions documentation for more details.

","path":["HTTP/2"],"tags":[]},{"location":"http2/#http2-negotiation","level":2,"title":"HTTP/2 negotiation","text":"

Robust servers need to support both HTTP/2 and HTTP/1.1 capable clients, and so need some way to \"negotiate\" with the client which protocol version will be used.

","path":["HTTP/2"],"tags":[]},{"location":"http2/#http2-over-https","level":3,"title":"HTTP/2 over HTTPS","text":"

Generally the method used is for the server to advertise if it has HTTP/2 support during the part of the SSL connection handshake. This is known as ALPN - \"Application Layer Protocol Negotiation\".

Most browsers only provide HTTP/2 support over HTTPS connections, and this is also the default behaviour that httpcore2 provides. If you enable HTTP/2 support you should still expect to see HTTP/1.1 connections for any http:// URLs.

","path":["HTTP/2"],"tags":[]},{"location":"http2/#http2-over-http","level":3,"title":"HTTP/2 over HTTP","text":"

Servers can optionally also support HTTP/2 over HTTP by supporting the Upgrade: h2c header.

This mechanism is not supported by httpcore2. It requires an additional round-trip between the client and server, and also requires any request body to be sent twice.

","path":["HTTP/2"],"tags":[]},{"location":"http2/#prior-knowledge","level":3,"title":"Prior Knowledge","text":"

If you know in advance that the server you are communicating with will support HTTP/2, then you can enforce that the client uses HTTP/2, without requiring either ALPN support or an HTTP Upgrade: h2c header.

This is managed by disabling HTTP/1.1 support on the connection pool:

pool = httpcore2.ConnectionPool(http1=False, http2=True)\n
","path":["HTTP/2"],"tags":[]},{"location":"http2/#request-response-headers","level":2,"title":"Request & response headers","text":"

Because HTTP/2 frames the requests and responses somewhat differently to HTTP/1.1, there is a difference in some of the headers that are used.

In order for the httpcore2 library to support both HTTP/1.1 and HTTP/2 transparently, the HTTP/1.1 style is always used throughout the API. Any differences in header styles are only mapped onto HTTP/2 at the internal network layer.

","path":["HTTP/2"],"tags":[]},{"location":"http2/#request-headers","level":2,"title":"Request headers","text":"

The following pseudo-headers are used by HTTP/2 in the request:

  • :method - The request method.
  • :path - Taken from the URL of the request.
  • :authority - Equivalent to the Host header in HTTP/1.1. In httpcore2 this is represented using the request Host header, which is automatically populated from the request URL if no Host header is explicitly included.
  • :scheme - Taken from the URL of the request.

These pseudo-headers are included in httpcore2 as part of the request.method and request.url attributes, and through the request.headers[\"Host\"] header. They are not exposed directly by their psuedo-header names.

The one other difference to be aware of is the Transfer-Encoding: chunked header.

In HTTP/2 this header is never used, since streaming data is framed using a different mechanism.

In httpcore2 the Transfer-Encoding: chunked header is always used to represent the presence of a streaming body on the request, and is automatically populated if required. However the header is only sent if the underlying connection ends up being HTTP/1.1, and is omitted if the underlying connection ends up being HTTP/2.

","path":["HTTP/2"],"tags":[]},{"location":"http2/#response-headers","level":2,"title":"Response headers","text":"

The following pseudo-header is used by HTTP/2 in the response:

  • :status - The response status code.

In httpcore2 this is represented by the response.status attribute, rather than being exposed as a psuedo-header.

","path":["HTTP/2"],"tags":[]},{"location":"logging/","level":1,"title":"Logging","text":"

If you need to inspect the internal behaviour of httpcore2, you can use Python's standard logging to output debug level information.

For example, the following configuration...

import logging\nimport httpcore2\n\nlogging.basicConfig(\n    format=\"%(levelname)s [%(asctime)s] %(name)s - %(message)s\",\n    datefmt=\"%Y-%m-%d %H:%M:%S\",\n    level=logging.DEBUG\n)\n\nhttpcore2.request('GET', 'https://www.example.com')\n

Will send debug level output to the console, or wherever stdout is directed too...

DEBUG [2023-01-09 14:44:00] httpcore2.connection - connect_tcp.started host='www.example.com' port=443 local_address=None timeout=None\nDEBUG [2023-01-09 14:44:00] httpcore2.connection - connect_tcp.complete return_value=<httpcore2._backends.sync.SyncStream object at 0x109ba6610>\nDEBUG [2023-01-09 14:44:00] httpcore2.connection - start_tls.started ssl_context=<ssl.SSLContext object at 0x109e427b0> server_hostname='www.example.com' timeout=None\nDEBUG [2023-01-09 14:44:00] httpcore2.connection - start_tls.complete return_value=<httpcore2._backends.sync.SyncStream object at 0x109e8b050>\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_headers.started request=<Request [b'GET']>\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_headers.complete\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_body.started request=<Request [b'GET']>\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - send_request_body.complete\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_headers.started request=<Request [b'GET']>\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Age', b'572646'), (b'Cache-Control', b'max-age=604800'), (b'Content-Type', b'text/html; charset=UTF-8'), (b'Date', b'Mon, 09 Jan 2023 14:44:00 GMT'), (b'Etag', b'\"3147526947+ident\"'), (b'Expires', b'Mon, 16 Jan 2023 14:44:00 GMT'), (b'Last-Modified', b'Thu, 17 Oct 2019 07:18:26 GMT'), (b'Server', b'ECS (nyb/1D18)'), (b'Vary', b'Accept-Encoding'), (b'X-Cache', b'HIT'), (b'Content-Length', b'1256')])\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_body.started request=<Request [b'GET']>\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - receive_response_body.complete\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - response_closed.started\nDEBUG [2023-01-09 14:44:00] httpcore2.http11 - response_closed.complete\nDEBUG [2023-01-09 14:44:00] httpcore2.connection - close.started\nDEBUG [2023-01-09 14:44:00] httpcore2.connection - close.complete\n

The exact formatting of the debug logging may be subject to change across different versions of httpcore2. If you need to rely on a particular format it is recommended that you pin installation of the package to a fixed version.

","path":["Logging"],"tags":[]},{"location":"network-backends/","level":1,"title":"Network Backends","text":"

The API layer at which httpcore2 interacts with the network is described as the network backend. Various backend implementations are provided, allowing httpcore2 to handle networking in different runtime contexts.

","path":["Network Backends"],"tags":[]},{"location":"network-backends/#working-with-network-backends","level":2,"title":"Working with network backends","text":"","path":["Network Backends"],"tags":[]},{"location":"network-backends/#the-default-network-backend","level":3,"title":"The default network backend","text":"

Typically you won't need to specify a network backend, as a default will automatically be selected. However, understanding how the network backends fit in may be useful if you want to better understand the underlying architecture. Let's start by seeing how we can explicitly select the network backend.

First we're making a standard HTTP request, using a connection pool:

import httpcore2\n\nwith httpcore2.ConnectionPool() as http:\n    response = http.request('GET', 'https://www.example.com')\n    print(response)\n

We can also have the same behavior, but be explicit with our selection of the network backend:

import httpcore2\n\nnetwork_backend = httpcore2.SyncBackend()\nwith httpcore2.ConnectionPool(network_backend=network_backend) as http:\n    response = http.request('GET', 'https://www.example.com')\n    print(response)\n

The httpcore2.SyncBackend() implementation handles the opening of TCP connections, and operations on the socket stream, such as reading, writing, and closing the connection.

We can get a better understanding of this by using a network backend to send a basic HTTP/1.1 request directly:

import httpcore2\n\n# Create an SSL context using 'certifi' for the certificates.\nssl_context = httpcore2.default_ssl_context()\n\n# A basic HTTP/1.1 request as a plain bytestring.\nrequest = b'\\r\\n'.join([\n    b'GET / HTTP/1.1',\n    b'Host: www.example.com',\n    b'Accept: */*',\n    b'Connection: close',\n    b''\n])\n\n# Open a TCP stream and upgrade it to SSL.\nnetwork_backend = httpcore2.SyncBackend()\nnetwork_stream = network_backend.connect_tcp(\"www.example.com\", 443)\nnetwork_stream = network_stream.start_tls(ssl_context, server_hostname=\"www.example.com\")\n\n# Send the HTTP request.\nnetwork_stream.write(request)\n\n# Read the HTTP response.\nwhile True:\n    response = network_stream.read(max_bytes=4096)\n    if response == b'':\n        break\n    print(response)\n\n# The output should look something like this:\n#\n# b'HTTP/1.1 200 OK\\r\\nAge: 600005\\r\\n [...] Content-Length: 1256\\r\\nConnection: close\\r\\n\\r\\n'\n# b'<!doctype html>\\n<html>\\n<head>\\n    <title>Example Domain</title> [...] </html>\\n'\n
","path":["Network Backends"],"tags":[]},{"location":"network-backends/#async-network-backends","level":3,"title":"Async network backends","text":"

If we're working with an async codebase, then we need to select a different backend.

The httpcore2.AnyIOBackend is suitable for usage if you're running under asyncio. This is a networking backend implemented using the anyio package.

import httpcore2\nimport asyncio\n\nasync def main():\n    network_backend = httpcore2.AnyIOBackend()\n    async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as http:\n        response = await http.request('GET', 'https://www.example.com')\n        print(response)\n\nasyncio.run(main())\n

The AnyIOBackend will work when running under either asyncio or trio. However, if you're working with async using the trio framework, then we recommend using the httpcore2.TrioBackend.

This will give you the same kind of networking behavior you'd have using AnyIOBackend, but there will be a little less indirection so it will be marginally more efficient and will present cleaner tracebacks in error cases.

import httpcore2\nimport trio\n\nasync def main():\n    network_backend = httpcore2.TrioBackend()\n    async with httpcore2.AsyncConnectionPool(network_backend=network_backend) as http:\n        response = await http.request('GET', 'https://www.example.com')\n        print(response)\n\ntrio.run(main)\n
","path":["Network Backends"],"tags":[]},{"location":"network-backends/#mock-network-backends","level":3,"title":"Mock network backends","text":"

There are also mock network backends available that can be useful for testing purposes. These backends accept a list of bytes, and return network stream interfaces that return those byte streams.

Here's an example of mocking a simple HTTP/1.1 response...

import httpcore2\n\nnetwork_backend = httpcore2.MockBackend([\n    b\"HTTP/1.1 200 OK\\r\\n\",\n    b\"Content-Type: plain/text\\r\\n\",\n    b\"Content-Length: 13\\r\\n\",\n    b\"\\r\\n\",\n    b\"Hello, world!\",\n])\nwith httpcore2.ConnectionPool(network_backend=network_backend) as http:\n    response = http.request(\"GET\", \"https://example.com/\")\n    print(response.extensions['http_version'])\n    print(response.status)\n    print(response.content)\n

Mocking a HTTP/2 response is more complex, since it uses a binary format...

import hpack\nimport hyperframe.frame\nimport httpcore2\n\ncontent = [\n    hyperframe.frame.SettingsFrame().serialize(),\n    hyperframe.frame.HeadersFrame(\n        stream_id=1,\n        data=hpack.Encoder().encode(\n            [\n                (b\":status\", b\"200\"),\n                (b\"content-type\", b\"plain/text\"),\n            ]\n        ),\n        flags=[\"END_HEADERS\"],\n    ).serialize(),\n    hyperframe.frame.DataFrame(\n        stream_id=1, data=b\"Hello, world!\", flags=[\"END_STREAM\"]\n    ).serialize(),\n]\n# Note that we instantiate the mock backend with an `http2=True` argument.\n# This ensures that the mock network stream acts as if the `h2` ALPN flag has been set,\n# and causes the connection pool to interact with the connection using HTTP/2.\nnetwork_backend = httpcore2.MockBackend(content, http2=True)\nwith httpcore2.ConnectionPool(network_backend=network_backend) as http:\n    response = http.request(\"GET\", \"https://example.com/\")\n    print(response.extensions['http_version'])\n    print(response.status)\n    print(response.content)\n
","path":["Network Backends"],"tags":[]},{"location":"network-backends/#custom-network-backends","level":3,"title":"Custom network backends","text":"

The base interface for network backends is provided as public API, allowing you to implement custom networking behavior.

You can use this to provide advanced networking functionality such as:

  • Network recording / replay.
  • In-depth debug tooling.
  • Handling non-standard SSL or DNS requirements.

Here's an example that records the network response to a file on disk:

import httpcore2\n\n\nclass RecordingNetworkStream(httpcore2.NetworkStream):\n    def __init__(self, record_file, stream):\n        self.record_file = record_file\n        self.stream = stream\n\n    def read(self, max_bytes, timeout=None):\n        data = self.stream.read(max_bytes, timeout=timeout)\n        self.record_file.write(data)\n        return data\n\n    def write(self, buffer, timeout=None):\n        self.stream.write(buffer, timeout=timeout)\n\n    def close(self) -> None:\n        self.stream.close()\n\n    def start_tls(\n        self,\n        ssl_context,\n        server_hostname=None,\n        timeout=None,\n    ):\n        self.stream = self.stream.start_tls(\n            ssl_context, server_hostname=server_hostname, timeout=timeout\n        )\n        return self\n\n    def get_extra_info(self, info):\n        return self.stream.get_extra_info(info)\n\n\nclass RecordingNetworkBackend(httpcore2.NetworkBackend):\n    \"\"\"\n    A custom network backend that records network responses.\n    \"\"\"\n    def __init__(self, record_file):\n        self.record_file = record_file\n        self.backend = httpcore2.SyncBackend()\n\n    def connect_tcp(\n        self,\n        host,\n        port,\n        timeout=None,\n        local_address=None,\n        socket_options=None,\n    ):\n        # Note that we're only using a single record file here,\n        # so even if multiple connections are opened the network\n        # traffic will all write to the same file.\n\n        # An alternative implementation might automatically use\n        # a new file for each opened connection.\n        stream = self.backend.connect_tcp(\n            host,\n            port,\n            timeout=timeout,\n            local_address=local_address,\n            socket_options=socket_options\n        )\n        return RecordingNetworkStream(self.record_file, stream)\n\n\n# Once you make the request, the raw HTTP/1.1 response will be available\n# in the 'network-recording' file.\n#\n# Try switching to `http2=True` to see the difference when recording HTTP/2 binary network traffic,\n# or add `headers={'Accept-Encoding': 'gzip'}` to see HTTP content compression.\nwith open(\"network-recording\", \"wb\") as record_file:\n    network_backend = RecordingNetworkBackend(record_file)\n    with httpcore2.ConnectionPool(network_backend=network_backend) as http:\n        response = http.request(\"GET\", \"https://www.example.com/\")\n        print(response)\n
","path":["Network Backends"],"tags":[]},{"location":"network-backends/#reference","level":2,"title":"Reference","text":"","path":["Network Backends"],"tags":[]},{"location":"network-backends/#networking-backends","level":3,"title":"Networking Backends","text":"
  • httpcore2.SyncBackend
  • httpcore2.AnyIOBackend
  • httpcore2.TrioBackend
","path":["Network Backends"],"tags":[]},{"location":"network-backends/#mock-backends","level":3,"title":"Mock Backends","text":"
  • httpcore2.MockBackend
  • httpcore2.MockStream
  • httpcore2.AsyncMockBackend
  • httpcore2.AsyncMockStream
","path":["Network Backends"],"tags":[]},{"location":"network-backends/#base-interface","level":3,"title":"Base Interface","text":"
  • httpcore2.NetworkBackend
  • httpcore2.NetworkStream
  • httpcore2.AsyncNetworkBackend
  • httpcore2.AsyncNetworkStream
","path":["Network Backends"],"tags":[]},{"location":"proxies/","level":1,"title":"Proxies","text":"

The httpcore2 package provides support for HTTP proxies, using either \"HTTP Forwarding\" or \"HTTP Tunnelling\". Forwarding is a proxy mechanism for sending requests to http URLs via an intermediate proxy. Tunnelling is a proxy mechanism for sending requests to https URLs via an intermediate proxy.

Sending requests via a proxy is very similar to sending requests using a standard connection pool:

import httpcore2\n\nproxy = httpcore2.Proxy(\"http://127.0.0.1:8080/\")\npool = httpcore2.ConnectionPool(proxy=proxy)\nr = proxy.request(\"GET\", \"https://www.example.com/\")\n\nprint(r)\n# <Response [200]>\n

You can test the httpcore2 proxy support, using the Python proxy.py tool:

pip install proxy.py\nproxy --hostname 127.0.0.1 --port 8080\n

Requests will automatically use either forwarding or tunnelling, depending on if the scheme is http or https.

","path":["Proxies"],"tags":[]},{"location":"proxies/#authentication","level":2,"title":"Authentication","text":"

Proxy authentication can be included in the initial configuration:

import httpcore2\n\n# A `Proxy-Authorization` header will be included on the initial proxy connection.\nproxy = httpcore2.Proxy(\n    url=\"http://127.0.0.1:8080/\",\n    auth=(\"<username>\", \"<password>\")\n)\npool = httpcore2.ConnectionPool(proxy=proxy)\n

Custom headers can also be included:

import httpcore2\nimport base64\n\n# Construct and include a `Proxy-Authorization` header.\nauth = base64.b64encode(b\"<username>:<password>\")\nproxy = httpcore2.Proxy(\n    url=\"http://127.0.0.1:8080/\",\n    headers={\"Proxy-Authorization\": b\"Basic \" + auth}\n)\npool = httpcore2.ConnectionPool(proxy=proxy)\n
","path":["Proxies"],"tags":[]},{"location":"proxies/#proxy-ssl","level":2,"title":"Proxy SSL","text":"

The httpcore2 package also supports HTTPS proxies for http and https destinations.

HTTPS proxies can be used in the same way that HTTP proxies are.

proxy = httpcore2.Proxy(url=\"https://127.0.0.1:8080/\")\n

Also, when using HTTPS proxies, you may need to configure the SSL context, which you can do with the ssl_context argument.

import ssl\nimport httpcore2\n\nproxy_ssl_context = ssl.create_default_context()\nproxy_ssl_context.check_hostname = False\n\nproxy = httpcore2.Proxy(\n    url='https://127.0.0.1:8080/',\n    ssl_context=proxy_ssl_context\n)\npool = httpcore2.ConnectionPool(proxy=proxy)\n
","path":["Proxies"],"tags":[]},{"location":"proxies/#http-versions","level":2,"title":"HTTP Versions","text":"

If you use proxies, keep in mind that the httpcore2 package only supports proxies to HTTP/1.1 servers.

","path":["Proxies"],"tags":[]},{"location":"proxies/#socks-proxy-support","level":2,"title":"SOCKS proxy support","text":"

The httpcore2 package also supports proxies using the SOCKS5 protocol.

Make sure to install the optional dependency using pip install 'httpcore2[socks]'.

The SOCKSProxy class should be using instead of a standard connection pool:

import httpcore2\n\n# Note that the SOCKS port is 1080.\nproxy = httpcore2.Proxy(url=\"socks5://127.0.0.1:1080/\")\npool = httpcore2.ConnectionPool(proxy=proxy)\nr = pool.request(\"GET\", \"https://www.example.com/\")\n

Authentication via SOCKS is also supported:

import httpcore2\n\nproxy = httpcore2.Proxy(\n    url=\"socks5://127.0.0.1:1080/\",\n    auth=(\"<username>\", \"<password>\"),\n)\npool = httpcore2.ConnectionPool(proxy=proxy)\nr = pool.request(\"GET\", \"https://www.example.com/\")\n
","path":["Proxies"],"tags":[]},{"location":"proxies/#reference","level":1,"title":"Reference","text":"","path":["Proxies"],"tags":[]},{"location":"proxies/#httpcore2proxy","level":2,"title":"httpcore2.Proxy","text":"","path":["Proxies"],"tags":[]},{"location":"proxies/#httpcore2.Proxy","level":3,"title":"httpcore2.Proxy","text":"","path":["Proxies"],"tags":[]},{"location":"quickstart/","level":1,"title":"Quickstart","text":"

For convenience, the httpcore2 package provides a couple of top-level functions that you can use for sending HTTP requests. You probably don't want to integrate against functions if you're writing a library that uses httpcore2, but you might find them useful for testing httpcore2 from the command-line, or if you're writing a simple script that doesn't require any of the connection pooling or advanced configuration that httpcore2 offers.

","path":["Quickstart"],"tags":[]},{"location":"quickstart/#sending-a-request","level":2,"title":"Sending a request","text":"

We'll start off by sending a request...

import httpcore2\n\nresponse = httpcore2.request(\"GET\", \"https://www.example.com/\")\n\nprint(response)\n# <Response [200]>\nprint(response.status)\n# 200\nprint(response.headers)\n# [(b'Accept-Ranges', b'bytes'), (b'Age', b'557328'), (b'Cache-Control', b'max-age=604800'), ...]\nprint(response.content)\n# b'<!doctype html>\\n<html>\\n<head>\\n<title>Example Domain</title>\\n\\n<meta charset=\"utf-8\"/>\\n ...'\n
","path":["Quickstart"],"tags":[]},{"location":"quickstart/#request-headers","level":2,"title":"Request headers","text":"

Request headers may be included either in a dictionary style, or as a list of two-tuples.

import httpcore2\nimport json\n\nheaders = {'User-Agent': 'httpcore2'}\nr = httpcore2.request('GET', 'https://httpbin.org/headers', headers=headers)\n\nprint(json.loads(r.content))\n# {\n#     'headers': {\n#         'Host': 'httpbin.org',\n#         'User-Agent': 'httpcore2',\n#         'X-Amzn-Trace-Id': 'Root=1-616ff5de-5ea1b7e12766f1cf3b8e3a33'\n#     }\n# }\n

The keys and values may either be provided as strings or as bytes. Where strings are provided they may only contain characters within the ASCII range chr(0) - chr(127). To include characters outside this range you must deal with any character encoding explicitly, and pass bytes as the header keys/values.

The Host header will always be automatically included in any outgoing request, as it is strictly required to be present by the HTTP protocol.

Note that the X-Amzn-Trace-Id header shown in the example above is not an outgoing request header, but has been added by a gateway server.

","path":["Quickstart"],"tags":[]},{"location":"quickstart/#request-body","level":2,"title":"Request body","text":"

A request body can be included either as bytes...

import httpcore2\nimport json\n\nr = httpcore2.request('POST', 'https://httpbin.org/post', content=b'Hello, world')\n\nprint(json.loads(r.content))\n# {\n#     'args': {},\n#     'data': 'Hello, world',\n#     'files': {},\n#     'form': {},\n#     'headers': {\n#         'Host': 'httpbin.org',\n#         'Content-Length': '12',\n#         'X-Amzn-Trace-Id': 'Root=1-61700258-00e338a124ca55854bf8435f'\n#     },\n#     'json': None,\n#     'origin': '68.41.35.196',\n#     'url': 'https://httpbin.org/post'\n# }\n

Or as an iterable that returns bytes...

import httpcore2\nimport json\n\nwith open(\"hello-world.txt\", \"rb\") as input_file:\n    r = httpcore2.request('POST', 'https://httpbin.org/post', content=input_file)\n\nprint(json.loads(r.content))\n# {\n#     'args': {},\n#     'data': 'Hello, world',\n#     'files': {},\n#     'form': {},\n#     'headers': {\n#         'Host': 'httpbin.org',\n#         'Transfer-Encoding': 'chunked',\n#         'X-Amzn-Trace-Id': 'Root=1-61700258-00e338a124ca55854bf8435f'\n#     },\n#     'json': None,\n#     'origin': '68.41.35.196',\n#     'url': 'https://httpbin.org/post'\n# }\n

When a request body is included, either a Content-Length header or a Transfer-Encoding: chunked header will be automatically included.

The Content-Length header is used when passing bytes, and indicates an HTTP request with a body of a pre-determined length.

The Transfer-Encoding: chunked header is the mechanism that HTTP/1.1 uses for sending HTTP request bodies without a pre-determined length.

","path":["Quickstart"],"tags":[]},{"location":"quickstart/#streaming-responses","level":2,"title":"Streaming responses","text":"

When using the httpcore2.request() function, the response body will automatically be read to completion, and made available in the response.content attribute.

Sometimes you may be dealing with large responses and not want to read the entire response into memory. The httpcore2.stream() function provides a mechanism for sending a request and dealing with a streaming response:

import httpcore2\n\nwith httpcore2.stream('GET', 'https://example.com') as response:\n    for chunk in response.iter_stream():\n        print(f\"Downloaded: {chunk}\")\n

Here's a more complete example that demonstrates downloading a response:

import httpcore2\n\nwith httpcore2.stream('GET', 'https://speed.hetzner.de/100MB.bin') as response:\n    with open(\"download.bin\", \"wb\") as output_file:\n        for chunk in response.iter_stream():\n            output_file.write(chunk)\n

The httpcore2.stream() API also allows you to conditionally read the response...

import httpcore2\n\nwith httpcore2.stream('GET', 'https://example.com') as response:\n    content_length = [int(v) for k, v in response.headers if k.lower() == b'content-length'][0]\n    if content_length > 100_000_000:\n        raise Exception(\"Response too large.\")\n    response.read()  # `response.content` is now available.\n
","path":["Quickstart"],"tags":[]},{"location":"quickstart/#reference","level":1,"title":"Reference","text":"","path":["Quickstart"],"tags":[]},{"location":"quickstart/#httpcore2request","level":2,"title":"httpcore2.request()","text":"","path":["Quickstart"],"tags":[]},{"location":"quickstart/#httpcore2.request","level":3,"title":"httpcore2.request","text":"
request(\n    method: bytes | str,\n    url: URL | bytes | str,\n    *,\n    headers: HeaderTypes = None,\n    content: bytes | Iterator[bytes] | None = None,\n    extensions: Extensions | None = None,\n) -> Response\n

Sends an HTTP request, returning the response.

response = httpcore2.request(\"GET\", \"https://www.example.com/\")\n

Parameters:

Name Type Description Default method bytes | str

The HTTP method for the request. Typically one of \"GET\", \"OPTIONS\", \"HEAD\", \"POST\", \"PUT\", \"PATCH\", or \"DELETE\".

required url URL | bytes | str

The URL of the HTTP request. Either as an instance of httpcore2.URL, or as str/bytes.

required headers HeaderTypes

The HTTP request headers. Either as a dictionary of str/bytes, or as a list of two-tuples of str/bytes.

None content bytes | Iterator[bytes] | None

The content of the request body. Either as bytes, or as a bytes iterator.

None extensions Extensions | None

A dictionary of optional extra information included on the request. Possible keys include \"timeout\".

None

Returns:

Type Description Response

An instance of httpcore2.Response.

","path":["Quickstart"],"tags":[]},{"location":"quickstart/#httpcore2stream","level":2,"title":"httpcore2.stream()","text":"","path":["Quickstart"],"tags":[]},{"location":"quickstart/#httpcore2.stream","level":3,"title":"httpcore2.stream","text":"
stream(\n    method: bytes | str,\n    url: URL | bytes | str,\n    *,\n    headers: HeaderTypes = None,\n    content: bytes | Iterator[bytes] | None = None,\n    extensions: Extensions | None = None,\n) -> typing.Iterator[Response]\n

Sends an HTTP request, returning the response within a content manager.

with httpcore2.stream(\"GET\", \"https://www.example.com/\") as response:\n    ...\n

When using the stream() function, the body of the response will not be automatically read. If you want to access the response body you should either use content = response.read(), or for chunk in response.iter_content().

Parameters:

Name Type Description Default method bytes | str

The HTTP method for the request. Typically one of \"GET\", \"OPTIONS\", \"HEAD\", \"POST\", \"PUT\", \"PATCH\", or \"DELETE\".

required url URL | bytes | str

The URL of the HTTP request. Either as an instance of httpcore2.URL, or as str/bytes.

required headers HeaderTypes

The HTTP request headers. Either as a dictionary of str/bytes, or as a list of two-tuples of str/bytes.

None content bytes | Iterator[bytes] | None

The content of the request body. Either as bytes, or as a bytes iterator.

None extensions Extensions | None

A dictionary of optional extra information included on the request. Possible keys include \"timeout\".

None

Returns:

Type Description Iterator[Response]

An instance of httpcore2.Response.

","path":["Quickstart"],"tags":[]},{"location":"requests-responses-urls/","level":1,"title":"Requests, Responses, and URLs","text":"

TODO

","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#requests","level":2,"title":"Requests","text":"

Request instances in httpcore2 are deliberately simple, and only include the essential information required to represent an HTTP request.

Properties on the request are plain byte-wise representations.

>>> request = httpcore2.Request(\"GET\", \"https://www.example.com/\")\n>>> request.method\nb\"GET\"\n>>> request.url\nhttpcore2.URL(scheme=b\"https\", host=b\"www.example.com\", port=None, target=b\"/\")\n>>> request.headers\n[(b'Host', b'www.example.com')]\n>>> request.stream\n<httpcore2.ByteStream [0 bytes]>\n

The interface is liberal in the types that it accepts, but specific in the properties that it uses to represent them. For example, headers may be specified as a dictionary of strings, but internally are represented as a list of (byte, byte) tuples.

```python

headers = {\"User-Agent\": \"custom\"} request = httpcore2.Request(\"GET\", \"https://www.example.com/\", headers=headers) request.headers [(b'Host', b'www.example.com'), (b\"User-Agent\", b\"custom\")]

","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#responses","level":2,"title":"Responses","text":"

...

","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#urls","level":2,"title":"URLs","text":"

...

","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#reference","level":1,"title":"Reference","text":"","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#httpcore2request","level":2,"title":"httpcore2.Request","text":"","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#httpcore2.Request","level":3,"title":"httpcore2.Request","text":"

An HTTP request.

","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#httpcore2.Request.__init__","level":4,"title":"__init__","text":"
__init__(\n    method: bytes | str,\n    url: URL | bytes | str,\n    *,\n    headers: HeaderTypes = None,\n    content: bytes\n    | Iterable[bytes]\n    | AsyncIterable[bytes]\n    | None = None,\n    extensions: Extensions | None = None,\n) -> None\n

Parameters:

Name Type Description Default method bytes | str

The HTTP request method, either as a string or bytes. For example: GET.

required url URL | bytes | str

The request URL, either as a URL instance, or as a string or bytes. For example: \"https://www.example.com\".

required headers HeaderTypes

The HTTP request headers.

None content bytes | Iterable[bytes] | AsyncIterable[bytes] | None

The content of the request body.

None extensions Extensions | None

A dictionary of optional extra information included on the request. Possible keys include \"timeout\", and \"trace\".

None","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#httpcore2response","level":2,"title":"httpcore2.Response","text":"","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#httpcore2.Response","level":3,"title":"httpcore2.Response","text":"

An HTTP response.

","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#httpcore2.Response.__init__","level":4,"title":"__init__","text":"
__init__(\n    status: int,\n    *,\n    headers: HeaderTypes = None,\n    content: bytes\n    | Iterable[bytes]\n    | AsyncIterable[bytes]\n    | None = None,\n    extensions: Extensions | None = None,\n) -> None\n

Parameters:

Name Type Description Default status int

The HTTP status code of the response. For example 200.

required headers HeaderTypes

The HTTP response headers.

None content bytes | Iterable[bytes] | AsyncIterable[bytes] | None

The content of the response body.

None extensions Extensions | None

A dictionary of optional extra information included on the responseself.Possible keys include \"http_version\", \"reason_phrase\", and \"network_stream\".

None","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#httpcore2url","level":2,"title":"httpcore2.URL","text":"","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#httpcore2.URL","level":3,"title":"httpcore2.URL","text":"

Represents the URL against which an HTTP request may be made.

The URL may either be specified as a plain string, for convenience:

url = httpcore2.URL(\"https://www.example.com/\")\n

Or be constructed with explicitly pre-parsed components:

url = httpcore2.URL(scheme=b'https', host=b'www.example.com', port=None, target=b'/')\n

Using this second more explicit style allows integrations that are using httpcore to pass through URLs that have already been parsed in order to use libraries such as rfc-3986 rather than relying on the stdlib. It also ensures that URL parsing is treated identically at both the networking level and at any higher layers of abstraction.

The four components are important here, as they allow the URL to be precisely specified in a pre-parsed format. They also allow certain types of request to be created that could not otherwise be expressed.

For example, an HTTP request to http://www.example.com/ forwarded via a proxy at http://localhost:8080...

# Constructs an HTTP request with a complete URL as the target:\n# GET https://www.example.com/ HTTP/1.1\nurl = httpcore2.URL(\n    scheme=b'http',\n    host=b'localhost',\n    port=8080,\n    target=b'https://www.example.com/'\n)\nrequest = httpcore2.Request(\n    method=\"GET\",\n    url=url\n)\n

Another example is constructing an OPTIONS * request...

# Constructs an 'OPTIONS *' HTTP request:\n# OPTIONS * HTTP/1.1\nurl = httpcore2.URL(scheme=b'https', host=b'www.example.com', target=b'*')\nrequest = httpcore2.Request(method=\"OPTIONS\", url=url)\n

This kind of request is not possible to formulate with a URL string, because the / delimiter is always used to demark the target from the host/port portion of the URL.

For convenience, string-like arguments may be specified either as strings or as bytes. However, once a request is being issue over-the-wire, the URL components are always ultimately required to be a bytewise representation.

In order to avoid any ambiguity over character encodings, when strings are used as arguments, they must be strictly limited to the ASCII range chr(0)-chr(127). If you require a bytewise representation that is outside this range you must handle the character encoding directly, and pass a bytes instance.

","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"requests-responses-urls/#httpcore2.URL.__init__","level":4,"title":"__init__","text":"
__init__(\n    url: bytes | str = \"\",\n    *,\n    scheme: bytes | str = b\"\",\n    host: bytes | str = b\"\",\n    port: int | None = None,\n    target: bytes | str = b\"\",\n) -> None\n

Parameters:

Name Type Description Default url bytes | str

The complete URL as a string or bytes.

'' scheme bytes | str

The URL scheme as a string or bytes. Typically either \"http\" or \"https\".

b'' host bytes | str

The URL host as a string or bytes. Such as \"www.example.com\".

b'' port int | None

The port to connect to. Either an integer or None.

None target bytes | str

The target of the HTTP request. Such as \"/items?search=red\".

b''","path":["Requests, Responses, and URLs"],"tags":[]},{"location":"table-of-contents/","level":1,"title":"API Reference","text":"
  • Quickstart
    • httpcore2.request()
    • httpcore2.stream()
  • Requests, Responses, and URLs
    • httpcore2.Request
    • httpcore2.Response
    • httpcore2.URL
  • Connection Pools
    • httpcore2.ConnectionPool
  • Proxies
    • httpcore2.Proxy
  • Connections
    • httpcore2.HTTPConnection
    • httpcore2.HTTP11Connection
    • httpcore2.HTTP2Connection
  • Async Support
    • httpcore2.AsyncConnectionPool
    • httpcore2.AsyncHTTPConnection
    • httpcore2.AsyncHTTP11Connection
    • httpcore2.AsyncHTTP2Connection
  • Network Backends
    • Sync
      • httpcore2.backends.sync.SyncBackend
      • httpcore2.backends.mock.MockBackend
    • Async
      • httpcore2.backends.auto.AutoBackend
      • httpcore2.backends.asyncio.AsyncioBackend
      • httpcore2.backends.trio.TrioBackend
      • httpcore2.backends.mock.AsyncMockBackend
    • Base interfaces
      • httpcore2.backends.base.NetworkBackend
      • httpcore2.backends.base.AsyncNetworkBackend
  • Exceptions
    • httpcore2.TimeoutException
      • httpcore2.PoolTimeout
      • httpcore2.ConnectTimeout
      • httpcore2.ReadTimeout
      • httpcore2.WriteTimeout
    • httpcore2.NetworkError
      • httpcore2.ConnectError
      • httpcore2.ReadError
      • httpcore2.WriteError
    • httpcore2.ProtocolError
      • httpcore2.RemoteProtocolError
      • httpcore2.LocalProtocolError
    • httpcore2.ProxyError
    • httpcore2.UnsupportedProtocol
","path":["API Reference"],"tags":[]}]} \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/sitemap.xml b/src/httpcore2/site-httpcore2/sitemap.xml new file mode 100644 index 00000000..ddf692bc --- /dev/null +++ b/src/httpcore2/site-httpcore2/sitemap.xml @@ -0,0 +1,39 @@ + + + + https://httpcore2.pydantic.dev/ + + + https://httpcore2.pydantic.dev/quickstart/ + + + https://httpcore2.pydantic.dev/requests-responses-urls/ + + + https://httpcore2.pydantic.dev/connection-pools/ + + + https://httpcore2.pydantic.dev/connections/ + + + https://httpcore2.pydantic.dev/proxies/ + + + https://httpcore2.pydantic.dev/http2/ + + + https://httpcore2.pydantic.dev/async/ + + + https://httpcore2.pydantic.dev/network-backends/ + + + https://httpcore2.pydantic.dev/extensions/ + + + https://httpcore2.pydantic.dev/logging/ + + + https://httpcore2.pydantic.dev/exceptions/ + + \ No newline at end of file diff --git a/src/httpcore2/site-httpcore2/table-of-contents/index.html b/src/httpcore2/site-httpcore2/table-of-contents/index.html new file mode 100644 index 00000000..3aed2472 --- /dev/null +++ b/src/httpcore2/site-httpcore2/table-of-contents/index.html @@ -0,0 +1,723 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + API Reference - HTTPCore2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + + + + + +
+
+ + + + + + + + +
+ + + + +
+
+
+ + + +
+ +
+ + + + + + +

API Reference

+
    +
  • Quickstart
      +
    • httpcore2.request()
    • +
    • httpcore2.stream()
    • +
    +
  • +
  • Requests, Responses, and URLs
      +
    • httpcore2.Request
    • +
    • httpcore2.Response
    • +
    • httpcore2.URL
    • +
    +
  • +
  • Connection Pools
      +
    • httpcore2.ConnectionPool
    • +
    +
  • +
  • Proxies
      +
    • httpcore2.Proxy
    • +
    +
  • +
  • Connections
      +
    • httpcore2.HTTPConnection
    • +
    • httpcore2.HTTP11Connection
    • +
    • httpcore2.HTTP2Connection
    • +
    +
  • +
  • Async Support
      +
    • httpcore2.AsyncConnectionPool
    • +
    • httpcore2.AsyncHTTPConnection
    • +
    • httpcore2.AsyncHTTP11Connection
    • +
    • httpcore2.AsyncHTTP2Connection
    • +
    +
  • +
  • Network Backends
      +
    • Sync
        +
      • httpcore2.backends.sync.SyncBackend
      • +
      • httpcore2.backends.mock.MockBackend
      • +
      +
    • +
    • Async
        +
      • httpcore2.backends.auto.AutoBackend
      • +
      • httpcore2.backends.asyncio.AsyncioBackend
      • +
      • httpcore2.backends.trio.TrioBackend
      • +
      • httpcore2.backends.mock.AsyncMockBackend
      • +
      +
    • +
    • Base interfaces
        +
      • httpcore2.backends.base.NetworkBackend
      • +
      • httpcore2.backends.base.AsyncNetworkBackend
      • +
      +
    • +
    +
  • +
  • Exceptions
      +
    • httpcore2.TimeoutException
        +
      • httpcore2.PoolTimeout
      • +
      • httpcore2.ConnectTimeout
      • +
      • httpcore2.ReadTimeout
      • +
      • httpcore2.WriteTimeout
      • +
      +
    • +
    • httpcore2.NetworkError
        +
      • httpcore2.ConnectError
      • +
      • httpcore2.ReadError
      • +
      • httpcore2.WriteError
      • +
      +
    • +
    • httpcore2.ProtocolError
        +
      • httpcore2.RemoteProtocolError
      • +
      • httpcore2.LocalProtocolError
      • +
      +
    • +
    • httpcore2.ProxyError
    • +
    • httpcore2.UnsupportedProtocol
    • +
    +
  • +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file