From 2e4f3dcd756d7ba6fcab2dab268c534d9bfe2518 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Fri, 13 Sep 2024 10:37:30 +0200 Subject: [PATCH 01/90] Update manifest.json --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index eea77ee..6a77c95 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "repos": [ { "id": "nwcprovider", - "organisation": "lnbits", + "organisation": "riccardobl", "repository": "nwcprovider" } ] From 81224f62116c9779f5dd504bb87eddd152338cda Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 19 Nov 2024 18:26:21 +0000 Subject: [PATCH 02/90] add rate limit --- nwcp.py | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/nwcp.py b/nwcp.py index 09dfcf2..6f6e296 100644 --- a/nwcp.py +++ b/nwcp.py @@ -86,7 +86,8 @@ class NWCServiceProvider: # Subscription self.sub = None - + self.rate_limit = {} + # websocket connection self.ws = None @@ -199,6 +200,29 @@ class NWCServiceProvider: logger.debug("Waiting for connection...") await asyncio.sleep(1) + async def _ratelimit(self, unit, max_sleep_time = 120): + rate_limit = self.rate_limit.get(unit) + if not rate_limit: + self.rate_limit[unit] = rate_limit = { + "backoff": 0, + "last_attempt_time": 0 + } + + if time.time() - rate_limit["last_attempt_time"] > max_sleep_time: + # reset backoff if action lasted more than max_sleep_time + rate_limit["backoff"] = 0 + else: + # increase backoff + rate_limit["backoff"] = ( + min(rate_limit["backoff"] * 2, max_sleep_time) + if rate_limit["backoff"] > 0 + else 1 + ) + logger.debug( + "Sleeping for " + str(rate_limit["backoff"]) + " seconds before " + unit) + await asyncio.sleep( rate_limit["backoff"]) + rate_limit["last_attempt_time"] = time.time() + async def _subscribe(self): """ [Re]Subscribe to receive nip 47 requests and responses from the relay @@ -383,6 +407,7 @@ class NWCServiceProvider: + info + " ... resubscribing..." ) + await self._ratelimit("subscribing") await self._subscribe() async def _on_message(self, ws, message: str): @@ -403,7 +428,7 @@ class NWCServiceProvider: elif msg[0] == "OK": pass else: - raise Exception("Unknown message type") + raise Exception("Unknown message type " + str(msg[0])) except Exception as e: logger.error("Error parsing event: " + str(e)) @@ -443,8 +468,8 @@ class NWCServiceProvider: self.connected = False if not self._is_shutting_down(): # Wait some time before reconnecting - logger.debug("Reconnecting to NWC relay in 5 seconds...") - await asyncio.sleep(5) + logger.debug("Reconnecting to NWC relay...") + await self._ratelimit("connecting") def _encrypt_content( self, content: str, pubkey_hex: str, iv_seed: Optional[int] = None From f69e79c78984606e4376f1c556d7aa2bd69b0da0 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 19 Nov 2024 19:13:00 +0000 Subject: [PATCH 03/90] fix spent budget abd expired tokens display --- templates/nwcprovider/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/nwcprovider/index.html b/templates/nwcprovider/index.html index d79df9f..89d5e63 100644 --- a/templates/nwcprovider/index.html +++ b/templates/nwcprovider/index.html @@ -615,7 +615,7 @@ try { const response = await LNbits.api.request( "GET", - "/nwcprovider/api/v1/nwc?includeExpired=true&calculateSpendBudget=true", + "/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true", wallet.adminkey, ); this.nwcs = response.data; From 1d8dc8803d10a57c760c9cd75d19ac52c07a6397 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 19 Nov 2024 19:13:09 +0000 Subject: [PATCH 04/90] debug --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ba70814..118a873 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ node_modules data .vscode package.json -package-lock.json \ No newline at end of file +package-lock.json +dump \ No newline at end of file From 036285b67372b535d1564d8260d3098158c91ced Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 19 Nov 2024 19:28:46 +0000 Subject: [PATCH 05/90] format and types --- nwcp.py | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/nwcp.py b/nwcp.py index 6f6e296..50f6ae7 100644 --- a/nwcp.py +++ b/nwcp.py @@ -16,6 +16,11 @@ from lnbits.settings import settings from loguru import logger +class RateLimit: + backoff: int = 0 + last_attempt_time: int = 0 + + class MainSubscription: def __init__(self): self.requests_sub_id: Optional[str] = None @@ -86,8 +91,8 @@ class NWCServiceProvider: # Subscription self.sub = None - self.rate_limit = {} - + self.rate_limit: Dict[str, RateLimit] = {} + # websocket connection self.ws = None @@ -200,28 +205,22 @@ class NWCServiceProvider: logger.debug("Waiting for connection...") await asyncio.sleep(1) - async def _ratelimit(self, unit, max_sleep_time = 120): - rate_limit = self.rate_limit.get(unit) - if not rate_limit: - self.rate_limit[unit] = rate_limit = { - "backoff": 0, - "last_attempt_time": 0 - } + async def _ratelimit(self, unit: str, max_sleep_time: int = 120) -> None: + limit: Optional[RateLimit] = self.rate_limit.get(unit) + if not limit: + self.rate_limit[unit] = limit = RateLimit() - if time.time() - rate_limit["last_attempt_time"] > max_sleep_time: + if time.time() - limit.last_attempt_time > max_sleep_time: # reset backoff if action lasted more than max_sleep_time - rate_limit["backoff"] = 0 + limit.backoff = 0 else: # increase backoff - rate_limit["backoff"] = ( - min(rate_limit["backoff"] * 2, max_sleep_time) - if rate_limit["backoff"] > 0 - else 1 + limit.backoff = ( + min(limit.backoff * 2, max_sleep_time) if limit.backoff > 0 else 1 ) - logger.debug( - "Sleeping for " + str(rate_limit["backoff"]) + " seconds before " + unit) - await asyncio.sleep( rate_limit["backoff"]) - rate_limit["last_attempt_time"] = time.time() + logger.debug("Sleeping for " + str(limit.backoff) + " seconds before " + unit) + await asyncio.sleep(limit.backoff) + limit.last_attempt_time = int(time.time()) async def _subscribe(self): """ From 56636823f68f331937faacbc9b7c3938198c856e Mon Sep 17 00:00:00 2001 From: arcbtc Date: Sat, 15 Feb 2025 17:07:03 +0000 Subject: [PATCH 06/90] removed basemodel (test) --- __init__.py | 2 +- nwcp.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/__init__.py b/__init__.py index 86e59d7..d0cafc3 100644 --- a/__init__.py +++ b/__init__.py @@ -32,7 +32,7 @@ def nwcprovider_stop(): except Exception as ex: logger.warning(ex) - +logger.debug("NWC Service Provider extension loaded") def nwcprovider_start(): task = create_permanent_unique_task("ext_nwcprovider", handle_nwc) scheduled_tasks.append(task) diff --git a/nwcp.py b/nwcp.py index b905544..c83131d 100644 --- a/nwcp.py +++ b/nwcp.py @@ -52,7 +52,7 @@ class MainSubscription: arbitrary_types_allowed = True -class NWCServiceProvider(BaseModel): +class NWCServiceProvider: def __init__(self, private_key: Optional[str] = None, relay: Optional[str] = None): if not relay: # Connect to nostrclient relay = "nostrclient" From dd0f4cad7f0acee3baa3e6f661a8f9dbccdebe66 Mon Sep 17 00:00:00 2001 From: Arc <33088785+arcbtc@users.noreply.github.com> Date: Sat, 15 Feb 2025 17:09:54 +0000 Subject: [PATCH 07/90] Update manifest.json --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 6a77c95..eea77ee 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "repos": [ { "id": "nwcprovider", - "organisation": "riccardobl", + "organisation": "lnbits", "repository": "nwcprovider" } ] From be3d4b9e5cfe1849d9287745b43186f8adb54203 Mon Sep 17 00:00:00 2001 From: arcbtc Date: Sat, 15 Feb 2025 17:49:25 +0000 Subject: [PATCH 08/90] fix json bug, move js to own file --- __init__.py | 1 - static/js/index.js | 386 +++++++++++++++++++++++++++++ templates/nwcprovider/index.html | 405 +------------------------------ views.py | 9 +- 4 files changed, 397 insertions(+), 404 deletions(-) create mode 100644 static/js/index.js diff --git a/__init__.py b/__init__.py index d0cafc3..d7f2a3b 100644 --- a/__init__.py +++ b/__init__.py @@ -32,7 +32,6 @@ def nwcprovider_stop(): except Exception as ex: logger.warning(ex) -logger.debug("NWC Service Provider extension loaded") def nwcprovider_start(): task = create_permanent_unique_task("ext_nwcprovider", handle_nwc) scheduled_tasks.append(task) diff --git a/static/js/index.js b/static/js/index.js new file mode 100644 index 0000000..e650761 --- /dev/null +++ b/static/js/index.js @@ -0,0 +1,386 @@ + window.app = Vue.createApp({ + el: "#vue", + mixins: [windowMixin], + delimiters: ["${", "}"], + data: function () { + return { + selectedWallet: null, + nodePermissions: [], + nwcEntries: [], + nwcsTable: { + columns: [ + { + name: "description", + align: "left", + label: "Description", + field: "description", + }, + { name: "status", align: "left", label: "Status", field: "status" }, + { + name: "last_used", + align: "left", + label: "Last used", + field: "last_used", + }, + { + name: "created_at", + align: "left", + label: "Created", + field: "created_at", + }, + { + name: "expires_at", + align: "left", + label: "Expires", + field: "expires_at", + }, + ], + pagination: { + rowsPerPage: 10, + }, + }, + connectDialog: { + show: false, + data: {}, + }, + pairingDialog: { + show: false, + data: { + pairingUrl: "", + }, + }, + pairingQrDialog: { + show: false, + data: { + pairingUrl: "", + }, + }, + connectionInfoDialog: { + show: false, + data: {}, + }, + }; + }, + + methods: { + showConnectDialog() { + const wallet = this.getWallet(); + if (!wallet) { + this.$q.notify({ + color: "red", + message: "Please select a wallet first", + }); + return; + } else { + this.connectDialog.show = true; + } + }, + openConnectionInfoDialog(data) { + this.connectionInfoDialog.data = data; + this.connectionInfoDialog.show = true; + }, + closeConnectionInfoDialog() { + this.connectionInfoDialog.show = false; + }, + openPairingUrl() { + const url = this.pairingDialog.data.pairingUrl; + if (url) window.open(url, "_blank"); + }, + go(url) { + window.open(url, "_blank"); + }, + async copyPairingUrl() { + const url = this.pairingDialog.data.pairingUrl; + if (url) { + try { + await navigator.clipboard.writeText(url); + this.$q.notify({ + color: "primary", + message: "URL copied to clipboard!", + }); + } catch (err) { + this.$q.notify({ color: "red", message: "Failed to copy URL." }); + } + } + }, + showPairingQR() { + this.pairingQrDialog.data.pairingUrl = + this.pairingDialog.data.pairingUrl; + this.pairingQrDialog.show = true; + }, + closePairingQrDialog() { + this.pairingQrDialog.show = false; + }, + loadConnectDialogData() { + this.connectDialog.data = { + description: "", + expires_at: Date.now() + 1000 * 60 * 60 * 24 * 7, + neverExpires: true, + permissions: [], + budgets: [], + }; + for (const permission of this.nodePermissions) { + this.connectDialog.data.permissions.push({ + key: permission.key, + name: permission.name, + value: permission.value, + }); + } + }, + deleteBudget(index) { + this.connectDialog.data.budgets.splice(index, 1); + }, + addBudget() { + this.connectDialog.data.budgets.push({ + budget_sats: 1000, + used_budget_sats: 0, + created_at: + new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, + expiration: "never", + }); + }, + closeConnectDialog() { + this.connectDialog.show = false; + this.loadConnectDialogData(); + }, + getWallet: function () { + let wallet = undefined; + for (let i = 0; i < this.g.user.wallets.length; i++) { + if (this.g.user.wallets[i].id == this.selectedWallet) { + wallet = this.g.user.wallets[i]; + break; + } + } + return wallet; + }, + async generateKeyPair() { + while (!window.NobleSecp256k1) { + await new Promise((resolve) => setTimeout(resolve, 1)); + } + const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey(); + const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes); + const out = { + privKeyBytes: privKeyBytes, + pubKeyBytes: pubKeyBytes, + privKey: window.NobleSecp256k1.etc.bytesToHex(privKeyBytes), + pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)), + }; + return out; + }, + deleteNWC: async function (pubkey) { + this.$q + .dialog({ + title: "Confirm Deletion", + message: "Are you sure you want to delete this connection?", + cancel: true, + persistent: true, + }) + .onOk(async () => { + try { + const wallet = this.getWallet(); + const response = await LNbits.api.request( + "DELETE", + `/nwcprovider/api/v1/nwc/${pubkey}`, + wallet.adminkey, + ); + this.loadNwcs(); + this.$q.notify({ + type: "positive", + message: "Deleted successfully", + }); + } catch (error) { + LNbits.utils.notifyApiError(error); + } + }) + .onCancel(() => { + // User canceled the operation + }); + }, + loadNwcs: async function () { + const wallet = this.getWallet(); + if (!wallet) { + this.nwcs = []; + return; + } + try { + const response = await LNbits.api.request( + "GET", + "/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true", + wallet.adminkey, + ); + this.nwcs = response.data; + } catch (error) { + this.nwcs = []; + } + try { + const response = await LNbits.api.request( + "GET", + "/nwcprovider/api/v1/permissions", + wallet.adminkey, + ); + const permissions = []; + for (const [key, value] of Object.entries(response.data)) { + permissions.push({ + key: key, + name: value.name, + value: value.default, + }); + } + this.nodePermissions = permissions; + } catch (error) { + Lnbits.utils.notifyApiError(error); + } + this.loadConnectDialogData(); + const newTableEntries = []; + for (const nwc of this.nwcs) { + const t = Quasar.utils.date.formatDate( + new Date(nwc.data.created_at * 1000), + "YYYY-MM-DD HH:mm", + ); + const e = + nwc.data.expires_at > 0 + ? Quasar.utils.date.formatDate( + new Date(nwc.data.expires_at * 1000), + "YYYY-MM-DD HH:mm", + ) + : "Never"; + const l = Quasar.utils.date.formatDate( + new Date(nwc.data.last_used * 1000), + "YYYY-MM-DD HH:mm", + ); + const nwcTableEntry = { + description: nwc.data.description, + created_at: t, + expires_at: e, + last_used: l, + pubkey: nwc.data.pubkey, + permissions: nwc.data.permissions, + budgets: [], + status: "Active", + }; + if ( + nwc.data.expires_at > 0 && + nwc.data.expires_at < new Date().getTime() / 1000 + ) { + nwcTableEntry.status = "Expired"; + } + for (const budget of nwc.budgets) { + const createdAt = Quasar.utils.date.formatDate( + new Date(budget.created_at * 1000), + "YYYY-MM-DD HH:mm", + ); + let refreshWindow = budget.refresh_window; + if (refreshWindow <= 0) { + refreshWindow = "Never"; + } else if (refreshWindow == 60 * 60 * 24) { + refreshWindow = "Daily"; + } else if (refreshWindow == 60 * 60 * 24 * 7) { + refreshWindow = "Weekly"; + } else if (refreshWindow == 60 * 60 * 24 * 30) { + refreshWindow = "Monthly"; + } else if (refreshWindow == 60 * 60 * 24 * 365) { + refreshWindow = "Yearly"; + } + nwcTableEntry.budgets.push({ + budget_sats: budget.budget_msats / 1000, + used_budget_sats: budget.used_budget_msats / 1000, + created_at: createdAt, + refresh_window: refreshWindow, + }); + } + newTableEntries.push(nwcTableEntry); + } + this.nwcEntries = newTableEntries; + }, + closePairingDialog() { + this.pairingDialog.show = false; + }, + async showPairingDialog(secret) { + let response = await LNbits.api.request( + "GET", + "/nwcprovider/api/v1/pairing/{SECRET}", + ); + response = response.data; + response = response.replace("{SECRET}", secret); + this.pairingDialog.data.pairingUrl = response; + this.pairingDialog.show = true; + }, + async confirmConnectDialog() { + const keyPair = await this.generateKeyPair(); + // timestamp + let expires_at = 0; + if (!this.connectDialog.data.neverExpires) { + expires_at = + new Date(this.connectDialog.data.expires_at).getTime() / 1000; + } + const data = { + permissions: [], + description: this.connectDialog.data.description, + expires_at: expires_at, + budgets: [], + }; + for (const permission of this.connectDialog.data.permissions) { + if (permission.value) data.permissions.push(permission.key); + } + for (const budget of this.connectDialog.data.budgets) { + const budget_msats = budget.budget_sats * 1000; + let refresh_window = 0; + switch (budget.expiry) { + case "Daily": + refresh_window = 60 * 60 * 24; + break; + case "Weekly": + refresh_window = 60 * 60 * 24 * 7; + break; + case "Monthly": + refresh_window = 60 * 60 * 24 * 30; + break; + case "Yearly": + refresh_window = 60 * 60 * 24 * 365; + break; + case "Never": + refresh_window = 0; + break; + } + data.budgets.push({ + budget_msats: budget_msats, + refresh_window: refresh_window, + created_at: + new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, + }); + } + const wallet = this.getWallet(); + + try { + const response = await LNbits.api.request( + "PUT", + "/nwcprovider/api/v1/nwc/" + keyPair.pubKey, + wallet.adminkey, + data, + ); + this.closeConnectDialog(); + if ( + !response.data || + !response.data.data || + !response.data.data.pubkey + ) { + LNbits.utils.notifyApiError("Error creating nwc pairing"); + return; + } + this.showPairingDialog(keyPair.privKey); + } catch (error) { + LNbits.utils.notifyApiError(error); + } + this.loadNwcs(); + }, + }, + + created: function () { + this.loadNwcs(); + }, + watch: { + selectedWallet(newValue, oldValue) { + this.loadNwcs(); + }, + }, + }); \ No newline at end of file diff --git a/templates/nwcprovider/index.html b/templates/nwcprovider/index.html index 819e254..143c7af 100644 --- a/templates/nwcprovider/index.html +++ b/templates/nwcprovider/index.html @@ -1,9 +1,11 @@ - - - - {% extends "base.html" %} {% from "macros.jinja" import window_vars with context -%} {% block page %} +%} {% block scripts %} {{ window_vars(user) }} + + +{% endblock %} {% block page %}
@@ -402,397 +404,4 @@
-{% endblock %} {% block scripts %} {{ window_vars(user) }} - - {% endblock %} diff --git a/views.py b/views.py index fb81181..dad32a6 100644 --- a/views.py +++ b/views.py @@ -4,23 +4,22 @@ from lnbits.decorators import check_admin, check_user_exists from lnbits.helpers import template_renderer from starlette.responses import HTMLResponse +nwcprovider_router = APIRouter() + def nwcprovider_renderer(): return template_renderer(["nwcprovider/templates"]) -nwcprovider_router = APIRouter() - - @nwcprovider_router.get("/", response_class=HTMLResponse) async def index(request: Request, user: User = Depends(check_user_exists)): return nwcprovider_renderer().TemplateResponse( - "nwcprovider/index.html", {"request": request, "user": user.dict()} + "nwcprovider/index.html", {"request": request, "user": user.json()} ) @nwcprovider_router.get("/admin", response_class=HTMLResponse) async def admin(request: Request, user: User = Depends(check_admin)): return nwcprovider_renderer().TemplateResponse( - "nwcprovider/admin.html", {"request": request, "user": user.dict()} + "nwcprovider/admin.html", {"request": request, "user": user.json()} ) From c9a7c41e1ff92af84c909cd6954f5c974839692f Mon Sep 17 00:00:00 2001 From: arcbtc Date: Sat, 15 Feb 2025 17:53:44 +0000 Subject: [PATCH 09/90] move admin js to own file --- static/js/admin.js | 81 +++++++++++++++++++++++++++++ templates/nwcprovider/admin.html | 88 ++------------------------------ 2 files changed, 84 insertions(+), 85 deletions(-) create mode 100644 static/js/admin.js diff --git a/static/js/admin.js b/static/js/admin.js new file mode 100644 index 0000000..4d15e41 --- /dev/null +++ b/static/js/admin.js @@ -0,0 +1,81 @@ +window.app = Vue.createApp({ + el: "#vue", + mixins: [windowMixin], + delimiters: ["${", "}"], + data: function () { + return { + entries: [], + columns: [ + { + name: "key", + required: true, + label: "Key", + align: "left", + field: (row) => row.key, + sortable: true, + }, + { + name: "value", + required: true, + label: "Value", + align: "left", + field: (row) => row.value, + sortable: true, + }, + ], + }; + }, + + methods: { + fetchConfig() { + this.entries = []; + LNbits.api + .request( + "GET", + "/nwcprovider/api/v1/config", + this.g.user.wallets[0].adminkey, + ) + .then((response) => { + const newEntries = []; + for (const [key, value] of Object.entries(response.data)) { + newEntries.push({ + key: key, + value: value, + }); + } + + this.entries = newEntries; + }) + .catch(function (error) { + console.error("Error fetching config:", error); + }); + }, + async saveConfig() { + const data = {}; + for (const entry of this.entries) { + data[entry.key] = entry.value; + } + try { + const response = await LNbits.api.request( + "POST", + "/nwcprovider/api/v1/config", + this.g.user.wallets[0].adminkey, + data, + ); + this.$q.notify({ + message: "Config saved, please restart the server", + color: "positive", + position: "top", + timeout: 2000, + actions: [{ icon: "close", color: "white" }], + }); + } catch (error) { + console.error("Error saving config:", error); + } + }, + }, + + created: function () { + this.fetchConfig(); + }, + }); \ No newline at end of file diff --git a/templates/nwcprovider/admin.html b/templates/nwcprovider/admin.html index ac9f66b..b402851 100644 --- a/templates/nwcprovider/admin.html +++ b/templates/nwcprovider/admin.html @@ -1,5 +1,7 @@ {% extends "base.html" %} {% from "macros.jinja" import window_vars with context -%} {% block page %} +%} {% block scripts %} {{ window_vars(user) }} + +{% endblock %} {% block page %}
@@ -36,88 +38,4 @@
-{% endblock %} {% block scripts %} {{ window_vars(user) }} - {% endblock %} From 0559a1b8dcd62984266d682ade13ae97535dbd4d Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Mon, 17 Feb 2025 15:42:38 +0000 Subject: [PATCH 10/90] update dev environment --- .devcontainer/devcontainer.json | 6 ++---- .devcontainer/setup.sh | 7 +++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 004c593..77ea65c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,20 +1,18 @@ { "name": "lnbits_nwc_provider", - "image": "mcr.microsoft.com/devcontainers/python:1-3.9-bullseye", + "image": "mcr.microsoft.com/devcontainers/python:1-3.12", "features": { "ghcr.io/devcontainers-contrib/features/poetry:2": {} }, "mounts": [ "source=${localWorkspaceFolder}/.devcontainer/start.sh,target=/start-lnbits.sh,type=bind", - "source=${localWorkspaceFolder}/.devcontainer/setup.sh,target=/setup.sh,type=bind", - "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" + "source=${localWorkspaceFolder}/.devcontainer/setup.sh,target=/setup.sh,type=bind" ], "containerEnv": { "IS_DEV_CONTAINER": "true" }, "postCreateCommand": "/bin/bash /setup.sh ${containerWorkspaceFolder}", "postStartCommand": "/bin/bash /start-lnbits.sh", - "forwardPorts": [5000], "customizations": { "vscode": { "settings": { diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index 6151741..a49b594 100644 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -3,8 +3,7 @@ echo $PYTHONPATH CONTAINER_WORKSPACE_FOLDER=$1 cd $CONTAINER_WORKSPACE_FOLDER sudo apt update -y -sudo apt install -y python3.9-distutils curl -sudo apt-get install -y docker.io +sudo apt install -y curl curl -fsSL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup.sh sudo bash /tmp/nodesource_setup.sh @@ -17,8 +16,8 @@ if [ ! -d ./lnbits ] ; then fi cd lnbits echo $PWD -git checkout 0.12.8 -poetry env use python3.9 +git checkout v1.0.0-rc7 +poetry env use 3.12 POETRY_PYTHON_PATH=$(poetry env info -p)/bin/python ln -sf $POETRY_PYTHON_PATH /home/vscode/python make bundle From b1beab7aa0dde79630dc4d99c7cc6ef96dcd9217 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Mon, 17 Feb 2025 20:00:00 +0000 Subject: [PATCH 11/90] fix template regression --- templates/nwcprovider/admin.html | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/templates/nwcprovider/admin.html b/templates/nwcprovider/admin.html index b402851..171a6d0 100644 --- a/templates/nwcprovider/admin.html +++ b/templates/nwcprovider/admin.html @@ -13,20 +13,18 @@
- + + + + + ${entry.key} + + + + + + + Date: Mon, 17 Feb 2025 20:00:19 +0000 Subject: [PATCH 12/90] upgrade quasar api calls --- static/js/admin.js | 21 +++++++++++++-------- static/js/index.js | 33 ++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/static/js/admin.js b/static/js/admin.js index 4d15e41..b6fc801 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -43,8 +43,8 @@ window.app = Vue.createApp({ value: value, }); } - - this.entries = newEntries; + this.entries.length = 0; + this.entries.push(...newEntries); }) .catch(function (error) { console.error("Error fetching config:", error); @@ -62,14 +62,19 @@ window.app = Vue.createApp({ this.g.user.wallets[0].adminkey, data, ); - this.$q.notify({ - message: "Config saved, please restart the server", - color: "positive", - position: "top", - timeout: 2000, - actions: [{ icon: "close", color: "white" }], + Quasar.Notify.create({ + type: 'positive', + message: 'Config saved!', }); + Quasar.Notify.create({ + type: 'warning', + message: 'You need to restart the server for the changes to take effect!', + }); } catch (error) { + Quasar.Notify.create({ + type: 'negative', + message: "Error saving config: "+String(error), + }) console.error("Error saving config:", error); } }, diff --git a/static/js/index.js b/static/js/index.js index e650761..3141357 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -66,9 +66,9 @@ showConnectDialog() { const wallet = this.getWallet(); if (!wallet) { - this.$q.notify({ - color: "red", - message: "Please select a wallet first", + Quasar.Notify.create({ + type: 'negative', + message: 'Please select a wallet first', }); return; } else { @@ -94,12 +94,15 @@ if (url) { try { await navigator.clipboard.writeText(url); - this.$q.notify({ - color: "primary", - message: "URL copied to clipboard!", + Quasar.Notify.create({ + type: "positive", + message: "URL copied to clipboard" }); } catch (err) { - this.$q.notify({ color: "red", message: "Failed to copy URL." }); + Quasar.Notify.create({ + type: "negative", + message: "Failed to copy URL." + }); } } }, @@ -168,8 +171,8 @@ return out; }, deleteNWC: async function (pubkey) { - this.$q - .dialog({ + Quasar + .Dialog.create({ title: "Confirm Deletion", message: "Are you sure you want to delete this connection?", cancel: true, @@ -184,9 +187,9 @@ wallet.adminkey, ); this.loadNwcs(); - this.$q.notify({ + Quasar.Notify.create({ type: "positive", - message: "Deleted successfully", + message: "Deleted successfully" }); } catch (error) { LNbits.utils.notifyApiError(error); @@ -233,18 +236,18 @@ this.loadConnectDialogData(); const newTableEntries = []; for (const nwc of this.nwcs) { - const t = Quasar.utils.date.formatDate( + const t = Quasar.date.formatDate( new Date(nwc.data.created_at * 1000), "YYYY-MM-DD HH:mm", ); const e = nwc.data.expires_at > 0 - ? Quasar.utils.date.formatDate( + ? Quasar.date.formatDate( new Date(nwc.data.expires_at * 1000), "YYYY-MM-DD HH:mm", ) : "Never"; - const l = Quasar.utils.date.formatDate( + const l = Quasar.date.formatDate( new Date(nwc.data.last_used * 1000), "YYYY-MM-DD HH:mm", ); @@ -265,7 +268,7 @@ nwcTableEntry.status = "Expired"; } for (const budget of nwc.budgets) { - const createdAt = Quasar.utils.date.formatDate( + const createdAt = Quasar.date.formatDate( new Date(budget.created_at * 1000), "YYYY-MM-DD HH:mm", ); From 0518e6f7d0fcaf5468c786be74f1a49d5f476636 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Mon, 17 Feb 2025 20:00:26 +0000 Subject: [PATCH 13/90] fix models --- crud.py | 31 +++++++-------- models.py | 94 ++++++++++++++++++-------------------------- tasks.py | 24 +++++++----- views_api.py | 107 ++++++++++++++++++++++++++++++++++----------------- 4 files changed, 138 insertions(+), 118 deletions(-) diff --git a/crud.py b/crud.py index 1767b02..c268435 100644 --- a/crud.py +++ b/crud.py @@ -8,11 +8,11 @@ from .models import ( CreateNWCKey, DeleteNWC, GetBudgetsNWC, - GetNWCKey, GetWalletNWC, NWCBudget, NWCKey, TrackedSpendNWC, + GetNWC ) db = Database("ext_nwcprovider") @@ -21,7 +21,7 @@ db = Database("ext_nwcprovider") async def create_nwc(data: CreateNWCKey) -> NWCKey: nwckey_entry = NWCKey( pubkey=data.pubkey, - wallet=data.wallet_id, + wallet=data.wallet, description=data.description, expires_at=int(data.expires_at) if data.expires_at else 0, permissions=" ".join(data.permissions), @@ -31,20 +31,20 @@ async def create_nwc(data: CreateNWCKey) -> NWCKey: await db.insert("nwcprovider.keys", nwckey_entry) if data.budgets: for budget in data.budgets: - budget_entry = NWCKey( + budget_entry = NWCBudget( # fixme pubkey=data.pubkey, budget_msats=budget.budget_msats, refresh_window=budget.refresh_window, created_at=budget.created_at, ) await db.insert("nwcprovider.budgets", budget_entry) - return NWCKey(**data.dict()) + return NWCKey(**nwckey_entry.dict()) async def delete_nwc(data: DeleteNWC) -> None: await db.execute( "DELETE FROM nwcprovider.keys WHERE pubkey = :pubkey AND wallet = :wallet", - {"pubkey": data.pubkey, "wallet": data.wallet_id}, + {"pubkey": data.pubkey, "wallet": data.wallet}, ) @@ -55,16 +55,16 @@ async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: WHERE wallet = :wallet AND (expires_at = 0 OR expires_at > :expires) """, { - "wallet": data.wallet_id, + "wallet": data.wallet, "expires": int(time.time()) if not data.include_expired else -1, }, model=NWCKey, ) -async def get_nwc(data: GetNWCKey) -> Optional[NWCKey]: +async def get_nwc(data: GetNWC) -> Optional[NWCKey]: # expires_at = 0 means it never expires - if data.wallet_id: + if data.wallet: row = await db.fetchone( """ SELECT * FROM nwcprovider.keys @@ -73,7 +73,7 @@ async def get_nwc(data: GetNWCKey) -> Optional[NWCKey]: """, { "pubkey": data.pubkey, - "wallet": data.wallet_id, + "wallet": data.wallet, "expires": int(time.time()) if not data.include_expired else -1, }, NWCKey, @@ -139,7 +139,9 @@ async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: async def tracked_spend_nwc(data: TrackedSpendNWC, action): async def r(): created_at = int(time.time()) - budgets = await get_budgets_nwc(data.pubkey) + budgets = await get_budgets_nwc(GetBudgetsNWC( + pubkey=data.pubkey + )) in_budget = True for budget in budgets: last_cycle, next_cycle = budget.get_timestamp_range() @@ -194,14 +196,7 @@ async def get_config_nwc(key: str): async def set_config_nwc(key: str, value: str): await db.execute( """ - DELETE FROM nwcprovider.config - WHERE key = :key - """, - {"key": key}, - ) - await db.execute( - """ - INSERT INTO nwcprovider.config (key, value) + INSERT OR REPLACE INTO nwcprovider.config (key, value) VALUES (:key, :value) """, {"key": key, "value": value}, diff --git a/models.py b/models.py index e8c762d..5a5556c 100644 --- a/models.py +++ b/models.py @@ -29,38 +29,6 @@ class NWCKey(BaseModel): return cls(**row) -class GetNWCKey(BaseModel): - pubkey: str - wallet_id: Optional[str] = None - include_expired: Optional[bool] = False - refresh_last_used: Optional[bool] = False - - -class GetNWCs(BaseModel): - include_expired: bool = False - calculate_spent_budget: bool = False - - -class GetWalletNWC(BaseModel): - wallet_id: Optional[str] = None - include_expired: Optional[bool] = False - - -class GetBudgetsNWC(BaseModel): - pubkey: str - calculate_spent: Optional[bool] = False - - -class TrackedSpendNWC(BaseModel): - pubkey: str - amount_msats: int - - -class DeleteNWC(BaseModel): - pubkey: str - wallet_id: Optional[str] = None - - class OnInvoicePaid(BaseModel): class Config: arbitrary_types_allowed = True @@ -95,23 +63,50 @@ class NWCBudget(BaseModel): return cls(**dict(row)) -class NWCLog(BaseModel): - id: int - pubkey: str - payload: str - created_at: int - - @classmethod - def from_row(cls, row: Row) -> "NWCLog": - return cls(**dict(row)) - - class NWCNewBudget(BaseModel): budget_msats: int refresh_window: int created_at: int +# CRUD models +class CreateNWCKey(BaseModel): + pubkey: str + wallet: str + description: str + expires_at: int + permissions: List[str] + budgets: Optional[List[NWCNewBudget]] = None + + +class DeleteNWC(BaseModel): + pubkey: str + wallet: Optional[str] = None + + +class GetWalletNWC(BaseModel): + wallet: Optional[str] = None + include_expired: Optional[bool] = False + + +class GetNWC(BaseModel): + pubkey: str + wallet: Optional[str] = None + include_expired: Optional[bool] = False + refresh_last_used: Optional[bool] = False + + +class GetBudgetsNWC(BaseModel): + pubkey: str + calculate_spent: Optional[bool] = False + + +class TrackedSpendNWC(BaseModel): + pubkey: str + amount_msats: int + + +# API models class NWCRegistrationRequest(BaseModel): permissions: List[str] description: str @@ -119,20 +114,7 @@ class NWCRegistrationRequest(BaseModel): budgets: List[NWCNewBudget] -class RegisterNWC(BaseModel): - pubkey: str - registration_data: NWCRegistrationRequest - - class NWCGetResponse(BaseModel): data: NWCKey budgets: List[NWCBudget] - -class CreateNWCKey(BaseModel): - pubkey: str - wallet_id: str - description: str - expires_at: int - permissions: List[str] - budgets: Optional[List[NWCNewBudget]] = None diff --git a/tasks.py b/tasks.py index 3f1f0c4..1adabd4 100644 --- a/tasks.py +++ b/tasks.py @@ -19,7 +19,7 @@ from loguru import logger from .crud import get_config_nwc, get_nwc, tracked_spend_nwc from .execution_queue import execution_queue -from .models import NWCKey, OnInvoicePaid +from .models import NWCKey, OnInvoicePaid, TrackedSpendNWC, GetNWC from .nwcp import NWCServiceProvider from .permission import nwc_permissions @@ -66,7 +66,10 @@ async def _process_invoice( payment_hash = None try: in_budget, payment_hash = await tracked_spend_nwc( - pubkey, amount_msats, execute_payment + TrackedSpendNWC( + pubkey=pubkey, + amount_msats=amount_msats + ), execute_payment ) if not in_budget: error = { @@ -108,7 +111,10 @@ async def _process_invoice( async def _on_pay_invoice( data: OnInvoicePaid, ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(data.pubkey, None, False, True) + nwc = await get_nwc(GetNWC( + pubkey=data.pubkey, + refresh_last_used=True + )) error = await _check(nwc, "pay_invoice", data.payload) if error: return [(None, error, [])] @@ -138,7 +144,7 @@ async def _on_pay_invoice( async def _on_multi_pay_invoice( data: OnInvoicePaid, ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(data.pubkey, None, False, True) + nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) error = await _check(nwc, "multi_pay_invoice", data.payload) if error: return [(None, error, [])] @@ -184,7 +190,7 @@ async def _on_multi_pay_invoice( async def _on_make_invoice( data: OnInvoicePaid, ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(data.pubkey, None, False, True) + nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) error = await _check(nwc, "make_invoice", data.payload) if error: return [(None, error, [])] @@ -236,7 +242,7 @@ async def _on_make_invoice( async def _on_lookup_invoice( data: OnInvoicePaid, ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(data.pubkey, None, False, True) + nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) error = await _check(nwc, "lookup_invoice", data.payload) if error: return [(None, error, [])] @@ -283,7 +289,7 @@ async def _on_lookup_invoice( async def _on_list_transactions( data: OnInvoicePaid, ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(data.pubkey, None, False, True) + nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) error = await _check(nwc, "list_transactions", data.payload) if error: return [(None, error, [])] @@ -339,7 +345,7 @@ async def _on_list_transactions( async def _on_get_balance( data: OnInvoicePaid, ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(data.pubkey, None, False, True) + nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used= True)) error = await _check(nwc, "get_balance", data.payload) if error: return [(None, error, [])] @@ -357,7 +363,7 @@ async def _on_get_balance( async def _on_get_info( data: OnInvoicePaid, ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(data.pubkey, None, False, True) + nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) error = await _check(nwc, "get_info", data.payload) if error: return [(None, error, [])] diff --git a/views_api.py b/views_api.py index 619e7ba..2bd68fb 100644 --- a/views_api.py +++ b/views_api.py @@ -2,7 +2,7 @@ from http import HTTPStatus from typing import Dict, List, Optional import secp256k1 -from fastapi import APIRouter, Depends, Request +from fastapi import APIRouter, Depends, Request, Query from fastapi.responses import JSONResponse from lnbits.core.models import WalletTypeInfo from lnbits.decorators import check_admin, require_admin_key @@ -18,13 +18,14 @@ from .crud import ( set_config_nwc, ) from .models import ( - DeleteNWC, + NWCRegistrationRequest, GetBudgetsNWC, - GetNWCKey, - GetNWCs, GetWalletNWC, NWCGetResponse, - RegisterNWC, + CreateNWCKey, + DeleteNWC, + GetNWC, + GetBudgetsNWC ) from .permission import nwc_permissions @@ -32,31 +33,36 @@ nwcprovider_api_router = APIRouter() # Get supported permissions -@nwcprovider_api_router.get("/api/v1/permissions", status_code=HTTPStatus.OK) -async def api_get_permissions( - wallet: WalletTypeInfo = Depends(require_admin_key), -) -> Dict: +@nwcprovider_api_router.get( + "/api/v1/permissions", + status_code=HTTPStatus.OK +) +async def api_get_permissions() -> Dict: return nwc_permissions ## Get nwc keys associated with the wallet @nwcprovider_api_router.get( - "/api/v1/nwc", status_code=HTTPStatus.OK, response_model=List[NWCGetResponse] + "/api/v1/nwc", + status_code=HTTPStatus.OK, + response_model=List[NWCGetResponse] ) async def api_get_nwcs( - data: GetNWCs, + include_expired: bool = False, + calculate_spent_budget: bool = False, wallet: WalletTypeInfo = Depends(require_admin_key), ): - wallet_id = wallet.wallet.id wallet_nwcs = GetWalletNWC( - wallet_id=wallet_id, include_expired=data.include_expired + wallet=wallet_id, + include_expired=include_expired ) nwcs = await get_wallet_nwcs(wallet_nwcs) out = [] for nwc in nwcs: budgets_nwc = GetBudgetsNWC( - pubkey=nwc.pubkey, calculate_spent=data.calculate_spent_budget + pubkey=nwc.pubkey, + calculate_spent=calculate_spent_budget ) budgets = await get_budgets_nwc(budgets_nwc) res = NWCGetResponse(data=nwc, budgets=budgets) @@ -66,24 +72,37 @@ async def api_get_nwcs( # Get a nwc key @nwcprovider_api_router.get( - "/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK, response_model=NWCGetResponse + "/api/v1/nwc/{pubkey}", + status_code=HTTPStatus.OK, + response_model=NWCGetResponse ) async def api_get_nwc( - data: GetNWCKey, wallet: WalletTypeInfo = Depends(require_admin_key) + pubkey: str, + include_expired: Optional[bool] = False, + wallet: WalletTypeInfo = Depends(require_admin_key) ) -> NWCGetResponse: wallet_id = wallet.wallet.id - nwc = await get_nwc(data.pubkey, wallet_id, data.include_expired) + nwc = await get_nwc(GetNWC(pubkey=pubkey, wallet=wallet_id, include_expired=include_expired)) if not nwc: raise Exception("Pubkey has no associated wallet") - res = NWCGetResponse(data=nwc, budgets=await get_budgets_nwc(data.pubkey)) + res = NWCGetResponse(data=nwc, budgets=await get_budgets_nwc( + GetBudgetsNWC( + pubkey=pubkey + ) + )) return res # Get pairing url for given secret @nwcprovider_api_router.get( - "/api/v1/pairing/{secret}", status_code=HTTPStatus.OK, response_model=str + "/api/v1/pairing/{secret}", + status_code=HTTPStatus.OK, + response_model=str ) -async def api_get_pairing_url(req: Request, secret: str) -> str: +async def api_get_pairing_url( + req: Request, + secret: str +) -> str: pprivkey: Optional[str] = await get_config_nwc("provider_key") if not pprivkey: raise Exception("Extension is not configured") @@ -123,38 +142,54 @@ async def api_get_pairing_url(req: Request, secret: str) -> str: response_model=NWCGetResponse, ) async def api_register_nwc( - data: RegisterNWC, # Use the Pydantic model here + pubkey: str, + data: NWCRegistrationRequest, wallet: WalletTypeInfo = Depends(require_admin_key), ): wallet_id = wallet.wallet.id nwc = await create_nwc( - data.pubkey, - wallet_id, - data.registration_data.description, - data.registration_data.expires_at, - data.registration_data.permissions, - data.registration_data.budgets, + CreateNWCKey( + pubkey=pubkey, + wallet=wallet_id, + description=data.description, + expires_at=data.expires_at, + permissions=data.permissions, + budgets=data.budgets, + ) + ) + budgets = await get_budgets_nwc( + GetBudgetsNWC( + pubkey=pubkey + ) ) - budgets = await get_budgets_nwc(data.pubkey) res = NWCGetResponse(data=nwc, budgets=budgets) return res # Delete a nwc key -@nwcprovider_api_router.delete("/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK) +@nwcprovider_api_router.delete( + "/api/v1/nwc/{pubkey}", + status_code=HTTPStatus.OK +) async def api_delete_nwc( - data: DeleteNWC, wallet: WalletTypeInfo = Depends(require_admin_key) + pubkey: str, + wallet: WalletTypeInfo = Depends(require_admin_key) ): wallet_id = wallet.wallet.id - await delete_nwc(data.pubkey, wallet_id) + await delete_nwc(DeleteNWC( + pubkey=pubkey, + wallet=wallet_id + )) return JSONResponse( - content={"message": f"NWC key {data.pubkey} deleted successfully."} + content={"message": f"NWC key {pubkey} deleted successfully."} ) # Get config @nwcprovider_api_router.get( - "/api/v1/config", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] + "/api/v1/config", + status_code=HTTPStatus.OK, + dependencies=[Depends(check_admin)] ) async def api_get_all_config_nwc(): config = await get_all_config_nwc() @@ -176,10 +211,12 @@ async def api_get_config_nwc(key: str): # Set config @nwcprovider_api_router.post( - "/api/v1/config", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] + "/api/v1/config", + status_code=HTTPStatus.OK, + dependencies=[Depends(check_admin)] ) async def api_set_config_nwc(req: Request): data = await req.json() for key, value in data.items(): await set_config_nwc(key, value) - return await api_get_all_config_nwc(req) + return await api_get_all_config_nwc() From a366dbce335346838e08ccf45ff6bad94ea92131 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 18 Feb 2025 13:31:13 +0000 Subject: [PATCH 14/90] fix budget --- crud.py | 11 ++++++----- models.py | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/crud.py b/crud.py index c268435..89a37ab 100644 --- a/crud.py +++ b/crud.py @@ -12,7 +12,8 @@ from .models import ( NWCBudget, NWCKey, TrackedSpendNWC, - GetNWC + GetNWC, + NWCNewBudget ) db = Database("ext_nwcprovider") @@ -31,7 +32,7 @@ async def create_nwc(data: CreateNWCKey) -> NWCKey: await db.insert("nwcprovider.keys", nwckey_entry) if data.budgets: for budget in data.budgets: - budget_entry = NWCBudget( # fixme + budget_entry = NWCNewBudget( # fixme pubkey=data.pubkey, budget_msats=budget.budget_msats, refresh_window=budget.refresh_window, @@ -123,15 +124,15 @@ async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: """ SELECT SUM(amount_msats) FROM nwcprovider.spent WHERE pubkey = :pubkey AND created_at >= - :last_cycle AND created_at < next_cycle + :last_cycle AND created_at < :next_cycle """, { "pubkey": data.pubkey, "last_cycle": last_cycle, "next_cycle": next_cycle, }, - ) - tot_spent_in_range_msats = tot_spent_in_range_msats[0] or 0 + ) + tot_spent_in_range_msats = next(iter(tot_spent_in_range_msats.values())) or 0 budget.used_budget_msats = tot_spent_in_range_msats return budgets diff --git a/models.py b/models.py index 5a5556c..6b0baa2 100644 --- a/models.py +++ b/models.py @@ -64,10 +64,11 @@ class NWCBudget(BaseModel): class NWCNewBudget(BaseModel): + pubkey: Optional[str] budget_msats: int refresh_window: int created_at: int - + # CRUD models class CreateNWCKey(BaseModel): From c1dab6a63254554cd4144d8e21ca44e4730933a4 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 18 Feb 2025 13:49:34 +0000 Subject: [PATCH 15/90] fix tracked budget --- crud.py | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/crud.py b/crud.py index 89a37ab..e8be965 100644 --- a/crud.py +++ b/crud.py @@ -147,21 +147,18 @@ async def tracked_spend_nwc(data: TrackedSpendNWC, action): for budget in budgets: last_cycle, next_cycle = budget.get_timestamp_range() tot_spent_in_range_msats = ( - ( - await db.fetchone( - """ - SELECT SUM(amount_msats) FROM nwcprovider.spent - WHERE pubkey = :pubkey AND created_at >= - :last_cycle AND created_at < :next_cycle - """, - { - "pubkey": data.pubkey, - "last_cycle": last_cycle, - "next_cycle": next_cycle, - }, - ) - )[0] - or 0 + next(iter((await db.fetchone( + """ + SELECT SUM(amount_msats) FROM nwcprovider.spent + WHERE pubkey = :pubkey AND created_at >= + :last_cycle AND created_at < :next_cycle + """, + { + "pubkey": data.pubkey, + "last_cycle": last_cycle, + "next_cycle": next_cycle, + }, + )).values())) or 0 ) if tot_spent_in_range_msats + data.amount_msats > budget.budget_msats: in_budget = False @@ -181,7 +178,7 @@ async def tracked_spend_nwc(data: TrackedSpendNWC, action): }, ) return True, out - + return await enqueue(r) From f72bfca206da8da513a89cb949361d25f19586ba Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 18 Feb 2025 13:56:24 +0000 Subject: [PATCH 16/90] fix async pytests --- .github/workflows/test.yml | 1 + tests/unit/test_nwcp.py | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d9c1264..c72ea92 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,6 +21,7 @@ jobs: run: | python -m pip install --upgrade pip pip install poetry + pip install pytest-asyncio - name: Run setup script run: | diff --git a/tests/unit/test_nwcp.py b/tests/unit/test_nwcp.py index 8ee0b75..f9a650e 100644 --- a/tests/unit/test_nwcp.py +++ b/tests/unit/test_nwcp.py @@ -29,8 +29,7 @@ def nwc_service_provider2(): ) -@pytest.mark.asyncio -async def test_supported_methods(nwc_service_provider): +def test_supported_methods(nwc_service_provider): def make_invoice(provider, pubkey, content): return "invoice" @@ -39,8 +38,7 @@ async def test_supported_methods(nwc_service_provider): assert s == ["make_invoice"] -@pytest.mark.asyncio -async def test_encrytdecrypt(nwc_service_provider, nwc_service_provider2): +def test_encrytdecrypt(nwc_service_provider, nwc_service_provider2): content = "Hello World" expected_enc = "qVurNVISSl/9CfREIhk5Lg==?iv=QpCo5dI9gUcoLsSMLA7o7Q==" enc_a = nwc_service_provider._encrypt_content( @@ -63,8 +61,7 @@ async def test_encrytdecrypt(nwc_service_provider, nwc_service_provider2): assert enc_b == expected_enc -@pytest.mark.asyncio -async def test_signverify(nwc_service_provider, nwc_service_provider2): +def test_signverify(nwc_service_provider, nwc_service_provider2): # Random content content = "" for _ in range(100): From 4210995c9ec5a17b59682ac32a43ec1b47115679 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 18 Feb 2025 13:58:43 +0000 Subject: [PATCH 17/90] mount docker socket for integration test --- .devcontainer/devcontainer.json | 3 ++- .devcontainer/setup.sh | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 77ea65c..5d69523 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,8 @@ }, "mounts": [ "source=${localWorkspaceFolder}/.devcontainer/start.sh,target=/start-lnbits.sh,type=bind", - "source=${localWorkspaceFolder}/.devcontainer/setup.sh,target=/setup.sh,type=bind" + "source=${localWorkspaceFolder}/.devcontainer/setup.sh,target=/setup.sh,type=bind", + "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ], "containerEnv": { "IS_DEV_CONTAINER": "true" diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index a49b594..7a8da6d 100644 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -4,6 +4,7 @@ CONTAINER_WORKSPACE_FOLDER=$1 cd $CONTAINER_WORKSPACE_FOLDER sudo apt update -y sudo apt install -y curl +sudo apt-get install -y docker.io curl -fsSL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup.sh sudo bash /tmp/nodesource_setup.sh From 7ee5552467135a65586981cbdac43156cd7e511d Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 18 Feb 2025 14:00:16 +0000 Subject: [PATCH 18/90] install pytest-asyncio in poetry env --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c72ea92..4938526 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,6 @@ jobs: run: | python -m pip install --upgrade pip pip install poetry - pip install pytest-asyncio - name: Run setup script run: | @@ -33,6 +32,7 @@ jobs: cd $HOME/lnbits poetry_env_path=$(poetry env info --path) source $poetry_env_path/bin/activate + pip install pytest-asyncio cd $cdir pytest tests/unit/*.py -s @@ -45,5 +45,6 @@ jobs: cd $HOME/lnbits poetry_env_path=$(poetry env info --path) source $poetry_env_path/bin/activate + pip install pytest-asyncio cd $cdir pytest tests/integration/*.py -s From 35a4d3ed12b7a64593437fd5e51b0bf332114546 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 19 Feb 2025 18:55:17 +0000 Subject: [PATCH 19/90] update integration tests --- tests/integration/.env | 2 +- tests/integration/data.zip | Bin 69158 -> 75937 bytes tests/integration/start.sh | 19 +++++++++++++------ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/integration/.env b/tests/integration/.env index 0f1cedc..05905b6 100644 --- a/tests/integration/.env +++ b/tests/integration/.env @@ -206,7 +206,7 @@ LNBITS_EXTENSIONS_DEFAULT_INSTALL="tpos" # to use CockroachDB, specify LNBITS_DATABASE_URL=cockroachdb://... # for both PostgreSQL and CockroachDB, you'll need to install # psycopg2 as an additional dependency -LNBITS_DATA_FOLDER="./data" +LNBITS_DATA_FOLDER="/data" # LNBITS_DATABASE_URL="postgres://user:password@host:port/databasename" # the service fee (in percent) diff --git a/tests/integration/data.zip b/tests/integration/data.zip index e89b53ec073079d9ab15fdf7a1bef52f9bd25948..6f7c483711b58b4d3dee73510dee188a5de4901e 100644 GIT binary patch delta 74808 zcmZ2Bhh^bKmI-0v3=A9$I&*@f7#J8Bm_P&r1A{mN!(_%333+CQ0B>d%5eAT&3$ufx z63*$%EL+0B@O&);gFHmd*YkD! zcW?JN$rE5Hz~CTg!N73z|7<>Y;cQ`Mbzv)h>DT|m!WSncY(3fVVeabZ333VCo8=x& z&NN8(uI)_B4LalCXk})+r$}+0chI((KR?fMK74CaELZN_^gVjtt0wQBeA&p6O(EI! zF8h&%8w%Mk$p<*|f3LHgX|^tZg2}sS%`)}5{AsOCW-U8BOm7-Zv|n4gW+k`mwnvk~ zZ9}^5-Ag*xBQR;n&U-O&_xA-HUVC%9;H z-M@W5>r5l3nRILBrr*xbFxVdVhdV3#d1}}`W`=Gd!-73azpPrYhHKi^;0rf2S*0ZX zCoJ_~sGl}B%+9<$_VlJR)%RkOMUO0B>ERO8+OY1AD%0Z+^TL_##I5>q@#I6{Bu_)L zd)v+lpPOQ{BtGQvo{y#z*WY@0hK<{H7W?#1bN(KmYat_~XQ*SJ@u#O}+vczHUI}M# zRWh$EI5#P1)wwOlJP-ETd~`G2Yjfno=KGCTB)lnpCzI|I77a0Y~HV z_v9q`>1;ngr8kDfyry`oY}YueGRKhgOIgxe<_fIex!cZg zdTV{0^{b69OSfoxX7$ckb~wz3|68KuEy2}Vvn^JgVM+;faanVud*KpA#vK0Z)dH%n zzbE)-wm9!tzEerRdADtS=JtyVvZJP_t$*}1iA!AixNP3Ved?U=If{F>$a0x&n0eq& zQr}M=9@E?G=1-hr?yR zTWD)r&9BU?Tr6yByP|%n|6|Uja}L{osaIrYWN`QuZhJ|{NokXp(*LzC?t$m?ni&ti z-`exI&NHa-?$LAImQ6*f6AuSU8TU>2xISn{Q|XK2TcvkZPVY%rvORkKeCbn6|9jQU zZ!GzBbWN<#cW$M7Z8LtKKQ8{J`SIF?b)}CVRh+md&LX>CwsLy>g@-|3_Gqi{&AiG` z_pkI?{Z7jwi@0aDZ+f&vj@*47^}D8LM&&+^l#HO}h-Y$t{@Ob(QY};CYW7f1^lWyNzgrp0QUr?iufp=-lOy!csZm=Dp#k3&^L+caAXDs+&>gp!!Yh$0>R#t`DJp;1 zClRmNs=F`TVoAX68E3Mm>D%X8`bHba$Uj_FmXXe|d~>LE6l>YS27Ud#Jl==T=hPjR ze6;6~&E2pBnfYSc_48}gPl%T;@Sdi&_SS`uYfjCw6~1)rYxSDFFD6`5l?pX%xLJHx z=gy}q)yE6=CHn;ZiNAXGY1pTkk6VRR|IRe&zUTRvf5FO!S60~PskLnAj98%ZF152Y zrMD^loMF-4ld?Lo2ThMo5%g2l`S$c}j?ZoPTTZ&4HK#5RPJ0w3+^5P_ucXncQ}lG= z8jjNZfAcQ)-#jX@`)8byJ&V@qO_MWq8FhuvFdkO@lXg!sFj8aTB)^hC1)p8zFM3=x zdY>(Fdz1Io>Ou%-#p0@IM?@;^ye~Dr z?TUW&>~#5NrEdqVBWK;?Xi9mv@z$Dp#wqOc%TLTd@W1QIz9oNVG8-^7_*O75OsRKW zwWy`jm;F9PZMl?H zV43!Ft(b4uPrv>8^1%P|UxO$0w$6=Pci#KBadg=|)+b>ameRY9oqn2eX^+YC<)o4Cmg0P=SHVwzORYG*b)zF!?7OSglMl$SKj)gUnAfwyP1mn%%X@)> z^YRb7UfiqOXrlEZ>Nsy#OaA)(wyN^2`uFzbR^}RqZ~L(??#9MnodHJ;>MP{*=LZ1}%(iQ3gUFsJ;()cyip_08}!Wq}hRWmCa ztDiDVxmMrQdez-K)HN{FIxxa^f{4eG16SWR$sYQ2QT&&((dn$G?S(Gl8PWGa5$$iZXBNuRAQTyk7h%>Ezvue|XMj*B-0rkNWX&;+*fbDuUicQ!?1L?U^}~ z`}f1v`96-0bvJiO^So^O^0Ud`@g}#P?c1Bpr&C-utDk0IsIfmcYn|C^IUAo__J^-@ zt!jJlwQZG5^~S;`$rnCsCnUM2RYxX8R+aku_qBMvs9wH%^B#`P8+GbEWLX0jW_KvO zPE)ixC7tSDJWFJ{-d^i>@>X~6KeOwsDn52p+i`yUmf)a;Z|16>pD%H}?AqF)HT|u4h31F2*m~(DuZ7nw_|%r7nc5`Dv*T_Ri&Fbn>r`XS!;U|G zbnaU7%&RL-Dp}?8^H+i<9>O{n7s^-6OnG)i#OEB}(yK0u-Y(tT^{RX38^t!((~G|= zFy&Ynyu28(C2L0hPY;!?-A5I9zi-M___}GLN}u#|-RL9xSvF2yn8y$@!*J2p2M7Me z)C<_~-1_kS)V-?x)p6<_iVua}d9-S8vCo}*OY^J9?Zd~|PDN*HbISev_4Q6&e3T_C zyYIJEm7SC7yt&=Au3d>Z&M&BOHH@{@TXuE$+51?YG&2?B)5}_}?eBTkl)CFl<>MF(m^e%|nHTCMPHsvU2~=v(8IiUA*VYyIfzt z-zPMF{QKVPV#>QDu0*D&>DZ4q`uF-u4A(548C)~nf6uRD60NItJugpP@#AU8Y{&5K zsR^JTXwL!Vb?ZVN)i2vpWZkg&uDoBXxywc8cdRu(XKE~7^*)os-ylll zr16eSj`?Tvr`XQnj*z)`!ZnXm?)JCcX*m~ecNm+^7H;0C_9ZZWf|*jY?v_lE6~_ca zeyO(_I?sR9z3}MO#|Fldlj3TfbN}~#UvuZgna5X8zxVj;(lgD2b3@T7#VggfMP~l4 zXP&_IwQ5t%*$vicS)boF4_S?6$Ut0TkYT%5&lTt1@1kEj-CBKC>F$q<^}##;Zq^SGDtvip-Nq-Y?#J)C zU}ha?@@(Hjv(-G+InTSBx7&K&xjElAbW2*9oQLYJDABu*vu3inXztjd@nwJOUS7=! zGIl-F_Wyb{eaZAix^GNVZNzzZWq9$Y>R4yw?{*Sy4OF}TlO@k>?k6A9o7HC5o@8Y= z+x;yR{>`7ux4E@`BRBhzdaDDC>)F0MPvUx$!I5cn;|l8|k4f5BAN%bKe_i%#Puy$s z*(aMOmmfT%|LW$-|7E5;Dj7FR-#q@f#b3ql=9azQ`3|3wz7-T@>pWoZ=+E145FUHy z4pYeuwv4-ZrN8I8bv3@%Du|wdC4^5Mf{IkopBFqPebB&R;z@-0qkgJwG$md7of#fJDR=?rlO_ zTmL!ksodbqzW()9fso?|xlVpOvP}N)l2;->ewvsut^TQ~9F^T|H%mE3nPZK5!0RjG zd378TJ3i><3N@bXt5~yH_=oHFsh8&;x-N5q@hWql!9BG@t8bq_t8*x~q15=n?;i(e z)=v(*8W70HGR47XVbt#VE2DmiUFFr6b>m&Jvne#m^TB~t4^F&l6pp-R_{~1~-%}U< z-_!q;9*9-dsq%YVKfU4p<%5$RboE7S5R)rgxAFF+3rSKsdz+?j6Zfu9+VY^Hx#8gL zRkg(*Z}rEv>{zEHW4Cb2pC=ItjJq0imS*|O?N*DeR}XGs&)+xi1XtLaXDSM-eF{V8 z@=p@JIRBdX`HWiri-}MFTnzQJrobOv3yR%z@ z`^se()e5cCy@!@%@bf;6J1v!_Cih1rg731SF|)EtQ_ieHk)H;8+N@Z9?~HLQ?(sQw zDD22I=h_pdS@m3eyB3ws?*BMZJ^aL$XZMP&PODv>D`}p5ykz}hPQ4d%x!!lay7jwS z{Ww?kH{VZ7*ZAB_6_1lz{2=9lzR0oY@9Vn0RNH*Wl<2%VFMHWjp;!6rC5I<#Onhl} zwT_e4U!JKcxc!>TkF?1a#hJyQ)P)b+^NULR zs3_=v^tPuP_W_$HcH6E`W;)*3a`*Igx#>ISt=|);tfMr^qNy~3!+qBL(|$FsKxoOIAfXM8LgB!$yNN`)GJwQ&42Iyx7bG6V8({> ztv{rsL;5_OhtU-w2D>iR&@!)UI6qcg~He=O#ZrCG&Ce z_LFjHPedvfe*K%jMvh~F<{MU4h6;y&{SVHZxOntOy-`&}?CCsbnWyq@>E(x_I}iHm zd=i?Xv1C{J%=O2a*Is8+PKY(!CEa^vR%Wu`znW)h^>=2w2n(r&h>6YqU~zX&-MIpZ zC1KnjrYL4{nw?hj{4OlR(w)RAv+B46p{}-mMHO}Uq zb^Hsa&1b;ZlHx+HjQW$GudlE1`W>N?}8 z#PsVc0&Y)WYKt%zQVZ$cB+mb8qFa7N>Z4heMq0KBi>i7I6!>n1StJGSTeV;wlkcqC zosT6N#hx{1OJ8nWvHsnQXAg@0h`EQ!t62v9xWA>QZ>OHB&y5+cCYmx}mLWuFiju88yXO=;R{9LuvjszpgeNf13~!xcK!yE1$+K`r_wYR99@j zdp-E1y;+F%%BfRoxBIWC^!0lGHeXmY)_=C!vAce0n|EJ&owZqV^@C%#mbO-$*_~Y< zQlldNwQ%JgskpcUOJzh~o)-T;@8!7wwPh9UT-K*H-nV8=`QTpb^`J3+BePSm)Zvek)+e6x}yvrNJ&HuJo&>`R?6)p_HKn_pELoK;tL{+_0= z&dOuDD05xh!6gOiMN<{zb~^2yR{rj?MU!m7topXwFD)x{;@*`gCT8h<;ae2pE?M~6 z{fBW+_8s1sfP`6Wzoj-$wVuhN-=CuWQIf@GYO9+6k#*Tiw!gb1Er0ZhNZ1=j`+|^n z%TIZE<<1cmxSFS8U0-s2!N*6tv_e&bl9Vol8ny2}5UKd|{$w7JeaSmq!EZL+K zWj|9yGqE<9H`)Jo?ABk=9!YNx@#}7tFJWI-V9I>`x{B%H_fwj#OR>KGXPUF!{ZwsA zC;PqDz*%1fyc(hc{GHc7?``$6cqUsSZn$I8%l^q7p|UEGJ@v0!A6^&qWb^2bXLFw* zeE#-7U!M5*Ik!1ndl=uX+Zl9j`jx+vD`Iue3BSuduvgda_^oM^H=d|?ynn-kwvt(U zq`cO;n_9{!iq`38&sF^?v${Fq#bvFn6YiXtZ>}@zOOW)D{+stg6KnfgcQIW(#>{>7 z)9wK{db_#(!bgr3ua|z;QakCWcqK`3uj0F( z&c=myjTd@XUHKh*p)SeiBwye8=WUa2@fmmpx^BH{E>qZI zZy*%5WW%#%4-TpuH3&zET{r%8#VIQAT8h?Z7w@$aKd-#_-dGwH9E`I>j98*&^kXcF${aJ#&H=9!r{R-T`v z=KU?}m%_Vsf1Jfa+?`AJd3=tYcP5%))y2~dn%P|)6FW8^X$)Gh>!!WN@|k;WPHp_X zadXszm(Mo|76_bKe)rzjrI85*_p{%8UV3GrM?I_Z%a&`A?Ps2DPOG?98bAALSnwn3 zmdVq^CjZ;L`%U;{*QH8F{cQ@bPr1o%9QSGi3ya`qxkG#wKWa1cMi%S;Fx}~*6I`ZU|InU-)|IKS%9Dm}9gE+g} zN?NYDh1?2^(`jk_c=%S+%d{)K(^}jFObaLYnNLhgGCIGqAmqc-#Iwk}L?KS^9Yid?gYRleDk$bP$+&`)(wdPv(_p2*v zr8Uc0ChS|@Hp$jbqh-D0nToviXKp^b{I$@dcIJxXs}oj>USpRr@}0YRWtRHyJu`St zM%(GME37^;fpg_4d6~skb~~#0%>1-IcBDPdJshFUyr6bdo5sC`6KnoRF3?v`s%K-4 zVv(*(i_Kl7G^6&xrS>D64a<7G=cgs!SRx(1_+~=TySaak{;J_jo0gC>ttkwGN3}q`2IvI@qJUGV{2Xxoh*4V+WfSvB?-5nEZ=X`PKrFUu_|O`ByHN3CVd= z{V-Oc_2Lw5<W$st*rtX5-YC82|5tipJWm(BxVVjrH zFzays@7QZ%U9-*FEl!10N12pGJ+m{&dvfLIw+mWXc^g93E=@Pz)m-i4arm;ywDg;v zI*KPx$%iL1CS)BKjLS8@60Mqic~^h0o7bwc>3JPa5i2HMTP$rWT+KCSO~8)t{mDmt zm=SC3wMczf*JH;-Q5{uSKaqS&{k-osV) znP>qslijB(^Z6k&u5dOQY~zr++kI+l?eF9#eAl^utpE0q!Kpm%(R}sa^?p6|Tlvk{ zwuvoM^E>x{*ORqYfm5b0pR`1Fad>VB4|}nT<4PHYiO&<*mTH8udByN_Sh(pc+8a75 z`Gt^|W;gm#pE_so%(Buq<$~>;LUfSH3mZetXH@@ww`i`hD%K zGZ!~*Zk@aK@_&=C%d5h|X7gzLpPH52Bd1tqw|&u4)2#l7aSuugPUJaotqGdGWS?@_ z{ER<8r+kPlGOc?W}7a+#)NEpz1D z^sDgR{R2I%maMPOCcQs+iJ$As{^rC?*|fZs&y<8zzAV_a(wj@{pWva|mKpQ6_C!57 z*SLB~)=t%)XIDNRa0y$;Zst^=5OOhYUz6_%WLMz*aLlA-j_ZTP9P&%2 z+4B4svwFzm6#mFNF3JC%Ez3s6Ls1=jCcQA*!EDNE@^aa=(lGhX4QxlfHu`b@s}WtZ zIyHGotqf1+X8U;UrbkmwzMehDuHyRZYjUX<1q2sf$P&q1_^4HKZSC}p`(D3K)AViq zXSR3po>%GBRzcs-?x|n?Vc-1IZAJ~7@^)B0T~w>Qc~5TK*4eBz8OBTO-baWOzcX6J z<7D{ogm3@SZ4sL#Jvl5-#Cq)2yR+c3W{&IaiRyZa=S*HXY)^SpSt+?n-0Dco|)^HAQ{iF+`m+Oi*9Qw!B5y5lge%8|1BM%OL>SGYP`gPvd z%7qH%GnV*r^lnjdTK2P9-j++Ucyqg6=Dplgk*|;5GC0-ZJ|(+Yq~}7P^v>{PpIq)| z0d^e|pWH8w5r4EpbKQ>s>o_fUFXcVc>J8tTOWgp@>P4C~_RaLGLGVza`liTb?UfVdr zr|NlEgg6?V`yi0=;p~U@=>Dn?g)PBXi!ed+oY zKA#zD_rzvy?s{Zk_)~~WWP)v_kW#?GDLQxk*c19R+gDDx7|B=3TOYq|jqb6TrB6~F zCu>HXvha!$)10TDBU)`NGs7_IK}=w4%5SeJJe@T<_eBooR?c)@bJZqsg3W{EIm?qa zDGPS@{kn2MxW#9uxNH64-4`ons=1$9{mQ2$CrGtqrmlYPa{g=k%cPr5={qScNt@#& zaOKueP#N-@T2;!p7nqCEnO1! z>ilH6b1Ba@{8^S^HRDU9?K?KsJy$oq3Y^EfLiNOQp~Q%13VbpqHFAkh!rr%?f6SET zqI+V>RY6(fpeY4>&8PoWPp%Kls<5tGV(WUmSUkOQ!n~4;4ovT+hpJ5|=-gfYdedc* z$(-|~+52Ynuf8)=v3};c z@}iLXwPjZv>#O>V%6|SxJ7W;M;qJ`ZB~#V?9hS9MD^9y}rRBM$@?NbswTJs%y7RrS z-Jbn%?~)Tco3{VomiR|lYx2o+9{-ItOmdG8+SYq(R(0F<0)yq#XD&@ndsMC|%ka?R z_TeD=`hqP!SIpflON&b@Z%Wo`?71c&x@P|W+Rt+&Lqh(>ohUk&7Owo|Ob=V*5rt~* z3vMnw5L)w-6hrg>}DpA{9{yzc7iApfg-oPNK0AHUWm?KWFo zbYK?4$}KB@%(%aBN}=krQ%O;~=S5ESl}vSO7usH`Czhfh>!q~kO|o#(CYRFv=lKdZ zo_@7x=FJ+bRGBME8dE)EMfS-xw{GoTDx2ZN^8Ri{ z-a{^>(9gHqWlzi&-?I3^s%M|AFRae;zPos8;gk>enOpZ(*reaD`|)c|*8KXuqU?h8 z#^!Th#Jw_`Xgaa_%C!)e_LE2cBrkh6B{X2p$I8~4ub0k0$gdW8EXeq$v+Zly^(hzl z+rH@~y^ejuJoB!-6`SGrs)tdGfAV?XuRUAWf*G+3a@;=~t zN^V?CNPWx^`JB6^79WCHGY*`(y5dgd&G+fcHPr1n45kP?aI-U=xsz4by4hpW#MJVt z)6dQnKW9zjm?m?MiF-o*|0xy{Q!AM_q<-Z{*~u9EMQZK7p2yoBI8NU-`D)&oTx*wd znPbbJZtU5~d-3Y(E^ps!dWl;dtN)amub;C0+sPHF_0N-MygXo}a=F#nbq2$_#ak|J z-G21W8@7wSJ64o@GM!a^H72|CsQta9;=}7-sRi0Dxg8V47?!(NvFG5Pp2Vs3=T3=8 z{AIbW%%!I|`J?Aj<>s>4IZOYxop03fyv{wn&GohGg{ohx>e#ONZ1J#;Z_`+;vA@@1 z-Iim^S8w(&ZPMP~V7PqJC*7AZLeqlJampeW-C4MDDrgWPL??;rC<0u zU)}aQvQPF*@0JbutBlViU*LK)m3voRP29A4O@Y(Q(b9K{K37#=(B|9q?sNLff0w_9 zw=H&FyZ2?q-sz7DUt3jfd0CXPlKJH6Y~>jumSF`&+8WEUudFz$ke*w=LQ;$mK(Nz8@S{p&n+rfG{axm7al5L@5HZ+5$uVd|f} zn@s1||DXKhkMZf)ji;yOKA3-8@c8bNyh~E1pHxU`oZIGLZaq)GvbQI;FyzkbtTTJt z4a*HA+jtdtS!d;%uV27alV+(aUHXb?>Tl7kN8EWff}29~>Mt6^$gO-M+s1z&C~B7^ zudG1z`PZ zIZgW1&Hwr0tG({kmjBLQIq)=G`%-y}Wyy=$BGcvTe_3t!C#z?^`VbphSUzQIeenvdis^^T?Jhh1+CF!O_ami_jW>(*ExFBprdq9al-J!M z{-RfIONQ0b+j6P~&;IH>;)?3jI9ht0Yw!1;Cv-0I&9kXmY2DBivm)yGw3>{n!#n(a z^?DhZE^Uc;dLzzeQo2IUArIX~lh^;EvWjk(e*JBxYRulb{Y#ET_Sb(l-^eR;wvt^XG%#KOnjFeB;h&T{70si{)ViHT@25C zZhYHXFBB1^qnGh3fNydN{|nvEUGsd?xgXSJggua$_b4t_LDFW)6ssu>%TJ{CE_`@E z^udv5vnrZj?oxjpD46lces17*HSSb49~VaT%BZ_%?-lN_PZZy3q{rUu+kN7uS<2#B zYLkv7WKA~RFIIi=);5t(C-w#{X1VOlh0^cVdN!-nLREU4;>!Z!m zw~rUE7CJYbt!=@CuYo?n2X`!LUw-((wBLsVSF*3@JHQb5cSq8JyxId_Ow;f9pK=#+ z*5`S4mgD3}H^VCv=1f1W&dVDX!Zq2P^^lLm!Re=44n{~YUgcgpd7Ao%jb&{YFYD&` ze7Lr*GV9;Jmp|vudpNOv{i;LyF_AIT4#|`RC+VBFiXXV;b%EhJ=j`l7TUw8(T76xt zBw&4dWv3_0(a$HPZ7-bsz56!HruWe^TX#)i(Ge??NwWMH&i3G|-M{tx>vLZH^-znG z^GuIl?tJ}ur{V#LrK;XN3;IrEl*C&3-#KRSXG40!^Bw-hrD?OBU)|pQQ=ndc`-i;k z&#RbIWInx?E}b3lNB{q&lPB+=+ROQ7kA=_|KaCR$WUMxCDl^ypzr-i#tb^qB^!T|e zLnp}{Il80x<-ryAwlsLLynVSNOJ6K2YVHoDtE=|^WZibLXy?1;Rq{slzDtkYSr_@q zsOnnjr#tp-d*?ay=DvzN%GK#mD&TrVbbI|3Rkw3ZE^A_{jMfJH{LPf--gA$C&V?7Q zC8ZN&N@T^&9M(HdE8S%m%*d1~^;*>~@5F_(dZEhB_vZ^PpYLqM@FKl*#+!==RC#JR z1OLo1*j4<#>hXtlFMUpK-(I=V?zLvneTRLrvG2Xiu6$U>lNEfwitW^u|3;^(Cx|^* zsos^ny8c-X#}_5TZO_hYEQl)b{cioob-L8se;Mbyk3I~)Gqc-Ad!aY?vfLf5-`?!a z{kD8*=Jh#7ZB;9mbmzaway~J+OUPt#+w})-VU1f{uZFFSHxr%tb_;)hPs6EI&(h6> zE8jAAPQ1IGx!rpE<@>G=!b9q_zZ4aoU|n-7EKTm7&il?s^;hajuWYbk@Je`FCwJxi ztF@1RuAC|xv&2wLaBkn5WA!t6Y>w8ZX=Hs;YFNeJmEK_Wscoj!iMugxuN+_sKAO1c zbyOVNp*1;&rK`Gk{+gD)iHC<}>a7>IRxzy-XUvp5vU{2CZMiQKtNDGHyVD>4obgk5 zE#q|AeM^4cniIy!^k$<_{rmKtQ;)8-KF@My@q-)l^F*&s-e;q+YEN#RbZkb?{bY-G z+cQ>eoNFdJf90pmw%=3E=v-5{cfs+TYvt07&wVa@|L}Bw{pPxkA8vX#J^pX_d=d{V9*D_T!7ly~YGniym|LDz9 zo9E&s?-t(w{j2A;v~#oek{y3P z#Anwx)|^0?99BbCUj9TPYsy40Mbl!9o z>&IKZn|S7#KVo%P6$|NOur`O12UP)-u6fG!C)ot}~m%<1Hx17Qd+Q^NtYhslO(=wEnA@JE8B1 zhuW-d4>%|0pWkb|CZqML){nZ4wW?4m75C^qSSpkEGI*_^-}mF6 zr)r+aKj670VwcdGZM}sp)|R)059|N1=SrrZVMp)RJLDRB z8|^qb|CDqI)7Fot7q&e#I>`U{W#b`-gq62f$S#X6y2p_=dFQ0JVP-FE)~C$c=Xzn8 zv0iwtnU}@hhbM}pJ>C8K$*Yr7lyc>+ z^X$;Dv-l7>z4nUR{Ru+H=WI9aJ8(<&ZdXRV<%%aqK3r7VyZ_^)zH59Ahl=WUzrTI4 z&#BZoN7F{cMW| z>)a>o?|c*eqUYaMU|Q6;iu3J9b>5Hr?i||6xZ?bKyCok5QmeY3Jkz$i`eBNHm)f$F zs%ul;Nwo?Z?^iuCrDl)Mf)9q-GXL_gulBd#UKqc&%_#nP+jXw``*&v*s4kxpk?@_h ztafI^+~s2B&*tPV=(RZcg6Dbe(@6evC-$F9l&8mshmG!&4 zYozCM3dnB0W^D9m>x@?3Q!naY8LSWg#L>J~qh9nm+v-Za@p_mJdr}riwZhzags`8W1@%N(Y)AVCHy;g0o^>mrO)XvPy zFiH1XmfmIKQ||MeJon0+TgQ6->IIieIihxN!s?fHTnR`#B-N_+YpK?vXUfYqdtKc1 zVD-xVxl1_>9^Sm=wb@7Rr~OOQ$5|JbJIpO#yT5Do^l5bu{d{g*4Xu*==(kBD_13|@ z^dSDTtIFLDxv=s7TCiJKC`*)oc~Owa*4u78)p4`$HRaD>&$zUEYW|X+^PcbAs;?}o zctf_XrR&n=x%GkSi3hIdioZ9pHi@#@R}tpk%{BM?`Gdb|4Q6)<9(vUCSbEZg8Uc&$ zX|EU;ZavPteNm6g(TXMIl1zeeu32G~Nhcyg66(E@_NfZ{JmGp5YI05Wv9gKgU#1UR zDnE5;&PtqhJ5VHp@7UDi;yF9ocfG&9+uSmiea$8YQ!lxH76xMVE-CLBBv^N;h|KCZ zW3)K7u(8YTn3lnFkBw?Y-6CPdzXYH9FooWJ+qKr{T(7ItZtbo&CFjrxAoC1I?~lc8{bTD2yS3`-BByy>d&XyZS7l@E#Vfmilt(`eE1Q?c z+?03Xd%&NHuBuQc@mBF)%=LLc#GeIzzOmCFOszTH({-tp%#(_8kDyZz3pVkli=2=; z;I0FqUUJKTi)c#wmEH^K~{>tgku}MqM_C}s>PN|OWt6b5lw6-(r!mO~% z-E05Z{ZL|OIo~|{bd$q%N9{|t*BU2Sb+lE#mD;W7vF`5A&zFyd+>9`Ce%W@geygn3 z@-?)il5Qri$QAM$*R?ZB#tDPygFu21^~=dV`-A z3Y_fOwRoA*r7Vxm6<3iqvfJ$Q#NvBx^-nj0nX|vR%>VAG?DRHNHhtfdPl4}?SF<_R zW$~K+RJ>g@_hR?d>Xo{CC%fJ8@^)ELveGi(tkuG(89_zmks(`dO{_k+|E2J&JGGww z>=v-h(62A>{j=MC!paV*&rwAtg}d|}8grf{9XOludZXlGo`hFbtXXU89~(V5b95e0 z;Cvkkjlvk7T_*od$*NwQBw1@ZQPy$|(|`8KzB`w#Hq|-2CgA9@f9saqw42IkopX;> zEmVIyYsHdNI@{;XGfV86{+c;>kJF#MwFZ+@`1Idhp2yMJUB9?4bWOuKp8em~3pwVm zGTPg$Au_Y=2K({Xr!TbjiiGMHw=l0bGi#Pk&Z5)vQ&;Rb*)FRuuJ@5g%c=6{PWM-G z#-fj3=v&6@_gtV{WRZ~3{C4`z+LGnd4l1M_Qx&@GA+Mms^E~0{g}Ty9n~I+V_6hx; zzU`#q{jd|CE?X`)))f6-FH*+5kEilXL@%@csoa{d*WRMm2EX4qsQqnqi=J%nb|mKB zi6qU(3sv4SOqp`2_0Ob#rJw!YGJh!WopQ?a+v`K@;#F>iIck#w)-BFszFHVqnwfmc zL^$R_cwF|X8*}oeN$hz4-eq&xm{HfVj<+d?rIxcrVI`%x)(IQw})@v?Qk+k(*QaFJto-h5mi#eLaDe8aM%Gp>LA7!b2ecb8R^jb6A@ zrbT5#ZT;^UFIS(s%tLn1827Ia+Ua|k#c9cb&D@7>@V~KK{Bp(D85b2*8$t|zUDb_c zsc%hkJ-e^BIhZl^0&kss#$46lS~jx{5e2K$vTIysOE9r-IOBHD_Q$)k@BE|ZafTFM z)eVek;}b0KS6RAAVXgQ(_fU4jLUlc^ZyK5&NBO4B-OpIh!1(g-)8#dLxBWT)O{r^o z$MpSM9Y1b5!u(B2`27vlGf6l0o|QgiE>`5XTXRzI;@t~2FO=a+U;frNV2ZDerT_Nq z-c72pKU?Fy*0|1}^th{fN~Bp}>m-)^_Q{@SY|qM;+uwZnCFfhbl=rViL7kp+dkc=) zUz(Xx{?78bbG_KzJ1gtCzsbgI$}O#Y=Tb32peQn1zFuqlp9$++WolacOZMjeI%R%- zlk`5uu6P-aHp$lpPT!tQJ|QF3^zr|PseA?H?50`Y{1kH(oQ#j1VbSN`5@*g+G*|et zs;6${q0S3o4{kjQy<=azTX)V<*-!(`y>cDOPdszp8h=o)Y5lRyWdHsX_3cxpd0PBr zndWyjN?kU?wzW^nqWaj@W$N5>uGJ(gniuqw<65e7rQY@P#xl-9h9=pv>*Z%1kJ$ft zvK2GapN^{nA!4#~!v4FK=tjRfIQQ$kuPd?+AAW5-HNmUHtm^B!C6`{CbY79DRdc_s zKS`MH{F=S5xH8x0Z#1$yH_I`uY;Q~b)(bZCioGqr8(SR`J7yAmI50xG?CgdO#WNJo zxW=xx{k!c-;QS2}Wm*(I`dmC8AkX!n^1JH`M`IV>KQsOZPxBFwlkiB1)j9Tk@lD@* zIcLlEtx-7Nu}Avpq=Qjg?N4<5o6@-L%rQP)8RNxw3=gU8-Y*NbA zaJyHZd@Di3{`L7^*B(nn9PO;Li#p8f&+&W0m$!#~w{SU${>})lnrT0CzQ;@#({mLw zzgC>L6yS9@5>Z&BTe|$@*QMWPJbrjx)4-_k0cW|F;g5Io-o}I)?&tcx(2B~cjEfqNzQ4H?$keU@oss!?()CC#Y?}mR^4w~uJyW3Pr+jeoly?sgc7z?zJyF!nddH!sq!flE@dj+yWuzA;d5ti zh3v7ns?`gQXg@HW{hKH2^OxK&oB2I#Ka?6@tkqpFdFs-Q?aS>anmpTI|LKmnnsjKJ zlfU~4$D1Yc8*T~9r0Kj>amtnK$1~Xqp)L$Au-m zz2u1Ww<)%4tQ%z5|CF#Sy~nWLHoCsri)Y)qjSRDHWOkX9cyv4J72Qsm?Rfa@r;gdh z2bcJHTHjt%>si3a`0h%<{G@+JHt6v_cb@Uk@qh%w{Cm51G}T>H)ctZzX^!UB$?OO7 z&hm7q%$t5)#g&I)Qm^#nDa?8|mbc^flp6OOmo?6mMo`u??yA@BgRLHC(f_uOYooA z;v@X#u<1g*RVV5b{)1ZE1o>^<9X-L?Ahmic+HNj-+%gV zw;0#Iy7!h#{yuzo@4l`2@yFLyE!M2r@b*f7e!z?JcqKpHziJQ88RiIVO`oq<{z{z7 z;KlJ3yS3J43(oIuY^vk_^i2EzqkHuauJ-A;wr>47UF?Wx-m+`{U;KZsk4@8y$$p*R z9XtOz|MBej!|!wJk4-~PhPMJ4x3uP`*(RQ!sXH*H!2V~Yio$c_aY z&NA35u*h$EFvE4?lst#`yu*7+}`*Da~9A3JtO5u(){PfX7yLN88lh4jJ1Tc zv~Dc;y1Uo@LV}`nJ=2aE`|T9i&z#V)c~mIyq}*Y_fdZpLXMJjJ?A%=Y;#Na@-?^*( zpT%RUt4gy~Ig6}*T-KSzTUl}Qt3U(GOl}LSzw73|mNY+p!I(cW{-T8?Cy$hr6ql01 z7g-aNk_-8*hAp>O|GshmZb^PU)1LWu)%H6*t<@?-nqutFf1fYu`cgJ#NA<&R-bpMs z>;LgO@!a3Beu=Dv%6@^yhmFpS3!`_s+Mcs2*nWPM_|~T%|5~kBxF_w3!oT=s%m;qU z>-OERyfAIUx2=qSM8DnMXZBA2i;D1rFb5CDTE~CiidY1?>MBw$cyKUE*E2CQJJd7s zlopl>EZ{d6`SD~(tc<)*^H>VtPb zZG8HLH~z2HzT>KYlK#A2su%VDdm-u>Aw z3bO80r+sp`62x`({GX~lQ+RK6vF-L$3J_ks_T%Ka6~42a7NvKw6sS$pG`n+iLeqaa zha2Ztz4K4LDefC~OJ$00zuwEhGinpBU3x0{TUpz=+u+sw=C(=N=pvJUOKxu zJz|yHy!B4YyKcNSoXg_4Hapb!y;q)*Nwmeh-N)m5=Wa8cl=Y=*_21G2xdThre@LD% z%c4Q`;o0+Z6gO*?>o^70Opx-(h&A?g$n_BBIGECqpZ$!rYk{FpPn6#==dLX!%e+@E z|Ees;T3;aH`R~?i(K$6SY4-K6u4iaE2He@C@lN^7S)Fwkrk;(qW%(qPEvx9?^&-sN z)hY1*N!7O+$%R)nW8zIW`_J4STo`uhdAEMbf}LDjY)eAwc5iDCV);^9mbU4%!_Dq@ zQVhm9#`~t5g`71F-P4|&dT5$lMs30W9naLt-DDRFSRXp@X+M+kN{*ZUGi79j>JM*M zn84t`p#Mg;&AQ}Hea+4^NzvKa+RZ1vZ2iPA*EM@fpfcO589QSwxa9+%b)LfX_D|0g|1mtebaCf<5%rZ{&91u` zKka(SRp$EWx3B7nhSu4a4MTZ9*Y5YoU^19vle0g1t&fTK#L0FZUk`?)yt=%CH9sSm z@muA+>-9796MfdqDSS0aC*y_Iq#sjEA6=g}KUb8|JtWV}=d`T9s&>wln3$s+;=yuL zU5XckItI3j`)xV?zKbE9`L|=>p{Vou*&V#ocQ%IhGKNX-(b;)I#`bP-e88D|FP5nZ z`A*innY?0C{=0?iES@!2GPyt7)Z+|= z)1$(VkY z@DQVfX5{PHz>q{CaHiN+U-*-;_7f9+LuEd2PLI?2P_7oo}9cO?hF_ zzooBcGbR<@-~aFN1%*f4ypw}x&2jiO@#z1O=@Z;iJal4@R*1*vq;N!@i#cd*@O)bF zv!97F3sqYey6t~__JivL&5vpvzn0!$c5Mh&-qyEOM^m`{ac$3RX17f)iuIh6BC>B6 zbrgtyvtg?^Ir*wd|3+*6=9ZWH&UY@1U!5&;(Jp}J{Wa-h`fuuXye_Fo5sVdgTX%=G zHr`r%>5t9dzOiLa%IsZXXwvnzOKM(E+;zux@2lL*em&2H%RXre%wGG<;HR)*{r44bn!hfddf{W9^htmIoL%Rl-^Si(`gV@( zobH|n>k&!N5NFBS)htnR-0xMAMDY>kjN?@CU&-~0c4!41aB9&VnN z^w0b@Y+=jPeq}dL@HzRg@_ozvq#a!=1NL}tTKe#O>$O$3e6rg6l*R6vCwJ#OpIBbp ztJb=reiEnKj;TCvPk#Mbv~~Jz^_XK3^Uq96^O=6O`$w0hqfa%D!rz%wgeD0FdIesY zB2@Ep!qI{&(#KYreu zm2*2We)@e`lYiGQdrxR+=9~Ss`}i6c9_i8`?_&;=QYM(z@9&>~=+NYRi-n=f`*j%Q zpS26lDO?l3L!a-!E2sUnACitei9VND@X<6&;pmh(e|idS?(;}$dn+40TBQEKx-IMd zPCvo_Vb#YOW^-OxywgQttMBfc9sLWspQ=B(zTkVvgMiDSkFN*xf3b=%Sa$1B;LoX* zMmqN2cFysCUiUff%*QG9y=x-8ws-%^lra1|C3AuMf%$IJS*03gTS-@_bZYaTQ~vuT zYkswy;_Smo4%%hTYKP5sHul(^nexT=&*Sz*Q$(5=u5xNVC+ZO*ea;nGes~=5kKw%lt&qZk|NniBUVMvco6bwyi&^F#UYK z4sZVcR!OVt%nXa`DtTDn?_1*=WWTGiuI$3Kn8-uHyU)Hp;NE?6iAaI%^|rqT%7jL zlCM2JWoE;M5WTQdZi2Oc4HoI&m|?#6=(3s1&AfZ|y)6vjmUz0OEcKoy&-~-Bn&$hc zeBCE+HR)%dWLN6q$Jh70RQ|Jjn?hrH`wT%{={BwfovXk8bx@cmxH#+y_olwCY1`}P zoe>IDukUB&W<77?^-m%xF`2t*;clZob zZRz=$&#NCT{n=6ac;$f-=GK*m!+uVw*t4D^WUn7fqspr-Ia{66Ch33PBkN&czx7G% zn(ZQH-RV0tpD2m-Jie!R_&~|!6TZE(+Bl-;|61~*QtsoNdi!9Hz)#;^{Qj91GVLJi z$6q_tLN-Nl?ajXYe(wA%*CXd|MO)psx_eCJN4n@emtv-MuL`@5uQRoM;QD;y{>Xbr z8sm>XT|CiT-Qiho#g>TIj1N1m?ecz_`J4aW)a3Iky`J9DtuvTY`dwgc$%;&sjP51w z*&9@g9J9jfZg0vGVA%Dm{lXt9$mQ5E|j<0XSc=DJ6XPISJy8{ z(wFs}ciYgezR;L^pTUcz%j@d)7oVw}art7T2$P_T*S7Xu|M*km9{Hr`I&b{y=fm}F zA4{nGcK4FdSf8inHjnx2HTybwR<|uEoxk+!&9o3N5zn&4yc}X-Hu;&nYwB6;?%WS- z=e&B;V1Gw(QSj^&{)O|>!wQwAinH(7^zlj*!w+lIJkIxx+*#XV+%4*IoiEC<{K?OJ zmeHfWs*x#1$z?&{u}zcYgRQ17^*Z!KHt%o3&kmKmiHawpqr~>#7g?k+^J?Q8mo+h7 zGP-BaYX5oiI>&}rZI$9d`@hC_SuZT8->32G^{O)c0%pbY6OB$^KK0A?#zLclO$P%1 zrcADk+~x8{Auv7GM{Q$iL9Ki6^`GCjmKD0C2(opXt^c&FHlWwUD_4u%__l?lTb^1` zU%kcy|G4&cl>n=ENzw6BbEdpFFU@Q4u>SuW%gW^(?>%q(R#k>O@`i6`u{`)ZMf!gt zOMNa+m~*V~@sMvilTZJN6J9M4>9bOQ(IcjyitCX|=g(iYlDQ?F{dBINtVycQj%-7x zeX_B)Szoyy-debv^MA9|-?yupxvyt>ALjBouv=J!+TVFeZy#KnB3J#;dX42x7l*0a z)+8SZPD>KK*R=AF!4_Y8wJEDktvg!re0rD6MdpjuH5Geb-`&xe_&L#pX}P)AmfNB2 zR=2YD@R#njY7kbc&+~HGZ?&+a+p}JF#;SVr#QcuH1M&R#Zr`by-oIW;S$18q#?9#; zysY=c$SMBwd0%y6USZgzNY}jr&$PaWEHRLi{@;G}^QN8VYb{zCn;u_of93wWYyWYZ z&o@`x)K+>Tr1R_QpM-rAHN|Z|o_`hB9WLP<8y=j#x(^?^+8h%3c)87In zx0jKNPKF+3biaDY_2i{y&mJDRH#+{Y?AvX>{Si$rS#BlGa^*wlD=$g=kIsb&*Ni&^Kra*_SXM{ z&6=Yr$CoaU=+FMRW0`c)pQ$1>3^S{1mN>roJ(1~jfSmi0_zh>DwJloDx&IN{_l))X z`_vC#f84RYPjk(NZ2@b1Cak?FS=iQ4;@lo-`F73xmSYnub|l_<9L=^+XX8(9`Q)~O zZS|*lHJ#gprC0uWV9om?i}NR^^1{{G&F{61#7yRG6xdR16z zu9k;T)Rw2L9&MgEk$l+UHpJ?Zl0`RrmR)GIv?d z-&F4KnZI7R{%pOd@Jc@GU$RmLZ{Kn*eR6Hto2|Pfe5D%NUKZUKn>qPosGp-h*E#v{ zZwj75eDA}jn|HRe2fvuUMdZqat&(r-wePb3ah&>k=1=3(^Lkn{|96=hD#z&;{IXNvaZf(urR4{9HLp1ex?)xDLIPxCAjJX3i< z?3=Jlf~*y8=mYUz@!b<{?rNyxZDe3rcHm!f_rlGMldta23HAt->pz?3@S@VC_4NyW^%?bU zy#mi|94C3+^E%MB>VCv;>z8XHKY!lU*0|R~bD#d2ON)0t-jX-xrXs)L$sAVA=_{() zS02cYYj|-WgT?!SY@hVJ3?t52JvFcOIp3R>aLv3Ysn%E!EyI++yNaJHyI}WKzOzL? zGG^^{fAElXQ_Z!5XD$RB<(r}`pd%@AVG-xX8}(8b*r)nUI?JUTZohIxpSs9vd4+Xb zZl%SZTjjXmp4N+J3};>~aXg@>Jf-nk&+P_Bg^3!6cBu%c&yI_$ikfk-;$7~4NCS{y%m+m^olZdv;{@9nYLr_s9_ z78OU$SDzBsS)aZpF-i21?l;!Re+829F6+(t?Kdka)^Yn;*0Q?DFBTCxrZg>m=9-%e zzLZCBs2dQye;SF75Ue%*Eqhi_J?Zdhd+NN zTL%g((YF?xYjO6=cBAzNRbs9j)U99r;A~Tw&WCkHI)9A4d!JNx7MRi2IVtyvNGOFx8} zu4WW1`NX{Tt2m=urni6HwEFObBd@kAyRSOTI&sZeZ4W8EbHO&tOHM~9$GkqX>y+fB zek~txA9BmM3PC|5gh!_pwjfx^s=4*xxxT7V>IK zHhB~W)nv9NFA_-JxF$8+<7sRBz0#Gw%QS7F zQMdQfqO6!7x_f^FoUNOEaQVS=$2aoNPpPf!FzyVP?%1K*`A+J|&Ew8u zt~KxHO!5%8cDE<^-|5OKXJenDmPOS&q#ZLuf-{%R>6{SwB1-J}F4i4vg%(-P%VPe7 z7%G=^FNmvW$(i^>uxDvXqW~B4$)_CKCOI*yIjZDai?6P&RD zX{EWLHp`KdSyer)4ME<2?VPS~wUuo)Je;!O@9d&Eoln;8Jo>_Q`J0NxrZd$&z8p^3 zXuAGiVf5ZTn#cEv{X7uA>h@jMa)p}SkV}`YPj}gGb@Vsal$Z6#e}|YgTrDzm?J{?- zZg}mkQS@s43Elmr>C)2r+~wAKlaJ=lxN|u_exX#(qnmN;OURyuukS^d>Yy`vlNecAE0;bnF1$K2D~ALo8Q?IpyME~%E-#ntdj3pL&0YP+*^DmpPV)GC?9$m_4!d_R^A8%X ze3pGH*lAkS+D*Avj|;px7gH*%!0$fq))7ff*0V>%-dIR+R_->vEi}cdR^eUe%}owH z(=XlJ_}gmwnruJ4?!`Byc0kh zs2iL<^m+M_h8&~aiz|Yi?(AQsAJ7(}&*$mtQ&RD$_?p$(xu!Rd1|&qDJN{+2O2zEX zZEhS@^}TBnYIiKoI`VzR)@bf$)$5~P?h4`BmA`pM{?X~#fw@=Llv@4B+dVN<>gT`Q zVCfm#b{H!#I2^U#qwsTo@uUAYw|vsCF$kPezwvfT!%NFh=NBbx`zjvCGIL+;&3eku z@{9Sl%~HJ#qyDOUzdp~}w8JiLe`m}muNgbms7`R#sp@BrJ$`8Z^S)HoDbqFiAKTqL zaBTMOWB2E4Wjwxp%(-*&_hs`tPyb)DN^dXk6*ZTPGg?o(-#uB_d&B;H;a9y~;tv<^ zY417Q@PJREUT1FW7TX)~%8W>G;l9WBj7is>cXqa4+fwfFb`t+#o%DrQo~GYpe!7-F(575yd8fIMujSM8-M`eY zyUtM!~ z-rH*tyI=i%{U!0ziaG8{%nVQJRsZhyo!`24W9RSve)m7gORqiq?bu!aSI_#gHPVp=Q}v}`h1hP zxajA`xc-CYQymk^E>DSha$K10O!<}Ri?8I$H3zfu9iGy1bjQJO-%B&%@~%vtA=q61 zq)M~u_rjAFC6QAWMnB%j-(1mDz!<$d7`KBfIVP|>ip{l4=os|B%q$zP<_%h=eh zoq9q>?b&H%u2pltKkI4vxU<}2&%_&c1$HlZS+3n$WGr#iM*KMcnj4K5&!&~1%Ma7% z(EQm^G*2)yzdn9S^W1F;Y=5uZ=zRRUG$LE;-<<{Qi z@Vx--^Ks|&)m^sk>rp-S?MBeMgnjek)^y0)R9@Y1tMbtFywx-d#gfa*yq_JE)ZOaewBxq=x2CHG(yPr6d!0VplsJ9;{@qVwmmRi>^?vc3 zZ8Y9Jt9~AJ41#+Ev-a! z%D?uazb?lnF(m6osBj;jyQ8oESevoA&ARG4GMn1B>P%L8by9Kar30Jl4sI~ooW5?k z`S}f#PbppzRPMZAT5YDI$)-~QqC+&aO%9@92y^nn|-;P6FeO z$&#;=427Q02>Z$TB{A^9!U;E0F3GhY-?K7L&Ac4TCU@&r zE_4e?+#)1$@%`Ml2YKr^AALN3-CRD&IeONTk#*dUijBJ)L~Ye6QnH#ZAl-~E1Pv_{Gr~B7(Gm*`@-^PT=+S;w6JL6Jyw%z?x#hA#FQ$v-)~mvJbK%_yl2tT_H9x8)~m~e z4r)4jY?&0dbV9}>|JlmzE#|d-2U=U?Io*l=49!q()H&(z11wO6rbgVT(Vx(!PRZCGF7p` z;Znr9Cwou-xw-tH$hU>I{>-`mM7B=yYWHFJvhqYx@s_`HpL4!QJo2Ta*)K1wsYt_N z`^N8AuO;&?xRZ9`?@s5%>ss^Q6#4$!6}9c#^8YVBJ04zJ7X2$q_3I}ui;rn@jh=^` zo$xYFZ$D~Co_zSop<9^RR3 zH@v6rbM2kSvE}UcCBj-Bfzu96G_$=f9-<@`vbRS_@5F-zMG+6`yEFm}E)-}rIL?1E z^QQGXO96(L-mX)w@x)krX_p57h*-rt zcIcDeQhURzOaJl4Z;zQGeC_J1ZO=EqfATq0?OpZezS~c=G{mDPua~~I_POl0)lV|= zZw00HKK=e($)?*j{u<{BmRt2Zj;HKXYgoQ#5#zHk`3lzdo_+tex#%R-EEK;mcL_`V zGZuZfJlRDr1wK;QyrhS~ZI@6S0XGhq@soG~w zH7*ttkygCsm?q`9HT{3Vu~Y9^f_vlp<6eG_z5Tn&-n#nc^KYkL^uEvD*Dr1wT)&TV zrn*mU9`Bs^Yb9w6@89T&nWv_d)y>^=b?OG4Nh=ni=aDbASF2^-?G{qujQ({yYr~CIEL%?B&C=NVvaLK`!LwJ2?VvH!oXt$`xwi2c zdM0rjekH{JI`wI}UyyD5e&2wN%qt2dl~4YwkNX@ock0!|&?ikH71zucs2paVw0F_( zdyQ{3Wq9>Pm;W$#t~bv0Ieg&QE3FHsgch4DpES~(OLRM<4p68lMwm)UUF8qEUn4DP5C5>*HUtaw{r6)${Dp%_s6E_}J* zxxRKn+TnS}f|OTmpQLPAJwan_sC4Fn=vOZVSl1o?xLh@GwsBDA#q&oh7*&n_J-l$^ zGEe+^aTD+RY;n_ODDcJB)(afG8}LNbe1Y)t;03Gq7Y9lvZ`;;ul-}+4Kz`QFH-DK$ zViTEmEN}jPFGztmMcgM%VSl})<`EIo6Q!q@iQY03*?hy4m$9pcLp^7Oi`KWz%igo~ zOmDkqeQsOPk-uU)pXO;Da}EtYXK_X8wC&gVzZJi}JQQy73QPWdk?cQya?x``<5LUEMazA@D~K8`)6{tW z&urd`78ceC+g``b^qp+|=fkgnsf&Ir@9l_Lpqu|TJ>0Y2@!Ua$3j(uaIwV(LF}e8CPV2nG<%CI` zhXP{VWAoS&<2T9d=Ct^m`SALSk_{_gX7K9%UGnFnu+7egH_T_Pwz(Pb>ZaCKHM^~E zDl_D6Tj=H-*_br(b(iz0E2iB$?!H<0DkrcvKXGc3&M}LBCmto3DObgR{&VV_TF%`5 zLov0gYfJ0T%Q$~7zpmn4|M>5ouic4tk=qY^x^~uPKi_isoO7|)pO>6HdVFHvYNs-_ zrtc2Qn;8v74C7pGOWQxNn$cKU5WmE?R{X@*XLgD_Pi{8PjJd_rynFEi&F-%Mx78lq zTbakrWXftV+2Y-UjiT4j?wG47z479Q=eN0)G#VGz-C?RPs;#fBN#HPyWHXt$Bza%Q z(LF6k**jgL%(~W;Jy$sC)8+e7;L_P0+dOMONKCn2qkUn9 z#^KMVTNdn_ZTy5c`<}mTmPY;h=!9pRUUV^w=bB#ZNIW0BC3Ve~m~yK|?!C66hh7{= zYP)sq-MIsHM_HJCf6dw)%{5a;>*lBR7f&ue;;r*w>E?AW+g856llZs*798x%2a?;m@p$2<5+O1{WuqmD6PQ2nL=FKfTf_K-a zZSX2~UvX&?XX%l%8@j&+WnEjFpFJ=Ai^c=dsfdgYwvgYHhHO=PHa5?z0?j~ zvUXy8&uV6gI><+Ax7f! zj%c%+%G{hT$6h5ceS6cXi_gLw=7>i5-+B7>ZF9ZE>?})HcMU3TJJtI~v29c3xKcFn~tVb0(8N^HmqF_e#q zT=#3Ctnt6p`o8NfTUMNp_#wTcOfTfTIfL+Hhq7lq8obAfrXG3sc=;9Kb(x+GSC8gh z`TNQH|AFPvGc=A)+1t8_>0Nu_;gVHtCNntKN4$vIFPxrnR&pZql(Ij8Y989+W>@(i zrq3p`Vt`d-k!gN8it={LVx5{f-a6K4{@Z(dp?Qs;a`W9#ABip3?lmq}4JeygJAam%UC~YLhnbzt-`Th{ z^GqHFYM**t#q^hXk8ks*Bk%X`+-hoi+Sfopw*(T$U z{@%GE{IjNBY4!H2Nq(VuDzski^mBuN(_ZDBt5Y5^rN|Y!@=Rd;urxiZp^fP_o5YjX zz85|C!kD&%n^bG<67|`Vq8no@5z_jrI?K@JP{&$J`>!eYmakBk%{qT8|LdRX2`8E6 z7ZsKrwb&NL(|r4i{+YOW^MzP*oKIhr>*|kQv99}C&Y7RN9%k}i*dMC|d|eS;Z_O@} zB)+TYol)!YJuWiN|P+>K7mOR*Ibwt--QMF zD$fz{VE*Q#`)Bg!Xy4;be;lLEY%0vUrSip;##=8V8_KS_PAa)P_qbQz(WR&A7p|W1 zTs37=Vg2M8M`f&JrZH7XEn|y1^x*xb$RBUK`tJS<{&Dr|O`c_!cIvu_Y_FXhzQ;ZL z;t#3Lwq}zbO453NZ)Mt)&TYQ&=cMkL|D1AjzVU9)|0I3>+q{+wuhcW9%D%twRNeF8 zX1`_YR!dww9L!;*HD}3nrpmbIS%wYn6-$N8%68QBug%cssNdUsV5znI>z^{&??d%3 z{!^cS`m3JM!K-l>lWPfyz{r_Ttf5Y$sAWI zPq~&GPLNFvIzQt;ZhGUHof8*VaOW>fI&a5+@M>%YA3y(0wVan6$6aln1suDeP$vB3 z*Sx#~8>4%UgwFc?`E31#`q-=|R{E9qBHVCjm+*3n|Pk~7#;UpcUFll zyx^?T>3ge#PdWT^UAO4;!C;FobAq0x2Xe0RIJIi_nar0l*^fEG6N+a`yjV2-$jzD2 zKlWyOKFvw2d&j>pqgCYT)<@6x^xueC=d1L5`B&||O7`EMUo}-rwc8&z`<~2%`ZR&d zuaAdzzq{-C=|iQc{N=oM)T)%U|*HoOu$bBp3HC{wm~H(9c`+FSj!HzN*vp z^Jlj-bf?GuzWMvvglQ!`#V=Pjdq?>(oAG#@zOSLS^^5a*1%}(!5mwc&m;-L*JpVg+ z?cunrS97CE8~55dH*H|&HVAwg^gr#L;L&gOUk@$vJ9y{xmyL=uqQhHHzi{#Tp3Q%b zwQ#}CT&_8cj?vd9=R0bg3ej)zdOYu~L}`)FvGv-FP9i6td9W6}?K@v{@MGkAGmbpg za-ToPH=Ft}Snj-^8XG=|9oZIX_wW zAIrp;C-q923JaTm6>QfpeV5#IRb0=@^IKZtE{U5rTsm&;TK@Ffm&Y60!|Y~?seC`h zo5i)JLPd5`;;cy}%NPs=X6dV$7|CaR)Y-LoU5WV?A&wBrZ*nTb=*JkaB@l6x}0-tzI2riJSk&08CL>d``_ z4Q(m^61L2papjg6_r(Z-{0}D{T)I2MNqP0r45bt17E^L}pE%3&O>F+E@|UqGz56$c zwRy%(*>drI+o{0){~o6 z95H(CQ)PG5=H9KhFU%-E{>WM2G|P5#Yu3B<+YX$*u%GwZ)ffi(i5w4gE&FtI5?@Vf zW=vMgJ`_27nZ)Tn#{~sV%6mTOZPQxmv8#Sz*MmIvuq|6#ABFamZ9M1i=k2y~Q_9Jd zy9?&D2l0v9iS6TMPL#HPEiC<~Bxj-e<@fu}U5S(}Jus;`i0!b#nU(E_`)Y)FYO3;> zJG?R%{Rwnm%(Q;N%Oe|VY#zU5qTEFh=PGPlU{hphYoY$C%9X2n@FmLMJ{BF5t!Qu4Guv7dJd$)#`c}`rNu;YS> z_|b>X6ORNPWyvf#;32`^Bvfe0#cUKU*#ElYdX90Q{zc<(^TX$@)~^4SV&}Bxa>L9{ zk+sa_tFChDmGrJ%IaOg|W$Y)1?ez)wV^lfaWji!mCcmrCyJZ^hyj?@)k5i&%81HMb zWBoVZZoPCSSy0lUBgsRxL6v1zxM{|p-{w;DMKfP?0TJ|ee&7i0gkNzbUew6!M*<*e<;QVpx z%*92)eJnmlf=_7QIX30=jTUbvW%WB9>rPx*Xu0cI_M?ll6&cTOQTutWKH$x&Y|}rl zh1Y+&CU*K`(t=kKR)^PKvbkWFHo5Wf){u>d!c3yoc_e-F80~ehMR)yoQkXM$>VxWS zTE%$u}zC zbInxo=^`wLkETrW`@3ySolEWev*Umg?Ny(mTOJ3PEte*BFA;e*=&HPrueOa12U6<77zt;~7 z$)9=K=ZMAP;)v+xn1&tJQ99rE-}u~Pb7gws#tXfyGZwv@+i}L^{a>NG7q&36Yu|jz zuPgm*QB}%k-9@r82NFxI8F=5a)%mb9H3kZ<-TZyI_W8Y0p_3lYWYaL4$$l~IvdITW z`{D@+*_kW(1Z5U%FFz|O)A2Km-R^41iF)6O9eKAnByHRiZO^#`JT%qRota;DCgaKV zj_QEWoqAO|`$}hBNo+D_c+FgT`l#yl3)RxgPCTvd3t+l&;`5^goZlC;*Re-_`R=^# z`P1S(7GGFSb45%jf2QLmdARe*pYL`;HTELg>do0szs)(T^t|f*lb_QM9)JGfl&aHR z{|lZk>obnV{$P0Hu$KGYt-$M_gf6(>O)mYRZG3k5D}%$F%=-ElP36_*&g2rm{Fl9X z`DTIb#uo4UA_{9iJG?mm{s+H^i_!Xb$$!e1=s*8GdzWu=+vL!x3NjnHDgsjP>)Bad z&KLG}cheJIueLjN|BG!d+_$dZ|DN&Y(9XF2H?>iRJ(k|6Z{K;=)olI_PutzxxveYA zH@}+mRo}Y1XVr;v7U7VkNAs53`E33F>Qtbk-o~74_3t(hb04QYjDDGO{gt-&3(@(m zug+arc_&fwLRsUDgA;bR`8ZB{`uo|;2#bj#LY`}0$r)stM!t!==M?Oi5$Z6tElno+ z=+Zq?Ig*lg+U<6+SJ+a2v&fxo>a>$;T-QvWW-j57$$Pkh|JMY*YpG&l=4%$VB)ICI zRyb-CuCesLWB3NPS5+7PCv7})ylq~L*Y1fk=VYzh;BD|lg>!Fq)V@`XzfUL~`TcME z9G!=a4sB|N3+^oo}u9zQ=m)OzcWRZiPEar{1dY_~ZKdnU4H| za{epL##dGzUh;Z!R=1Ae!oX>g=A5P4?)+DLjO5NWg&22F*zGK%n zse48J4bK@yL2J$DpWo?JWwgeEd6w2Z->kygTNA%Ok=onH_vKke>ZNn#A+vY{)lPDI z@W|D?T6#cbb$WWjryom|HvOA38o)OaE;E|9UPB%$L{?2ofis^aV>6Rs?>a^7~(NB8a9gQshrygX2@{4?nN zccyzC#Sij@7FdKZ&-ltXslBx6(NvGVXW2_wF7F8rd2&a(E3}PQy0S1M-)voe+acLG zldCrUvfg`t_FmUjGWF?yLlb8fNp^l?+iSdBkvYZJGn+xix=Yul_4~KCo^?0v3^Vh$ zq*>~y>M31~@HpD@_g4Pz%Gu_JuPVtgKkn{vkT|f!vCH=LU%{opdjFDA8<~GTKH+3s zsA+VAJ9?wi&-c443oP#4Hr~-%$bK)`^5&^!Nm-5fuh1LwFb4tudGDt*e<u1S zR?}G~tn(+u$y2=Ms=-n-EkTaBh4u4_F9o_6`G;p&AFlp1%`>#(dEEr5uVGqBN3O3f z+xGT=bY|LN6XLv)^j=rXQ^-E~^aBe_em`KgkWRh1);{T<==jQ>%p&IGtNCepRX~+{1uDeSx+8`2BihhKV28z z9dm~9$Fa|Xt+#)uJ~H{A8ur2d?la?GuaYDVFUeIo$y6^Kb=+>T_nKqsH-7)!cjokI zp1f-tt}8bj6PXtg@=|<5`9Ghkn9Xmd@ab818YOO;P|v2{DR2Jpq>^mfBl%O4i&b@O zmPFYqc<=f1@pq3eS?g78B$Iy2 zCs8xVYRZR_7PoALmA5sYo;+1_^GJn+_T1U|ojc$DIwz_4-&kpR)ZEj06l-z)|G+Zy36qVL{A7VZhWR-P~A4=vu6}%?YB$87uRmD+$8s5 zpWUnKs>_o<|MPkkzUcAs?%5Ka)|mzuUtB!opVIr*ZgR+5%gi+OsW(?B^G)dW@tYMK z_10_k>;uwnHN0QHsB^HLagn>IBRTbJujV2L-$nlqvrM->6!UO4OLx7h%N)Dt<4n3+L<#Mw+JKsd< zJszcRub%GvFW$~r^_au?$b9a?fA@Uq?IfEQmw8z(KFB)lqo)whR)(O|xwgJPLR^#% zu2EQK_wP+QW!w_N?6&gz*Kf0@N%^ZTZ`uF%ui5#P{Pj z{vp>_b<-fGu8u9c5+BA)WzT3!Y^a#Y>@hzzrEO(zf6P3_26dgEzlAGjUYMEEe~snP z{g)!F9oIS*iE3RwU1K|2h~uu=9}wJhFx!pp4QSl(>&x5>ozvsmAsR+ z_gOWBtuW82{pG!*zb;U8!KIpOjk6w~JFggS6uDDu4c{5t8?`2#56xcg4b8I^i+N+B zy@yw3s$S!pLw1*UuYD}7bGk2rsmM+1LcCGG#8Qd7TjKBMd^K$jy0w0`A@?dp^ZFCt z68%)TpEq7PvVhs_ z!k^A(9cxp$f7*xcTqn6F{bOg+qr#~|riOCL_f>EFs`_|%?rXPtsg*q2p7CE|JgZ|; zsUr4AyCH+OXvcr8J&!jYvQSztDqkdK@Zj+D*5watqYvJE$u2yH^NO3=B4+6;Er4)5(|%WsiSpI>f!QdGbFj*Ujh>q^I)6<#V&&cPdi8f=+?2U{B`#{O;WZNJis5}L zd4WTu*LZ@4v;CjRk6-WkRkXNoo4)K^3mtR*u=!_Y77Oy(Cfe^!<6Yo!nX5>uK4Jmu zua(}X-z;;sdzrXi;p+>P!d;UiCNodI!MwKWkhAUuF7^qxrcKk?#FCy{W6JrBY0dhN zAuB&JUyi(4=bgI#lZnid%!wkawDrGEv1D+I?YtlJ)OYpy%{D#@%uNIJ^v-05FI^rz zbLpBG&T6X(%pT(1EtSbT!c#9t_odB@cVPjrFdiL z@5$FZEqVVmEHl4$@c2rRxCedeJYP?TUgFhCmoZL0SbI#eJokNS&oc}An`chy7WM^A zHYAw?`G{um)WSE{_^O#_5FWbe!Z+~_^Hw|?|wbUU7rKrbeuddYZ@Le zgo2T+v$!{?G?-DG{`t0$d3Lo{oVhKg_-|pjn-?H-a;?V!s95!A`xRHO0Qzta{ zPuBTZm9EbZD=s^2;@r7%M!ozglj;*f6)BS*XKEFF=jmIWK;e?X*vNC3b1+`vBER6I@rOh`O@=n!4rdkAfucozl-j9QTBZ zDr#)(UHULiPCj4p{0e!`4U>2M*&I^k@!!LK)$4n$%O~`eu0DBs<>QwN6iT*cUpw}A zq35AIsp5cTj4#>c-YBtf&3!%R>>bnf?)j<5&tGsZku96WdY!R8snC(zvD4&V#Ilul zoaY@5y!y4cfBp}{&?On3ubHFE*Vivz@MCc>gUtiN(RkSIk;nCf)26bo#B+l$UoCGPn3|iHbX&5PMw4=j4SCm3%c~*}t@3{VlkC zWKYST6Q&z~v4xxPozPz4Co}on{08^-koDKv@^9^m*j|`-;n=21S+6{+E6dg<)LZ>` zlqfe=`gQP|`mWYjnM;b&9~W;aWo!t2X zh9`L@`0zb$JK=8}*S5JV^43wEt-VP@RrbCL` zdS72ya!FRk!{(ar5_8dWy3&h^|6b6jds7lHM`NSHwF|%g zn3uJ(KH{mLd+qt2kL&DaWV*MW)#-n7kNMwEMbiXUqyPW*vgR#q+ICYpC2-!Qj)=NT z2~+=@1aWws&8S^{R8UnW`RI=@v;Uj&FB(2Dy&&^Me{#euWuZMGHEE^S^>*G~ef{aa zz1AyCZkIGk#5Wn=IdtlcUd|a0yIUcTZgec0n>Z_NpW6cwC;58ES79F=Lz&&)H=H`X zFS+fN%D>;$>sJ4{u<*(~l_xu1b*%j^`9f#Cj#EcMc08-`y^9}}s`65&ABZs6VxTm` z_DL_Raa`|{=BPFS%^SO)Og}nxz0ZS=HQH9kYFcOS5#`mXGvvHv`{R&>g1G2)=Q2y@ zitq7TLT9Kfwe{h+?DMgQz25uf@tny``(=Oa-1xVsmz8n1SXWB7iqX`-+dw5`@e@*? zBoxF7EtNK&dHn*X_wr>Mw|R4lwA+WSo$Py1x@%&PZ~bS5b8BTZzhBuCm^t-&{f6lV z#-5fNH@#~zlwZ4Le@o1%q&0#kJfGj=S?cdHL2b3|{xuS(EUqT*d{(+!Tuk!u@y>q3 zXZPAKbHPGv0cO1H$mmPPFu@cr70(cLSy(^?3TW%`@`TqWnI=Y zOO4abGZq~A&AWF;7nGN?wIAes_b%_?-Me=c1!9_5)FU|F z=^f-;*Z3iIe(kGj^UBoup{ARz^{?Jl{cC09Wz$;rnCjMQ{YRT!H!>#f{c5=F@wskg z@q4zPuIJWEF8eC8S@fb1k4^1Ome0TRD!tb!%rTz6$vyMt?}%zOz1X>Xr+dAru!?C_ z=Y0L>NxI7UPtziouju94uDVt7hWOUp@`Go~z6b5?_{CTixZ$BK(~H)RE;l(og*~g> zYJc$!OX1XUCNfdoa8_a@19axuQP5tbwC}!Mtn#)J(4M zewR??QuG+`hk&|K>f?;0{4aqB9}8%68ArheLefg6sDsY3J*eqlrM!avaK&D zP=0>u-1$w?-`gU0b>^jKahM)FqW|Kopx$oF5344x*7ln5I&RX9A5!!!_4UY!^vJ+~YuZ-&FCmbIngvy$njlR>AK81AO3nzheZO9mrnfh`OThheN_dkjjHecN}A|9 zZ{@8(`S5txs_8Em%n6!ZWc*rV-^1q}Z<6&6KajhuHh1%frd=nqzdE)sT$|%oF?|`| zqQhcMf!2Gko}Bv6&wOQ9SL_7$)uD&K>->(@5Gh=Lae2qtxNr{F_^Eca<=?mX$@b3s zs_{N^x=ww6#KBOxgI^cDIeV|>$?=4~^ix%5oK$B;S>?Q2W|Yk(66G4Sz_qhqYtgEI zTCMB1KVYAFfYG}1T6yuDYUOG9rw^)5^^B6bWyh5$`2E61-JtDpE1u84!>jKRceQ5W zT;6p}jd_;r&bR+XE?BwqfxY{Vt-CfHQWd*Zq_BH>faxauE9~C; zO4p!2MW{{gl^PqNBX@WImat3xlE`RnwiT)1tsHgbp5+V#yw z6)%Ilb7I2Wmv7@a$x^QKW6E^NV6E2GvCChT8XbSm+AN#XU2#aU^>D-vt(+4gvG>jf zd|Q}oc0kBu?l)!a-r9W~hf>lPUjKcv{%h>9DE~ETr=-iICjQ*>`S_0a(Fb?GH!FBH zHLyskXWp(Kk*w#Prb_2!LtwCI{=O_v=#^(GhIU+*7vESY=1zujMkS6hnD z`5JAS^X>Lezt>zHitFvlKlqu8%*b3f_pFIsNa!lF6M8bAp3e|GnqG9jV!OgrtB0!A z^WH73U%F<;+QjpdCqB0AT%0sBs`J)~srkKEK6k`kHqOvX61M7_F1VFj^tPxe>yMi& zbh|ijsyyAs(DBCQ{F|D&O9ZBPKh@eN|9NJ9b@t5p{-#Cxx9-ZN3ftbj;G0wv9i8tP zyEbl%-IiJ5D`%fA7Uei}@__BTbpLlR9jsO6nbyg-#j4bA4y(+$bC&!0I`ysUa@_N> zwpnd{6T@|*;m}P@sg#An`$`JAXE$%~xU|Ti%KprR=#@6r)1215D7t!3W1iR6f?p+7 z4@3B(`dxM1gAboq?PI(n|KjFOS6Ky)noW_@Kc0KjzH{q^thMc}*LR$K$Rp*J<)^-q zdtvhKMJvrKr>)CQpHROwtKmtB#;?5RQYTV9EYnxtT%-Q(w}nTX?h4C(IUTMwFOKS( zv3*l|;Lz*a|6z@G{Dy`O-z(2O6wQm=cD+v3)tSBJ3b!$<_rfWeE4PMQG#CDu%WSdH zeZupXpDislO6Ga!KHD~V*=_m$MPZZA7+0;8QMT>9qP*FAhL#OK=g$vM>jV0y8kB|k zv@B|#XSh4Ccg50E&*wiE>SRc{#aJ8idw$j>6q&bvH1X6&8yiY4avhS1A# zyEm=q4>j4+$v#F;AwJU6*{~ z*gT{D^tW|ux41Q3z38gHU4}DjZ+pnOb~fj4SAR%wiGFmsb@XWG2Hn$tdJmVqco1o@ zA?G)1q59!7{Ory-DrcyFrRDG0l6 zASJjr-E?U(=qeIhP7X6s<4YAo)bJP=4u@mw|0_Y!0f2uSvdbe5PQQ_nf&uc@FsXP4~F; z%KSm!uVnd8rMX`|7rs=Q;BIVn!`ZCu+15V|Ps7VLcKp`+nf&#h%0aKV2`{ppo=@CU z?zrvAWgYXmwO8ElOskJ&4f~{MBR4zZ*0-0L$sc9^hWUPVC=v7dw^+J#*_O+mEZQ+b z4fAs5{quP;DWv2TqtC$SZGtOOU z*z?ldLFWCR&kN?P^$J_BQ=R#DUt43fruxO^IVX!&A6$?}KkL3^B*sP#Nu zxqV55rk_Dj@9CzDHCOr^4E$o}h)t2H|1+i5-S7_Iy=lu$R!%LZPp((| zii%%Z_dDmkzIvu|x1ha3l)9Z`!d8xH<-C8NT-~wec*~;VO{*5HeHvT0cE0=#vwbs9 z8%%X}e$oEX@j*w@VPDU=efOktbLXbMKF4(R>DB|&cE`zH71?{VInRTA)!Z)vH<|7& z?2gW>zb<}lw(Z}{;>u+Q?%d@~I>!Hc-`$SX$p&-3>82lG?de>*CiwdrZzXS76>xjX;fw;eyNuW4>`xXSc(XW;2KfmZ+LZ%+OxXfWaR(MKtVXY73& z_2*G%Bz~2X zS%RbEvA7b~ls&tS{i#%Rx#Ux_O{Rf=VtdP({DTVJ8r&a+3SY)(KHRXyM(pNq)eEKH z6U_6ICSEym;OmQd&sHo^B@Wo2)P;btRz}GS>s@Ijt?aDrL zbKY%U!6PsG7aB@OPuuvQ|4~ZG5}sE}Tj!p?!K$=U>)LhprqJej9-9_@Q8PC(EWB60 z@9Jq27kQh?Ti3Ieo;c8~!q45_cJbzP6@9~v?8SH29-gB5?+O1@jbu6F6-R_v@2BR+7?EKU8(=eEtO5@#Sup zzIXB7^yJUarEF~qlwRrYm=l+IU9tGx*VY$ROhq}YeSJL(`@_#J?AySV$Kf*VDdUdM zg-!A;R~4Rnm|VNZV*1u=m1NveUm=&v(;iF^oh6cNSf7zBqU5+#EN5BbZlNE~Dl}YH zT7)E8NN8U07daVuWW%hgs@w`gThr5%*fwic?Q@LzWns6aJfl%IFa5{{hrnO=79=YL z?&{sNQuDL2`+nX%eK@$y;wCPemm%6g8=H<@d9ON6eAV_FawURdeD!lqKd&jYtkQL-&=$@bOV8e|vu7Rum{cge{OA_nvX?sHr*4c#xF*L>jGqyFP$kZ{HEz(9d8 z=S^LUW0SS*+;y}I<#;~1ul%*De#sU`iL!2O*U#6?7abGOuY0Sr>AA>3{@WiL!+dn4 zQfHl0j-I|RZ{GSj`jtD52`mpazjNuh!LcLH%l?14yr8U7KfOY^(DKo-9Ltx6bJGt= zJegxs6j@?dzGe){gtBADf9&eqMi3 zw#tKVF76SJe_hp^aLn_U&)VY!*IDjeS>}E1aQ&5j@u{ocGKSCpU!b?KvBg~Rc+7zr^E1r(ah7Ren+Y>Ux|&(CHng4^F)ww)oNY5Av5p@9mTPYr5^3 zldj%MuusX1_Gn zs9bpFjnfnfsj`cHi3MlE{bxyUs^mOzcc-_M^y(?)CeMR?wq1Xn-W_(p^jP}U4X2I7 z{;fE=*ZGyZs{9XAGoOV~-;5$21a){yEdQqcZpE|hi?kkkss?b>uiv8oFy{QcdHOMG zXZbr^UvIGf{4QBvW%iMv#3-dY`N~Uzh5<{Z{X8DIZ&}BF(IL|P^9{+q^NX^Y=2k9x zBd}`f+}t2fccB#iS54X;&o&9FMmyAVt^U@{(Y9HF<+kT5;m21VlzTAqP7>*E41VOR z^t;7SUKg8$Q*cn%Zds{ z3tO6UVZ->%Bgl_fd6ySFrBaan9C&2_Ft;@D%S8pOSyS{$uNu z`GR?hE*e>@+LbIO-|38fR@TBNKb!Bws<=hcY159Xe(}EayU#IW2gjw96*_hc7#FRI z`cZ!BkN)3yIo&09L$0q2OMiFm$p*`J?M5Ly%=LC9?5Z-#dQZB%67{`UA07YvcEPDx zo;%K1Z`}M;NiUd#{am-shv#$jKHrdJ?OR{ZUC=FdOLj}0#+ws|^ABGw+r`yVCgEVa zl3|^4mV&$5<9QQRBa%h+TGbwCifN1dV#;{1!t_>OP`foxr0|pKyY`naOR(itFBkag z#_6E3e(zJ!+p8O@{P<=XO^tsMv1hJov4O!3=|9WPm9snYZuAr>*PT&+a@k^~pRZqU zbiLkrqu!;#V)?%SH`bSO`>yqze9CEOrM&rcLsiRKWj`OQTKB{yo-HN}hZoDc6YYwPe94(*i= zV{WfcZ{?Oewmr#vrIVrJ_FJDHX{%0l+L^L6_E1mak7?)Ee|8VwGi6h6YYg`WtLDys z77urNN9Qk2P!ON;q;0jf_uN>KDw?i$lO^yZ2q$dl~(ON9Ebi_ z30pM_OeJ9^ZTzfL^4>yMX^-QC?Th6|pU$GLpr*d!BOzvbuGX%#Cw zU!So*Bx1n#Ugb6C^QVSv^)9y(b}!7Vs^L4-75D7!yrf?{tploF%sO$&Z^uv5%^xyc ze3RDy+rwgIBXulDn%%vfvGLDJclO`0>+?L{PC(dI|JKZ?JK9+9+7 z(zo8xr)#^?VbLVL8;w!(Cx~EU3eO&Xnd3$T*l}($kue$o} zv&`K7^JkBK-aeye(anQPZp{i_V(8{pFLjlV?fjQjy2p!_=hW%@Y71*G?yzP|Z}H<~ zZ)E*j`i5na*^9=Y@BJ!=n<8pnSSjeba2`D6u4(n~`=N9t=dWAsEA2Bs>YL6ij^8A* zV@kbb%liqAif2FXf1G%mO;qFkqEe#{^OO}wzq~zRk+$4Ve#ckq-rE`xib7l6CeJ#= z5%952F>W){TRDr8$H&%~iZ8L;x8;?t#grKd7G=|`DrU|;^wx?a!D~mvtXIJ^!mhB3 zOfTa*7yhs&e$wwfEW5r{ZrGircS*nXi#wO#sf|zn&#OOuUB6gs!x^{wPnQ1kboNQR z70#d68qx8lGsf|5U4xWJ+~;COKBdF^j%w|Ea?@R4d6`4PA7{Zg+cVUk`Yic#=d@z{ zni+4ui7;gf8LUrVq0qFvwSBpbeV2Z#UB9fD+xPd?Io}sYyqbQYx_(T$WGP zq&~|Czmoef&-nMx`kxlDGD}}ie#)Ayr8no%0;_@xp^87J6u&OWaXozP+AZf~lc~l2 z9IP&G{WByLW1C;qY`24RQ~0*_w}f1h9`@JMXlABOR1JTy%SjGsp}}&>?ri! zu2yKW+WT|wj+}TWk-lg7wXL^i)NeWPQSprQ{r6mcn`KJo`ED||)qCq2rS*OHR!?4w zpN8%Fn{M?P$sXRMJ6W?}W4NNHXuX$QEBh-&{;SKDrYb(INaHmKQR7&=$Aew((=4XP zy|pv$iCWp+TWlXx;8J|!Bm1hSmVU{4vKQwBNR~F9DT)+-GWTCW`pK5xFVoq+W@DH`Oj$*b!Rp&Qh11{6U$azU!9%58wVRdAo)?(}9AG+K zzbrKCv*7%V?aG$2uP+xwN`KxIWO7D%*XC3$J{11@ z!Dgdk^H#7=wC_g$G!Kpyu98m|^5(Hl{a$irvgZ5gv#f%y7#-yIp0e-aRpBpR&PIJt zS=Z2ap{w~A!-J{bhM%+KRV;&_X9=jE_cs!rb1=QWXbFqn^0Z5peXH)33avY8;J>Gl z@mD~Fl*Kl0m6zA=HNIKIu*`3#ll<&BoAko2AFXZ^pGdHs^Gtg>!_ID*zKi=(V~5SB znG2NRacIAn8dv4AZQTlQU=zLNP>rjz;WsC!%GR{rc*>g}1SHb4Gs zue?AVW7Sdv$NIZdKL>j#l{`P&DWcWxbh6Vceg|)V^5rQDr)V;nUz=ciNaEoSD>k31 zbH3j?qs*6l)$N=!v-6S2lz%7dr*2rsv^S`->90Gm3@TL|LQ~8%UbK|uK#_W?tb+_>c!cnIlWVl zeC(0mlJIn)&as3?M=N{|@i;BB;ozwFUFx!Yar6oGoteDR-o?{$TDX2`>zVy7k9bml zk2~h7+p8eoOJ$jHGZ!(dR&0$w?vWVyeZnJ_6e;gxC4vVZs6U;PYI^#)`q5;^$?q11 zyzB^yo857R&zLFc_&z6oP z@7H!MG`T8bQLiDPrx*3-*`>xK?-ciJT=8Z@R&sU3hSz5c^1kIvdMjE`rFSy;VUhE> z6@909zb@V(5MOchQp@dg-?thh=5jB$GcWg9y}j+aILwmlWw~+Q;4Upo=r8sBWmWf)b+c< zcJy~X=Y6zZt3Oik0K>l(NwG!`?q#|=zS<#kY5RdU>R)djm{hn#v&Q{m;`gOW3bOB4 z&EBB#GTJgiwe%_PsfO6|jiylxq#qvL`}#{{fmYy7J57@b`oFn0o)<`ebz7lx{~{H? zjUV3n3G;Xsc%EkW+3%8g@n>-T3Z)v+#!Ka<*Zby5Sf%MWMy=Cp{&!aTZ|>yOccr&y zvA)=S$6Hj%bwiHjrq2@&uG(f}rMjYqll8A|#zp&0U9%f+&v|+(sbbRP(|fP#tH~Ta z=H2BI#rYz+);qtse@%1w%>272F9kl4Ie3YwO2k7^Y0rsehP-MwrtZo=EU?4J^ zq}RpM^q$Z8rSsbTq~3+D4QB;j8U~o`o!3{k;o`4=+d>UTChq&2xmuTRsYdAqT^`$< z(Bo(OPdP2gjo7jK#K{DMjg_VBVOKToerDz4^#79FThVB=;d9~-S3V0i(Z1F9Cy9pI z#nc>Vc=5X9e%sCUou)hHS@{V_G6nJ><8E??1o?8vt79Shc8SmP#? z?HF0~H6yP3xFqiaBl#%KrW7}yn~Gj*)|Fnjy}07o;}Z7_Fv}9>7V;xyG+WHtV>6nryO*6@#3q1@H){qHuk?5F5cDC zuS++Xb<0kz{90o0?gQPdmgR{}CK1;PIi9x75?WX45FL5Vs_2-%Q`5pQfAO3MiOH8| zm41_O*(s-O64W%4d+L;6i>-}cHhgOR+`p;U#WefX-^RTuhV_}>zR8>3+^~PCbkEhv zPCWB_PPKgu?M_iCSMZR(D+qTx>gaJe7 zia*WeUC+<07y4htBBuJHe#Jw<*~t;JKJaNhx;$^|oksojr|&razPnN=?rmg6%&HCp zmCm%|9@!VouAUE`)$Vlk^j-!hrKCqn?XryWXN+T?v#}MubdxpA6D*5SuKQcMGb6{a z`sk?%%RlJM_xa4qw{wwvK;He`b40HCm+hJGy=GeLx0S5A>*lk3FFx{jTCqj_t|d=i z7i|06$#-7qJa5DHAHjEyKlQL&o;S@g_)7ZQ$#W$0@BUGvq z?Zw3pZJHsmtGKmUC95B0aOQV?D==&I{S|mmp6kU2abuIE-P#R1KX<(A>fN^e-tKqd zI}a%ze<|2}Q(%H~?Kz%JJNMh$U;oWxod2@k_{U1gr9bC2Z(UrmB~&S}PUnl+{_{&} zq)$xR{7#3>Y?qw=Gj*K~qbv7w<+n9#e3W^vV)K@ur{6b8i7-07Za-e~Ek`%<@tuTI zXL6SavYSYMPFr|g*#GYLjYWD-cj;gA%xP(=pXvH{S>8>*%E<*`M>i&QPWnSU+_PP=G5W$)YCdt07= zzs%42$i&4&p!0^H)q)a#R%xe0JrDB5ZhYT2e{1kwhfg!p9AxW-mXv;8$Tw|y&#k;S z&h>BJ3IFWOvE*E}*Yec?sn0Jj96TcTW5(?-6K4MoW_q2mX`SP3zjus}Ufq(LviP}f z$2OiL;`jZ3b1!&4WoG`LLqSR>mY-Rwt})>sbGg>tu5 zKEHo*wq7>j|L2(R_kGfhqm7ltjn&rwzwzW#_2g{3m&+9YRrUYazj9Iiho=JdkJjqc zzmc7D_TRRZywzJ2mdA&$P-JBI5`OJwws)MH%!(CUf1+1d?|ksu%!FY>6B9$iz9yrE z@s3&!ft;)gljpv?AEbPA*85%cv5h}WYi_JxA+{uZN@L^Hy;D~=9<2X&?5FJFrc;q; z|CX9D|B%ggsBN8TabtFLq(S6viyQxSuSuT>xWZb`$`F(E$1ch+W4&Rz`Q`eot42qc z-`*R~oYVW|_@BS#B0ZnEHf=30-u72LQ#!2P>)G|0kJq!m(_T5_!PJ!Wl>F4ZXODiJ zx7||zEM?B$(x(#t%KPShFilT=nDZp-X~O$Y{%f6|PIzAW=c+%)lKbhc0w=T29lUbp zTmA}rajjpgoowq>>Ros4_?I>Pf&vX67ZoBrU z|Ce}`$^ZQR?^FK7zw6G^`7i$8dvX7I;r|IwFERe#vFi8kFTZbHmcJBsZT`~x;ftm` zS+L;0ZTknt7aJHHs$TB5t5XgO%TxA~Gc(gO&J#8(^D8U!;}eV1GcGGOE7l8E77H^I z7K`%}p7)&=P5IcS zK~*6C3FpM&og{L`J8o8E1`JYwD4l&!PQZ%VO_ z)|=DoaCfa*RD%WEsrUEyRQ*@}v-6&=7}LYVvhC|KHb0%^Z^NrPGhqAdOYeO>tAa1x zo3h3{^}=kUH@=cDHTUM7+F`!*`8RdfEhkz;0+oe>T>5=H1YM03T}@85h|~wF3J1AN zuVD^ynd##pm}{i)_3N!8hr%u$JnBc$2q!blO}p4BEy?`iOLr5K1oMk6 zJ$`?_eavHeQPS(jVVlSE|9k!a>;He-|9@FyK3`tZ%x_;z!QFWQm;ZgcyL*29ugDGi zA4YFnpEKuuyyc(7t$%F_>!J>bh31)A*6UBYTf-e4_I0A1VS(zA`C=P_RX^X{e|qma zH~nj;+1vHy(qBJ))TqDhT=J%QsxRjx&uE&aHyr1{w&wXoa|1adcRnD7TXSdZn zd6~7ney9DmmydI*`4@2W&E?zwzyJNce_!@~Zmcg0J9&oT_glTz{^jRZo9F-gW&2%z zfBe56_J4P;&i(Z;-af`wFYn(k+3G!=HA4UU&&%5{;s5-^_us4e`~UR*$=vz(;oo=q z_HVAue>T7VPvOhIxnEcK!N1dB2z+^UYJ&y^brt^gnawO|G=3 z|94dv?`&JoTJ(JR{m&)k=B0HW&!q3&_1>&ozHRf{IsOY5$2q#+{rBhg>)W%p&z)lb zMr`McduNNbpWE@^d*lCUXP(#8-_}js23aV=O<>qQmNS+qf-&KO8v|olaqEIT<^U& zbdqIe0&mab>wb#8tr2!DvU_jKT)pr4;J+W6_hqSPzuTVQ=eS%oF*dm){@n_vn7(;sa^y@)^-g4D%o8nO;+?0?El?6^F>m+(ytHSC;u^iaWiN0-I~WKP9L8aGumHXJ0;OHV$;{+&8Lqf?z(aIc>>Fa)y-Y9 zSIf0t=Bt13uV-&*7GvJ{{p*&=mwL|5kPVtA-`BAD=;I)rT^o9GTT37P(OWj3YtOUQ zm6J*zUR(Q1bjcj6o3`ieIJjO&r5|1Gx;0LE;l<6a+gP~YzI(de9dM3uH^g7soO1%<`~|-(|oLB@6p_n z(`7sVD3nD^x0o&V;_sVP8;bef-YGZzzh%~1#+`CeOWsR;YV0k#QIoh`n_bQ))z1IG zqdz+u<7Vh@PN~z+S#wDy`au2KgY{`_o$DuGee>($ZoU0wVOwX;`ZTA_l6Q~I^NG`! z8G2R<{$kO&Vsn1-1fl6ga_)|Tu2U*BeLY+@A9&nyG*Rx=wwl=K^R{ex$0o7I`F&Yg zx=Q)-9IuYPl~QS!x!GbCbbHHj|0~?Ty!l3zwdy3Pe^hGtmKR&PGy{vG#{9nm?*4WSWVaLvI+~^(`{M>*4zh7bZUGC3r=~a{C7r#*7sK4v| zar6CF*HsT~HUGG;pkwvTn=Cx9+ceW&pZ&J&UZ~WJ`hD+qFwPKsd5mSvTb-vWq>R4a@ODg_);?BwAsewPrdOVjN{hj%@Pg#nG zd&*&l?uXZZx>=uQtY4KGv^aM~*vr-Zr@ylAYg_m-s$I z3mLQ1^~6x<7M+iBToP^vG9{wvG$`cio)JSXa_Fw{cRIRbPTj zpjF{{r6iT^jLj`Um9^gMyJgeIke1fT4!cipI#BE_TKW5Q z{n-hbhuB_pEl6Flj%A+tmmM{S7PPN>z%gUp8%@2X+8agY*6b>77jVfwByV!|j|F!` zm3%{wX^k?Q+poU@5(o9&HtVp+uayt^5Ga*WV0V1Sg$FZVG}Yx#n|=E=kJg5*^D@`w z^<-FYHOza__4eWQ`Mcg7;osfp>J{q#eoDlz;^krW3mq?dg;=`>oNSdU(A@YvR`K7b zw>94kZtweYM}Oh>!~^lW;`64x&i(Z>b?(GM?IMGHXVPD1J*=Mj+4q`ek9}ca>f+k9 z3I|k!rm!D2wLcLu;p~={d(zep8?|mHdN9wN69>IsC4W=}i9cY_0NkPtPiaJjfk7{27@6&mY zoSZeAst;N?zjQa6ayH;suJcKW-uAf;qHMNpLhc9JF71C4FzI7kQ2h@1!}FYXE_a>7 zdC?)g>Cl4X0gpIt1iaJKGnumDKkqMn4!(~ef7|M0H!E>Xwn&ydDQxfC)No;n+RX4H zI$U=w((C5ALxVS{~>uzUIMjT{E74O9~)_H{K6hD znZ4rliWHZxJA+#UTLbOG{jA07O^%10T)tDuZl&If>1jI;+QztvZY$%S(thS%G4p}? zMmz7I<=l&ZE~)OWNJU#?Ylg&i+#f@Wf-HM-c${* zRFcUqOjh2#^M3B?*^5s1bDzC_??`S|QwU)@-%(vjy^={HvI3 zH8^Ii{FtA8dFjO}-3iw-j+RTE{8-H?T3O6``+5CF>8p(jO5XcsF6;@NsF3%dH28Md z#1#xzew(Rn@AbZAB>3ym_lo{C{M#$tb{}7z5dTAN{h|Gj<<@_yJ#HKKwEA@Q9BeKZ^;Qi2DWB`N>LjG^I38U%Ig4N7o=Qr7zX^_rihZ+sh4k@* zf%@MxUp$U|W9`Jhy&rCvDEQ!68P(A$mP$!@U8nwq0^V$zNW6>Yp-u%Ki-(0RV_BWc+VY|c>XN)0 z!n8Y%%?>fTwEP{Ta@wr;{A2F*_1j%eFP~rbN^-O3lIwmmH-4SaKI3xap{*DF#1zBV z6nHFt%TX}#^(KpTm2w50@~@|#R*dyI-C~v_#B=bgO-g0DNlHmUl8LVN#23OVGbDaq zJMGB2;(X{-hIT!6Rpr0$jz}2q%S%3{e&KjsX^mSn-wK0Oi_-GMKwR2`j?HfwEV7}M`xdm<~jZtJD(>%Oxy zTTr6!{UP%Ufrl0!y0-jaS(0?e+WW8D%G&i+L+s~HYEn?EZn*g8+f$o)>bWA5{`6|M zygVa(V;T3Nt7krUPWgO6DnfgIUf=A}gtr|DvJv&xllXYnOm)cEyZ+pPSx$Xy*S0J) zR7elie6a37)Qe+xuWW1FDzso{P9)1Ut*B+6z2{qRC`+-eOYl9ouOPwq;eEk~;C=5o z)@a_3X1gZx>)L@?w`OM~`2O6YyJ6Y4Ntp@03r+aftQ0C^zqZ9Bx6yQKs%+!dE`4n+Mdyj)%K@4&1>m$Wu4 z3+R`MuwL}ucye8=x}{#5bKh}lR=i#M-f!*OrGG^>@BMN&C8;`7^K6d(-j=u9 z#J%d9Z^r$aw)I9_EQ{3b)stB^@7>ZeZQJxZhIt3Ry^1*Kwrwxpoj=`@u2IvDxlNo_ zWwO|#dtGh%!k-aLN(!Y_`!_2z^PH^uFjDQkKpUpX{itRUNZNUlzJR9?A}xrC&6-9 zLUP$ep64zlp&jYnbLwARTyVnp#m-aD3>=+X`7XSA-97cf#-nq$J~>jOaYpIhVas6E z$_E!t)!Z>NQkC8KtbR+&-au{j57~&WfKcYb}?4zWMF`-U`F)r8;ZZ zSHz^P$a^Cf6p>MF$i3$H>xaepPaS41bpEzuPX0rCw`XmpxtqPN$sc>V^qf&d*6OPp z&PR2>D_fzY_Ib2UAWOB02+|J>j=DZKr$@8Kp9^+|s_@1EYYz=P}6a+L*{Vn+-=9^CQy z@g3g^pBHPTpU9=Q9?QACc~h>%iBGzJ-f*osIla!2^W^59lsLC$gI>$iPVasS`ZsAP zxSe$kfBV5AP;OG|2e$n6ljkg}Jabsdqdr#ZXWf(?u7c0%CLWeI^i`9u-1UFQj&djMf`q)EUJr$r|C43Cm~G$bkuk@tl0o@b-QB4XxU1RcUhuc*67N0D3LX36 z#>Csc6%60@YMuP}Aw#3SA(Gc?@y%n^?;nZIPrGF~%d-5(uE_1jw2J-QHk_I>*^@ox zoNPnHV$o+ai`_q^De+CST;3MXYB-UrYVpEo^EYbSdhXU=W8l@kV^bD=aoSCp>3w(2 zBKqZahi=rD-W~dL`|-T1@2!)zYcQ2yPA6Ccdy;4>A1uASYGHf zvyHcB?MhVdmE0YA(YM~YNGsLbW8JR^U*#=4XWiCG{adrJy){i*A#LK0+S0bqR~KIJ zGW}!tQfk^M+iSmOeA&2=&0(41-e0P_(k_}lPO+SN?b?G?3~#s_WHa`5i!)4)?9VUI zydiG3L*$<<+w@Ph(+@5ch>(ims$G3>X_ek}+B4Go@mbwBGARZb4?| zEgrqCsj_V0(u_$3TPJOijNwY;Z}ygLP&e8U6}G`xB1Uxkv839%=G93zKm3lAjN$sa zf^B+J-dvq<=OgDPr0irnapPnW?+Zq;NX|=N%%gAH1@@c_JJdH>I*fVMvLhE#EJbhJ zFbdZ=d!y&3V(Ny}D=9nK-W3~Nv=yvBsJ&Dw!#le{Cnxij|D*Jcn>if6Fft!g+N}`C zx~xC@M1rhkN#Gqpb*=dJ(yt#KABfBpt&=~eVYV_k|J1UbPwf`kooHGhdt3QkXya?; zNm8ksJF2IiuoJp=HFI9(sRbubEXzgZ$3v zN9)&K*w<&OP3-<_P^AxpO`O!gI;cGANosJ9?y z_qq8FA)dmf^V?o|DZG01^tM65oSh5XH*dyZQa?feYBz+}PE2SzO zrJn2h$I7KTT)Jelf14ENy`(xA|75;IxW=C#`(DLl+*ST34x{wH)}R5GUc*!5N+)5fAZGDclQ|?kxMtu z99$Q-&o{9yg|qwX8lPiZa{1I29yj(X7OHAF)Z(*OLrY2TUVb<8gwsoQuHbocr+C7` z>%2De`DQk6{Ijoq4cm_MGCfZp)y~+_Yw4lk8R0kC;)KyGNA`&=$2#YW7fw5%xTLsV zNGJKSrG<-Vvd&T8yj!i$5@O!|TUNYb_4NF|9YwFi8|O_uIb++|gG${+5kD^7;TPhX zY@n1V^<>{^q4@{-izYu)Qd{SJ-kQDk<1y|@3sh%(pV!Rbqt0UZ@LT5!QTsKkWkkpbmiJ*Qp%`?L1&mYLsyrk2^B|Pm+3E#J{qm%d#UwyEtc*B%sH7*xR z_{zS1%6%xRsj+U~!y7*rZGCvwQld3-=f~E(DVMe+1Ukm*Grww4OMG%v?d;K1i|;Z# z2HYGoHpi82=0C8Iv*72fJ)ASrt?K#PRya4PcFq5C?BSd6uKe;Z+BaQ})o#9S`%%1R z)>XmD(Sphw=jJVpNqEya$8xEH+pdfUceD@Ax_3uCS9DU>y3DC_yI1kfaVxy@{%oVv z&m|p(Z8`f5jtDnNoDkaJ$@!M+VzIhnl80x9n>TMm;`D-$4V%yVo@^{U%)R-KUlLE1kEWzM6OSX0Yj}h0DJg)_<-o`D0S>?!%%F53cxUJTROU ztgo!|WRA!j!D9zb^;8`DJg2(lxla3fi}v|DE9Ha?`VL53J$+%z*Sv)EySaRgNw$nd z)3fi(iqDx}7bD3dcIw*Gby-@omu@?HDfV04EwRO??NS@9U2Z>`TzPY4ZsDw^b%OIR zUhpr{Q%h#aZa)5}zG10k_e1|l>NW}+<&WjfGJ5w^@bl%4uKPRcw)5P*C3gDhchkFt zj=9Q?p#uM8yrXkg=D65ddeege>h>OuY!BnscF0RocMD<_mKtf&gaYW=CDKx zZESJ%oUv3zDNZiP;_*&SUQT}{x!p65$ILiCQGVH7qY^D?&JWQ`O3UkGf^KHHFYDb@ zTEX~RKUcx$GwYhVTVjvDPh-!Dw&9G?&Q-qibc=wTbU&-+QbGNg=^u59A9B3hq@pQN z;1v^KIjx%UJJ+M1jttS6ryi8AiEhiw?f$sSZu)hzSK)mg+_|qmm4Cf%CZNW{o+X{I z;A?nW=54u~hjJbl28!4`aCNDvxBsGSezIxKk;)054lQpvW>b9litdj2j^c;bNpDo> zbbP*P#^Ivn(-k*dG;_SL@k)Hq?WR}1*0pXct(?l15v}ku{#RzSLa2vK@a?RW;@s1l znpg!pD}|a5PAhydPl>~_^MQEcvtyA*_L`iS%yN#^?u|&M&~LjpyItSyzEV6@V4_yN z^Y(45H}-y7e!=Wn=soXHDWQsWLKZ)YD#W}`3eU_pI)A$2i{q>vl|E8)VujKbyB&6Z zSu*KemR+?F-_zV+d5AI^h9i#57qs@P1|RrF2gXv*|G z$-Y`#W9wU?%S$Jz$rbNfqSC)ZT0APuu;^JvZvBsn%S$IQeze?hV)64idM;BY9g62vY^oG-X)2eexm-5 zHx%Ws)%@A=t6p&O?Xu37L0-Z)mxPx*n<^lcdd7F^;u{1l6sL8UV}ePBAxG}%TV0Ma9A{SNmrh)8RH3A0+fjuQ z3I9p|)i{g3B?++SO<%olX>xsL9FLQ`ZJc2TbJgQLS&=+WO)sK(9x*Js@?wK7o1;Is zp2vmSZpRRXi${3B(|fo2z}fSk zAK?7B|G@TL<)(h~4Wt@-Z$9=<>v^&zXi8xEp*M_YlVra1zm+(hYsi-+w*Yc!mJgQ|4+`4-gi4ufBwsPqEhGh zLXS@VKFKXZ!tAi0e4|lXtG>*?r!u>$Gyeq2?lSbBG~r2A7)xjU7PA_a_IHkKN0xKF zKJZg!muT@9*UiGE+e%+_Wu>VdNXu7!tGM!{Uc!&Cpia-bVv_|9zS(te2fJHPPgDc% zeb!YH^%c5emnTeIyl=`WTP1_p0#~%wHT>Q`HKed($%5OLe_qMx*;}vnec?>4qha4x zElZnoQH>#I-X5#BjslO*ZQe2AHly4Qxwk*VF3DM5iaw%yf-PV5?ZJsA8}dHr9ejA8 zEye!Cjcda5eonpcIE3{;d7+y4+#~nBR_&YCf4MAQ)sv$vzh2dIiSs?LTg;WcVG(<# zE>SkG(_X2xZ1RSi_g_SNI+|~+-4e#|MdR-N<-L0GyW*2-`!e2gemlB&tNI`7#aq?y zm%C^CbF5jsRsD!B^=xvEj8pIl$4FSyn=F;jA_?Ls-rsOqLX!ItDtkFURV zwD=LxJCVOm+p|edq(@YN_whpOZ)Gv_&&$+XPt0lgK1nMg?4VTZ*C)rM8X{Z1ecO_M zZ}0D?bAJ@?jgxzOM7VI-x%&^lcQ1Y1C|W*2^48vGtP+|(HTURGI<8uO@m?W|)UQj4 z3F{B6|J>^q)bQ%=Ddo2_qh9u2_sVzB-urpmCHeJJ|22gDO3zb0tfeI^HsRhmt$MFx zukDN${5~PMyMKq0(z|)fBBkasg+`rjj^VvfU@}YoNmi8Q%a=y%JK0`e<6V4buB7B&n0Gqm`0KLGH%xYKKjs(| zuQKP`n>c>9Q!T>Z+(LXx^XF;a+}nIpKvmFZ{@v^o94jp~jg3ycTYGVX_~)dyrImA+ zwa+@$TfFI1wd@%`*)o;fN(1%Ksl1n``C2CDPdv&vt-fZ(GF|>>OJAAKx|@B9yE>9T z+{?G@eL~ubMHxbgzB3co?|L}dVX~La49R&aYg6v>JzKhJky&n~fqV#W>CL@vcbxw0 z^{Hu^yX-dKvzAqRCgoYr5M3p9Yf5Tx*^58Ba?0{md(%I6M5V_~kbat=qQ;?Ja&(VN zS-vWB*pG|dO`osUpIbGz%QV51%Q$o~@$Rki3%Ty0BG>gFsFC2i+nw?F|B+ zi>|I!+cn2`@k&|modN#0DsOaKW<8I5nse>JjoCZS`W`S!7oM=veBp{P_P?k8ha6z$ zoA6~1yNB1sS^hz@eT_e7dz7?abS|6cpV_c%;o=!?!NLs_zw<;l^lq-dkj-|3dvf3n zb2ZHd&e0=rbJ>~OED}^pz);;bd;1m36*{t`e zIu(4|wOSNb++CA7^{v`vF1hdfBorpN&xyU*vQVpsGqdFQ0yg)qqVgu`FOCUHJDy&8 z+G*}Jv(WYGz4XpW{>9fbb|(ka-mN$JpYvYAL;ys1wBI#c(J-r3Wz9Q@6;H&5TnVmCf6)4SM6)}x|c7LiR_<0Yf(bHg{kYq`x9p^s<}UP)*^w3 zWy?ao^yY3dHFfn$MI5>oJcX03)liZb>S*NXnf^Tt5sJ}8L zY|^$XBCQ+Tv${Yd(&@6SJ6*E8POi zNdhU=#}8aiDVJHuo-!{)f%ox4%PZf5mP$RXYiw9r)c;jmI*i$KS^VplvtxJun<{P{ zr{Yu6@A*tBtuRpR*Z&tw%nWyiG^Abqe5zhx)`2UJCRf|BFHSdZ)hw$vIFJy}6AvH{>mvvPE--@7(JrlN9e|R7W&M?iCNv zaXro-KP4&inxbNOvZAr*>GyVOS~W9b%C?_e^{qKa?J0N0Oy0ZG)e+$c;x$?2E zui5gqS{t0kL5gI*t2)cvtdu_1n5gHfiUp!b~5N|9&tvZH^r2CtdU-|o6T=k(*A zdXX2K#m|Lb|9+aiuKw?ilM8CEUv>X&e`Ndhr`r!rwu-F%7o}aj(u)U-CW=ymiO-`Tc|6&1Gg=R;fQMcv6&> zwWss&L}&J5Yrf-sbISfN;cS0g6;UmbpMCbjsTUg;ieGLCR=t}R#PG2s*p}ai`T3?e zzr72(82i3^-P!QT{Zp%!k)h6`WyL=A+k*JZd{(`1k-Txtas9@^Y5#5avWCvh&Cg#R z7pe8@WKD(o+ZA`0sI$Mm)^jjas3&g0G@kUnos6$`khjEJpbs;0%P4DX1n*t zu4SwjDGN}Vx##J7nHw&fRb{$Q=byUzkzIyNNt9Qnp3490dS0-;bcQvQFm1WyQ<1h~|t)F`9cxxrL zXEmoU=AF`aF(*4$Am{P(HN1tY_n&TE$o@Di_e1WM#>#p(*QAVq>%ViBZsX_SWQf1Y zrEUK8@~^_2r~=RM?Gsi9azD;lm-pbY;oPNvV`A@CH_o5Fx>{uAydziFPOoV&zIfSE zxVp&j%TLad(oH=NKEGzpdGYx*^WD?WueVQZJinejXZiW{{AnO!#nSWZ`MIO#$IHtt zv)gZXBh7BV-HEh%5DDg&+1cB+7ytP4WzM{X=kxVn6o2~J=%YMGYYl(&ntc~O#PCP! zOy~*r4u3JP>i({%Hj7{FhrKiH@0~vo;J0mo$?E29=My*>?N5Hbr26Y>cU5}TN8g<@ zYiw=*WW}3u@?5;@X8xV&x4T*h%TLv7ZL8kBTo(7!_w-ePde$wK%KLu1wL8gW7;QgS z&+zW>j;{IyImhybSd}qB{@$`S2Hc$ckE%xhdt|fm7f?XE>yg< zM0?}9#-ke;d|w_HUddO#Fn5k)uO|07kEgtA=VfI3^d9mK74tRRRA`a7HYx-~fC zo7OvvJsXN#)k`-YOKjtv7Igk>+uVI`VrS>g2{|X#D!J;5y6M538H(cbqodf?RM_)6 zRxZ4yF`Y%a{rbjOS0y7>G2tKA6+B8}{8rcZ8XHKMuT;BkQQLar75(`=<#WbK?%LFEOET}KvZf@QclKWUrg3$Y zV!M+-!H4(9z6AbWp{NsP9^&fED^waXwW@wuEKkjZ@aR;#Qg@lder!9`oX!10cj;^Y zzbt=qHS2%n-~UnrQ@ct|du*KT)m}g0wEMigX*b#T-Sv5$e0WQZ{lD#h&r91WS={=; zs;Y9{Xi}vl?;(?CI@~*-yW4OsYDn23QtDs(_0f%R{e6WCwl8{+eKGdHhh<4S-f!uj z{aUXq-lE=rQ_p$_E7gkC8|>sFWE0(9>^BemDEzyya{C?jkfTM(Mmj5AnY=pC6B6v7 zST8r@O#5VB8)56C&+2yWWi9=)A$DDll-DY)dyn<=Q+gKf-s7P?$J-wH1*r4IJT3RaKw(;Gu3!i29ny&P9)wJ!2=)KYx zH1X@vS0>DNV?TMZx^M9iyIq#ezw!90)R^C?+N-YB_jgyz{5Ht*KhB*K)7R2>G4J)$ zs13dIJ{I{hUE$+sa?8ED_&_X|ntN?jJF>E}da_;PyT&60CM zW9N!%liQB1C=OuCTc59!e8{L}ZK}qz0|5%f8&4fq(-HT+uwQ#deUbKjR{1?u@dghw zFO_b4b-3mWi%HHJSJ@jEk6TTdS1G+-Sjj}ga)Ypv$)8L6g_Tx1UGbP3U>D`ni?luS22K4tyHzwVjiC!5N~ zJx&ahCUG$GGN~+`c|-4g>Wz4FDc%K*@7QEcJBm-Mf0%HX>-mj&xBDbnj_sGW-&6ft z_~+A2U1p)PBvNcZ*q|Grw+luKIV{m|$CK3{D6>KDGBK7F5GSNcCDB;P*o|EIFuKlfDq z`1kwJztX?434cZJ-_N(-SM`1R{5$dSd0g^eKdpZ|?c1mR_bU!n?f<{MBv|P7Ea_>U zxjVl9o*p$|^S zN_X9eJKwwg;wqotTc?Ds3{1VMHCNbmuS(ahs_&;)uRi^K@09%Ql}=Zq#cun~396fa zDSpvat+l^YdscOv;aIJ5_Y80Gv&BE{ zO@8tv`|eI-|7@=GX};j(m6^`Rs%NU*zo2R1ueV5a;&h&u?Nzt5Cjcf1ZA8+f?5;V`bm3LgA>vv74OKJ7x z^P#gY2WE%7USu*adRhLh_-@0R_YEJP83#HquG8h1pZR6B?aTJ>N1ygxIZ?Fers&+= ztP1;HvYjaka($})*j(wT=+pnR1=pHoPO%Z#xoMNue#4|yE3S5R&FXX$V|;VNiJTD2qJu78g6GBpdtAH0{c+pf&3rj#J54WxT<*;Oq^haN*`b8oxrpK&u*%Ga%c`V*+qj#dK?(d_+ zX|wB+MQ*>^b>r{H?5sblSFGWYmiGLj5Vas;+Wn93geB`^w`UujYS|~Su#E4D{7IM4 zoT67wPeQzyF6qU*6$;UhKKA*$^sBpje|`Ae|Nl$ZIp6;`(x&dXzw1S>RhiU^t4TVW zZM5?{j$YV#;?;_!T3!AnZrfrOziC%HeX(wys&Mq(^ds6{;ev&F@4PQHgbKQ^mfkhz zns&Zl-FC%yf{A9`*XnP+IXCZWy!7j9%8^SrKM6m%={bq*Taw_e?vj_*dWCM2R61*( zL}~aQJ`l~uSoD^)>kh-wd2@GJd=ZW}+1=$tqbEtzn8zrlp3-;6Szzlu7hvAFrKWxb;DJ+axY zZY5Khm3BF`RD@1QWm{J9`SW@EzdrSMb2@5|oN4m-z31)2vfCRy>+{1VIw$k*d3J2R zeNBaa-lF8$b;~>1^?P5OFJAF$U;XEUGp=$N-`=v{Am+6A;RkgyQnzWYUR}29ZGx53 z{@w((JbSf+t2R|^Q^@|KWqPtE=~(K|`nPwvZv7Kds$2SR+xF!<7toVIqm0gJmOkgfB(WQj>W$s7VZzsyU>5N zZ^`}BY@y|C3Nag43l!h9pK(dqcRjz0|r?S(Cx3c;=M}rR+UD z{W%F){4)-036aRmj@wp{q$De~vml6V?nJwUhb@8&T8rHam$eEDe!ca#cJlq>uYC)r ztG-OTc3oFQC~DENE%BQ3HQ!D*C=x9(`8&l`QhUpW+m`J|t@OoKe_7=7cx&@s|FYE& zU9TD}H&)s75`m+7ZI?)f!!Drra%)I7VaI^Da#XF@N%Fp#os@^pT zF4)OExBT6qeJ?q$i@v!TcGvuU{Vtj0kQrOpo98~c`R&Hsn}W@Zb6J!f=5ASR5w6~P zCh*_m%F`hN3m@;?F7|b<@Ij$`^T;(Hz4;SW;utxUKQ*7c7IezJ;+pHv0^a(d8(dB? z6TZ9TIPQ_!cvf~x@uC}tF1s(x^?9LtLZUp!wfyw6GrFfs{?sMRs=u&!u9WwlXdx*R z!!1&w@6RlJ)+Dmy$_?w#3-&d;PvvcX)tX!Dy2an>PwUsv$edM24|ki@RJt-xi&wq5 zZ03(Rl}yR+T#sjnW#nY6;C3vCeWoIRs6Mp(E~ko_?!xcpVIiBow}mt;y(j;3b^d0X zxZKHKe1&5w19P{%3@_Z$wO!jNM=z7*)l;*bYI|Ml7b$U>l%95tTt55unvffZgw=|U zE0(Mc>|;LeaJz7VVux%y^U+8d_T_w1l@s_TzHUt}tvHg9-Kd+7@n^n6itm`hk_~Hn!eb5Hv3(aeoLxJo+xTYK-e;HR+RI%PJ0dK3`vK$Z7i`fx5;nvx z+dp0Pz&s0cj}-37^>5F~R=r_UIklmubbHv0xx4$8Ur*T5-G1<7U};sW;DVQ;^NXuW zUluyvh;-D;-xeCI6LjZ!)B4=YuWERw?G_N>I?y|Z`H*7bR@r%}(>E(9?or!neP+L~ zL5s1A^rv@EHhO!9tol-zc`4akm2Z`Bk?#3-%df2!&SLm+CVi^a!dctu&+W0UW@g^4VR}!6zFXA(vhlvb4DF6P4FB zaMUcBwQKbW_nK7#Kjvv@oXEd$bw|nhPPwaM0$1uYLcZ)gD3*UpGW1p6oa}_clF0fS z?yIEJr{+0-IPsC~xC-aG^DJ@-F<(DuHuCsJAMGo3J<8Fcpv=C|dC|VCu0m!Fxf?tS zuJI^Yd|e^gIXRC*dCe^DRma@toYr|_e8%c%&qm3PwUblV+u}TZ%P7;h1UB?BtN}UU}`tdVv+hIISF?03?#}$1x zU2ClrvwCfgrzU;A^dRtW>Gu0un%&u1-aZKQ<+`VLN!sSoiGvR&8vJoSu`yFK#_0L4 zup9nsrEOL*?%Lez_F=`sql-3Q4`%P@TeF;BuJA@WpIqUe>iQ=4JKt>&D!;2f`#{iL zpI7eVEtY2YJIgmc5L~Z%^?{)KN;#WHs&Dw^I5SfYD(_3RJ-E2-fUpq5L1oQOor)uZ zd>nFx68$?iZEKpNToF?ITCeleLFK+6F`HHP@8o{Xv8y<;@d}q*;g!j3{d_NWFPX_d zTf=YVLaFolC(oqj1ZDZuyZMMZM|*zBpWs?ERVw~WUf1oCvhZWBlg^#7Q1Y6yR(_Uh zPTBN{Wv;7D_TRpHv-smjroU3Tdi8rE?02MDM5l6psw@qD^2J|O^0j#Oq3!!#x36kl zvDhnJdQr|LpW?qCj+!6SQZ{>|{9U?v&HU9lGpD`QQ2!+1R^mVHThxs=dbRcczFMZ- zF_SgCebP|-Q{R+rudfGfQ@ZMucPY!eYTd-GKH=V*|GvCxzwM=&>B&>~L~En-W@(@9 zJJNBg-R4|Zq;E)BWmVkS$q!1V6#0JL@iW*vb=myKC9%JCpRIn@w#Q_p@zQ@+O!;ol zTs%STZ24aK6F)aa9{2TF{kTe&;miB)wioKzo|o;7xORD0oYNcQU2#tTgsyx4uzg*1 zGfcm+?Y-&}_FDaoR;~M{e+WMDU1+uE(eFY*tA55MaX#HA?!o*s?$I>Qn)P-}jqk5| zGyRNna`L_JeTT9CLG{-&3BteQs`Jj>oTH@Zox0q^!**t{ii`L?raOC2i3>@ zIUY;-R)6F8Oxx-gc|RxRz3NG34Z6X(?xih5nVEC&ooF4Fuv>W?npbc5tP(Ket$DNe zsLr~oRpEcxi}#+)TRe5<hID7rdgHPGHCu6^^ z3+R5`_q=C^z|VbCPj1OQ5_2i`^hyP9Pd~F`mp47mU6(4p{*&XJ3BMY0Ep@{pzaCeJ zi@2?kovu1(nq-Fb?c1y~OW6%SZ~6WDTjGYohBF8Bc58=;{ycl+&VprAUuS&IjEeiC zp&XoREX_AF``}eRlOq}RTP4gao7OlO|4BB?>EhZVy>*}FC7a(i9kDA8<;73F|Kscv z^Xrj*{>cxbYgfH73*C2i`Bb*q(@s^D>-a`4yFY3FZiT$7-07V$=AFsr+mfIB>^3;M zasDm832t!@c6u2#1h1^$aPPLpa`jnPb-XSpaR%4F)YTEO@DqqUy>!0C>6ZFGLW@r9 z@fY9SUp-TP>a(V@W%HshGPMhBe#KD!>DdFG$+jsRWz!@!UH|Cvt@D{}Ggi2~S(S7;w}Jh6kPzREMKhbuDW}hsWf6?tFTG=5 z(Xo4SXGCB3vNi{Q`<4D|+S$kQ8@D!f9Is#EQ2A=6GuMNM8|Pe!@aX- z8z!y%(IKN+Hq$%wV8*}Ec*Y42%QsN;b}PMc(7LcXBMGvZJ&>rOe&bSAoWwh zyeSSc=O$0~I8;~f-Umot6CM|x)GSQ+xeWmcZ?3LDe$EQ5Bk&89G zayZz_$@c8=nzWf|Tl6;k*bv2iw@~`me5*C5Klq2&=}*b}lU?5?vaRyx(&~+qimnOz zuYSGEgyGkA*0-5&H{TaKvT5Eu--jE{zgbrBr}_@)^h@(rAd zHIHk(TBv#J;*j#-3eMkmMHG9__&$uj_ITL|4hC~qFQwvOi$jcgT=yCKpDgo8+aSC{ zlXv^Ml-erurHMB!Yc3Vl2V1=Iyeq;NYyEmfYl3{t^|My58hqxKUU4Wtuf5f_O<~F* zzsV_=nf(4l?GlK%Df(37>J6Wj6Mk)|yR>F8-@D+VoY&Vnrv}VBWYZW$&1D;Mx3pM+uEMCCP$|!2BkWzoKp}X0W zDfu!-$0Utonq80Tk1Dwdx>-cBY}?Kue6l*2U9#bh^zD}_UcU1u zINtxe>BekciD%~)m}^BRi2Llh$;dAu@#URiK)7t7HS=M&x+yw;TDzy4MI9?lQPw|{ zx#PgTtvx4wuAjfe_(@n|+H=DQt==xC6gKIfWm3vhcIew%n6 zcT{ZHYpj#V`DE_~o%1Oh6o04eUS$&79DB^sNop<6D=4)m*q(m9(*Rd<-9Z#5>Dsu6t{LOv+IU>3z zres?iMhZ^vzQI3@OULkz?Q_!`QBo(qPx88KdgDOcC3OBe+lNEl&;aZo_ z{y4>A>%poEP3|)uJDN{?*H|n1VBU5I{)7cx8%`xJ;Ch#JRxM!K&zAL#+b;chGgqg7 z3*%bWz)ga!%$@a8YpQ>IUa^+RNS<}=rQ2br4+ILd9nK5So7lfDyJf;x_MD7e4c zR>z3lQn)qkCG$Oo<`pKa0tOn-XR}-Xys;(s1y5Fr{tdntPJJxLF6_F!c>lepZWpf? z#5{94U2nFo`_zd~T6dpZ%(5^0yy(=l+!D8rL}oK7tFwU-e{EDQchs+n$iL2Y>88W8 z-+VuNo;_{xVZCDz+xozzaYK6V#n2P?K504FEnXLMtyyx3b{Au)OJaRb>`u9u4;Pf? z2Zz5o{Qhu>=%G+ua^LA~_PP)J{=OCk2`MX^KG3*ZyIH_+~J4?M}E%V{eGTTDEg_&Nj4Vm>aXZ1wJ z4|@s{76;#&=B-_~ke4OV?$9;^iDf0u>y49kZ8O!AxojiBByz>j=6rIrM34Nbr8D*F zWiFp!IP=7%ZL*x$wf74cjvsCLxnX&ybi#Er+XpQtOPxQ?vd}9E`uwF)xU}uLWzOnp zY&&9I_0E<|ob1M?@bQG}H_z)XF6zDu%BC5~%UC*=rrNW-N!pm(%U!g_0Cs&1iV|jISYpqJc)vk_!?OCoZA2l9YyG@uJ zzV^+|x$Ad?9jOo6o8{_a8+-MX+}_Q?m)1ljDzt^IedD+zN$KvYsgJ)eh<m@c8=1vIApHkDm z>>~f8=&-3zuf1U3`m5*T9K(`Y^>V=tM*0cwUq^JDmYEzg$$Fmbf2LJGzTN*gr{Z^; z-pSBstU32o-A=|&T7Bva+c_px+hg~mt>?`wFnYw5IOQh;yOYr5=lTC+&-0i#y{o$O zagT$sNX(zrXL#e@F3?`@`u${IeLDNBM;Bdp3Y+jqB_7}YUu$!dI^Xk}^vTwlF%RxU zYn^pTpIj~3@YvDF!oS??rUCo=>2{k8?{4-qH;ENZ*y>$WKEWe3D{PO-_G2#7j`%Yh z{1)mhKj6?3&$OmOG3W4sX*&#)tN1K^rd?|}aHGUAd@G||ooC)*#e^o^{&JfZr}`I< zvcuZ5mWgCpPHgHbUOIE;hRQF}iQk$uwEdM$_p#sEoMZA~(jD0%g|cAP6I|1uygSf% zWK!J+yMrh7xHw!l-?+srw>jMN!1O0(@tdpt_j(sevh4LPDqnJ!y}(rOr07KL_(`_~ zlrP)Y#YR2Ijo^w=c3i-(TBTpIF;vaZm8u&Bqn)f2to>xZnSN{9_-- zmd6$DUu+BaB$s+Us&Jow>T$*Ktf2nKvVpITeC$&V>3qzY@uYCi<7r=yeN137=u=mm z2-3xV^kbj(gNrr11#H%yGW?tU@6S>0D?bus+*j^mTPX9MBUbrX^UdkCPYmTg8Oqzr z)_T6Hm)o`Z-FNp?zTnrL%Es=Kd0xyW4nw}Er-}i9t&eEug-&;PMd-p{-z$soe|PWGjpwELmH&$Bzfb$W@A%%QoL}xl&x?C@ zkLwEO&h3Ae3w;k;pyv90+VYUHd{&`vyS67ubyjO<%)GOAs!+$>Xv@wcd!KTCy&LVw zZqrw-J^SFY@_gyMyBT**-i@BOw6FSfu>Z?@pI+R`%+hU1?(qzM-QY8K*)<1inJs>^ zX6d)iRnuP0`sR(fx>s=hEY9nX7z8uf+~;wo3;$hF(4<$#`?I{lb!Nfhn>%7IwO9!IO%yE9=Q!=5D7?6SXz9P$m2*Rbb!NfhnVB}?>(B7)S|usR(zIpw#WN3Dob;S?P4w@Hv})EZ{@IYG zajGTw(X+$T9~@?WV_}+WqJH7Y&MR9ku5s8buw>!wk|x&{1y79LdLl5ya?r`-54Q=ZA`7Nl}(pi?*$N#m)F_p3^y9QI?YXENd^#UAXkY!v|Xe zyJTiaY_aBu)Xd$&%KlF74Qsf-onXP3;sv+Ah&I2wqwX!8yYHQq(yq+KvMhJETx{DC z{eRU|vs06^m-GfDO|SH0=UHvNVt$1Ax_b;II^N3b?p>(A^z-?f!mrG)Up{^%^KIti zS2F+S?Xdb@8y_=Q`9jZX^DlFkI!T2;-`Do|)t%*=c36GiSQImNaY+B_&qCjhUu`wn zw8QHDrg=Md^)Pg-_V!FEEbS|Bh?)Do!TpmdU(+1rb#cY7cX2H5UtO%T_0cPtuS*I` z`C=`foeDgawC?M1x#?%?7tA)x;(m0SwCl1Ig-6(_d0$p+Y8Jk~Rr z`KKnw?{oL7SBA=niXGT0?Vr9qH|GxfWQmlldrPz*X-)ZjEY)-Ux5WReQ_OE(yZ(H? zcF%34o9lv<`|~>AoR6AtI9Ww)>(cbcJKk4JE8blfwBY80ZSO=Tn>x)r+Z$dVIPY@z zx%}%XnRhrnM2mlXh}0EZFtsl#^k~tqSld4SwD%`pZOYotwlwm7t=)R|tD$?vciyT@ zEZ%Lm*=Aw0hFHXc8GE->-;`>MKK@amDENoXxve&hA^$4p1o;*58<-?*e7VZH<5|i6 zEn177Xx%zuep6Pm_Up{oufMIY4qDzPVO@Xb@zbJXnUiO4ect`bD`IPpZeQ;AqrAS` zO4XS)+rE#2?U^w&DlRK#boX6lB= zPyI{g9X#2xFu3^Q!=@=!Umh~`zblfxee*@B*tuWdKWitgiYzTP-TpfIm0YfI{T06L zoquF%+M?4xrfg4?_STP zY|VtazWhahtoAOFUQ)ErXZ4R~S$h>1q(~M@?qC0JreoNo9SYTlf6cD)sNGX@*J541 zU3$tSu?~S5TeZK0gti2HzH&EsD*tV-(zz$H_4OtOy_SCyz>xmr;JL@|YD%K&3(g%@ z)S7<$Y~y8lK0&*$yKDdF^R<^T*{?mk&~r)El*5V}pD1s;zb)gp?S$?}dNUV&Zcc5A z{UnfZH1?Cg3&-706njLH5*3ZABC%HYd!2jCc?-Kff#p3%H-`l!wsv^(7yd_(=d^b;N zPInP~x%cb6H%5!Ro8(nJ_s*{Wwl1lT>t9&Rac8hJ{6TkSmUUQKQ z--L4i0)z7RzYE`Pl5TVKxPM6YFk9jGXWU&Imp@$cA+Cc@St0wntKEeq+*w5_VP`va zc^`9%$Z<+958zmHP*UTS(5=o50u@4Wdp2@t9b5j8W$UWwL$;ji@o#7LXI40xE_FY8 z_Od~xt_7W;>)wyFWcU*?_tC--`Nz=yu6~M1@Sr#HoCn1ty4R^yb|CX0nIx zZIqkIzX`LS)Gt;zSZAqsao)0Ig*=~!Urcs2xxF*p*jO_)_I^mSM3;Q{1j*R#e`HB3Ud%^w{ z2Y2kd`a_Ew`8e;dzO$5Pm6lpfgSdW#-C89+_s?8Av|`QAUS*6ot^T6_@wClfq5X9m zbDZ-38kH4Ko@a0E;aQgLa_+$ISzN!sv#Z~B-s-N7KQ~9U=&nlN-5Y%qpX(nIIbN4# z?I=~*`21MBM1A)oi`dD_3KpvNmDa5Iw}gAgk807!^;VzmbiGazf47i1)>ScKdFd-* z^<8%xlHaY2cy#fSBxKEA$*Bz_H zLNd)*xf&`BbYyZruFCLUTglby`t`>L z^-b67<}dy^991u1zRVc?D*LYUVJ78G(>`S9sRuuw@XNU>-EVUBtUL7+oHxw(u?P{( ze-UrI(&TgApLm0O;d>kbO2^Jt9{JtRv^inREsw<)d>&XHwADVllJVz-;PX0**7;uk z9bYwNQFVcnf~{!a*IsoNem#kVpHm%l)Fk^Z%wRKgZ`0K9PM8{=FjM@Ycn9E=E>dRUDWe(R%V&X4L*T<;6&z7$;FJB_WWRPGK#K~A;ViUv37`)JWqL7T# zX_k4_vP)Z}Bz8pegf$)VTfunEbYo!koVKN1OEY4kjv8`=J`;O;uhd6nUw%=_`&(~w z?fj3N{BI9gcm!H^^nG@4RAQ59@e2(G28Iue3`z_P3^{p8nI*;XnI);klX+9vCv!6j z)W4luT_SV6@&@A@9Wm~Njf<9ux&*3B=MGYEVX(G-KhftR1IHu*#t)1^BCehv-kh0R zd-mL!b7$TqEqtLOpsHGUYl&~|n_Ip$Qs$PKm(|LmfA1*0Y_{BUmiy)8zZ2(ODXp3{ z@5tIq$Lv;K-c@Ph_kQlpn{y*|I5ao-dhfK)+-d#2{`b4ryZd+EpUZBxZtXOg31Pge zwJbBM9yB%{JlM#;>@qVm^L`%t;}4&6{NXv&&tZSWVfw+wzdxTgR#qBxO_^NZ*2iBR zFTumsd@#WPLhUQIndNh!UiqXxzsmlJf4Ke}g2{jse7={YBILWPI}f|MbQu^6K~7P))v9-LqvogVMhtZL=QOZU6*O#Gr5da zQ}y-(bm1b&9t|NVXSxe7l&9oav#Lg{1T4`G;12kR5=vA>b&>su!q867Px zp~&GiRmE_+@C=#r#+GiUo=e!dpPZz$vT~;Qm1RpZ4dB+5&2;v;WvfzTXHsGV)9KU&=g&R#*q(F2$AHt$e{)t}U~1$k!#PKo z49|aBqV=3*ea@A-)MSyq>7HGJE>qhgKR2x(}{zB5_fvN*j!w(BHAn>v2S8Xgt})+NT7g--$Tubq81ZRYfgDGRd;**%?JL| zPHHYW^CTi7D3F1NH)4jlez5_wkXZW^)*HboVh-BRKN~4;;LD z*A$fG-r7D}r&w!^{M6-^YWl^CJc7CE4+k!C@^V-*^J?jrjJjLekLpxeHq@p}O7u`X zZrn6QT(hmcce;3^f~SmrpqBIHE}hFpZ?a|h4@b^qxAbBVQZLwYr|#c>$CAJHv-X%w z_;c||zPi5Z>XYa1zc=hcN)Kns_0^TLn}6qOxK6xOXKl?AbSuAGwQ0(?`rEH1oX-D$ zzy0L|iGOzve7JC%`G|P?y?GTmbL3)W8Nc72CUIu_tlg(BC|h@)IB`oeN!{?nuRsYG znMQf1GtY|~mT69VsOia=5y25N@61M#Hic2mx6v&dUP+q3+7C$+A6%CL_oXIYx}o-;3kLKV6FR&UGwDB5;s-BvEO zmDX#RaxSNQU3Mnl^iK?Ma#jDUe%icZXR{5%7Owh;S*Z`tXfsG^aGkj5kSMx> zm4QcDv~_u9P=oN72ea$T_pjWteCBolghe2%%f z^5xOCplPDLsnOf6UTO%MqPgnMlvB4=mUEciI5kO4TzBT}TWQ-OPCx6KwC3X!r>i$} z7b=Q+2CoRZBo>>q>2|$o>+0~_-8|fvGDNmT%~{2`>VWa4Fug6O*182xI$Pwbxvj+2 zczai?)n4DQDA%ouE4sX9AKj#2=o-C7`;FO+b+?5!u&xU*IbGs-Unn&0@{z8b>pOPc zQ#hFxsVm}>y*l;Qg(>Ijx7!b%O7Cea3(C-v+UA1UcfXZZLSBszTw!e5KId#5G z#+CD0Tf;K8<}6**G3C+( z-6n84( z9R)L@?mnA4D=XJJEcSld_E)V@2OmXUeVcn*=hWAx1&0%V7T-<$>G@^nYM0;U#te&A zt!iMdU*!-i;?KE6rI<@sD@JaGh_kWM1W!BvRSlCK9$`P<$8_3rk=OGS!3jdlvn%(f z7W*65KUxskHhbpn^)p>J_;%h-^ImwRXy=O=B{TK2wy0dS*m(0%YHGCJB-Y+FtLA8! zGCaucdwFi3%*xCK9=CX-1hSKy6JJkq5Sm-GJ-J?6ckZOh*@+?hE{43m{d87N zQ_;~?CW-8;u5HiQ%y)_@(=+ter7c-=bGx=(U}0UT_4&hnbZI`80k zc;d@hv3mK9v)+7gSi;~R=yz80M(IYa(^I>)TwSxFXze18)YkU1e~j;@{bTucC$!_= zSs!L01Ffu;GN+$Py45pid2Vu;c5==P$k3*wl7so zv~8kB^!n`%qVwdoCw9&%+kEv_(2=$S*Sc9RUEBV`>+ln9pNTmee0OPtYSeZw?{bP< zb=_mJz2VG$!rlF+tq=rt6oN^y-A8{4flYn4Iq87c8iwgpE29=H+$kA!;&9=S%ML;f z9;Ym)wY*MgeDt}q{$t+sAbHD-X)9*B?w@+|Z`90`S7)OZAN#!3t#J*@BX3pqkia8^i z<)FW%VoSomlX=?pEVUQD{(pGnIGfsmBl#-!6MsZJn(g_ke&0G#MAPTldae^dswU=hEXet` zx32y|x6iu&_8%`feB$<0x3vHG?a1;6jK~eA_idk9z9jI!TBvu}g^hm?>%(P55B}B* znNMZTSJ<&qrlS6U@6!X-YA^oQGxOhhUe|-C&>f_m7F=CZ?R5S~LALrY=i)sk-+9Z$|iy^DcZ^+6N|j&Dy(i z>K8BbD^sFu6*nbX&))XrhU3ynkJu;1Ez!C#_iTe@T)Xg#a&mQw zxx~^Yp}n6cMLP(;;JWZs=tWDZwS)B}E|ukZj7RgQgzx`<@ZiQPDX;F-pSw75;{LL8 zhP<=qJbzwnzD`P-J9D>2B*W8LZS9%t5gSgbymh%)=<|DJ&b3LiKF390Pb_c0*7W!A z%y!;Mx!)zG#B9@=`lZ0!{owm0^^2X}yt=WWz&7@_eqZ>M*q_@?H;V-%c7$x$%xgaN z=i5m)mv7$x_*7+labw`aYg?-S3Q)Lo9UK6R-DXXko-3HX35nP(@hN6 zceh=d<-0p~g>|N9IFsx#6EA}^0hhP2eBN<9;r8;MMt2*3oSU6Czi#@^KAz{cZMpjs zr6lT4<>i$8t=IVZ&EeDAC-V2-Z#u)Ohm?f;k4p}pzCM|H;^UKzKZ=DvHtMVX3w|?ko8wzUwXhNzFJRgwoOsWhu)6nc@Y_lo)^jN{%g9aq_*KFi_S96HEoqo1`zhqw`UB_BUcI`( zrddw%W7=_Gg%LOVpiQ-@$}TIPlu}1mwx&A zl$+Z;JpV^O!%49T3+^p@vLt`a8r}Rm5fQs@T`b(}cis2tJuTxS!p!lu1+VvnSM+uq zQR|nJ-BW%1t?MKm>C(F!|K=-Q>Hl+~{PskLP_4|k;I>1)C%4URTe_qF_m?upD?6=h z3(R=8$#`e|{})zo@;T?$n&*G#nHw+T`}^>39v9Cu>!YvJA8$Ola^*q!h!1UhBR|cb z&HYD)m;c|o1?hiIyDEfxRV7}Y&+*MdGUVcuiE)wly&YK@Jg4jH#oxC*JUKD;{giF~ zeW3xSzkICyIL~U$jZ6#=Tb_G7XyT=pFN42*$*GDmpLN;TxZoIv&D{DM^SXSvcksJx z`77WvNdWa#CaDB+1+yK54rZXZ&&1|sJl&PmoY!`d${bPa{q-J8)EuGUOanZ zt5Mz0x#|BLiEU@jew~_aKK=4?>uYm)&EEOAm!~Zk>GhpwVOa5f#qIiC{IAODdE2Y} z&G#(-{APa#M|j@)bE?)$*ulvp3dEw!aJ}bf5bLPqIv3@p7Q-w!X#pxJVr_;AjQffIJ zU%o!&K7D=q_36{hcWK++h;n59xjx{=<)%{a*P?7o=FPlyH|d(cZo=Y?|Ls1!*`Ah` zRPWxd9=`0`rm_T~TW47Lj;YO){IfXUm(k$8;4`;2b@9G8SA%aUCmLV>C%C-5U0r|P z4e!0y_PNh??N2tCeShcuuYbxWskW(4?|Wx?>(=X9iz~PGFZyy}@0t})ZtJ@?1n%0e ze7pJG$)x9Vthvir@5VbX{JCCQZpNP}e{A>kY^%#CtbfRrF0}DzBWIJePnYn2{Xj2{ z4lP5RlR|QWC3HR#zeSYBv z|CXkzy^4#oq^x45eEDeO^=#P^4Y3Vx?VPr-e3hMbuU2UJ4fPvLTdk^2PrPh&(Dq2^ z1CidklfSs$e&7D3{^|zbEi3L%;awUp=5=?{1?k)eLM4f%{Zn^tFE8g`zW9CKIqT9> zOnN6jyC+XhKgY8#tYG$;yqkP0@@^d{T<|^VyNsP!)-kzCG z)Wb}dtA8k+c-<7p9BN%%Q}OB6%)NfQY?t0&QpMCa&-Pp1qUTjia`PGLnUynqVr-3U zDpRsHJaap}Jx1SR1B-nA?2^>Ke?EPFxy`0F)pk#zK*_@NIQw4}I;CG;oZy$qn&Pne z?bjRs%B}Z451W?%Q*PqixEn8Kq$XFER=#vI`1y0)eW^`4LHl-=S*^HvuV;q0zD`~X zixz{iv4OPxX+J0Nb@7p(|E~6X@T&e(tMtqC^=n$PCD)Z~4|%z{j_I@N(#glxdS9si zT$@*Y@BVAM*Ou#FYG1#+chRJ`Z$ru_MMT)&zntk@n)P0Jj<5giQpu=`^U9LHY&>q9 zS)?|F@66u#pbdwXTX&uZEUT~PT_Ynmucq^UaVP($ zwEDYxdAGjSJii;2aqzx=#iy;+`@oyKz?rHDl zD|zcOQRZdbr$vePjoD4Y4_#X|tA6I%bpc+Do%*%6*5Aq5&D9vT_s5A3Ph`v1UwgH0 zzTS)MuiUbG(3 zy-WF#3g3C#o^F3L!F%)dycf3R`>VFOR9A<7U-ISD>dSYJow2LYKQAy(GU~ZQrBqc{*?L&xilMH!nQ)(b<`IlYjA#=#Ya3H>6Fs%yKfl|9Vxz|F@eHKExL} z@5t7vDEo7xHg4m$$1m%h4^IwH`*wTh72f4bw(W|Ze(xi*^>g_S-*abp_H7fnwfoDG zhl^A0-}UzYrh9W=P5AD~0hSj`0yEkVKAEprEc1OIr0E5%g7)mU*d}OUQF6bl5v}!B z^*>%$O4j3u@NxBjHa`WY8te6gPAf6bdq zFMaZCi-rFuKQjKfwR8KT`Mvd4|0Yhnc;kQ1-?TUB$@WskZToHh zoV}53SfAx0v99mWtrP#{em*(T?r!F`N_f3bP01Ol-vC4cWvK7M?k#kZFm`}^wa{=9y?-}v8qwLagN84J{tI_LY<7=Aq5SwFQvNMEJS z{-gTI_3G1v-~8QX!q)tA-II(bcM^WDzv(qA&BVO)!W)~r^`X@!huW4n+;rJqcI%n) z#2EL6druy+N*`DDt}A#Dc5c;@=^+W$+v1mmkh758cYH zY`kwxT5gux!4)=wJD;&@I!t{v>+y7X+u3jS>n*tx9T+in+ZvWPK^o_MZ%;|N@Nf1e zua65)%#4eCSkQ8R>H8@%^}H(>PoF5gZMZ5=)A7J0Kf#cL%O2iUSi^Ga>b3LUUW~Tk z3ni!7NG|;C`T4jK_ui>__oaK^Sxq&XC>oz5p14?ycgAAPgDH({ccNF?i>%n#`|cn2 zo%UUlC$3Jl406i0@5{giYd@8~3^3&Oj~nYQNE+iUGv z$#g;QH+R45k-AH(wv<|5IOQ0)a)GqipG&e|yae92SkOPQj)`Q4u#+RV=rGpA$Diz|{_#F*Ybz5nH(qlj9z>P`-; z#ODFe8xva>HUHE2zAW|B`2~y(avxu|E!v-;D;;{Heahw&+Y&W@tRoXZOZLN2`wm{(utIsb!|{43MB|0++t-lDPQ?(xJ2p8AgA7j+g+&^-UI zu48@@+f(JtpJG<|Ow#if@K|*Cl{ho+%Dj@f?Q_@sCxufs*T2!0b-uhH(xf5o)+d#J zujll=oAjel&i!rP42SEytSszL1Vdi*EeL*kT&`ozE4IT8hc#ZVi&J>%9ys%%X8o;I z6{fR&T>7^6C)(E^G45hcpP#Tz^Zb&$0`<%7dp9?VzmR;O`2Njx&QHd*7v_GjZa(LK zvwHIBg$GQY+nc3CEoJk0-}pfDi1^O+i@n&MS#Iz9I?4S1;-kWIGS!(36L~B|e`a+a z@LVHn(ziRhE+wYSeV-b!A<`^TZ&E05c)KG43Lbsgj0s2$JUEo|OebcGr8G_i&2 zMseC6e(t+bS!42s1xt>^SgFN(&{t zPEPA(+i=I-t4(O4aN%yg^S|B|UH$sM{hpLW__6)vkM8^ZId{bTG5^u@$IlCJ`U3LGaa}ciKi0nZ-t#B(NmYv8ua6VY_x#y@L;px!&ZFmQr#9;Q|M7To z+7C^k4m#{G$IYKQ_Mz`BD=i_0QsBm+sLwH=GaG*IWHL-~Rvck(r&R z7k_)v-&33N#{5`a`5LotcOvrM6fZV+pLub=M0LuS3oqXH{(F6KzQpfmKbC&H^CRUE zcc;C_pR`AlJA*r;J0p@3|GfPe?`AIp#17w(_SbEdqBr%-R}cKvoS#;uE4 zq{BYSTB(@!3+!CC<@Hs?nT3<;BVL{OwX@8_bH3uWUz)9dt(Qdl3j2Rgxq7vHy7uHF zKJE+OzFhd>l;oo*^*?g&exZDl-{{I1!+%e>2@OgrPLou2BYO1+3_a{Gl&=Cl2-xV_Wmp}A8j zNA(PkeS&YQ63vA>*Uwit_fG8hJLyY1#7s7X-I!TK+HZy70^O z^VRgeU+4cZ-=k1BcZ)@=RJwU7F=<`8U9Pv7ypmtZ z+9$2LEVu91$8S(N$R6w1FW$}a{LVV5vedvI#_u}rT%PaRv^mfCZBbU>0ropDQ~A$} zvD&}A^+xWUu8{3hGw*tN@zySW;oy}E7I!nTUe}4u7jOOe_GK#nbn%r1Z#g%vzuzr# zqfGwB+doR0m-7zA@k^Y1;e6y`$Z=jb#Srziaq$wK#c%&@SzhnlGv&lLiNLbiy1zLL zWd(lDJlCGgVtp`1{kZL%lqDv&JLQ9%78%R_{#H7D;;G59zrTH)Iq{Is@+-2(C0Xb5 zvHzYrlTTbNVy617WQ8a0$_H0|3*fT8>`}C7uIGWpZU=+ky1gx3JyGYeSil-^>iS-l<99wg#@9=C_P-NjPqu&eZByMm^GR}r+S_mcb=!12 z=*Y^D6YTB_+wZ>lW%bD8&x+{n4d#7J>hdam%XjHna#bzKy&AV)=48-YH7@Jt9-j(+ zPm%g^A@GOu+pov;%w;*{zxd6l{_)D=aX`Vd_k}km{%O1*Y58QUa-osM*YCx5>nC1v zG3ed!zwb!rgCs=(yLY!1U7zee$#8q(@137LtX}aQv#qUKB2+H?;`t5bmmRYU*O&LJ z80yE#i_3eq@2#+{vzz1+tNp$F+r&8qyN~4c%b!$wxI=Nf{KiH|#=%&Y}TdNPQy1v)9;kfuip9!yG zxBR*^nfpj*%&Of5XVt&}n8OP_muUgPIHtv#Q6AF;Z4gK#nAGFzfC@V3CcJ6cT0D& z>w2a$R&HU}N#jP7 zi4-x-E`2O3+Obl2)_& zJ0|$N-5BtF>LnhVz@@)*uhsS@Z@J!DE&gWTpF}RbTfzSp?VX%=&VPIP!*>y-Ul0pb_#!eLi5Gk zB~^Qb_gfgNckawtb=|q~^W&?nw{0&!KB<}X%SY?UrXN+|;Z{*T^=&6~m;8#6_;OpE z?cDApi|#aO%k_=v{sNI!TTgF4sk27!(39!YrkR_W<;U#Yv*%sb$#_5_Lihp);|6DSyp&szwn>>n<4S)r{=GDz!`Jt!s_qygesTKb^paNi}ROd_*}_n zh9-yKlx?W_`SS1)O*7GwO-AAC^wzJBx7>f{^0h;YS@utP^}3?f=V5lq**P;+mYrL| zWEZ*Y)~8ultc#+53qJZ0wCeGqud7YYrvDATx^aqm{%Cj|THMIZUla4z_V0N+j|(?LM{n(x&hFvp*VohC zT5mpGUpG!=c2IF@;lo>74_#y0={L=yYucgm(<*BVK`xy4i*w>vQ= zdP-0C^iK_y+rswj+purThJxCUPLs>lsBMoZ>REkF_ghim)`+0&xRaB6zlxWt?^e8h zJ}%{K^il8YdHLZ}b@RUdDqcPHXpL`$qn=py>+MUj!>{YlnRq>HYwM@8pZQ9CAFZ2H z8Cb5paZlYo|D!SWzfC6x);+(YcX&r#URq)0&!3+gvgVlU#VzA1_S+Y<+u-^I^Lg-RHN>npzV&dD_&YpQehx@NO%9nD+Np>#nU!x9Y{26zR|4X8LJ!JLg)y-rD%x zPWv}xNZLG3tEp;=;L=%EZhc{{X{nmy2idb5#P43TH1a$1W!W{su;cZMimh{2U0=BG z@xDt%>z166+;#2LmiWTXb<59`s_{y^*m<~EV_WqLtAx4E_iev2-6{QZNaNr=udl_I z?tAv-30*FHbm!rfdGl<%H@@ww&1p&CU;69kXUY7P(#p@Oo~j<5EGu31_}j;qw+k2N z-H}^=Z}L)3Cz~m+-e0el>UW>8e)H}6&H2aWxsLMx{5Frx*kjI)X|JljOL``L>f)%F zdU|q?LtvB3Dy{VatC;q?xSjg(@BhY$>v>e}d;MGdMB3Bzq-wBm{OpSCN9pSC{N{Mq zn0;jKoXx3bX!P&zka?q)R@`vDMQy9)od?Z^{oDF z^P9r(8T%DW&$ztaU02?=wR~~!gS?XO_YC}RU0LjHU6L-n?fl!s@_S!fJM*;e9qoL# zvApuo*@|^uYka?*G_N@xnO->ma>w%GhfyWUcTc`xJ-uSV)NR_IiXLbmIU{QC_1kTW zk65g!=E=zK@2w9B9X8m1=kv0-58rN_IQZ=W>2e;g0b2ms!d#8Zh5}baQ$2tIPM|W;<6ES9)G=Y+d!0?`oR$ zY~EE-m!8RT=SYj)s%Shu`;(<}=w17?Vzc9&{tFa-OkT#?c31o7q7+SE&TU(_UoTxh z=}X|-DQvmbH|mAfY)lj_yDGu?JSKDg6=$dX*B-9X?zQ>_dHvtG2tZ0XT*aNoAXROP5c{aGXB?Vm3A7g=AOY*hHJzQUi8xm+e~f$PPx z&ghwsE1TY}?OFZ$x|+HmcY4+C+6UhbpLt~^wDtb;cguc0Y44coH>>(i?~C)n*2=Rl zE-#OJmGS+~7;kZn<8ZaLCA`eB0cnQ2W0^6K#e44!?C-{kmHtZjQoAGj`a9Xl zl2?pv^?&(25L#V-KP5fL;;YjGmkqz4dG7z)cVF#Div8AATb{mCI%6+C|(eio9Vpfmr%!8iUY(3-aqM=?kCd3mB*G7B{;4TeCdg zGil+r?QehnXGE;EyxsjXLN0F-S8Pmh0_<;%%&DeA{t1pO`%I=b+}mxi@Qr<43UB$7)vhuqv*vfpTH{>Il=Z~ncj zf4cYmnoUP;3gy@2{)zcn)?5g(mf^$xUsH5+w$1W={du04d!v1q(C4)_vIV!FKDjlU zPrbO|-PO!4nMtSPcYdkausNNdFJroV30Gr%CkIpf{MM@4&2Oyz3>Uh*h%fzDA#;46 zRb73k+v$nnJAyKmq%tK}ri7&^eVv`Cqt?i?blKc_r?>xXnDNVjG)DuY$f@ zJp3hip7_Jw`Y7+<89KA?elKnA`{Hs|?#kU0?4>7cjN0~hPn;WHUAyC&<^JtA_@7!V z(OsUudv5)qJwBTHJv>XjmL2ypo#J`R!}->m?{iNVTM9ZpT7Q4-m8kyNV#bC4V?UW0 zO#XBv!hQMgd6^dLv%{`Vm4D-xdA;t&I=yYTa$i4wn0Y;Iy8ox%=vKaS{QooMUzcb_ zuG+)tD$zStZRM9%HolgXHzFl>+|?FS@LyM+y;Us#{3;i_LWlLU^Yv!@-al6?(K2@J zzpeFL;J{>H_`!Z@`mc(A>=5pZ{EGkl5T?QZ5C7yL%!Ge`nWpD+GNx$SGb6472g!jV z8$^qP2q=E*7ywR261oB2j7%^c7iI@XC7jcjS+<0M;rUty2B^_sJxdzfAvz}KrEs9= z0$n){QUbF_7Q}(#w~kp$A<1=TGPe%0UFf<{UAKHG_%?DB9iYPwrBQAphg!nGz_6t8 z9z@4<(B0%1+O$fL&qzepW`7Z6kur*hu&r)}=~>d)^A+MDZbktVU0CudOcTSB#w~J; t;H>sXS{y|emMn>+%UBtrYqf%aSb#Sx8%TQ1A-oLi z+w&Kt2`MZ}1JR`w+zgB?FPIq^z=XGtp{LhIA5(v0ZzF?^21c7aOgy}e{SCdm8H1*& zbut8avvZ^*w=sas2jKv3W)=|!knPjU5VkXHU}R8YP+-W(OUf)Mo_<1|QKlYj^E|Ib zX*2Q{rA^IWl!j*W+qvF3DxOgdZ_94KJ6=*PS!QrJW5G4!-FJ0wmF<&f-rapS_U>Cr z`(3x+RlenOO>s#{4NFZ;d%AejD!1Yf-;6vs^f)$N@>1B+5Z2(pp;+h;V^RF@g!2K` zj}`?nYgwG?T~b1?old=euIff&)&KReu`>nh-TnyHyQH|Jq#S*?IM#fjs&$8yhUUrQ z`7>wFpZ|MjP-b3U-rU-_r1|p`=2w3E$@DvBjz<#`ceN6Iy{WX97-Z@ns_OG>;5hh#D!0_Saqf3VlaewxdI5IsXWX%2&xb>) zc8mw+|3AMzX7*`uBnKSeXFmS$&(ys;A0NHCUN?SEM@N$2wD5I*@U-`=wxY|LmqdpBYCp50fM&eY2NeK7Xx-M6xvo8L*cAA3Aa ze9z@uH`R=EvpY;;{{J<-<*+V1^WurEv0m5Wv~Qm1e);y&tha83K_3H~joj_O+B|!< zP}uKCuQPwCT8y)}dZx*%3-Vu#r<>NF-+o6W?)QOzVJ|DcRZg}4KR^CwyX7}_geMOy zpAatgP4E1yqbKBl*FT$lO#~s=@ZbB#=X#0%%y6Ltn|bU1?f-G7{@mI>f4=VD^{+L1 z{~11baL;4xi;vl}>HDR7_wL`KdCec zOk2AkE!`zJ)Y)OyvH(WKtQE5s-d^S@a81y#Bu8SKW9h*SBB#T6qXk{ooL~!@kk_&7 z@7n9a|19f1J_<08oH)@-Bqd8id&W^^<)bb_8-06NTC;5LK8f6wxFkS!_M{A9?}ZVY zO6q-6IJbn%?r;(7=;cj{Smdh0tI4I-wkBF?B8#Y}RC zN+h$Y7l{GneTIx=!{{Qph@W>YZJ^>HaIhh11%m++^qO zQj%D-PU3`-s%w4vvCTeN3QJykY!Z!BlQ=zNs;O`KJFROgH6%qc+teQa`~Cm?=jZ>s zwfUcg)#W~w50hJC687)UMjBg-@4T=^a~i9jN%p$O zO!fckuPtG&|F?fjMe4g>zlz_-{QPifzTV%*kEZ%t=`+?dFw||ZsonDB&&RE;-qq9X z>OcOtb?16~TAsM!w$QT^e7k&Hczq(R^Rlg`@;+ObeDDaHsBW)PpC5ldG#Dv$LZn zl{&3myFAf2xM1_$p87==ea>4~UR^xv!EaN~6ILAQieLB6dT$!Sy#3Gwi?SrHAhnjb zJ8GQ)U!S%Kv@i6kT`QN~^h7<2n{(pzPbofs-K3=E>L``^7EX$qB(yfHm-YVU*;oD4 z)k>4Rmb5C%iF{qMCGpX;{4EpGUVECZzIJ9=R#{e>SgWV9vhVyKUC*uS-!93!K0*1l z)9%|}gw8ML`?|;E+T>-jrIR(j?#{AaYqomgwak*;g)bg#$@=ka`@MgUm-mbL-(aWEvcr56-$b3Q_jKC1%z9o=K(O)VzCKTJYp1KiQrprNi7l-% z=A3>6LS@wDPWTt`eMk^9%nxyImERmKlkzNGjgku_{fo z%Q4q6K=W8rMpskUgtcBx4J;F1XbGBXZCW$c#8=@+(9HR#a;#RLH%+{pKL_MltIauD z?Y?(~ckP?L#B{CfWsAv+*Ja%ZJ)Cp3w@+MC(b1&dFUnM^eCist#Vyx^nWbgtwnT*o zhFBLpS{9sddi$!yM46?RO=b&vr)(Fje%p7SPj-=pN7vsi&eDDnuZ?;)S-dW}btFeJ z>s3hWjr`MJ!&Zcgx@WAM`DVecC)-O;8fIzaa_xB4KI_sHlie?0tZ4fakaTPHypXAz zRJbB5KfMzA7+fFrX4ciTRn?{LX=Z=FU2f-2HmmKteMM+RuWGMp?y{x9fg4zaGbJRo zf_RrCdz+<9+uoHBv8L^Xkt>@itIjH>*Ami`@?w8?-=BB&_uLIH*UvZi$_w6Xu+r-E zlBP*%XTyT8&tAJK!2C(XL0!h1i5}5TTZPr`w!KN275};Bq`{R{^>?pY-C6SWgs1fz zy$8bjJkhefS3-i<&SuM9DrlS@oHui>Pr#}bm(ye^+O7OMFA?9RP1ciY8}nKLr0Lf&7SvmrWr>!D?jUgX~O%ZV+1Qg!2H)tdGN+rE~0 zd=a@_rdt*i`7Ue4%vqV6pL$P{)atxzwshC^w?CSW?2?dOdTZ_CD(9fD8lNUyd^5r7 z(xna)8PCEfO}C(}oi?5a?kwB?^UK3OC$qeAqpw8Pi)qhVq2(gDam}kKr_4fALsPdq zHz#>mvpvXUXyn$^w!$R z94B{$dC%H+S;^GLCiLx*z~hUL9Gnz#I$*7K#*q{6m&uhWt=YQUE4nx7tmBQ#s$rg2 z^j?3oaLO=Ixsp~d8uQkybDG(s9mhm6x2}5ImsTCJ>J`_wtgC)&FP{?N%PxIXQqh}l zeKq7A*Vn$}?L4z@6ur2@v&3TKOrfpbyED(cV`>XaeY-v8>+NN0tLH@?FAVnnJ53?Q zbaxc*;xhG~$gq8XrE50qFL^6neEsFu{c%5^ZOxDQJzw;v@S7H928Mb_HS%XeqW(MC z_}M=le(ve#npSo3%&fC^@85h)(w`M6yyp4bfW0^R(~hMas(k)K3?$iZ^?uJ~)>DgT z{`~WAPq5<8AOC+<7hnHhs~UTA&%b+L???XZ_TTjZ(JYy7bV?j#_GFPtjpy^4PdHnC z7jc$5wKKh5;8VakTgQUwtwlfgJg&d-pC95N5IL_l;lDkI0l^jD8lV4%FhS&pH_Ye% z!y7gX4{o;G|DV5K>fA=S7Q3{%`oe#Y?%kJBSQK$&$*#4LO-UY;8d+{%>r4^;ma6sQ z?^dh&w+Z?VU%3jCWwvBoS-E85_HR*{xo^udUv%3}|K)j9b@|UDBJL)dHLLR;ExC4b z^|8C^>o}WMxi60~er8w4>m|H=5=-f;@C@q`<*3XZb+aza;9N0j6{nM8i;eyXjg=-D zk62oM*Qe_CW^Q>m>Fa^-RyHPe?-sMg@(0SKJGxxECtbhuk8+&Vg_^nS20nitY&mgo z9&`W6&${NF+I0>Ys-=-OW}lL*zHkJeF8=uPUv0makfObtMIp1jo#xa)ZJ*@!_G2Lr zEO*B0?XR8gwRZQxzvfF`RV7`W{ry_>zlXP@vtD1Akn;JfU)XjjIjzZWZyntIsaav? zca_=_{oY$~&;R{(sIM`9&vT}~fB$B> zoZY?3;@2x;suut8d-p4}KL7c@=CxUs+4+)a6BYz(JR;%cI z^W3*L8o-KNTp$JgJlei(hO+5LTq z^pdr2?dpoR@5?pqE#LUqf4rSu!x#{66ptn(@F?#kZ5! z|J#SpPX_ZqiJL)QeE*j}f3Av$#sB#9@$_`P|EH!;Ht1;Ot#!7kl90)pn#ArZ5-F#< z@p6#U;v!6H{$S&!RWJBeqwD3Z?4{qY|5(jflWG#)q(39?qDEPB&Bl^-G5_?O zTV%Jpx{FtR53v-ik1sM_WLE5WwPN$s_DvT{57$_hO>moG#Cj;fWXsIX*R^Xen|*%p z>T9r-&HWWe9rv}|?bZGpZrQd{C(gJa;LV4O(5qKU8b8c^ADSY4#6iK}D%bl;pA zO>G^SozvEK95FEQ4G1}D!m4ySM8W0C##4_UzP|cRWV`EJ7u(A_dQZ*1Ocwfd(xdU@ z^oP@#c8e&Bv2$xX3&tO{=czF|ynMF)b?N%=kN)pCbvJ6>7M7iHF&|_0+g;Ignae3I zbHr2C&C^Ef$)rP`FJiAe(7*k~_vBK$7wuD7L|-kA)8qeSvcztoUD@aFdHX)yGiXuj zDuRze9^Iu;_!E&u<;lF24TkUs>MM z*V^pjOQz1>^XJ*u)5Z1GZ{M%`_xh^+&aC*K4^Dl1`dz>N<)!V@{}=4s{bTM?`>2Yi zkJ`KUm!I?4|LxhQPp`c7&;Ebpbm)G>i67OLo_GH5DtTU5`TE5j&fjv6G^Y1$+g5&h z>AvKb&!%4D(9@Kidf%@8QMK!vT-&<#_o9W>J`MY=uL$3?PnfU1d-vmiKkq4Lr+Ys6 zZFeQ}xz5am2M+u!<6Iu-QhTR(f2`7!m;RoazaJ!Q-?P=8V`a(qn*7%%-vxf;66n)N zDiWPCrLXMUsdo41YJPU3$}3AvRMNZeSbY6~0d1@uPm9#k8%h zuiei^-*Q-Y-TUqg>-$Gjjf}f=<9^L_yzSZY>$tpk)B5^MPrLF$76t}}Ithz1@#*3A z-*^68uK)b|iHF_04liE1@%NJpwU7KPcMBWt_;O|*o8KKV*%AS@U#!a8&uAx4x4n74 z^2?H#T{ka3`ev{$nt5aNvs0H|-Ru2ndA(kJi>$e=`9jetYL0br8z;2a_-Nl)xFb&R zxZisD+t;Uu=iix8UuAlJnc?}3le3d&nm#j~7Qc7ioeH-pa?{^Wm7o6o{S^LoTifY( zq|Pc#+cmBG{EM?oCz`*se02Ntve|ntD0`t)je+|2(= zrT6;XzL5Ro!>NkvxhC&622Ffkz0X(5a`PF}itGKVuS^(c2fd5l7hhMi>9khQX}`^H zT&_>})uLItNZ3a2>Vn<`ul+`amH!Jb{I_0s_N+x`j$X;>Y$r^~PI-uYa2-@pH-KGmODJLCHQ-&T8{#Tl>rck}A6sovB7PqG9L_I%KM{_^nr zh`NVQr|Z|w*cvnI>+yiXk9XfE?AaMyw^}0p=+d=^9r+(^*b}|4*u+ZX#*1?M?`+`4e+CJAw`{Gocy@5t|Lu7jExLZNG2X4N*$~cim9200(`xsn*ZIqivAaG_ zUb4??slHfv{*DxZ1JV39G&a02IWB#4&QI~`<_DJ!KEAYMy7YIo2KAsFTkE%%6zixS zy|9?0+uP@4lm66}lN%z|1hdqag?#w;xLKXwyZ-ijAI}%(y1iGwf4RKus!{w0yaUB;U#uQ_kJ!MSLO(Wlq>!EDd} zxZhl6Vf=S-MUF@DttSU(ZjKke%shE%mO}00zx;VTy*q#2-0arY`MUha``e*M9=&ky zx3<4kofCGhH*AOa{qy~j%L`VuW(QjLH|&lJPi#Ow9V{>+q* zjI!Nfn*Hn&ztHt}Jj?Z}pU=14_j~5ktI^w^?JrBudAI4gb=@|j(r=rdf8Xd6U$^9@ zr0C^S51!5(v7_&+(MIL+hx>vln(8XKEJxKw6q--Kxuc z;&v4g_wL*8h+YS22J8u}OZU-=e|vBG+xGzmABz8mJxH>8CvC;}^{&~>RieSCxD7u2 zuz8=oY#ql=ujJ_;jy{SM5Ue|Sn4SIU-?`i0i$#^LeR)u<^KDSKke7M=orKL-xp(bY zH2+5V_V;1i-rdoZmkaCTyQlH~xpiwr*z+?1t4$snHOst-Z7}S8>?L$1bKmzP*WP`z zR&V-Nv+v~L$i(MDI#13{+hJMf8vpq2-}Y#o2kq9ba$i)cK066JEoOVeUUI2wp1;;r zjU&lgos;${Zm55BYX!@)z<0Y}vhddL%4EH!c6oY^THKzA)xD?M9QCxhniBeUeK*Na z=vkz2e`#`1?;?S@ibju2S8~@c*w87vZ)*EfwHZs*?_WQ>{A8Nk=VK3UWioEEIS{Ds zqaoREx~S0TYD#lW)mZ_a#NynLf7NH!#(aD1b1|YJeVGQ=rIs+6?b|1N)Q5||yB%KZ zQvXk9^W5BxHp@2aooDsqZ%*Rh8CXAm=Aw%dC(BPxxZakuXX}Hay_XH5Pj64@T=6_? zZp(Z1%iZs;TySx|Yx8uLp>(T8q1ogF;cC0@cix2lH;ne-ObSp@)0fv35x(A9u_-{L zuKANeLFDsG>P-(s=Wh+=ee%3l!}@Hh+G7o~4Ig9b-(1*uXT@P|4b(t z&YMm%OwTWwke0e6JnG#>g?p#&y0s`D(Q1Egc4x_>=hFP1$t&eP`qi5EPhNRe>q>?f zsB^Gd@nOR2dG$`hWw%%Re?2*0V~503{#bXjI;~CTzwWU}ZYw|cDcN%Bg%zz8n%7$v zy4XLo-71~&p=QZ`6PbQ z?)jHZ-~SeVrMjX%J&{MXDm#DXvVGZ`t-k(!bM`9tqV2*Vg69&#>(@C-cD>9z+kQ&q zmW;0Ql=Vu>MQ3lCcJ`@myUDUoE9y^(EUr`)GItBU8r^ozwIXcZqtL?DcB?<{J@fhV z8EKQ}>M1jIkFPa)b<_BH=d9;D_SQZ1JS_N%y=M0Iq|57T7O$ST;pgWaM|?l&uB}-6 zyzh7Z-IX$SHj1sQ=DmJiROXVouijDOee}BTWii^kQfvMxZ#nr|y-Ys&>;5BFeR4Ym zr%TnyI-Yoyl(IZd({HB5{p>aO8>UTCNZ>7aS@>%D8wIV>h#JGMZ*KpLoM2(nl|TK4 zVwbmK*QeZ50`*0`uca4zSvZD0d~1?jxOxri*Nlyx*LUc0Yz=&+>UvhQZ2j%K&-ba< zUv9f>!6~)o&O|NS#OZOVyh4nGdi(ZQ*)h_GE zfBwz3>#p3F)48|5noa5`YwqAzy-~?pZ@D2?Dm3PkYoPJ|19NXI)RFG0iu%CU#bL}7 z`#$oAj_=FyJvqBVgDYE@tLXV6UAu+K?}d59cRq2wvEI$mR)5-^@+~KN*X&a? ziMKfP{+f=Y`eievD3hOiFWA59mAyaPhnGLkNV$8C-PQGvF6VqW=d?fb=Yx7i(0tf; zMq{ByDFz16tQTTF>^9PD9K!?#76whobez^i1BLCseqWhxro?!S zC&>uZ_5+FLKbFg_y=X}T?d0W{qPn(PywUa!H(qX3?4 z6IH-D**3jcnbEc0`PBEzYEO=T&%I}3BjOadzi7#~mnvP(3ttLGr%pRMPtfq#tF)Dy zieJ{HX5CM^zIt=}?)%fE?ITk=H>=+Jaqq|8PmkFigWSsSp#H0BWJHeX>}%I;b^Dm= zMO2?fSK2+;cKYO2b6LM<47MvSi&&~m-(UFhX+rvWIhhN3_Af-3>V*Ya_StcN{grmJ zd`^;6=Y{>R{(Q9Pt1bQWaaGSW<@E(iFS(dpG737m=7h_u^1~56Op;!{*0$60KQr!q z5dCf6<4bOp6)IPkzL1ZOj~9UX}0_QYc|=JowICL?4HQ~YC>fS&wnvx z>;2!p6|60;%ikz}s?a0a?|zweeQV{+pg0Lhucq_q>CcOlnvTTp zk6*cUo|$giqkrvBY7^9+c5dwR`)+%=Any8_RoeS+?7g(^@0QruoUOO7JwJST-C4c) zPo&GaWar5LyKZ;wWyq$GO5rX8DQ(}Nm)yKE9Kjnm8x`yh*KwE^^Zr_v?!9@Toi&eg z5TcF|Ilf&8TA#gaU+BO|G<;6 zuZ;|zF@Y-j09fh(8Ip#aIv5xj#35-<5$onHU0`OW7y+;6mVno>e1vZ`=SSd(>9 zc=6(y@oGYx3XMK09qu=#ipL4QtN2*Y`#rzrk=w-2^5^>P>;H5ADckLPEqbE0^u~SS z+38#3(vmh8{_72p`uAJjga7OLlR4JWdrG^W-tr7v{Zq$#+vcZ-ZhBm~d+I9F5yODG z?|)vtmVfa5Yu?5Q9Oaw0zwR=NUf23MTVv(vJ#}72GbZsZOKH~pnQ$t>Ak|`q(WT&D zf2Y)cOz^rd?bj7CkyA6tO>Ies?92&DZ7EJ&5tBGIlf2ZHbm$5)2OXK=;~|)Bq@Y@r z{U}lWg!CoZB?xwd*kktKUfp496I(w3GE-zI(6MaPHa+@0*2* zKkonkxBma{`TtAy%{|{QAgvy+*OKSEBD4PQx2Nar>;LK8yx+ApCfw{?xxZ}T_FHy4 z&h>LgEIM^mP26?U?EJ)&tL!c*v&C_LJkGi%-`lG7+ml}B-0yt6|5aprZ|L@$)A*HQ-ffHpIUP`tjpf<*z?K{cU_i5|$e;se0&aa!s_4@BW{iMB&w|5oVg#S|8d*9yI zENT0^`xfuF-M)JE>sEiK>&^fFNWZJRSE~Pa{q}ifzb&Yz*R+e+I zp9DMBc-T$J-CtPOwsPh44>yZ83PfhkGbp;OQmrpm>D;=mn`Z;tv5(oyGrqRYv0Ea) z_qNR0`=0d=>iyV)FH0T!?e-+z`+C*Hc-7(w;%#4?Epv0_%%Tg!dH_85a|&aV9{2I@-}cYh?Yrq};o}FKraXy16Ak0lQmc<1UmI~E z@O4i3>E6#vpSP|1KUGedr%&R%eUp^d*J#I=W+!hY#Fb&i-@djqvJOV2qx_>`BvV9AxUM;oOj171!0f1r1F?TSf3 z&odAG$-dw>cd_KRpE{~b^L#mCrMBK_&fQe`{tsK&SGP-lo~eA^>hXzv!{(c5yMNv~ zx#Z#b=R$SMW@{c^wfWY)^Yw4_CeMDEWIn%HSYaKXTA9iH+0*`hWBOm=U=d*`@H_tQ zm!Mf2X9g)g{r8Z=BKnU0(+m9@+3K^`GXE={XY)d)uior* z{?%l@8M^Po46?IoZ*RCY{mPZ~i4P;!iL*zuPPiqwGPdgyZ{fb0jnkGJoR8c4=jHr) zC$~O(zx!s`{e0gqUb5A^Q?d%XZYFK3WEWGuF1CK*w6{e+ak7@cUwD;&Y~3 zJHxmB*fDD@9~9QzXb^jLT4(0|$#!8c`*a`p zXMdRK_~>F#~s*PmWLH}vhYWlHIZ=a}rzyFOW-=@T5-($dsE>v^S+(JMp6M;aQ7 zIs)xeIeR0-el&fuIOBYG()!?+p5ED}4$oz`++KZd#oBY*v=v2zP0zS-v&A?ZRqb#6 zu_6AlW6s|B^+H>v{yi0Ezy70pz3c@8-hD;u=A5q+efd`CPwU#|Q(tEuwz<3ON?L)) zam`6H=Um>$V)Xp?Q>(d-`FaAXLAp+6@lE9|!8Y|jKTV(h>HAlyHpgY*|IYpsDbcN4 zKWBb&a{r#ZIre+2zB=7^d9*umap&=~tS|Hxf@Yv6;=eWMF{&oGc0RPRKJSFb& z2cNk%`|a$i(98s(yJgG<%D4JCBW_2Q&27rI64&#Yoww~~P4WLD{GIaE`^0~-^(3_! zbT#q0?T`MXsCQ6m$)}ljRr8Osxm~-h`lo)UWV!kG{I!-zy1}6lI*GIP?rVwS@`!m#r8VgO*ageO|2Jw-~QFRF~YznfRA0fP5!y`TMhOV%e;HHEu6Ju+bAorNY%H0F1F&U<+#yZeDOxuTmh+k;X}E=*{0W_(rs zQR>&$u&_hegiZTH?sVJ#}Ah}at&AZ(GMtp7fR~x+WmS0Fo{jQ7L z0e75P+NSZ$j6UeN>B(i&_HrFDiNy`IN@=1Q&ySXMdo$nYUvzk8_I}0(Hzvwi-+a1x zEvG@+{#BMd(G$MhJr+>SXD3AQ&p7eb zMytMYw4Oa@`HQDJ)k-{k!>aWh{P%uuZL5x)bnW9@PH*Mu z>;*fQ&b`Vk@+JJtJ*fxo&m$xy*0w!n@e@g2S1u+93cg^C?DPK1gEdZ=7ICF6ULGLB zINRxFed_W6ySbeoF7R$yt;1il-ejWq{yTk=YBeouJ)-(tiPp%Z3)c;K;$xi-%yJ2%tvc!(ln~=KG%<`y3_Q3tl0+n-@&tHhvJ4^gdMa|EIGxW#+f-KJGp5`1`^`|2^l;Pk%M5tq4j_ z*)!2nV*c~ZrKTTkPaai!E!wt2E-NQzg*eNOEuv2k7MwLV5=}AIP5f|(FJR9pvl)A? z?m6Xp;o&F0?Na|<&c3NsKl^>r$30y}b~o3RKl-dQGkv#Z&w*&k^R>H9-*-BGdj5=# zrnO9W7p*z+D{q^jML45c;BN0Tf2S+!KH7ieiuBX{8a!+MPS<1E`@d+(j*kCMr%Il8 zwzb$V(pJrFC{InO0BP{qW1bI)g$#5l1}24XA2 zk7Q>5487##{c=WK@|Nj*v5zO;l-g4IxBmEtmv29(>(Af+EBQz4{UrVKJYTCrgj}np zzl%A?+tDO*=1XVN!#gK7A1j!Zc*cz<`I>2uWa`BmiD%sSlRE_>c^}&zZEf3VBiys> zrI*~6m_Ns@)K;)uT>c^8o$zes#X{cuKjtR)+8Sv|8rHrOc^Z;v@`FA zJV#Kz{;JrQ;Nsl}nfrRQa^4EvcxUu`vNQwVm&i$0(KFuYbe(WcQ%T)$_D0$F^NYXf zBpaXp{7t0F>a_dfzj=M=iqazvWSM?~@;U zTe|jGHoyIRqxY3Vz)aQqX9A9`@(9rX@Ox$MYL5_xSGCfUZy!_5oyk%Av3igDwf5UK zlkYwb-JoC7AO7%uaew&Feb43Af7<)hHm-HwXSwyOe80%8|CD*%HZIhA+4l-jug}$c zR<->7Ua{3A_It(EX{UjLpj**JPx&fFtKJ|ALkpM?-km4Yi}{P znG1-XS|{BRBDbrmxA(+P{coB&YxTZ`Ug>@NV2Su|kuNXxzR50hk9iaPhHHq zja$9j@A*pW+xJ>Nyv~{aL*VPpm`BM~SC8gieK`Hc7hN+4lY5o{m9i%v&p*^suflpU zUu5xz65(5Wr)q7i$qm`xd$m~M;o-6c^93*7-`MSxRyFm|g#Le9)VP>qvl^>DBpzE@ zIpzC`Z3i~|OI}V~=d{l0_3KGXRTZjL66ID-vXu>K_!V7MqCc_#;@6T zBT6TPIemRBsmYPFiA|z6|I)d~l~>#pPu}0*IHS*|GuNtKF{;fqxmEw!B<*}xhQTb(>v}pt#Nn!bEPA+8E0Ld=9;i} z(bHYUFN@i)^{rXXzee+hINuu0Kh;dxr@q@Znm(;QePEW;eaVR6t(|Pwrugq>%3d|i zhdG;TX=Q@%)D89w%f<9m0KYle?DEaW?$|0m=pVR6V}A9ZOD(D=C_LV%0|)a*#TxImt$>f zzHK$0-^knEQ>VK*`1xk1oUoHjPYUNeVb*!Obi?NAk59v=Pbds8J@PfK@AcC~ic9?u z2c3#q5_Dqgjdu&4YekwT#qId&fB#RddVSfU)~S0nf8}jnrxic1V`7e+*v*{ESfSim zHq8s3a9Z##-7~c+=KsQFMMsbOtnu1^v^MPO8qvy`ec#%b75;eAcJ$LOkITOg&e7lh zc1LDrZp?b+hQHig?zdiCS{FY1>y~xX#eO%fn?9|+{q@qn``%VW)Y!oKO#E?oM4 zsr-QQk2qW78%OqCZn$_dHtrbmleq7oL{)^|_4)N^(TSEl-#{@T6; zz1j2F!v7tOU7KEh@=ol5l(IgR9Z@@eJb9OxzU|h^1hxvdomrx~saK`5e+$0~SXLRz znECAI@ijbu9DX%i-eq;=m|^#(Uv&~Jk0m6RP3(E@QX1Nk-W^jTb78>=^9wOgi)SoY z=)|7!_3KfuTQ?r9-TLH8{T}TzO7|XH8mm@5xNxfGmRXUi?8awXTDBH4TK~c;TzL)o?o$Gt1AZh8C0Pa@oV_0osyuGd7UpIm+RQ}%vrx|6==!j9bPux-5Tk^36!cQfUG z;?$H_S~>0Fne!0>%QilU)Tj~aROw*Kx)M`ga*eN_`KeyyiOUb(mQLDi((f9Z;g{jcz$^35PS1qj!7}|1e!W~GzbE{|j=yJE+j7kxFwXc9I_dGlivfk~i=}$pHuvzy9o4ow zyQSEq_}z!n&3V0{&tjwxY89{ZwNfg6$8bb?t-<*@)|1SI>kBuWu{8ao)tR|^fw|PK zuZQZAPT$Doz3}1C+2rk_xiilezPyp!{PoGkXwl!BHbzgaFMkvEcb|IMYM~oP^Fn{E zyRp`7Zp53gzgv{cRtHW_d=s|Rr0;H)%A4N1uQIKYw$GYYdOXjX^UKEDd6W8Xto6!} z-+i^@z+y}H7d&RQZ?-*KR?qVAoW$Np{4wYZ1?rFCA}_Vwl?72Up?X@fpP*@Cb7aSUtDR#mloAKbU$@X`-9qC zt~k83=GN1Km03omJ4C#S+r6i5xc~6dr4q}StkYF8>-3n8Jbb0{vS^3MAx6IGw;21M z6qKGxNH5r-mDhXn*B`#{qnirfr9UmuyfWD;hHF>prWjs9>*PsKr4)kIPn#}quSik# z_`K)lt?!*lKHG%KX5HB!6;P^rOzrf_1IOmo?{vyMmgdzu<=`~W$xo$r%%9Z#?lec7 z=2egQDCU%h-o}rP%|CKViS;5ok468RCKu5ecIz&(y*|0H`_Vj$z@JuYmiO~BEkCj5 z!|w{Wjh?dA!Dj!Irzc(DYSJomxU-t+y1R<$u{6Q&S`#^iu3e3smw9S|=lO-1)70m@ zWeR_qyep<&KG&KdeB!Gpf40gwqFD?2?`%K1_QJl#`}0ybxg&yHR?a`Nrem=N|ECEj z%5#%uO!G`SBxI_Y`yyg;OX?-zz}0RRd9ly^6;>_joaOKQRaM|?=1*UVf`fZ69FM$d zwr8fpl&ABiyL!$`iP@myeYr<<&PSWxKMK8{`#e5& zQD;sr5Z{-b(DiJ|+eY>t$H)x=S3{le9FzDGIpay@jG(w5YffxBlJ0oOb?+D0=% zcq7c@*SzRy>NjwG;5=c^+_1}f#%xPX%#t_wpUw}GkdHi+Y^y!l?yXd_=Zo&1jdR-U zQVkS>?Yp`>PJF-ph~bG*eWsokv+Z|@Cof8w=Wj4fHpttrznW3bi0yINM?0T8$0U~Y zsM(}@%A`o1c5pOFEOh#$bWZ3-%a?WjlTvf6*pAOg>RGyD>+G_Hh7#ec_rH{QbNQ3B zkl{fO!55J;zhqvQ(AlKX-l>1qbAo|Hiy-f11$8-pj`sQ!zO%Y_?2xm5FHx`ZsaIUZ z(c4JghK+H?PLaZg-ws?$-r$njp?^zgyCIwBM3qa@DRmM?^Hnu_gy*L`*e;SO=GMyT zooB_yK0E1T`{T5Nn}!iy!FG!>tk`~U`Lpapw+K)8{eqnOi#IQBbMLtEuZ@tdT;Y9 z+J5JxLUL`E`RVyJ7pJ@bclBkN``Yqm-d?fpHxEyWUzi(zVuIosA^(!VTBXmcXQ?j# zf3tG;9jnbp!`6tO{A19sGwpU{;PL*g5_U#$NkOuO_0#=pw~OqGU01d`&iCpGcHg(j z&wju7k@?_`pzFiK>*jAd@LVUo&aF~|MVDpyoaX70ojy-?epq>;k}sZ<@&B`@l^zEz znbJe_oiAVC-8!{&yCqB4SC$j8>-JjdS=f2TSn`M+yH*}^)x^v@yF0r4W_x6GkKgYe z_Inc9-Tuc?*Ke&qn#r}zjWb=*vq+IWnWeb-yyt<-J;y&-pA{CoFr#JT^kp$WDvx+d z8U7UR|8n|5es1CJKl|Kd#kZJAg|I$6Z@Bg7v}10!rQ02ksTpoK{m@3nc&q1=6Q^zj z`HM($?osNy9PlIV)ltt0s)GI%Q(7XulwUnpY_^>@eZzz<6`_sOf7ah={wOoi;O+E< z*KcGr+*ewAwa_zpHNR1A&)VlA1wXE^9WseOAeEMDSeIY9Wb4tq2a%D|qVp13Z8mEMBlHxUXab4c&K2>Rz|j{`ufy4Ti;I9y<;XQ?yATX=rU!(1edr;td_l>6+~GR zryN!KeCUcc%SngU4X@m6Jd!r-)Dbhd`!bayXN|AW7oV@ww`^OmYhQL^ZtZd}Wl5$7WO+FqV>9~PNU zN$L#jahJ1hmJGL9?#*&=&9W!WSGjYxz7;yWbW*+AyrLaTO!`~I#iPOuH$8um^P}YO z(n*Y##SbQ)KW7=ULPxb#wuR}l;NjNAE4xkjq$WEQ@8~%_dsT(h@ox7BUiV`0+qt{X z6fkB+@qK);XQc&$x+2$<*s!BqGjCc;+r{1sQDxq=rI{zaSA07Eb|p`N19SNFY7XbE zh<_VznrP%zpS*XniQdtbk1}P#`991Z}F*+> zVEw+U?oDFN7X)vKHP>HAwDI~E?LA?$c(X;p?wGH-vfiJQ1gu`Y>~fU3ApJY^bdrE> z$HJoudVRW=CdAr&oKe)dURu_am!)Z_TpmunZgPD_u`n6r_-$0 zk%21zF5djm$ydT}q>#SKfPc<=hwVvy`!dRs&TV7gwQ1H&&J8!CJ*z#^HgQSpn;Md2 zRKNbPs*Azzb>{CHCyFfQOE_HKsKr*-e%xf)bBWBQMgAOTV!Nu2ihlU8eUcVmp!SPz z73oexK zJ+G{ZeU;jo{7=lI5bvt}?UJq;I}?NNzlip9wBJ~}C5(wj_Dy?XJx_89{tp=9cVQ+tA6CTfVhiQj4nA zTIjhY%=xnHTHE^E$ows0>JE#y%BtMGcuV+@PH64Zx7Qcy3$C?I z%#>VfyKtUGRCQCHV9VpT$Jg&}F8HufN?HDISP*wrh(TDB$(;6oH*Oc!*%kkJ>#~XS zp7*MRO4e+VYuV=47|tkd*}lB?->0Yg`cL1#{`%>K`n-skv?-Z+sNb#3p&*D4qCpX~CqGAq(r_}9(vGGqVdiLYlJTz3CN z=$%=HKR4$;37KXlZ8^2-RPUUwyt!r3&I0K^w{n?NUTwL}_T|IeI94Z-pE;NEoPD;{ z3zf~%xh%Dz(8f6M)>^KdU5~>xf8X4&QuGqr9EG>rj^)bu)@Vi7YexP(_U(u5F1|BY zQu8m&JDqy`b=l_|CcC#Ea}0`)vbcM5uU*L$PW3mvD`vdBXA``s+I{mvFQplFyRT0W z3@YAq_JqRj?QVzT&U9N&dsaG2E=$Y&+)1tXr6$((TW?R?^7P`IkYF>PXtSq1dtJrY zBR(yhwasSM^sM_CW$QKd-=x~!(J;Nack#@HZHqixOjFzTzG~xV^40p7kybHj%cN54 zS<|z+Zf$vbu_nOyO6qs1Lhg^>jXpA#&C0W$C7kuiYuDS1uoaOR!P9(iE`0oY)6Kn8 zP4=Bt&e~h)7&oQ9dGZW}H5Vj53*Fp1l_%n%yFJ&raO>4ca$E1-SlE6;ROFrBr-hzL zLKb;bA66Yfs=(#lBzP+8d zV_0;G%@}9?)N@{IB@y;-Ig{MR#+2uG9gNzp)nskGX=1#;%_UsIwm#+kzbUL4QdV7= zCMJv$mFG7w->~4`o7S+`K(f_2d6JODp>;2N*ym-vXu z`D~LBs#LY-Wdv7Kq}Sb$&s%%g=O0?jrOENiJUc3N_lc6GHQUwezTeM(>vLp2_^r>e zx#W&)GuMhpk3+Be8olxgk2?rmz9#)9BaJKZ?~!dQHANkgH6oTQ3)xciZf`}_sfk~| ztkmTC)*2iv^3Qgq=Be+sD>b(mYQrmo(Xr_NfmZH>C=(ryM%-E_hJfI1lsPRDKKJT<;$#|5igo_VrfDv+~l{S~(=Wbz&T z2^-d|-I$nqIBUVQ*X{53{g(%=@aoQf)jd%~iGcyMFebnocH{x_feTyyGB7AIKn`4( zoPUuYvRY<){-QKrRjem1oQ=(ftd?1xV3A}~wr2KG_5<$j8M2dfZq6z_u_;>0+GbUnz)#3eFL3Uw8kpy04+m5P6l+}S@y6Ma;KPWW8d zC{vR9Gn~(CP5lR{+t;@xvo(H{Keqb1e!ar}yH^53mv?UTT>X2C(X~*?<+FP~mLD(u zTmOHuvBTfuDOV#4v)7zD)p6~$P4{9eZSG{}!0p+=3=KZwvJC&e@Bjb$|G($3?@X_JTQ7JK`@FTbw7en05tZYxw`U2pGE zbIz6*Qmztf{;^6yx$D!L`MrKtUqVCgNoE$#4^1tcF1EE$J~VR6nP85~i#P49{`cqT zS>OB#Cu74T-p5JaY-wDAnRJA z(+k&6Z~EoyO80BOp8kHD{k}V4@}H0A@7H}Bf8C$?wfLV88*0D*`Py&4W53;MFL~Zi z`Sow6?R)w@KDd?F?*H~Jw*+qQGSiuS>%)W3=NI|zTKg&cac%7S_2S&OKl*n6NsmuH zy-BS3%l)adXBlPxlfIS~IdQq>rw5DgFFF18?beS*r_5h&n6}Bv^wpYkm$MhGNOuX` zzxUtIpZVtbY?|?T-7TxigY#BfEd67*#NNGf-nGL*Zl(1uHcs=FT-}-SO|+vSNdJWu^bdNsne}8QnL}{3Kd>(6vbP zsY{&EQhDj^TPyEesec)3{dIciXKy8r=LhB$G8;ZBTXLjPAWyfzg>8;ItKgOx$!%MI zr{2k36m^7m_O{!`EuR*iIK4tL|JO!8ZmaCxs@S|9eVxnZZ}pE#>?=P|@p0mcg`xY! zTF&$QIy&#m+u5Je+_O?xFXs5wZf7`Rezzgg?^VXk0ZkxPews*>fNWtkTuKR00ZM(IsK3?+awtc$g^?xTx)yw5(9X{qJWZNaCG3{xv zU5(P_*Ll8aGY!O)uAFQ9C0iJh8hSxs(SjhM33(4+OgIlhlw+qiMWwlfvnnjocIo&$NypgWX!rcOUk}xPRfh`x?wH9s zao^{6yydt1wEixRb>(Ze{jkeyU-j>Ay%imOxxe-*$}KWkWPg6)tKZ*_MkilX(8;;{ z?@WPiJWq3bVp!zXmG$+n@8t4d7Cf5EVqDN}$Qd^GXt!$Q(*)2Q>6VA20nH5GH@3?M?sL1@&_`e(s$6 zY2EuD=ZSx^8J}?rTN@Vi*o*J*HGbLe+r8?wB8PYmV+_Y{!+9M#*JjnE$oW5tQgoC1 z<&twy*h;1B$l2)IGynZtk^W=t!5fVd_13r4BG)qUNXq8(J-)O3$JWHlff5tX)ONE! znYpg1c6qz)6efiyrNf8dNKE$$Y=^>Bk&zo9>g$XMWUq&$?5;bv#!ey^y_d!UZAI<$t|?p2^(bGI8~S#Xn=kQr8$9 z`ghv0Ugw(Y&NG)+`%0~seN(%^nwNi5$&AS|qSL%KvK>4+tL&O@z@q)3Wvd(H=N#It zoD!veFje;O#`j7$glolTz1f|>a-w|U=U;knX3r~#JvcAd^!>B5{N}+uT$4X0d{C|2 zW?PzGb|m45caz|P>01_CT=(Xhx%kg%*V7>ai4S&e7yCN5UihF;zIo)Dm)`t|DshY) z%AcBVUJE+qUUAL!X90824KAmc3Ew+!G*y@;wOeOBciGswyx-~e48y1ihVO26y_&dRCi`HCzrFUB+=OL$X=a0^83(f!W zv+#JH!$O|Z5#`yfk@rjA z#5JE(lw+H_cvW?)pu+dA^DpCKt6~Jcg-w|K{r0Y0F->`{gO|5uex1j5JC=is^+DP> z#)knLZuy?~oxgd3!XCw~)o12&NgNVgq+5Bv^35rssaEy1F;QP`=yx{%YKb|$xqW5n z@0KWreV-zi`mb1+tM&fey~g5%z3W%cTg%*j*shqJ?|A(J=Jx735D~YTxqb2UvIie- zu~--Ea8H%B*fTA}y1>HgE1yia3Q zK}Y^A5f|jT)%;9Wr|vV^{Ogwbe!pvej6E^S=Q44+zqMG_YTtU(n^iDBgXw?8W)=RQ z(mK&I`ja=ZnVmD^tZbLGe8ksrzV+sP=FKE3t5N9p4=pKb}*6z{oc>Dlz!xRaeD+_u(B!TEC7#^l&Q zLnfmWCmde{tXLnFbcd-+-Hds~Q%9ENa=glg7kLv~LbDyO{^-b_*;;cfa`_BHGv)RN= z_f71-_+*pI6_bGO)tVFJEpEMAz$y|x)371$HZHe9IL;qg#qIlAIAirAmWiwU^lh>?9&I~$rrzZ4 zhc%34M?~}Ah+Hd8>tp@W?!lr~9lL9yT*ijHjYnB?ns0C=bzk4L@>Ri%pcAJhH3eN# zc>`wM=Zl_Oc+rtDb@m3w73XZa*1i(hnl|sT(ay@uPb(^S{lB+mvO7D=+b4m}T=(>h zX4pJBaq!7RgTKxvHfCzZ7(M?LX5q7TwoMj8{jYm&%9U3xC0)GvdgWwy_G_Qj`z_uW ztM^;{V?L?;?q}l@!S8$0K6NafuGU|X+jLU-U0~#=j_Z@MK6NY(@t6B3#HZfhVzTLp zp#7%CCxPA%I5``hOq}8}&E^q@yGp-B5BIt?a}}O@$eG^x<-MrrQ^(>ds{OOtf4AE$ z_m?Zw**dA-UFPeWlZ%;ut;=|pD|%GZG~{u&^`o6VT1$_m90@Tjnd0)FE%M0cD?f5R z?%U%n{(bfipG&Qh?k=6(Uz2yY=)N;HTBqUP{rm1*+wk}6F02nM{rvapuZyOKUFYeZ zeEjwIrUmu4C+w`-s#Y_5cioDp4y#usfr6=%6KB0Xetw_Pr=A=28~X38=h;;E?55V; zHH({0BuiXmj=UwExcT>&ZvFF$kGItdcF&dR-t@vVb9bF`s(O%e%G7JopPofUnrH4a z+CBf@xBlE+zP_6_eRsW|x9Z!eP0EIg&L#_{KV77F>q})-+~LU&zDz0d{u=Rjo9*KRftagr@WimCW{*`on``ehs6U5GbUo5ZjW7Ew8z8JQ#y6qWo~qx3f>s@k zOX7UGQQU+1XxyWTo=NK!nH=AkdN3W0b8ut@S=QvKBu(ZA? zKxN51T@9f{-1&^};-7MJbo5-@&ahb_SgZQY<5Tl&OZL}#ZZA2ukxBCn&-E{I4Arw2 zTE5d2W75twZ<&&nlNQPm&1U!YUXob&-YctrcJExbX}5+s_oH^dz!z7!o+}A|-@MpP zH!bV(x)YoDx3YiO_*$+#^GQPCm7>mVZ>#T_)Vp;Z6}oJ>a}l@XW+hMiK8b(??TmG? zi$X6rEVTW=b|cA`cioPw)9!@Ui)K~ceK|*Py3+lAqnYJBGqiWTwwRitsd?g9MO@jQ zv!!ny?U6Xjxzhhe-({oouj>0AwQlX*#2I#|a%SVUjeDbo)?0VYT>f|8J2`i0_7glc zsozuMCflE>Kf^0^D@`_3{@K%`=Zzj^Mdw=_yWX@~HlrhOpUiU^$FK#G|B5Zoxw77B zj@qw(S?RY$SL}*IdG{yZKX&#B|Mo~n|KtbJwXfdjh3-4Md@|eYX{V~nbxzP_NAJm<5q;gu+U)(U&9?aXvrq0ha}^$0Y6i@!dOCrr z!eU*+uAHuxq8{|O!&0=%(T}`-TtdfFYMir_#?R8SNh+}Tkl(g zeE-iXB6iOR*`$dlIV4M?ejJM^2@g9RJZ#_C33mjX3sdZFgskfRNxK!_0rXS zRSL!7vRg0w{p|I&Ly=?YhR-55OB#&pbz?c!$aED=$;x>a;!zx7pM5ou|9dc3&g}P1 zt@B&#mo;^quQKHOa_)Py!N-Xv+-3ojMOv8M|9mNndbX|JWLofovb7&e+!mhFJ-aIB z4Yzp#H!Gv4wNmQErtZm}Ov#r$B27;4O_(SgIWLQI+Ns&hr?2%{ynZS(YyGvv!bK_k zchn@UZ8fhP-MV6)#miG&w-?p=)>R9+pK!jY6>%%DBP>xsCGL^+7io6Ij~#wX4hflP zCSLOoxU%Sz8q+hWxcVEr{Ng8E^kSa!>BQ2P;weWuQ;#}MaWV7@6w#k<*ky3&q|t`G zsWUwGnU_vrT(NiK+_;5T{;*1Z*&Q!dy_xaw9m%h~r}%ELa_5&FP*!8xTg`JN)c?-C zBO4~lt9sYJd^EK;tWf6WiS7a^y^Z;6lODZni?nj6Wjg%HhRu6vU|_?U`UK_se#tFD z*SE*ItSQfAKd9yL@_L3-|B9?hJnvTWiZ!#I*w(yEBIiV%pf7{Xu>|LDm$W?Y%saU2 zL~lXUq6^*0BEqaY1-X>fBU=kylx{fkdq*&p>g${~mdrU(w<$Js*1m)59w{ht-!>}T z!y(ws8&m&MwXao~eR93WvC|E@CG}Cwr7zb0bkJl?wY!zTXhtb$5XL#Q5iu3+xzFO3-ujv+;iEIg}zK0D}VXPzr<)jaEmSPnan zqB>J@#$DM9_a783mdLiyD_;0?ztr~B+!WWj^2n;0IS1UFm)mk> z+wq^|S)_OU_SU8nvw)xbob47@S}I;iYZPw?%AgLHKDG5c&CMX{*fT@9M9*5*m2tUoLT-$gcBk z&aO{0>H|vWth4#Hx!w5HspeVgdJDC4X4_pTe0)=E`}2P_zbfkw3vUpc_Po;Uu8Wky zLCxuD`-*>ru`PIhbhGU1Ewl69%#tu+OfP9VwYMx*V|{Z$!b0I2VTXlxU2A+;$#*+z z31{QiFs-vS+peBsaEY_na8Wb&^itXV7ucE%<|jl;_yq5&UwD1CVeRc%)A};)C74XE z7}}gqj+Qthe`@JWec8*W7%GaC4tw%*&wjsv;rP*(pF8}8w;x!STXleQ^6R!oriD?@ zmOOmPtp1AUeDRGiW!{3_T`{wM8mX`4admiq&>9)hu1xp&`0EtVM{gWUYfq!u76#luhfV+BQ}d*S{6uys=eD z>B`$E!NeGq+T$EWpVm#a-TvA1dRN4%^0gf+p1+Q|x%hjT)2vu+o+CHbO||8??z80f z)}lYQFZiqsbl*!vEzVXgS+b$nB=Zg9PmP4A>s=fXYqMQlRvt?WYu!-mIC*!N#2x=- z*-Iy$DqV2d+-II`%QokUI!76~u1m<&XU^|PW^K&5zxO%Io82cjFX9&Mf4^>SWAClC z`?Gp(>@ho$Vc@;b{c;8Wqv)`yPp?(*XZ@ADY?=Jxm)|?3gw(hL_pWag2)9(*sZwrb z{f~Raquce%iyys}-lY;gQ+z|^bP3gZ&vjbH(iYrP_89)VckAVumUA81ErHLNWjH*2 z=IyWlS#D)~fn(?E!sVZt&IS~GTyJDvv9)>K9K}$vcIK zUD;uKRJI>1JhazgX{0f6wT0DE7`d5Wz)heZkvCT z?o4w&pc1WDZqwrQ;!$>3d)6|MEY^uleZ{KheQw13ahtJM;nbTLVga{NuG&Z!f>O7yN!w44dQoNq1y3 z|1VaIbHpki zZ@#Jj`$VzLlSI2}tDlqZ*p}qql|Oe%Cgydgv9bH4vju^9+}+VP?ry(5`+UXwG`Hu> zE5vpg{-672j|T7TBevD(??LzP)_NdU-qhzCBI0Z{Pms zGxI}T{{`arK7HBrA#8!4#-6A0Q(Lw(nQFFew^>?Lp*^9%V2|i!k3-Q1Pds_Jc8Y_{ zy;Ghl4|V-l$lv3NJCJ%PdM5j9`#rfkziuv6=g+U4X7y0l-!{GC^y2L4D@z6X4C|Nr ztYtSUpBcsdw%~$QYSuoHvU#i4@NL+Bf6hvuUiPrNhdxX>oO9t0S0ZD&M)2!`>gu)r zsm?B{ulI=+uTl`-SHRW2YHEQj--L;21y80Hm|g7WQh)L2`h@>{>sJWn8A(sqo+S`| zNYjYv9c!YbX2_w^j0>hW6x+O%`n*?$JZ-bA&%D~{T9rCdZq1Q_>0?6~h;r z%@oh?IwZ9JWQ~KdNa!KW!p{%AKRo0tim zt%%cuR*{}NtDY{FRe6zrbVBoP(Jy#@o$O;QVXb}8@2eL0 zfI;iSJdPg!>_Q3Wr4LSgYrZG?d~s->?Xy#@r+*r0aeV38wQ!X_%Z=Y6S$QiJ5`L&j zOkLMLt*L$SX*bQHgrp1a6jGLMy2vN9qq;yK#<9TPwcu=L-sSZYUux&C$=Oo7OTOd9 zwBBz5C8yn@FV+2D9d@%`!+%|%nOA4*vtp}+sJo7bkL;@aDz+d!QmXRnv}wQQZ+?E2 zf6eprtBY@>pIcr0hyBy5JD;5^OZyy**WbJJeHvG0+}vuZbE}K{PknlI=kTe@(!LEUMruVG{TJfxkC3u{`L!dOaBM&IMX~mE9K;i|IDDN zR{bk~mvQX8<}?9(10;jEQzqq6`e_I1WIV z*Z@8MKp1v7#zg4(2go{}uVrA6hgvbQfpvPk8Y2f}LKmbBba*`oqaACPtt#?|ZUnHjp!-uC*w_V=VZ>@LuSI!+3T&!-K-uz$Md(QvOOINRL zUfMZz?dr$%Ne+MZOB_0C?2zifz|i`Df#J#jdI`Q`VaI;;9ozEmTG;=l)nV7R-&x}R z``en`4`{($`Ucc-wQ-0R1Zxi!o7e{HAm?d*^ z=AD>*&F0#LM!wj>b8Dq^9P_iylASpGu0-T(t1~w?_ueSR^FC%OS+B>$fm z&2uMg(T9r%-^u1U+L_(kbx!u!43ib%5pTDAG@ZEo(z_#E+_tm0r~jGr^?I)ckC2|C ziGIPKo+--~Kb`kUID@N_d1b=6rh2DM*OuH0yf;wO z7@|H&D|^e_g!4Oh#|1ubt=}g5^TrRWTQf9vy1CrVQ(ndWdjrqghR~U=B9U2qn>2KE z>Z9Ix#>dF>Z)<;S+AwKN>50`AhxD%84VgFl+|_A2ZZEiRxz>4a_`f2<*3ay>dGju= zvljf$QQWhHm&VHHp5HN9KVBdf1 z!t9{Q|1W9$UVF3fs`li_Ri*4b;*)w#EQ#Z7xSqbQeyPw@x7Dv+zvX<(AAMTi*F@;u zDZd|zt7cBQG0UN6$=Aj(FV+*49tz?zCet*Ew;yq0ZQ3sI>+cs~cE;9Dlg9dYeyT6D zUfgXj(7$~>AgUu^HpA~=rxTC<=FQ*zDy)0P@qJs@q`!|g-Ssy6w)uzs-piLoYqLI^ z|FgdI%Ks&McdqQMU)%g~zs0)M+0XM<0mq zr=hc0I;T3IjG&;9q^`rAU*^(zJTq!kzll{9#KELPmS$M501S+c9;dMj@~JMqkd ztE`0cVnd+6qvvEk<>HUmzkEIR?OELBdE(o5vWBP4es-ti>1VZB@!qwye^O?hk4W_D$lRRl9D3=YlfBnb&mU>Y_GFZ%?zZKNOO4@f?F+x^{WJ z$>&^WhWNOu7t`D3N7lAqK3dVTW4F%18}?_z?JE5z=w~@j*XfDgvfy#V6q8-*OL|^? zi>SJwxVG!6_F~4(&vwn&`DDenzK1o(BvgOyTQ%#H&Qqgf+-hCFjaG>76*?~O5PWDw zKz&RvXM*qsht9iR!dxEGEa&DdO0AxBYo>Mcs_uG?L$cj7-=4Y^A-TPO3(M^1leHbx zeU6%_%XB?$4dj}UdRi$$AnX1gn`QEwy9~-c+bpgBFm-yWTJY?@v(;z(Y485&v-gs+ zaiEimOs2A_3fKF~UscvreloeL?073E zBBQ5k>f@KD^(Q!{FJZbRvhB*5Y46io-!_#QneGu_@wl6`CE|}JpWXWj_KpANuH4&M zY0RF$z%cs*1B1r@b0MsWb&8pZQQ3>@3r(Z1-YN`adAQtdd)zLU4-DE8j_es1Iz>tx z6&ap4oacQ$#cDT~m1COrZ!Mo^*Drtl`trd0_g{k-ZQZ#xukU-k_iy9uuy?Fa!Z;+g zcl|p3G~>}8k>ks)XBPVgzj=N7q{~O6(ka3ITCakS{+3$td+WqHqug^>tCj!DSRdz_ z(QH~6QN>#pHs!oR!T0!upH|GXyBOm2LaLqj(~tb~3*SBJZxYv^f9=k-ncC7e^5^Xh zt2hH(4qxf4Ie0x%?9`j$2|@KvOV<58%KRtvsEL`(6W74M&oUns9Xyw=uy10EVvcOiy&2OAPUl9Lw$k;3U zN!vzOv5Z;wB^{S=g-!ZJU*=PP!0sOv4cvD8Dt!rw7ylF>gFo#(k1>m61L zC@XTVT)d&D)YtOj1fJ_*2j7%m-@@u}A7xBGA5^w{ zTkWkNmaZN2J-^b>Q1r_|Zrhm+O@B6(U6sDT_Ua?s+@?)WdT*le2bRXo4!*|J`w*eu`lu6MN3;tA)RHfXTCf2 zMdidHBlSW7ht_p!Eo6usoX=60z$`*8chz1=X{EtGqcWC%&4Yw(g>rU*oo3 zg?B~*YR}p|i?#{LxNj4&isD+K)i||j^3=02)t}S~qq)C+t*I=~nzd%}vgdXM>$6rU z8GiQ8rZ;H=UB5vTy?5qU+C# z-ahM>xb}L&$pswD51%T(*)m64uO_o&+KJh#odeW6&C}iQFHD*;FL*jV(r{Y1>y}oYK>WsKMg~5gBGwlDTc$QGw7grJ zd-wCYf6u;7&`(pI_g?JS?0U|~4O#1ctnRsF&}wq;Lgv)(W|Q1xf_Bb*?mHu8nflL| zMKQ9b03RQKEN*!BTdy(_tC#}~U9XU_>gJ=Dj z{^e_Rcl4>NuU3EWx&A`HdAe-!Ye6M$@s?u-uV#B}&J9@4#+or{<8&Wp&V35J^(|JF zKC>@#=_~$ywyYyIUn!>~m}hZ8LX4B=sfnAp+%r{XaK|jKf3B@p=CUGBP2kvO_RfFd z_YzD+>`Yl+T29%0l|wyt^Iml}t9-UAyO}TDT`6cj<(8W3c5Wxl-i}2=7bkysBYCr3 z`*&h@#qkYGzn}Yi^YhymZzmk><7w|T_A#t?bUbw7UZKaeAkI6{OnbN4o>yJDVoi~M zv&%!prOYkGx@Ib_3)Ia#va+)FXPn%S$5$4+k=d*MYsTGAdOxJ=riO5LPc^mnyKH51 z?>=`-yV!DzlXq{wdb4d};D^8Or9WzAdE8wQ@ucGG$D8qYWLGLhum>OC;rHHRYp-FE zsA>QEu6luur&oskJ(uR)s8GwZelqWa$WCpEf9^7}CtG|qmzpuC-`+3tDZfLhJ%+oY z$arGg)ccnO#>Q4_dEM8?X3R7v*k~{**)W8C8NG@{r$>kgbZdW zA31nRgDvoV?xdyf`5jJOedY1l#OXc9`B*8JEWat9%O5c3uUr@QVNtd0G@)PLH@))e z&y=1zum5FG`Som@4T((el2dJ$e*N%fd)eoVIlrQ6W25E0w)KU(C4TFk?7`)-;rGNR z$EUdFh zo}wjvs-ge>U25BMt80PbSHA60%WnTI++|U5d-8#qe{Y63W+y#v3t6%@@S5eiN$cFF zv~>5n$ZNe=>ED*}J#E8}tHHZfc8X-Ct=4xp^shcCE zSGRneu^?~az9WH`rYO{8yze!s60ml4e%<P`6tUw_;Jiy;n}*^FLlrBoqN~S^6Wr}a;bDkgNv$fWmN4|&k3(P)@HBw zbgiAIn4F*yG3B$ot5)&eW{b@VzsuyNuXbGVty%QZ<4)iBU!GGnKYV^^&!Lmn&Xb{g zwkm^f1FymcIS1X~c#Fz|2@jmMn{@uTW}Rf{*Y`j?HoULCo;z-{;_pzt8_tzdoa^%J z&5b#?F<$d+eE*m&%`Ym%$>oP&0Fwc0c251WtQWIF&1|+xURn6;Q+TIJ1G84M(yCwn zDG|qR{OkKURnYED{HLo-+`h)-U|^w@hnGWrRJ_gNkCra&Q@?J$xI9AIl53fYM2WQh6G;Cb#XMAfJD8x7L-{Wycq%DFoH7n>Vd@ z{qDEdIlY%SEV~=veE*_#bV1qUMGi{!Kb${5eWqr8%ykEkj-{P<`*G_(-}aSy?6UZ$ zv&4DgUa6_4CQ3;+u6thSBI5O|BPHKdmFo{51LKm6sp+hfO6DGOY22|@?Tq#86BC^$ z&o!6i|5kR%rklO9LhG8F%`E&mS?Ynz}ukZ9rt?+kI4j^bNAVF)T=jo-I_9^LuXa-EX8L=sY{ov zlH%4jas6^?PKwpb#ZreG1OIPtjZ)^2NoLtx+27xo#p$QFVCy=MH5|!8?vMOlTP`&2 zwZ7b{`A5BcvhI}&h7X)R|E^!L>;C**3)n>%9x(p2?=p5~Phb3h-HSw1-`l)~Q|d+L zUS-VJ+)q>9R%V715(bs zttkFwd3fFYprhwwyH;pkP?@Z8wY}azV2yvIfXIF^9jQg9XX;KD-s;zJeCQSQUkO+^>Ig8&58dht~e0ZkQc*1NxevZ}pc6&^3OB_AXU^oBaf&D>se~-MJ zE?qsH&-LD>dZu`_;4)u5m0L5}xLYM6{`&Omo)*3xS}(Jq=liE_*680icPSOmoS^;i zt8?(Kb4yec#O}V`KkN1Ps_Z9Q>gVp>W*qUH`>nL_BkL7Tk=|>rZ8$e^kwT8ej{=`X zWgg-;B=ctFhJ>y4N%dut$hqnu5U+YD%w&PL(AI}D8f zt9q)qOfu87+j2RgCa|wdb>UvLZP((-y@&rriv*U=c;WD_{PG{mXPZRq6aNbSxHzx= z`J^7hn*oKde`RHyzVqK(E8>pG&DH9!`1d-t_AOj@!%FOHb?SnRFX9@e)@r`VYnNFk zBd*^Y>zg9s7vGncQfsfBSDSA0%jY+${YstR8r=3EM)8lr7QNZ!`xB1T3(Xa3pMFBH zJK{&c+(S(nUsGaMbbR%-{F8p`+p44IW0k3xBU7(%Nx|wswI;)MGb<0`y95e7p zKe6B}pXT$4mV6cBZiUxk4eI5x9Cbza_NlXJ{hN_~z&GN**Dn1q8@JSk3d3#eZT`^~ zoC>CSk}{5AI_1C36?19}^ORW(rFN|T<)!KG^gRDi=~RjG8Pn~qZ@VGmon7`z>2UA; zLrvP3GB0IuOx1h(q+mzNjlDgg%Z?QHm^C$)cRz6oVvc{e!Q+v)uY!D9bb9^HtCnJ~ zxI(nebwWPBpFQ{S{pzIOP3|4OS8Y>zAK1yR+PFh3UE})sJf?Q#1?Q&ETm8bN`lrC> z)-AtoJm>Fi`B}jfeoAP4Ipgk5L)U1FxcAarTG0nQSW~A8?f00U`#Hh&ZiY+Lqv^*@ zL|*@yu&;q5;$hRP*?-vIbJX)?NXqng)CU)9vPwQ)*(2289`ivs+>JEQ5u=G2!|&Gm1U+WrG?)V6K% zXkS-;3xj-_kC3_0bl;wXRTcAs zn1xDqJabEV6`04YZ*aO5W!r zcwEsiOW=Kt*csLeW~HxsMZeFoO?bla>C(YOw$(akgeEBdE8YC@NdQ~@ceO)F(^ebY zbz@NJJTv*xrr_%>*|XMGI9&N?(fw8Se&N}Bv*W&ciT*P>6!&sXp4YnbN$RFyr?=kD zda`fp5@{xn_rbLv<@7}kU1vy>nVxkie2BSW|>@2eb9F!FI+*OxnK)5M$0 zq`99h{Pk%AYguOEbvc8@99pwBPV$}TaJ6v5ffIGrJRgqOHGT-w_<7G!bieZ|&Fa+b z-EtM_9*QPQyE=@N-|@UETW&h#;*3xEZ&sLZ`uSsO{j%@eRR_4ja_{Z={_^FEQy*gP z7I|E_;nyjV(eRO>0TD{hfl23KLFI?=`EK&T-|Dtezj`#0n z+8pg|d-gpNo9U5J6yV|Sap>-xS5w}3cDDE(H!(O_dfYbt^sQ@q_V0{&ZD(KKnk#9g z@Y2_l!8-k&L~Km`)jw-&joCh}y?ajkqmH>v8i-F`<4dv zR|}tgh^n8yl_h!kS%p5MkojW0GSheR^+;Ki{M(T&W_C4t#gz*iCGQ=yJ+}N&mc&WJ z_bMX7>Cbvs8!;PfOXOa=P4dOMNt?3n9d}Vw4cqB?)m=#^#QWu?zIpYXcC0?rPT&81 zbW?&FlZBW}z5CsrwwHb>2EF%BeE#d5w4RLI%}N1@1#Qgdj!C60-=3O#?U@;q^~ouW z4n4O;UsaW7uvJBzo_%SL+-={r3}20QU7Eb%{D~T74Ssvegc|! z7wV4QesifIvujP2=CilLjIIh>%j*|weyTrv=*hH&lh<8)baRbg*{5%Lf7d!55^#=M zvV`mFm;H>4@|AmM`|EhTX>gE;X6b$9`1H=czlJ5vuNnW8|1V%zXsrM5{Hb^I`#!$^ zcQESyu{%d@Tzq*y_}(dDR!d7S&RK?5Q`uS#4A@1cbk!wUmZ=4N5>j2z;`;wX@|UDd z!u81}n?x2*4z5=|-p=B7a>wF2!N*gSOP)49Z%E>sa}!f3K-p(%@yv zxyo8;YiHYh|HApI;)}!kwyJz<)f0fA8J9{L`SlgCT0}<{%lC zhewyG#RwnRd&;EE*7(SdTpfn&mSp=c=ajeozN)kQsHj(?$cw-<-ITS5b&nmbn(pRs zQY~wW!)f{De|gVH%n05v&u3en&fWtI`>iFOO-o$%Ov}%Sk*WOD>{~|^7Ro!$aqsvU z*?q!wUCs`!Q_rI7n>6@x%Y9N(trDDBs+m&PKGnX#az@1a99OfTErU?Kz7O+>NS3%y z8v?av9^R0DP`J;b#P!}1)on}eItyegtZD7g{;2oYIzZUrv7VN!`qqgB+5u})R$p0g zKD_akR2bW=`ZO(>mpK6K~YpCb2EDmWz@W@f%YId6IxLIeoJWJ@pr4Uw#8(=-n%ulbIwl{f%fI= z)2D7(oN{$-`)944Gx|GqYyAB$bd~RQs*(*{YhHcY{yxLQ?tj0dbxpb@_C&-zbWpO2 z+k8*|Ny@LuCLa|Ar?s58QvY$0o8sd9Zx>Y0?DDb5vWa}CJIn8Du^mkW(cC)P6Q4zVUW8NvAD_XBzS{|D|>B;12A8ighm1}TvY;j(`@xyVp z_dhhh-sTc#NqxzpO`F*=^ohnisI*P~}|~o@=e5 zYaZ&Ink)8U1=A9l#Dgau%ueLrzD~EjkfZC=?QY*Y#o6oM$JyKVAD7i^NfBH8QgM^x z@uP*3cLbY!*VOmRXYsPNFWsjp`H+#n;l0$22X4lmhBwSEom5qsy1LoyLz?dzt8kU| znr~+qMDN@kwCt(t!bL?#pJ*sl7aeI?z;tq^mF%|zZ-T!CpIp58P0_15yEQYTd5mA5 zIL&k{*hFNbh{>5rcjD`(y!F|bcr2r#*yYLOH(CLgj(*-yGl_NE)A}X+8^elQ9f}(J zH_q?!=x;fD`*jeLpMX(Hya>-bx5rDQWi{5VG7{M2A#!o)cAKm7?IPN8%vq+yv9x;n zSh6Utn3Hh(qGRH*173WQflYfqKJp9NnQZoB+45_~#~BzNY~=gJ5^DG6LfD;vMI|h0 zarc^6-TJ)lxrO`EOWZ3SoNHcH-}EgaE=Z>7>x+BY2j5Q@FzyP@3qDt~t}Bj9_;-z$ zhtAb`>UZaQoK5)Yb770&OQYR)zkIG-m2ySN_ETW@ME|4C8_zhrxw*3PuJcKq`@Hjx z|McaYJyCPjq1)*ynh)NvPy72#tvz5><*oW9HZI4C#nN|9oL6$e;m`Z&Q`ILFbnGgt z&)ys)I_bmw*YVrFJjkk64tPInzOsA%jYzjIsw-u-6}Q}ITE+Tvh3QY1Rr_c3Y2Tfp zP%nADd{bzhZuu35`d$5($}20=eGDi6-(gtkt?4_j!H565gU-%XTxW}2DyH53*&^F1 za#w8qcGHKIUXu#ha{0F={R!5ZeCmwH-%Fb(xW?88ZRxu;qq4fYvz8^MJt)iP?IRlmcv1tZNE z?@tqX<#1~4se5VV8cXMJS{ls=(@USWG`LMNP|;NX9_{r)9QwcOISghh@4lDL zZh14MW})*S*(x$XJq89 z&CmL?-!`JL>hrZn3)vVhBr!7_`2XMF|N8e^%FLGiZ`xUA9(H+3+}4f7zP1+{IBxB} zc;k?u!>UJ{xosyHpU!t)7+8Pu@#f{h7bop;*G|=cwws-+wy^%(uD>5X+FiAheH!#U zDm}~Q;?66XD!D4f>sRXab4~60cii``rsiUchaWk9y;wH);Qcb~BZ^Ev1o>XSTc^25 zp66Zckt>$BSq*m9ZsAXO_w~S5h97sO?nF23p0`A#wf2zKk+!4zOcNJ4MdzEJ6{}ZO zT_pL=FMjeDje9dI&UxHXd89wf@`u{Is)gy(pYfgBrYb+RQy@dxq}wfdPsx=}Y35nA zlLG!+t>39*@O`VwCIzGKB0nXTyn12eJF!mbdg=AQ2lma~lI8q#XN(p9zlUG!8`Z;$ zGxAMUd3QZL-t#i@OqEQ2Qlb0VGc%dKd@bnPSiiO9_SBt9)1nS5$}!)rZ9k~wRrEV6 z_RNmRl}nswecm+nFOQ$?)L56^wNo@#-CU<~PReAFV|n7_4R=DFgmvStY}Hk(J$+JJuOc zXR9&wJ7evcs?4>&wk0%FpDN5x_t+F`HuL;cr6r0-f2!W(`fJ#KPw&B5&ZUvM%$>Iv zt~z&T&yE$pc63mNJbSy7*5Qpy`s#xzku z_3Wz;lTOZieu~#aT*Gb->ofJ=n%m5EzA`18ee>*m39H(B!gw3D))+bg!UphbYxRJuuMrYR<4C|I| zxVCZg!8>o5E_Uu;QSilZPWi=%?E1ok*7uT1kFI{B6lS^PZcGqcSmsW}j$?az(k7ld z^FaPD%XL*AEw!oN{1&RVmd(vs__OVNn~vXQ-pNg_uN^Pc{90ATcFn`U-!{HYLsfq_ zul>3WhZe8h>Rs5Py}QTl`PM_)+Z*bBte!fP=lNx)SKmBTPQK+TJ@F>+aN$mtIU1E; z>iIffU3NRMP4-CZmJRufY|pH{&-7>}^RBv@xLF6~5A#L~U#atlb4H?J6J5;5{k49b`@XQaA(!bxBQon##>Bf zzEL)P27{Rbf1r}@v}qnyGHm{fj;{@Oh+ClaTs_vb-YN5?jMN^B#_Ze~XO!2Nh<)CA zhEM38Mb6wT_vO#^PHOA_+?Qxm`FXK>_6(QmMceXZA4}+n`?2(FswnW4OMP#@=KH@X zMZ1@B-`QX1pY-|snR3^2(PoVG^6oP4)XXPLnxoD<@n`uf=9t`_`=4C7Tz)j5aNTNy z?{dfP99Z(wyx~gy)0Nv}ZJ9rRoRMO>_UejHQ{RWL=+N6y(CQh!)5WQ9hwA3C7xoO^ z85!wUwmQDqv+Vqbi=R)d_cpz)q2{n8+UcKN)E@bQhnveTyx;Pp?9swgnf6jw<0e-H zMan69aeJN6wL9a!@~h0-)ZezjjMHP+dfXLExxDE6sj&I`US;05x)xmTI^pj5i+`Wy zdOlvVNON`0Ri)R7YmOEN9=sWN>C`fv=aGE3fBG=Lyj}K0tB+Ux*Wp>kCnxSdseU(+ z^;gEZtq$ow7I@xOy!uO{&+vV=-0b^K9*WC0hdtPO-aD(Y?8B3L&R6+FUijQJ+Wy4% zuJEbSteQ-g2lH2*R670Z(L598L|L!;B*rCy)+q}Qrry5!{PK(=A{y83?0vZ8=I76M z;xzK-+)@*ilKc4dnc>1kHQU#{zs|UBXNS&(i^@82S01SD40@lJG_x&v$AT1I=>?xS z`+hR4wh)~6;*G5%ukf$DQj?|mamV}W8LZ50_8fW2;_}I#3fgu6G_T?6I6_++H`9C2hDV}GZ z&TPxJHs0y|vXhhFur7N%ZHag1`o`}iZdWI(%y?)o$T{alVx@WY@ps?8EZ@+YXvvWi z6>)8u9rsn0Mir^x`tB_+x1N}MY}w9+=x;}Oi{O_-4)1yvtnpE)HT_sQGv?6)hssug$Yh2yEs8ZWOEh|RDhAZgePHDoX`}D$ zt|9yO&@mSOv$NWdy}$qN{!7Wcou|C^G)+C4>UoAS+;y9ga7EpkwH2iWZ!he0Ey`^yY_b4@7#Fgg>1lt#+zG~EzMmwtFBX0MT+r~ z-g&!Q!K;tl?dab4JcxOs?aF_m98s4yhR!<^VsdL^tJYNK%AaO|n=JE~wd5~3t4&H? zcfJ11&X;#z-`bfce|Vn%0=H|WI*V9a7ToGMl*ARC^+-9r@zAt$cO|E-sM-5(yK>um z_P&ggLsqvuzFF~cOE0*taQfEV`I-!jmv~Db$(t{Ev241QpyK=U9hc7^e92I<`BqO^ z#)C({>{vAR^-089mfLRJaea$g%I(`W5%Wu*Xyz;2=d0H%KPtUyNBA#O&HTH6mu5Nh z6undVxg(1+DN5_6^dDOf9^FdgPb;3yxm^3r`NgEgvGTb)4R6$NSr-egJi2A2qsiCp z7vyZW`_`FU$(0Ir3(yzcQuuZ5T8^EQCNeDx`S2>{#Hk5pE26YYPpci;EL)Z+_%L8* zXid(tL+ke{Tr~Q`jfByRWz%Qo1Y{TcJOhak<6$FRi`vegu>@7JdnEk245nx17CN_EkiJ z){UNRb5Eakm?64$M|1wg@cTtQVvLLnCP~kYp6XC~NZ~B=j_W2%Z!_Pk-}IhwWkTVa zJMzZ$i?2M~bZDAM-0UE2hlac1k7{(c8SN~2CfT_2sqC*yI?B5*Ph)qPvh8f%Vy>PK zyLgY)iu+#K9=!aK(Ukga&*$~baCv?7)$NlOn(MB7pYx$we&3&O`PcXb@1IbSdLcLM z{)$|~PMLn5H*50sSJ=Flz0hy=_?5PJ{hhV0jcRY#O9mZVr0cQS*x8y#^+;*=sW! z4_WGyHO?n5n0_R3Yru=5n=;q-^e*e(mS=cj!`~GL&CXb6Oe*nbZ}@5w(-o?D-lcf` zv0~xWG@0-7)K2EO+dR~8ZPu34l9yKACcW%)#w&h3zF8~HZrWU(d1bW}hvUM&!s6hy zE)FX?!uBV`oq7{*R8zfTD(9ajIbXTg2WQ6=-$`4g_!7a6}guap$3 zdzG<3`O@oCu7RfWg7Quzb|~ygmR^_Y{e8)u(N{MaVSvbA|ny{+)8#`cA+E3bdN|M=ODnKL}KuFYWI zwYvY-)}I|R?zgzR>UR`xyQ9Lp?9wwn;ZWtLLb4|xo_AbTv@}$rb{?N||1_pA`x+B& zoveOY|61XP@Z98fmp<|0%^cj7hn9tk2mgN{XvLc6Zhu*mXZd5jRf^MI*~DKeHRe!% z`7tQrwAig@ojFah_ZEMBQ0MDim-qzq zrWU_mP?g^)Gf&zkKxXo;@I#x`tBQO29a@jxzSc4^N%O$r2c70Qa?>-G1=tE{UzS}j zd_hRw)BWNTd&N)hc9yn?t=ka6c2_^F^1`utOOCyq>?)fCWceiz+-8V7^=OLCRf(kX zTATQp4S#;kKhm*G^H5f#bnEVk8|&>Z{%_KMACtdl)61>hwO2cvV&!JeJTW!>_e%EU< zn^(9iV`I>Pmv&Eg9N4k?hCs3C>88&6?-!ksH{W@+pXE}5&n4MD6=Ti2vFf3|YT{Xi z^}ClGcKvjy@x0ah#b!TP#H~~IuieOgMd#%d_mfVlsx7@@ulSC7T14Dr<~;f9-M)PH zi)o#1frWp?^o>_DvY@Zd1WX+(h|suH!@w5Chlrx z{GxJ7@PVzLb}paKvnl4>X}Qk*)4A_#t1J|g*>}C3dA9?zTJ(}%t@Y6#Z`@zRH2=Y` zT&1k9bIj-NQ{1e+P~}F?*~MS(7Vye{O7t>2#q{aXiW+r|?>p))om(B4xl#7MxuC++ z@(Hp#OxvvTYV(>ubhE5Dvi<1XE60Bpa9;hf*lvII6p{?<(UUW=LaP;-hF=i zTUtWtoLTp07H(-WOHf~UdH(iksdg5M|E*Hl;-59wW!ilGtSikOy@e@q^DEygS}s$Q zM1P6B|Jf>_p)@J^XL;gageFdsH9S?J8O0Aqp8>J&93Gw*d@7r2XCCT@;!Z*t&NN2 z_Mc=};&rKD{h2${_$R!!lRx{XuRiYG3JZN6BiD?EoJIpy-+bQ#8;l;6Y@GhFWWlBF zpHeu(l{C61q{s>=o>uvy*f#Uj#OB+^CJIiS-TNbRGWKb&Wm_ftXI)kO4vh^@w47eO zbmfzM{5RR{#Y>l#ClarE_#&Q(3Y+CbM;x7-ZB)13U}Mcgr-+!J$D1QkB0nWBW>Ky` zRrsF8_NI^&m#n*W#+%zr$srlLACV)wVbmEb`xEQ)E|TwV7qD@V>5B zx81nph39SEs&e_q#P^f^l((_fa$U*1{%ZA#tjw33i} zY{^Pj38{FnKzx_B-9ER61zOgTj;l+LEcm_kqi+3+ww3d()_T8m>-t_f&-=B}A;zY& z|J*ki=$_>)6=JKooA%LfaqQlmf4i$ow`@3&`Cn$udFjm?ITTHn_!<%$ifbA-e$WxV zC91ySL~@T!@HQ21rs)NaqV4*L-&6vozFqf1>+qe3mWi{QKKLDfQ#Jp;<2ln=d7*#a zFf94%9qOOX=DaOK`RvL5$#;{^NKNlJ^nAK&r;G2o1&@7|UW=F3&)pn9J=M?k_)9Z| z7i}@-Kl|G|(pgIqBO2u&w8cB>iEdwO?CdI3u`DH}>#yUs@ZBt}I%e#z3##_@*wwgP z68*1V+7)TeK2h(X`}5}kx)(pN++LWs?z|AUuiuv{J(btDi@rGXig=c$?0vRnRi4k) z?+3*t6)N=Z#Hg|CGK*Sxu70Cg%M(YDJK4`~@YV&LJ$HY8*s-p*N0MCOJm=mDM5?Y$ ze6exoQ~kU5?nXA<(dATd^wnu(Y7DVB=aa$6k^A(q{>!e?6VLvJU3;EAO*PB>;WxYJ zr;oDtRy`{VJo&VAX`%INb-~EWa2M0}nZHh`Oq=cz+IML&x9Qe999cdeew{m5uW>)w z)F?T*{ekH2qDh_7j>$zm&mN}E_6RgiIx_pw)SCfmUwJvV)n1gZJdwEaXYbvgvXC-Q#Ulp-g^?AS5`{+=PO~KkL zPV&!u_WFz5nmOLOE9ZtR5|eUrI_ll~PitB|=hUVrk9MCvbm;20Io$hv-wP~X=e_BB zo$CRcf7y%f|NY0qdgaCSM~gcz*VYxK1gF>Pu}ObFo1w}eJY73Ld$08KI(5HoDjmC2 z8W}!5R=TkCWB59ckI#BmtnOUXk(l~p|BN+WSLf<3e7TJE)V0#`qrPRDU+SHn&rJ*} zDW28nuH{=_{OU!uftqFXZn7uY7_Zb9W>>| z8`lLMS6%II#K*JguTj;ko^j}{&cKUE?boylCD7 zmi?b%f`1--Fz2olicR z%P`G)d1`~>RsVcbpBV+U^SI7?F)Hshj-4fQLt=%quJiQs2TSJ{^;?F=PK@1h+P7Hbg?D~(jZJ)b4O_Ba!sJUyC{o|0(7Y9#Wo;kT}+O$n7hVR~Bs*+N8=HzB%H`k8^v@apbb2!Nz^kt_HvL$uVrO!StPdY9BGU~=X_ZJ?=Pw(2E^I2#0 zKj{T8j>^@~SSY4kk#9Hg%04@e_xkys_Tk|P&2HyK4zVejIDhfEP*i`q^e@A6OTpYl zPbRU?G4QqQqC*R0xcImdfh1DwC=|>JKOj_;T!ymFaPe2DezpmV{y5| z$&lXAM~%;dPpsHC**(WQO6Y&)S9Y~mnoGAkUUb*yuc3-+?c`@4e=UsMa@AVC zQ&{0Ze}-wD>%)VYR|OV%zYH=zx90kq>QrsLy!D+H$u(0Rt`28in%7>~@~i%ZvE;3~ zg=+#L+|Guk7evQyUV5?c8PBIpr&ZVNJoa%;_NSfeA6}GK^a&2l`MEW5dP#BgZ^__&gahE%9-8C$dS~avbSWbWBt2w`IbBr<|_^TKld;7{E^7W*b?TtXpg;AY>IE# zn&+oK74e+dJ@MR2ovFW>bzbB1B>i$XJspqG} zNUwUG!N4HG{Kv{_)+sCd?Rz&LV6c7t=OO2myV9;7rQ`%3e&uK9X(?SR>As!q(2d7z zXJ;(^8gjTtdY^~egwis8=Y{p_^V9TJK1kNqX3tv4bGxPfO1bGvvoE|`QcpzeJ8u=c zBC;%MAFt(!Ub&1jYmzpyd_8hr?rDqLm7di-5gx3GXa3ESSXjc#-?H5zCp$*tO-I2E zYYWX?|6=brx@#$aI4<<|LzPx@6{{Y%&}_nY?d(!@Q1nF>Ej zTBK&U_O9MKdtsd3*(0kO^?$zRqX(IP zYInF@aZTOXZ|~f6iSw~_clW8lm8%yoUbuMS&IiBE7Eex@GDY};LqFr++6Nmd7w(*x z;#~hCo&9foJ>QE2hua6HZ~Hx6obfyRJFADUe%`&KDk1sL&agK3^Q={e+D_bYl;^Dm%yy1!wE{=PKWyUGK7IK7-gi&6-xm}MUpTe<_SEL(58Im4-8&XLHaapf z*Bxh9dcwTsu)CtX1ZzDzcg1$GLz_9PxbLn0{B?eDL8i);4?Pj?yr#H`1w};fc>170%KwEs&^^ko36cIx3>1{ z<1eh&r-fY&a_pJI_Rpj{%~vd}%9caH?-fs<-}cw9i;f+&`*FtiLbQcny&F$+TU%Qb z2S+VCFR$#6=scE(zh0S{ZJGV7wg30!?C09nnWs7Wo8~`${qdjiVuh{E%;ox5$~;>X zKA*p@aNtAdU#~ljj-Pm+$-lFIBEM&9?3Jf0Sj+#esR@jgyT86w>P)T^?~~uDHVk|I zUrhNwmpzv+H~RJQ=)~P`bD#cl@;9kx%VTVLa$WdAwze~a;`?TIw%&#Z+rJ&Yex3cv z@c`jqX2xFyu8sVw^jhT)E!sTX1Q`j{cUGu08GlUg^p#X8w4CnTd&o_ZWBcm&f7{oKw!bIy7WCe+X)`+k*H^!NTh`s4dTGq3mG3wcjnz03RR;9Ofx*825Jj`!BCOPCxT$C~i^`tuv6 zol~}ZuHUP4mY1Pn?vCkwGyGe>MoiFHvPG$-phc8ZOJ?!G6DR)_PB;|nH8Vc-`q#R= zgseN+X`dX9I0>D-{-$bAi|DOMzx)?hG_ZwbA6A#XI7?(_#di_I2R=N>J~JjWTHd#9 zn6N(e?fte(`mfGhsrS@)ohLhK@e5z4vrA7KZ*v#>m8N)QKl@kz$*XQWeEp(fx617F z^Bbn{-ic@Jdun()`PN6KS=Y6s;zVPXWSAA)DevF^%6e_`ks>LgDI!3s%dd8lol~6JYXWxF6=j{iHE@hJ>k1Jx}|Sm6<)$ zC;7j2Kl7>Xfq_ts>2>WJl@>nxLe>XPVp?FabYhJAjM+2iC~D8%zKbK}YS^tNxhH|T z>$q5y>Lz|4r3bwFYwQT;S{N+hHBIm{9PdF4m&8U8{qGsFLe@8i9yw34iGM&*# zJoYNXvU;D&_^3eBYas>leN#DR?Os^_^}yex*;02Uw(vIRax$H2`;i_buxXyrjoU}t z^Bol!8yMnl+~O_E*!k~Q!8s!hldB;tlU`*$W3uWD$zIs@{kl=1WwD5s!lx>xndNMn z-|n~;Ff!iV+rw+}H*^IN|oTpIgDqyY;{C*WR2v zb8mV4=a6gOX(@B9CJLUt#jNwECu~{P!!X-r4R5`xxA-k%Kr60iE+G= z=mhg?0)4_-H5ZOlTvRO%43ascKJU(>Thg;VA2aC)W}WKzz}=d^->%cJj>XeHwRfXj zw{NP!fd}~;y|rE)OujUG?YA&B+3geRwVi)*3+!pwQBoqeTlM6ty=P4geJUSSImHJ4 z_;$|*jH ztT)lWSFHZB^Y%;rg^E4)OLm=>5dCBR`13A>f{yrtz)zJ5OXjxMzxBL+=18R3)I+@Q z-Gcr-+4#WIY}xcM?aU;fYxlOjpHkO*l#BbqggY7ES@zX)`1%FU-|=I!@Ro#`KR0rB zt_=BeKXCWw&eeMh8B`)UEuC!7&N5sxVeQk;(yEiM7amh#J+qKOAgJvL^T$e!!0qQI zJgm!MX;CVg`u*)wL6>uTIa9KHCY+xZmPap51x(fz7Q|mQ5m(0J(bpCtiOBc5zMxj05IaQCjP53`U`v=>zyT#}C+W9JN zU21scWqGZ{KF&=l_gfwIPpw+OQIK`Sd_&lhl*ffNeg(w`J*H_cahR0#HmXnH-QoCS zjO!~l%@#BGCYCV4z?RR#kSFV_kJ4>+uLpOl53{=1^nIJt-=~}W>d?v1`dtg;vz{-W zT6g{aeMR5RIRd8b$2QyzP!78A+Ui9?+WOhDV*I=A?R}Pajbl;=yP-KxrATw8^(~Vn z_KUbKEY-LYx}W87(G}U{b;{4@htzDW+bV2r_hu2xi^j8NKUURtMP0DFabTzGw0Vm4 zdyYFKMQvuj(iyme-=fN|`|+0zRWcXrjlcD@c-zc5|KsHEc7AV}iN|*yaH!Z;@z8L? zrY#rlOSPnW_v=-u|DCE7a<)Y{CU{Lxo&MJAG6gRpKF;0nqD~_EiB*5?tn4isN2d51 zDy>P)^v~A|TebJ@{s%_Kf2VBUnzTD7UNuaYBk6WBEqbQ%4H|tMtmHk@! z^S<-rdi(us+*YqP-P}`k&hyx&K=th@d@A0ow>f_N($=&4?J5ve{_B+BhvYh`!!wWk zbpP>?VU6xL>lU3+f-ryw`Er?xYd`nJVruU;WZvSNix1JHXD73b9_4Y#Mowvie%KrX3c_&H09 ztyv7-g&zp`^78aOrLW7SU!=3=o}H|0v-$om&Z2m!S9GS89g} z%v~8`XIA)lx}nyFbatVVx)#Zsn=+Sh%-RxmpP%KCsAZb(K8@!~Qc92i&Y9O@RjL%C zQt~eHRCY^iuP#g5yJHpy*Ie~2jNYDkNUAn6t^L{;sr0xF3H`cG`d(7=4D$mYv`&Ag zU4O54IoD-gk#&sGPorP`+^7}t)l8CS(vsVo?()ra-FN77oyN&OcP7>Eycl#vXX49s zGuk688ms$xm@oS(+uNpzX(bguo4x9N>6zk>PKv%KuO~lvKRq&%PyEdD*V7_SW~u&J z=)AwaaGC5(gXalPi=Nkr&z6`FTOxg!bH}ptx`Ny9)qm*_pM3sbUa2&HoosxA+r2p) zGxxu|nY5U{MLF!X;@tJZ1{ON!=S5FFwln-whRO4Xnqe;^E_+-MbM3#D;QplR%DPYc za_=f|l-QnG{iV&4me> z+S2_0W# zIb-(9yXkprXp_g+tAgull-7zd{EM3#eJTCHq*=P>IsF`td#qt+{O?}hX36$=X4V3M z=^TO?JsbCYx!!ZGbmt_4)akbsTojFFMwf7W>YH}-zy4H>sIpuIbx!SmA@}I)*HZRR z)!6+fcV>BXY_H$8TR`dx|Iq~Jv;Rc%6uzi>m8H5JUBGVbBj(3vv1@*gmVI=8hpfu4 zJ>4fw*72=-U-4_%gN4`Z?#4IAfU1UpR znSzh5jM04xD8C~2SADzo*?osgnosm($XKH>}&V`;?2EoXd69O0d7<#(ZhDh z2KA6bJsowqL7d`~|EX!5eNcDlAjjf>1#)|~@BF!sA>KDk&FQd^0ct-Ek@dCCjX zh%>W~K6FwJma7taf2(dy)=Z5BhYC;h-}#OSAEJqzRFGcp&i%(~Pt zIqKr1ked%h+|>BXwoRY6__tm4!Bw2Qis$MwWgU?!UAkufk%=rDqJtv7?KswJ<~xCv zD{srGmfKxVPfAOzH1XYeQ zrM*U0L|Zr|+b?a8pu*h?fn|Btuf-R7ipb^dICo@QqJ($M!AH+`2+q0d<@{>G#V2XA z7=Gk2@2X02e3WtH)~^T0SFKU)4cBGO?EiQ@=VjWOBTqk?E_`?BXjkl>&t_*{FP~Ar z>X`A|dOnu$6KZ#*=KWtT;k|x!kVe_EWgnLN`!;>~Rm~@vT68O7@y9X^Q~#o;t}Q!r z{ku3r>!nUw^%rn{_kA>7d70F)Glvsok3T7`6nV33sX@=aQ13{hiedT8}?m zV$Z!)W!2)oy5np%ICL83LwOr8TbklrAiIEAgXR+L76=e)Z2C8fJcQwSKjG zZq$SZ`yIQq)&*(v?OkARyX*nK_m;YyT4_g)P4zHXl`b~Laf0k)3(c2zU!E^N-SX

$FGv>lsv++Wjc%?e}fA*(`cUVZyCF7PA~5ufF(6{MFBwDPkR4>)V2jSnsasf0O(D z@U4|9zaA;X&t4vVKKw~@b?V1I7n-`(PG+!c-?u-rDoJkcuF5kBvlQpF=RDkhkflvI z?ftP!-rlw)A=6xMt>&Ebw;@v3c-!Pp_Nie8ZcIG$!>V2^tzTcfuXhEX?Xm0Xs}EKQ zeK{!Mqx|{CMu|UM=}Otpo1ZDx^H)Ad{&TTr{+t6K>9;3y^F+va5sfZk4yTTxH?L*#f*;!9toYYC5f8ero z%F{i~GZ!xGlGO+|aM7~Z;L4q}(sTpARZwpUJOQYjj&Z zVYjlu>dk75yVn$`MH%NYvo)qn(s;coVNXo`vHhDiFY-CYEr0rq@YMw`jo;31WjY|b zclPm5)70iO&Wm}a8(i|I<)*uw@9G#s#RKvtIS-V4v_ztf1)j@th8GoHtA+ZaF0Xsc7c7rwQTn$$)xiMhKDF}bDx)UIXI#2O+<;1 ziLt#_O!5?*EYDP|`D?Yh=r-E~p8Te=T($bFWv%~2vL4o&E8f1krY+=xX8#tm z`z#Wvy0)x0?>SD)w)d0C?3?aVv@KuZ0-W(VzZ|H@1K71 z|DE;!^RJcZE!)Ot)~2`YzkJ?=|Hk64>!<(T-}Ha?+Zrv4?N2BEXHe$(Re!_t-*)aV zys|o9ec$xXeW?@kFTQM&`l?%>qIv$G?qEDFeDavnIfm}KxHBiFP33XiVrjXse$63G z&lwwC&aKkk^68TO|7B;)PV;Em>dl=#CI3y&@7#5*1xsw$id-T$B$qJwIqYAvBkEmT z&@LUOkMo$WZsqVV7TsMj^SH;Pe-k{j?r}+;_2}FaGuK|BD%(;^&n#fg1R>e3&}#>e z$sKpT(=z8_k+GuB>icCMDmQ%2{Bzm-r~_mDqZp$zr2%6VUXy9rlI zss3l52U(5xPRLA_S@?tTU6=>kRi8G^a-$NSUDJ*(%@bVb$kcbMLzCa$_m0F}qaEUm z(I%-P$(F7LQw{}WsZLtE<-`O}j+4jlUENjAT2lYPb=s5fwf~lDy*}p_docEn6l3A4 zS#rsS8|u%TTF@`BwQ1qqnmZb-ZytP;KbLaq+n=B_lZySCKJI#Btnw?c>&LG0|1ERt z{%r}4?{>N%fA#LYMeG9m(xftP-p-y>KlhR|>!~xBou#A?+_EoJ?J8GiZ_rOec*-qKj-zUrVuXYp@T6W{#H9oQX z9$cL5Q*Xbw%YM3t%gbdpgTJI^=C1S0*^D;(PSWT;wrQ;~N8P)b@(T-JK9jy>>@+Rv z?I+o-%LCq=v*8U^@K>K#e``r(rt8`zVs9#>JXwF2?hcw_#jNn|Zn>ek(U-LrB2m0m-Sbc5B4x}PsO zAY=6VF^jR&oy4u-8p^A}k3UILv$E-|l)n4y+^ji58XIz^3;(he+Ot;0I+>;ZZ(?$G zMEtuKQk}I~bFUq0z4tn7m)_Mw?{??Bv+kT46=Gc~eV6aw?!1(%ZvXzPWiel#Sis1_ zu;K^5p2xrQGk)xM)&9@QzszgXw`d*%+w@l)bM+2Pe_!)DA+hS>S|&$_JsZwmmU3Fg zy+VBL{`{5R(!yV(Pb|%E@zlQ6^z%p(zeW9pQXQtBauL@K{fy)?kPGI`si}O;^f%LK zTV1Zr6pNql*&=r^>1Rn9Sv%w&YEfHrsqV$Oc~%{Nx#wM%Px?J^pVsda7Cans4T?rL zJ*=DmntsqyX)fEl;K!n#KgzEgWiD&yd`^9{)u;Ed$WrD<2H%gQ$4_`t#KYBF;=k;t z?Ud+>`V8OS?pM~a8l3qw?NsbPG1~w;HUZVo%Rfd{EH<2SnXzWYp2B0xCpfEUDwrh6 z*}eVOaPyq_lFX0g*SBm*y}vU;C-%#>1L^v9d?E!hmHZKQwQH~5j>{6}bT^x9Y%MK% zFmHF*iZYJB2^yjsm(M6U`1^HRq_Osam(R6sJdK%L+Izj;cCM&(`oGLT_8m*km@LS= z7U(v8(l!658zg>}ev5SX`6RdZ`_z8VROwgh>;7kYF1>G8^m-QWt&EsCWd~t-s zHRYUJb+*yZvL@VkShT(V!K;I<|9{S$T(G>;QkHAY?Y|6CnQ0r3cZurve6Ql$x0;V> z^X#S16z%64CDbk0C%63V2Z?!_MG{NZ^p5gxtIu)xT)24Nu|BC~SG+G<^Y|WJe0m|z z-I+c0QfdrSI?QLCJ6Qj6{rY4phCOrA<6d6-evj9_VxrT<{572)?UUKP)$Z2+PcB(> ztnYZhzFYBH?~{L|l^=T7eeAz(#fI%C5?;?aDNljxV?yyiS< z`zt?I|Uz~v*zMAd(3DUebr@B z?f+z*yJfCg{UJpvcE!8cLJi)tA7fr)`>S5^(k0fnMKa5;*F1jkF?X%YGlQ)WlA$55 zYc?dP_?+17{;2!Vx7N?D`3f5@3eG;N@o=Y2Wy(>$u1vH2<(1p(Ts?FhrhM=6ssF!B z=FJvn!#B&1`OUIeaX2cR_W|29`BN&2BC6JM^S-Lif3d}_V#ll;zIykyHuZaV%o4f$ z&upU1{rYt8z3o5i>b9zteR&joJnMO9#78~BR~t-YxZNa7kF0#vn7QS%WyEf$xxu~H z#C{k%N^a{}ro2hd`0Ash6RzAgzmRUdOKU~+%+ukmmX22h5A^d-nYr|E)&cd^iY3<< zdOtiUsa@>Rw!>cGTiaC=`Ss?)8>;2z6=c`lLrLSbsvZ?Kj z#17-z{T~flH}^h#E4pUmk15^%cljwV65AegI4`MxceN2Gi?I1VzH<+j-m#dvRp~$k zzu?(p9~IUu-uU!PcgOpA8yemu>YiWJQCH@(*ksG9c#~CUUd?>}@~ru*B}F{Nhdjgz zq;Gz$|E_d2c&=|1zivSJ<}u{J0>a^nL4+ZOb>`KF#yfQl#(6yCdA+WZQq8 zEvT3_Gc@PHjTEB_q4~(zndpTNW-ZIy0?PmU}O= zo^JK=$A0_x>O*U9HnMqViT_(TS=KTyX6d>qzDu~{oGwVm|L6&|0};iwo5M*+?v5-xgGIIPQt>wCT<-^=(IHIHdkt+Q21ymfV5sNR<+vldoc-hJiC5u5pc zkL!bHsYNT7w%WX{E0I#tPx{RqF)PwK!L{4$R(8tOKXVL@F?`(Ow^zY$+g;`>8-D1i z&05g%RFWsGeKzC7h0^Tx9P`=wPoGPET+5Q@doHXeuHxLP_Kb*&6JBig%xAtk*YnK- z$t+vZe;&mboD}R1lq(v?o84RH5m*}eAoN?}N$VrmY$9I0h?4*PVt$Kh%g5KwYyWX9 zJT3nE(iNe-+8J}!ZGXM-7G6Z1sf7RRm{86{QA((=?_i5 zO=R|G&OK?yrFT9F-4)48QulXYI$r+#KytuMOUJ?%5JI{ap7RP8i}%} z^fZJDd#!~0Lp_AR(`YGtLP zckjM>j~$!VechX|V+)tBvF*uE+q*O8ZR`s276`a$86WvkZZuTarhQ5BgQGvT1))DH_n4HpP3m}tUq*luOeGYXOIB>`=iACp`QDStt=rf1_CPrI&tRZA2-qrKK$ zVbtB$cXT7r`RcCUo`Q|LXh=R9|vdw2)bym;SFmqaScumQq zto8pUp1Hc;bD7kCxxbsH|K8T$TUYk&)B3sBH%9N@&J>@YwTvm)NPot!JyI6`-^^U& zuy3cWPTr{%bDFGJUuO$isu(Ko{J1++Pds+{asmH?d;ff!<1v5j)E_s$uCM>RLB3z- z(ys7S520;6-?s{UH1*85{(GxI)@I-N`xGWgmGU%+vsj3`_T8%bx4|Z3k3jFieLYvF z>fe1*^{?*s10nZ-$wh9Hn*TogYL)$Z@v0TBFFW4IJ7~7KtFWu~|8?GNY$0W*<<}|S z_Al+$jkdw4<57iW1tU8H+JCwg;ei^%7~>H7cHcO(`VM*Tb~hD$6KSb z@t{lYr3SHSWrt?RE1_lpDj*eJzu>g)9Xv;vFA$ zDP0hler>i(%3?=v#U+)$ebgR3z3_RaL}Yo#!?qdLeU&^0A7?E5 ztG>k}E2o$7MA$a|qE$;2pC<}rbolBY^$p3M_2SFCkhF!F1}9q*R^%;OzpZKG`Ut-} ztaB@)Sxl^DbF;0Y4xiemQUABqFTdWBujje8zxmYaZKrcO&abJGn|<8;e3w+=n#d=+ zA5Gl!<&5(CZB;9*qOS-=MJ$!{Ht@6CY&qj>r`@%^`-+P=qQw^(Uccv&ZM*5%MJAgq zCyeg>-1qKJ^2~U1osBhLHtFRlymPvsEDbIHQ%ysA7J4z1J@SZuy(=S`^^Ux-F$7GshC|_7VS8HnZMj}_c>Nx zb1&#@k`_H1R2uN4#ERWBEjZV^Z9<-UiO*~2V+;3)M>QThDiN2rpq1xNtU`X|=la)y zhkx8@-V}BuOm=6+>Q1-bs(Hz49;H0lZOjq#Qg(&FF}7(&SGRvJW9QRQlgu!>7JDc7 z04$h-;{}Lzc5?kf)vy0iq=EC+>_;JsUMqv)4Vw}%EEE#RKF~Ryw>=njzr+M`0_w%GLQ zyf3jjw=Ad5qW`PNytzSaOr4uf1uj-E;R%znTs&##CzV+1RgX{X{bq5gdB;BSus+l6 zOpn%Fs(QHY%^R6xx57?qTQ0P?v}uE(!=kN<52{&mq}j8T!~BH%SntRrKEF5r?1#?8 z+q28UL{3iM_sxf59$-yClWUEKBi(W%0#{BLJ*uPNB0y3n=$=)wDk zwiYj}+RHp+7RyHCbhm7yf5E=5>?-}NpU#@d6cPQ(&GtvRsKA#RcHy;CcI}UdJ5m4F zB5{i2)d_sYFJ;+dU)R54T5GCZ)p4oM{uoQ<+f&QFX>Lk#m>n0f$ST+Q#jB4i{uO-8 z>uG>Ek7bi%WN0Utq{$ed_Af$G>$pYu(siZ~mq4 zd}hv$?QNXR*KS!C?BO}3SN$OR@)3W%a$O_k%K9G{9Td;@su`vERtEbg6m)D){h|Ld z-D3T=Wob(}mpu;JEvp@V?uN~uXUkmI?6~BtI6tF<-S@%P?UP>xuAa0jOoC^#YTQw zHCwEC)ro}odfRF4EE`R~Z=ZMOInUQE&VOB>?~O~4H*)>pZFg@U%W=Qii3RPyrrx~$ z+I!Q4+zi!Y!7nqVujZa?>)pA4_vE+9{|cH|R>_rCf1lv=C&>Sv^R^c){mGBd&-}RH z(fk{ETE7h5uAUcCS|I(;u&}LTaedE^>fg_;Bhsf%|HgAKp)ItzelweO$fl&Jf7(Qz zR`7pho+ogC`C$yFr&?LBYTcIm8}f=%r_EN=|9+0?%QDNI*AKkSYL5HMHdAM|onKIZ z!G=pU3w7q~esX|GQk7j@bA{z84YMnPc?&m|PBsY9cJcAmlYLsHd3d$!C;lo=hTz$& zSxRD7A7M~=WOK_mf;aZ1;G25a2;b<>8s-x=mK)tNJ(P5N_ECogiw^9O{rA=>Ao^q- zi}Z6g$rU>#7Q9Vfu5%^tywaB0a+9X)zQ+{iC8HO5P&@W0lf2^OwY#6lJiBnQ!{owe z4$})pZ4T4lJ_--_y2F=$vHW_t@rC z;;WbRS$uoP0r3itU;K9(U&b@tb~kcby?;WfUsLk*{UWXJ*=DxQ3rgYl7kn|pV^baX z6W6)3pEAfj+?w^{$Hi03+a@&&e9>c?e$Q#nb?-UN<$F`C^BJe#t`%vT-5kIW=XXgb zzLE9&rup5oT|Vi=9#+d+8l)GKxOsES@uPbl)~l(j3$8f5W%a!v0qav!_Hj1;ey23k zTiN}j*}bHr`<(5XX1AZPk&`p>{qf1LZ?(&tiEAb%-Vr--micZ&@OF#N**xE`S07l= z{^f;lUD?SaEQ^*-4yg1r+I--N^nPSsg=VOQ$5=JMrR79Lt%<2rru zbdMXXOJBX8RBsfraZ9QB%+H@%zdbWt_uv|z;e}NF&Tj7QC)}@ZdiC?sAshXL5v?Xq zdoNvYTK}VFUarvd>1U<)PGb0e{VT6pYGXs)?0+^B!VE6oeqP#r?{DU*AAxsysx~`X zNgaCdUTx;Fe8JCq_F0^=T)cMjStCb}e%+#jclY1gr`@vd{%uLe@cQ+;zJ2artC%}8 zV)`ay_v>Hou;oZhnD#J3?Q4(n`vivF)e%t53{2TsY0`tq65R`vft&% zwCFyf|1Ti-N8#d=O1j&_JT*NgRxWl`4!sunUUX`t+q8{=NqZ;gJvgI`VJf93V8xMEEw z^RSSM7WK>5#a~@kyzuNNkahg2N%+(6*{g(Gl^pGbW`net)|DuX~fGr0GN9 z$-g(e;kY?())o8xtt)x&wt9w2p0zTZS)8EPYqVk3%%HDLdw8X5<~J0qR(LS;Q{R!@ zOl8~uKYT2a$f=W9<@|OQ@As3HCzkwqeP@?%(3$O@MfOB>*6Z1q{J&TCqw?8>mwkuZ z6{hiK=9lr+{m5#ZzO-I`&FY;jc4~shqRXUWV~$->W@kR;bFpc&p||No>2`;QEbbLg zqq9Q8rWU!29=*%CDkGcw@M?+INwG6#P3#IwJ~{2|KG&Tbi)A#cw5sG851CaODwzFw zd&A9t;r;5_Yd71yYf!CcU&_tFDIXgp=AK3bORlIJff3*MQbM>4pP9-`A`pq8Q& z1G^R}Gn*}1S>HL^bbe9B=>>I$PGZ{&R{ZB`xt4Q@dvA>slkeuWj9&V8z82i^JW-?d z-K^wOYWdn8CHBShe2-1CHCc9QO|JFHnU4#$On*Kr&9AxPo$UU$4Uf7dX2_jdzC5Ul zBZa5_z_r3XxvMibEsvkLD5XVLUT^v|IfM9PKaG07)YeWi*WUib^MK3Vmc7b3XLtDc z>{Kx&=m(lEV`(J`w+T`Ekt>Ry|hb8>Df_kM+KaoAB|437t|^$IQ1w3h_SXGg)iYh*DirN<409{rAH%gk zX#MUFnyZ$b`#Ar%hfPVhr>cQ}&z@%qu02}X){P04^Id9t_yQJ3Ua3)MtUsPPH+O{y zdy@;Z?BbM}PdEk6zCQO`*R5MDZdQ241<{|mXOApPmAIs2mcz02&g9j5Rl|$D`D(qp zN<4dfy>|=SZP8s{eIeRzpYPW8mvicmYF_vMzom??aBWX&3rBm-k!h(CCmJQ^r(~Di z*4XQ#{CL8Juk(d@x8*YRW-VQAxpHT{{#(WPVEz0qsk(a_zhfD4KlFI47fCs8ob~m2 zuAAEB9M!GYe(QX{!0~LaoULvmw^i?{`AyF0?om#rLV8EKFYD#jd^pWB{~K%E`LdLj z@8_O`>}o2#zw_{~g!Z3K?|(113(dId@cmnvS-JF66MgZoF{0J#Vqfj5o;M`c#U`9P zT%VM!C^MzBYNc|`#DJemveA~ zq9(8Y&9E*y$ti$w>*rc=_n)hmKAk?Hu4Z3kU~S6#O#+X5^%LImd}es`K69f@+eUGT z$`$JmJzgNqZFtniN^oYT-7nSM3p1Jd!;AmfZp(?P?|3;`cS}cU0Ym%sw@fBmq<c|pDUyqBq{$weasI*q_W$Rco7OI0Zs}IkaPO{pdXa)yg#53t z%Zlc%io0GbqOr>??m%GmOswlJ7<%%?|YnM0&7i@-23?{GmdLoY09o`(Y9}}UE%w%+WJ*hozkxv z?sL{Tq)t0pBAdpNc;Tw(u4|8{a0g!uayyW4!pH29pW5@khT7}m?dm!H9^HFj;i8Od zU!8LftUGhnsXlmnJ;HLPrI_rcKgjfJ8=*99z^)$`--m*q3h zZJ1{x`o!pTpP$!x<9mF0X8X3j^Q&Lm*tMkYWaX55IdfmxPE*Vk@37_RjDBL0QrQ^4 zZ{<>BPr->#X5CYqTsHaXy{ob&qAg{tA(0W!I!kL_Rj(9Kn|8Z9`;4;FY}xXVg2)y;ZY^Td-?fN0;QH!==G~!;W?!z< z7yVlM=1NI%YweLXDYmgKE7GQGWR_o537#o3S4F${QhU-11Jl=U3adV*u3C4HV|LJ$cVCxFPiFh) zBmeNG*%tS`@9%%d}f83{*uc?uRY+FM1 z&bspWcgZ5T6Q7Y`kO?Koz}R#?WAG11ibLE&-coPxU6 zRYz;)Uud2aJK@*%hQ})Wf({lOEEAu^tp4<-P@D1daTV>)&lo4}-M5hG$*V&GsXMr4 zZ1>XT%}`qDUf%YuVP>SIMZ@&p^;#Di-@ATXZu^FPpYZcT_tl&VSFjpMGc4(O!KSV; zSw{bg2lvw7OIDq#Hkq=bPr~%m!wdKF?%m;Ywb-TdJ>`4(uNsrz9buMdSyvo1dTJ>2 zmj74ESqHXLGbdhSuqd4pQPufI-eSU^jkSrF?q!`XjPQ(eTe*2c*X$qL?|=Pln(w-z z-rbH>RYbbkpy6c0l!~kD3a6ID@g=7=GqXN8;b>f_X=u?Au~~^#W=D0Ag{_6bj`m`9 z+XTzoA9D|_|9W^^ht8+qUlS|eKS+I~;+1{z8T)o-6M^;n_RTyKBx`S)mzi#^zAPki zv$p47N69N`Jv~X2qYO7rU2PS)@>6B)_mju{dFo~7N|x^CVsi+bb8JD_ibijQ$NbNB!BSH#VUF0v zaRrwG-3!l$yxMV~`r}mZ@E=cVCrNz|(^6EqvbuEJ+e6aXPYpZ_Lx@>8&Q&RxgAdlDmBLR(|8Q+EJrwzc#w` zRLhk4ZnKRdPc=+e^O^A}WpbYZC(qNsoNb+Kz9~$=<Y3UfS0ncj+b(ZF$csOUK2g6Ry0S_Aw=WcV41R z-}JNkTaMf-{rjYE(&xTYt0S{I8>O=A_V!z`&Y4^}DeP10ywHO-HPi0%KY7;Y72sYx zttkFN$O22Qb90rS)=dm^n!o>BNXhH`xp^#gIXyq;-u?EZZqLMD(_j7i{7}vHV!fZF zpIOy54uP8q)o0Ygt9@tQ_D(l_<;CzsVe;f>(?WM&e5LxSRrtPx?Ps>b4KuYAW-VW^ zX`ivH*edUD^|KxoxkqXIn~<=v#p{B&59^8AfUvhGE0xT6)kGxa1D?eA|M{i(ns=&Y zhGB)E5n^Z$~jecl^nOb^6J$M!WQcfTW#lDptwnF|K6{;LgMFl+{=6aa%QtJPe7~q z=8p%$1CL#177SsWc(c{@@M2?cBipLN2Ld|}cZXe%+y9QOrdVQ;d7qKXr#LT;FKMhF zPD{yc53WBY&9Aq~$7f=~3ie5>UcAdbxLi?)GnL(Vs&bP0@h6Kn{rNgAY@YHGNh7cN zoGtgaU8&HtR_FWv{r0{kwy#b4(jUmom(AdH(YQAMng_R*;-y!u?ggQ8izHi_AEojt z)J~l&xzyCIu#%N&-X;+lpJ(Zg=@V^l3UvHQ2@p}brO*{xzvA4Q58rbZ-f%Fx+ic?B z@%{I!IAal&*k|rf+kY2_KKko)ZOb;D;~g!(vopDN=S0RI30fUH_n*s5L!AZ535C%S z^KV7oJGV6AK1Xh}AYay5N8VLQJ^6m7h`=96hb$S$^x-9OH~+3J_GX^ll9=PBvc zPW7kl5~n1VT(0}S;p%lBuh)BWkLs;zz4vL7?14E!>2H`e8eCbUP;{}XjP0RT%hc&X zOV8~(T=2UnY%VR&>@!4?VUJhKo|qiukqb9&9{hp}2m!Ore<3 zgTvF^mpuL(armZmi@+T2Yi_CwnWe9l*SqNUJa^on_e!byaEfyKVwQ6Sb36IGc5c{o z!oTiz<-x$Jy*1ukcHh$YSSzBkdiaere!LR1xOY8xPQOKi<=04Ykqd3l3b)^}(+YcC z?R>M!Q|;OLds{Y^l{QNCKS=smzVd{)ztGAZze0_VZY$?Z|EBe-%jltJiep&Fo&JZD zSG=i@OR%vNeD(R1&dIZ}eXqo?vPpBguWkLxlfl+`RN8CWV)>8He(hYd_g>Zl*%L=p zdQa##TzzhEJj>0&-|Ebo+YA~Pw=~UR70qg{dwJ1l_v=ail~x*F_LkoB-l|=Fa!BQ? z!|J)80=TywVqCIy>GBS}!#8Kd_&4rllFqOT&-!<$B&>eh{XokVcKs~bk!tNPH9hRp zc^d-5ADM^$ydd>qO^?6}fB%1z1s-l*f9d+_Ghu-%TWqCIurBF#KD5X5)_SA2vN|i% zKNn5B`>ws?fL7_*6qdbX}}tW=8BjMH#;GH`lgF%EaDnT)SO! zzUBY#)UQ9i?r6;&>DDQ{At%+-vNvpb$ftbVX?g2TV`=j{PFl$aeu+Ma z;yC5{_~WuL2c0E<6^(OOy=L+HJESYGBoYx$K$zEL$DjoL8_jBYL5t@wVX!<&<_bz8r` zSGJ#8StpTT$GcSAz|CBIi**jKHM$m8FF7{;+@m9T{pL=U1{8#$<`+ZHJwHiN!CDtB%_&jw5*W1@x>AZzYG=w9aWB&hKK4trXq*-1&Ok`&Z zlo@YSzP@C0+`58(W}4v&?6Buy?VLN#5((+;COCF0;ouidQTr9=q1B*FXKml&Wj7{cEI?uIU8wP7HHn zNE2QY`f_4pU2X|`VZycC)C-}jcevGbth~q{v)X3yzgd?WE@rTIsjoO&^uzE_#D<-h zqbHnx^_gd4>e2e0{&UY?*KqLO!F$ef`MtvUg@4y^)&)BKU@2s+TWgcH=g<1I3-eXh zB>cR2`tGZ#CGpoH?{!I^s?lEbTFU>niA(y6HBIJ~EA3aGo;k0+|F`kBJVWQ_a-l|& zkv(31o<1AmBi-lAtFP@Uu`aCPizGe&-2uCmiD%|@~(6kZhYD|-BJ`d;&GU!`)IwR++- zxkay6T(()lC(z9uCE>N@<8`gruZ*9V`c|!*U;XIH{FO?f(Z?8WEUSLZ&Z^2Vmnk7N z{9(+8pZHZclVNDzwZ#eq(Wfe$kn-xsq)y!nS$(CrkowRP$H-zsvsB z?KOuN$NSe}rAxFrgTG44q^vDpm9jcecJ^$mu(M8UZ?lASMb+^yiuo_*y}5Q%{nb}) zVz1S{6+}&IyPy4FwTrfc=l|)q&Ax4Y9KNsfs{WEig$|B^xu04}9*WqgZK+yomUQ~u z)n&cKlg;|h{`SZ^z0s^z^m40s;-R}UUWi*ayx?24eB!C*-uoxdi86%kG_TE>usu+D z)*AhuE0$)blX6y+cG_J3A^GWhahIe*tIV-_*}#UhMKbAsSFP!etYSaxF!OwlVP0k)In>Jk45T zc#kxh$THPW{%}&hohQ3FQ-M$ZaNJp3Z34H_QF5y>XHKUqh*!IfvSKufA@b zdgIZl8w|3urkN=|R@JazHuIkx6#nFo znc-=3my#LYeG)n(}-Q| zV4NYfuwNl}_md5)7#Ej2eEoVrGdP#)|6}FzzKJh9s_MCloN}+6doEMb=g+4YvSRD{ zCdv0dQaEkbZ}Kj%VTod?7d*rG>Dna8^=_{MZG&fsym5YY`_nCdvy6~)yt2s)55*pw z#U{4Dh26PmRrTu3dB3ljr&wA_#7s}Q`7GxeZ^@%iGb88REmAsqF+cQmNbreeK~qXD z7uX$X-75Ta-!6WwwWqAU8KsG7s)v26<#;xE>$&Y4vMbl{GFiU-vwPy1l^T~qwqDTJ23P3L-3-1kR9$%j}zavu8>bZ*?qceYcQpAZnFY)a< z+kIUw={{O28~=P`)-iCgPpuHL=ue|FZom(i9F zZfW1C7M!o!#mn(}ZU08u@;I5DAKp#epLg0|?eiIHJEkQ(czIfF#`W@((M7Be=j@zf z>vj6x@mt1)FJHac8ZjZ$Y&SZ;`fq2NdWZD7DaUR*F{_Lwh+%Hzp5t zJ-sB!1J#?ET^Lw)1pZm;6THJpZe5D#F&(wgPv6dESN^c6;eLNr`1vDMqf?G*>{2)1 zb5H4BBW9%GUVHY+vMm2a_4~4TH&z|Iv&Kow$ z^1OOtyLGn1_X!6$xOei-xV+*>|E5d2yh$xLoT9efVxGRS(c^xTHB-xy8E(p)zj@zB z-B(#AqT$BOxPFq<#ARFt6|K$Emf>Y})9&stKXb{q#5&k{1*ck_V}4)3&9ja5;d5hR z0}sV~pLFEd^&erc?arsxrR|zN?Z7dq0~UqstKLL#I@eikoI6?AiOcih3ynQuh4Gm( z<)6)FZLK<9c6QAh{wuR?c6BXX=oBfs@KlB7{0mpkJv*73@KC7GFiALyNg~Y5G$-}- zjYH{{$>$h_BFnsYaUR{?@VO{hTQhj!whQ&gzb}Y7yv54L_^IOickk03H(Zps`_ycb zngx^R_rIm{`d589(%{Vz@kzxn@yHih=c_j?PN*B)$(JnbciS;vVCS=f)G7}qp;ig~ z-X-(XpKmR{(i}bY=I3kT-8r9puJ--f@k{H{ZXfoiQ*KR}9qIm&*WNuvzF3m&`wX*} zb6Ul(_}0g*=2v3b@XX}UZj(|0*=+(nw_dLGTlb}WmuG0mn`dAG>>0Ws<+)iEeAVN8P0s{HBjO8n5rEH(t)2_vnh; zv9&_AZ15#O@04#Nzrvw=&rR(;OlI=E@e8o{{rmPj zt)!pLcQ>W$eM(mG^X(NEFz?**dv$k3%iXmqI)^XK+`RpC*wU?kUW9k7D68LK8uj?G z0`qQP4mlHrv}?PRv)a-__fAT(Tk$T)F69aP+cdWKFL`D8xt`42x$$9mm*S%2nv99> z^w%`@ys8qH(PKKfeXZl9S#CRd*LcTxbACV6b0WH_iS_t5~lM&tE8lP)KGxpMTpR?#f2`;#{B{L6JcEj|9$ssvNlm9`GrCo3rfW!c{?A z9m^h0us`0TVK@2rvE8gIuW;(${8*x|n|d^tw|ZWW%zIB6(bHGFuDGqM$zC$g{mra- zj>UqrFBI4Z z4c;it+Hzz9G}%I!Ubc;_t+^ zJ6=z3ZWbwWoxYmS?PEy&s@BWPFLN(1x=^K)WjRZ#POp&X!9R!d=X75&I6jzsc2`e% zn*Euztzp@=I(v@g@}*xe2r9PnjOCEME$X}X*h6~%qq*BFP2+hchGY_Wf^@o z&9?CVamPsBm^e7>gR1V+#t@#o|RM8k{SOh@6K^hA z8aG2Tf@`Ud_u9ROBzq3OmpRaB+hpTE|NKeEg`Zur47blUx%;m|Wb3Syc^9*vO1#Wm zA~!SkP{_kdj}z_s?Nw`9Hf~N*5|RDVbF(+gMK{#$zs+Pb@3&p9*PRgYlsB$r_P*fdGdAhPBp>}z;pJV!wcere;Nps(5*$p2p|B=6Eiu2aBXMVnDp1-yE*D0l4 ztmj+y{dlgO-8|>z_bn?X@%CTIQj)EVvzvakYFE?e))TF3j5S+1R~$PqFWq9ssVg%g zj%#hGm$~HXbmYy|5cLPQ+Sktdc5A9@?V3dwWv6^~N;5fpqCz5lU8thLut zhVN#&#=Sdpla`g8%TuNGTXvsQ;FmfQv#mULsj1MKKE0})Pdx%&+b$`xGm+S|{@C$= z6&>oA^z{5%awDJR%WQLIKi|}tdRxE4S~9K9LLx~y@oN3tLucjWn&+DbRc$zS-NG+W`!vD%E@zLIM(=@1)mxj-Dy;ALt+CXn-{{E`PP?5+ zvbX0Ywq1^S^yW-DLw#A%9+ydB`x(ox$p4XaA;d z*E{7W+hyKcf2h-<({~F zeJtm3GjZqhw}#WX!dw1NLv+P#YriR|D0 zJ)LnmBBj?N_H5KY-Mh8>qNYER{+g!eRR46%2mMvd*_&-^<0t;kzy4(U*BukJZkpZB zxRCN{3(qM>_NCUm_LCopDw!tg`0rIc>Q&e@F)K#QC3$HXOH<*iM_U#=d9eJAb=SkP z58G^(dd@Y8a|)2jeXsb%Cn%tvgL9?+580yV^=apB_x@nKX!VhkX|?NyJ=rhR*B?u@ zRTG(8KRJ{&SNHv=?7x2wZ2NdNrfsE+l#_iAKa;zNbe`9%k}uaXvR~^&my4~?ThF@f z&evBfmc7uGD{;08c)O(igxCkZ*gHkL_iecM=B5Aa)5fgN-sK4x*F}7P>!vfi<>i)q zOJ=E^)?Ec%Pc*gOl(=y{UL@DY zwe;hoMkSSfE0%pe({!IJ+ysQo%$?2owrupEHVA-d5AMU^0@wt zRYyEZmsfn<&c#x^JY3J8EqgcXF_vo9iO~xqPJa8U)T(HgeoN%OcTw%$Roxrs{GW2k z<)#H(R7j zWXJRl@8@2e?Mt6-JaJFIaoukA-Ic=KOVrrbxqmm&*OJ!OJfroYQ)}%6b^n^6@GfWn z*p*RU4&71D9qtxy{d^%d`P{cVc^wLV^*p^dZ*1yetrt;WtehI4uluIvn4W-V=*E3^ z^#W_8zPL;hU248_VrS>)f1lUJEmQpU;N<0fVcM>2aw?S(7A8IC_Ni2McG}K(ohQ3Y z=c9W43Kz-GGaN(z+BRz^T3Zv0d2dfWV1C?L(d+0!uEPgC8tWE$oKtGMdgXHV;qI3!Bd3|n@V)q%_tB-} z9~bU*=6+LPt=v}6+I8tWo2+o>rQ9jLzBA=du5@quv46&U@qadc%S57b^Jl5et8e*a zUECy7A>g`MCH>KxxAW|sW4hTg6a$TYFigic2;b-#g)*^lgFB>G8(jM9D=lte0p4bNz7qo(rcR<9+4#;%cCZCiJB~{)8Du! zVDHgy3%WNHJczM-zIpP|VDm?u-l?wyc8aZ1@_BIDGi%M=D>i-N-M1}tm*sBqPTv`H zOf-0D!Ts-^?Y~rHa)b0YoLeDQFJ)WpEU!BKL(RNzg1O9Ii`Qs)n18xa{W{n^KC+WN z#>f77bNB<>gZ|TI9kA}}YT6(*DOBdIRP;y7q{z7vHv61khZzLb8hd0KPwuxXpc+FcK)*|iy}*=_&5e11LK z*3;FNhow7D3!0~$_UwOYBYaHZ`I3vbKfN|kymIDj@%$qPSLOQHvCf#yUQ%nhA?fhS zl_n?n7fCu4&lg|Cb$Myg?#CUvoUf4@+fb`{n!ok#jh}yyONht$oqsLwI6rv*x26eE$71=` z{n;iZy1(sz{e*QNzMXxsexvF2jFaEXqK=t1_$W3`u}D_1o6~A__2h?NJIq#>P5$xc z#HE9Fx!-T>-~M?f|I<0I3pRhU3%g_YC#vf7hF6ybMZbFcpKIUbY~ZoxqE2O=OR~bw zxVz@6^Na#dM_6WUWabvQ=`-K)BzJ0>_@W~hHguP9H7D<@x^!nk{aJ5^cjsa+-H2Ga zXR+n{q)mI{?4!3ZtuwS+-4;7-;|F)$cd|kDT0al0-l}2V+V9RRm#Jq}}G*x=~J zz+=g0ANMPnCSBl^?5JAidX!tj@c!ZxELARd+tf}cN!DF_Bja-S-Tj;GKHf8|>w`P| z9)4zcntAyCvxgDh#uubE&s6kb+w8K_QD1rXW7iPpN>_8+1)Q5+*Mv6Jr)g;xwHIHt z_tR);YLRzKp7D9_f|}ob`b+-w6mTm#1qR!S9Gv;Y?~T!R<&qyaN*uzz3f(o>tfRLu ze$u^i9;d^u6V#kjKQi(PgkC+gKloYw%m4MCG8Eq~+f}yJs(8Cv``JSKDGQS%etceN zt?^KzP%%7&t2$6iz|bLZrkNhg)N5}UU{+>$ObZ78cBZd(K#r!x9e3x^;!Q7lTvfTix|H;#jW~7oC{0@{iN;M{jjzHa8x;`@p<( zpEXBThwq{t*$4l4o5_lvjF0cv-Q{;gjp>Nx*LEWFrBg)R&8urG~uv(6X|g_fhQ5Y_TMb=eX06D&vq8$@kF|Ep34?v2(O#lmoI9`16OY%NDRN3x`>jwK&*AMg zb#v`^Jz6>?SLaDoL;Y1rpD)Kb&&S@Xl4fPzxj@A{CU)nKw#?<~C05h6{i&MrnKOkk zMexI+tRE**qd(2pD05Q2_)5Y++O|ObgVKbA@((4OKYw>>ls>kuLvHq$+9ZwhzhyPb zN~i3SwA%Q~eIG*_1THSbGRq9=JH1eTy zi*T;fWPWbZxuW?;=C59_aPEa*_05B&IWIj~g{JOVk#941#f2>jd7D0jty1WoRE-SxB_spVcbN7a=-8TREi<+7|y?OhOrih&7Q@eU?j#96o(XY!Z$_y%&h38sM zv#wA5T%8#;GeXk!4yT23iI)Y3&WrWQ>Jzp&@=w`SuOcaSR7ev+lBd_hW|E zrN0iWy`Ooy@59kK_B9bTnuCasiLY4VAXetb#VWHa1Ux2G(ePseH4+U|0S9 zl*W&weyRO}0RuG@N z;)bQ=RgHz(&-*rcXK|jA;F(nM{bl{+877tGW$JEa$1NV)Ze4fv*q_C$ef){{e$<5* z%zC=ubIzo_FAFpEF9q$qzt%VFz{!5gnu%A-ro5DxmOIm@v3oC<=c<5D8a4s^l`G72 zb-6W<8)r8xG;)-9>S|Rm@w$ja{+q*J)?N7cQSR@=CgoX&`|JaB&lgG+zwCI{a%u&4 zO8vCcyA;4Cf+c0XKL?Orbn9&C$~i2P3zd5 z@;^nFm62Ec;@jD>8!e|VZe$XRFk2fmyZ=Xzt<1@n5%b$l-Y_xsi*t2@B?Vb0 z-T0vDe&g6{wR3wm)T>N&Z|?tm-28#!!_5AIH3diN>bJN!Iq06!;Lk14Ua@C+@;sl) z{a3C`Tr`cdE@IJ_-gWa9EYH8TOTC!2q$NzogpFZ+OxMit-wG#ZT7@@TRMt(J`GCi6 zva)J{rRn5z#UWqUO)k)Ft9-=EbD{mvD*N0!~eNAyj) zRE`@I_!(&*|MIckuvXDZYcAugSh)^qMzgp3c2?^>zIo2M?D#ENO86)D{hs*jjipSUGBf6uRT z3RjE28TYp{u)5r>Kl()QkXYcVTg6tY&iO0et0f*@v9T{JSG3nY%qrjb<*XAiO}jO1 z4o=KGva2b}tohHK8in~X*1?hMPai)YsLbf>le=PM7wj>59z} z|MTP$Ct18sKiOnyS-VZaOyg+5#`D`l^L~i3{cLGr-I_LG@6=M0=&L@xj??!luB_jz z{pIuSclP$ytJw6r@2yG9UZc{N{$~NJHh-!io3Q?|WT7+xqo3iIRRc1lcvnFlx{(MSAR^#C6zgBKs-MiXF)D-Bs*&_im1|PEUMpDY$}z zcbd_i6W1QPyvS;}qS<}y0K;ZY=iSfN=0BfSZE35~v8|&s`?QQwR<>O5-tQMDOx%1z zJ7l7aO4|4OkBMqLXA06L-0wHYw+ZxzJ9jrISLmI- z%f6p?uf>kE*D8J0iRwJ>_wU$#jd$tFWd|G&78G85WImlwrHub!uWM?1sPyf_O|kiH z#hcS7=d5qIT@B8c2-sqC+x%VO_Wk$bv*=qAdg7@E&(tvu7k!1lpi^z|gh?|#-?LC2p?*vFb?zw$iW zv>s*Oht^$uyY)pGUsij)V5g!-)HmuBdS{1)tX;EE5W15JIXHMmnv8Hx%p0_4_9+c*|&OU*_$I543jx8 z6_rYU$-nm^f3{BX`rFrZ9PU4jTP2{`lzMvN+;*O@txqp%IzIK*c#-ee{jYvv=pCLr z&ve4Y4o{vF^KNaO;X@6xxFD5FUJmlFqpPHAQe^j>u6gY@txxGW$274EiygQGAG(_L zW*Qt^ccoUk?Lev)SO0{V`I}2DpI=FjwD&4&3~R}4^XP9}^zv)Tmge4T?YE{esPuh# z>mQw4sNuS@IWO@=;%ckBx)3p?+{1_J@4EW2HFus}ZM|WY+sk?S1s)ZPXQn7`B3toZcs5i^@hy!#)sGj+ae4t~A!@<@BEN+Nq!tU|My*~Akr>3$Zj zu_kKU_PVp=wx*d*ir_vqX|?<3D4TN`3{!tz@DfllPCCUGm{huU_q$FvQ#p6{RBh%d zUiGv6cQDOA-*}_FK~{F9%@3=J7giM~_PBnL&%Sqm@gGY?pG=-hV{?$?kAT=#NC{|c2s7)Gf=L2Tw@zI2Q0$}HKWk&ZkH7cjJUsb| z?P{`)E_YnOnM*5A*Rx0dPd_eTFEewe)(*k%VVciosR(-2y#BFz;y;%s2g(XwZIMrl zZ0cUQcF6|!4_k9to!S^zI6al$6KqpnH}%JL*igu5z&f!$0{HsC@gOIhT}(l!n~JO<^~hI z&0lpCc5iqr_3`!k)2_+gH?_msY+BQQrp(eWI3fDCq3HL$r%P7UZF=0g=lN!xE&jS0 zg@09c%vXN5ea_*Fs;cqro8S7ERESmPG3+@y|B;=Z`zg!P%{;Rf*=5gva;D<-GxLKh zuk06nrm|*DrCVtwH8haoU8lfB*j6c`toNrT6@U{%1ALewSGz zdvx(yq0Udq3%CEQReO5dVcMM1bi)l7zg8I9Cpu19_%HAG2G$-?|Kek_mrm8%KmF@Kz~C|#QZz+x9;x^{G54n`Ic4Y z7Zx*0hNdU=JkQjg6qtCj)q%rNMSkjci(_Wj&xMC8*XJ?!ol8?STYsmmNJg#u_!0ld z?R^`1?k#+i`~LGX+x_$FGz69_E^72R(szMzX|>i30iiUO`ppOSegC^=?km)7~3en;@ju#&p0H=n$B zX?=Si*s_;b>*CtR{J)k~mma2Z?fmu9t$o_nXLqhKKfK=e z^*;Nn|NH(Ok9||G68&#)!$+@#YF&fKh@DZpB>&%6Srk6$ZM?S}-#N4TXWRJX^y*Xp z{oW@N@k?~iqw7}k&X@p|=< z|GuJsoAuj&2s9(U5al@78aYJn%k(`IYvWBM0x@In{LX*3pCi@;BadXj`PG!SF!n@%M{e zj@7-EyJ!9jUOi3I?(Vz4QVH2h?4P~gzc67=_=L54XK#LM?|FN}uVAD7=Va<_3*tSG zvaDCBw^pv!E;bgwUjJ_4Ut{&hZ`Nxc|FFOKOUrsoZSHjCaBcSL>GfH%TJ1LLAFr=- zQuu49-Qp2f%(pCUTfOt&odFl)MPDiY)IN3eYxr)TfBB;Qzqyo_|Ij{h>fDJ#Z{Byy z{<{|*-oeOl;VBz~$AA0p>kq$>-|_$Esb?AaAGg1Gzwugqea{^^jt~8c*Z*IMUlab9 zH;D1ib&p5;w||I_jIB@qD;M}@*X;f6BL6R*onFuKUv1M5|IhEY@40SY!P8s+BJ*thqW?-Wzm)&_E<3UQ!c)EfF8{x~{omL3yIp5G-;d*=ckeH~e|_G+ z3EMXP)A_qkXsHT2>)-d5t}Xly?W_!!y#IgwD7|r0k#ymw4I2w*7S7(Vv3S$w;-U>7 zie_${y?JKwOsS0>LT_^kq&iVPJT^mVseQ1A-oLi+w&Kt2`MZ} z1JR`w+zgB?FPIq^z(jyIBNNQ*>1977zB3vNHA*osFl=CCP(m^LHrVXRd%gy{-U(0`HRx<7<#+=XM|h?i-ZLW0|UbZ1_n(OL(fQ0U#Q9`GX04hqxeJvB`t(w zGU9$lyf!j;#>B+Hz!1QI=9p>)h`wqKMyPW{6$m;96i8`tKO;ai42vT<=dI&grRjz0 zjFJ!!3Mec}J3`olkGg+GbZ5Wno~XpYa8sR;K>^9cC5=wXU=yd?s55dxjNOsHD9uN8 zQ5uNG6Kim?PKY35L5UEAF&xUu267}f12@A$76yiVPDTa>1_0xzz!?Al diff --git a/tests/integration/start.sh b/tests/integration/start.sh index dd68b60..bd510a5 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -1,5 +1,5 @@ #!/bin/bash - +set -e # cd in the script folder cd "$(dirname "$0")" @@ -27,18 +27,25 @@ ghcr.io/hoytech/strfry:latest # Start lnbits with the nwcprovider extension rm -Rf lnbits_itest_data unzip data.zip + docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -d \ --rm \ +--user $(id -u):$(id -g) \ -p 5002:5000 \ -v ${PWD}/.env:/app/.env \ --v ${PWD}/lnbits_itest_data/:/app/data \ --v ${PWD}/../../:/app/lnbits/extensions/nwcprovider:ro \ -lnbits/lnbits - +-v ${PWD}/lnbits_itest_data/:/data \ +-v ${PWD}/../../:/nwcprovider \ +-v ${PWD}/../../.devcontainer/start.sh:/start-lnbits.sh:ro \ +-v ${PWD}/../../.devcontainer/setup.sh:/setup.sh:ro \ +mcr.microsoft.com/devcontainers/python:1-3.12 bash -c "while true; do sleep 1000; done" docker network create lnbits_nwcprovider_ext_test_network || true docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_nostr_test --alias nostr|| true docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_lnbits_test --alias lnbits|| true - +docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "curl -sSL https://install.python-poetry.org | python3 -" +docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && bash /setup.sh /nwcprovider" +docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "ln -s /app/.env \$HOME/lnbits/.env" +docker exec -d lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" + From 0f42344c6b00ac9991207a74e5ba640aca7a7989 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 19 Feb 2025 19:13:49 +0000 Subject: [PATCH 20/90] revert listener refactoring to avoid cyclic dependency hell --- models.py | 7 ----- nwcp.py | 1 - tasks.py | 84 ++++++++++++++++++++++++++++++++----------------------- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/models.py b/models.py index 6b0baa2..5884d4c 100644 --- a/models.py +++ b/models.py @@ -29,13 +29,6 @@ class NWCKey(BaseModel): return cls(**row) -class OnInvoicePaid(BaseModel): - class Config: - arbitrary_types_allowed = True - - sp: NWCServiceProvider - pubkey: str - payload: Dict class NWCBudget(BaseModel): diff --git a/nwcp.py b/nwcp.py index c83131d..3248317 100644 --- a/nwcp.py +++ b/nwcp.py @@ -14,7 +14,6 @@ from Cryptodome.Util.Padding import pad, unpad from lnbits.helpers import encrypt_internal_message from lnbits.settings import settings from loguru import logger -from pydantic import BaseModel class RateLimit: diff --git a/tasks.py b/tasks.py index 1adabd4..ebb59a6 100644 --- a/tasks.py +++ b/tasks.py @@ -19,7 +19,7 @@ from loguru import logger from .crud import get_config_nwc, get_nwc, tracked_spend_nwc from .execution_queue import execution_queue -from .models import NWCKey, OnInvoicePaid, TrackedSpendNWC, GetNWC +from .models import NWCKey, TrackedSpendNWC, GetNWC from .nwcp import NWCServiceProvider from .permission import nwc_permissions @@ -109,18 +109,20 @@ async def _process_invoice( async def _on_pay_invoice( - data: OnInvoicePaid, + sp: NWCServiceProvider, + pubkey: str, + payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: nwc = await get_nwc(GetNWC( - pubkey=data.pubkey, + pubkey=pubkey, refresh_last_used=True )) - error = await _check(nwc, "pay_invoice", data.payload) + error = await _check(nwc, "pay_invoice", payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - params = data.payload.get("params", {}) + params = payload.get("params", {}) invoice = params.get("invoice", None) # Ensures invoice is provided if not invoice: @@ -128,7 +130,7 @@ async def _on_pay_invoice( invoice_data = bolt11_decode(invoice) amount_msats = int(invoice_data.amount_msat or 0) res = await _process_invoice( - nwc.wallet, data.pubkey, invoice, amount_msats, invoice_data.description + nwc.wallet, pubkey, invoice, amount_msats, invoice_data.description ) error = res.get("error") if error: @@ -142,15 +144,17 @@ async def _on_pay_invoice( async def _on_multi_pay_invoice( - data: OnInvoicePaid, + sp: NWCServiceProvider, + pubkey: str, + payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) - error = await _check(nwc, "multi_pay_invoice", data.payload) + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) + error = await _check(nwc, "multi_pay_invoice", payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - params = data.payload.get("params", {}) + params = payload.get("params", {}) invoices = params.get("invoices", []) results: List[Tuple[Optional[Dict], Optional[Dict], List]] = [] @@ -167,7 +171,7 @@ async def _on_multi_pay_invoice( invoice_data = bolt11_decode(invoice) amount_msats = int(invoice_data.amount_msat or 0) res = await _process_invoice( - nwc.wallet, data.pubkey, invoice, amount_msats, invoice_data.description + nwc.wallet, pubkey, invoice, amount_msats, invoice_data.description ) error = res.get("error") if error: @@ -188,15 +192,17 @@ async def _on_multi_pay_invoice( async def _on_make_invoice( - data: OnInvoicePaid, + sp: NWCServiceProvider, + pubkey: str, + payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) - error = await _check(nwc, "make_invoice", data.payload) + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) + error = await _check(nwc, "make_invoice", payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - params = data.payload.get("params", {}) + params = payload.get("params", {}) amount_msats = params.get("amount", None) # Ensures amount is provided if not amount_msats: @@ -240,15 +246,17 @@ async def _on_make_invoice( async def _on_lookup_invoice( - data: OnInvoicePaid, + sp: NWCServiceProvider, + pubkey: str, + payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) - error = await _check(nwc, "lookup_invoice", data.payload) + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) + error = await _check(nwc, "lookup_invoice", payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - params = data.payload.get("params", {}) + params = payload.get("params", {}) payment_hash = params.get("payment_hash", None) invoice = params.get("invoice", None) # Ensure payment_hash or invoice are provided @@ -287,20 +295,22 @@ async def _on_lookup_invoice( async def _on_list_transactions( - data: OnInvoicePaid, + sp: NWCServiceProvider, + pubkey: str, + payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) - error = await _check(nwc, "list_transactions", data.payload) + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) + error = await _check(nwc, "list_transactions", payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - tfrom = data.payload.get("from", 0) - tto = data.payload.get("to", int(time.time())) - limit = data.payload.get("limit", 10) - offset = data.payload.get("offset", 0) - unpaid = data.payload.get("unpaid", False) - tx_type = data.payload.get("type", None) + tfrom = payload.get("from", 0) + tto = payload.get("to", int(time.time())) + limit = payload.get("limit", 10) + offset = payload.get("offset", 0) + unpaid = payload.get("unpaid", False) + tx_type = payload.get("type", None) values = [] filters: Filters = Filters() filters.where(["time <= ?"]) @@ -343,10 +353,12 @@ async def _on_list_transactions( async def _on_get_balance( - data: OnInvoicePaid, + sp: NWCServiceProvider, + pubkey: str, + payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used= True)) - error = await _check(nwc, "get_balance", data.payload) + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used= True)) + error = await _check(nwc, "get_balance", payload) if error: return [(None, error, [])] if not nwc: @@ -361,15 +373,17 @@ async def _on_get_balance( async def _on_get_info( - data: OnInvoicePaid, + sp: NWCServiceProvider, + pubkey: str, + payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(GetNWC(pubkey=data.pubkey, refresh_last_used=True)) - error = await _check(nwc, "get_info", data.payload) + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) + error = await _check(nwc, "get_info", payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - sp_methods = data.sp.get_supported_methods() + sp_methods = sp.get_supported_methods() permissions = nwc.get_permissions() # Filter only methods supported by the extension and allowed by the permissions account_methods = [] From eaf723919cdf74cbad79e4c65dd509feace05c59 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 19 Feb 2025 19:31:52 +0000 Subject: [PATCH 21/90] fix broken refactoring --- crud.py | 11 ++--------- tasks.py | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/crud.py b/crud.py index e8be965..400b5d1 100644 --- a/crud.py +++ b/crud.py @@ -79,14 +79,7 @@ async def get_nwc(data: GetNWC) -> Optional[NWCKey]: }, NWCKey, ) - else: - row = await db.fetchone( - """ - SELECT * FROM nwcprovider.keys - WHERE pubkey = ? AND (expires_at = 0 OR expires_at > ?) - """, - (data.pubkey, int(time.time()) if not data.include_expired else -1), - ) + else: row = await db.fetchone( """ SELECT * FROM nwcprovider.keys @@ -108,7 +101,7 @@ async def get_nwc(data: GetNWC) -> Optional[NWCKey]: """, {"last_used": int(time.time()), "pubkey": data.pubkey}, ) - return NWCKey(**row) + return row async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: diff --git a/tasks.py b/tasks.py index ebb59a6..a1c8363 100644 --- a/tasks.py +++ b/tasks.py @@ -117,7 +117,7 @@ async def _on_pay_invoice( pubkey=pubkey, refresh_last_used=True )) - error = await _check(nwc, "pay_invoice", payload) + error = await _check(nwc, "pay_invoice") if error: return [(None, error, [])] if not nwc: @@ -149,7 +149,7 @@ async def _on_multi_pay_invoice( payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) - error = await _check(nwc, "multi_pay_invoice", payload) + error = await _check(nwc, "multi_pay_invoice") if error: return [(None, error, [])] if not nwc: @@ -197,7 +197,7 @@ async def _on_make_invoice( payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) - error = await _check(nwc, "make_invoice", payload) + error = await _check(nwc, "make_invoice") if error: return [(None, error, [])] if not nwc: @@ -210,7 +210,7 @@ async def _on_make_invoice( description = params.get("description", "") description_hash = params.get("description_hash", None) expiry = params.get("expiry", None) - payment_hash, payment_request = await create_invoice( + payment = await create_invoice( wallet_id=nwc.wallet, amount=int(amount_msats / 1000), currency="sat", @@ -219,6 +219,8 @@ async def _on_make_invoice( unhashed_description=description.encode("utf-8"), expiry=expiry, ) + payment_hash = payment.payment_hash + payment_request = payment.bolt11 payment_status = await check_transaction_status( wallet_id=nwc.wallet, payment_hash=payment_hash ) @@ -251,7 +253,7 @@ async def _on_lookup_invoice( payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) - error = await _check(nwc, "lookup_invoice", payload) + error = await _check(nwc, "lookup_invoice") if error: return [(None, error, [])] if not nwc: @@ -300,7 +302,7 @@ async def _on_list_transactions( payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) - error = await _check(nwc, "list_transactions", payload) + error = await _check(nwc, "list_transactions") if error: return [(None, error, [])] if not nwc: @@ -358,7 +360,7 @@ async def _on_get_balance( payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used= True)) - error = await _check(nwc, "get_balance", payload) + error = await _check(nwc, "get_balance") if error: return [(None, error, [])] if not nwc: @@ -378,7 +380,7 @@ async def _on_get_info( payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) - error = await _check(nwc, "get_info", payload) + error = await _check(nwc, "get_info") if error: return [(None, error, [])] if not nwc: From 49d8f75e0678e97617b709db1f3dbc54b2d07cb1 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 09:54:55 +0000 Subject: [PATCH 22/90] fix for new api --- nwcp.py | 1 - tasks.py | 18 +++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/nwcp.py b/nwcp.py index 3248317..ff8aff8 100644 --- a/nwcp.py +++ b/nwcp.py @@ -323,7 +323,6 @@ class NWCServiceProvider: # Reference user res["tags"].append(["p", nwc_pubkey]) # Finalize response event - print(res) res["content"] = self._encrypt_content(res["content"], nwc_pubkey) self._sign_event(res) diff --git a/tasks.py b/tasks.py index a1c8363..9ca9bf7 100644 --- a/tasks.py +++ b/tasks.py @@ -55,13 +55,14 @@ async def _process_invoice( amount_msats: int, description: Optional[str] = None, ): - async def execute_payment(): - return await pay_invoice( + async def execute_payment() -> str : + payment = await pay_invoice( wallet_id=wallet_id, payment_request=invoice, max_sat=int(ceil(amount_msats / 1000)), description=description or "", ) + return payment.payment_hash payment_hash = None try: @@ -274,19 +275,21 @@ async def _on_lookup_invoice( raise Exception("Payment not found") invoice_data = bolt11_decode(payment.bolt11) is_settled = not payment.pending - timestamp = payment.time or invoice_data.date + timestamp = int(payment.time.timestamp()) or int(invoice_data.date) + expiry = int(payment.expiry.timestamp()) or timestamp + 3600 + preimage = payment.preimage or "0000000000000000000000000000000000000000000000000000000000000000" res: Dict = { "type": "outgoing" if payment.is_out else "incoming", "invoice": payment.bolt11, "description": ( invoice_data.description if invoice_data.description else payment.memo ), - "preimage": payment.preimage if is_settled or payment.is_in else None, + "preimage": preimage if is_settled or payment.is_in else None, "payment_hash": payment.payment_hash, "amount": abs(payment.msat), "fees_paid": abs(payment.fee), "created_at": timestamp, - "expires_at": payment.expiry if payment.expiry else timestamp + 3600, + "expires_at": expiry, "settled_at": timestamp if is_settled else None, "metadata": {}, } @@ -335,6 +338,7 @@ async def _on_list_transactions( for p in history: invoice_data = bolt11_decode(p.bolt11) is_settled = not p.pending + timestamp = int(p.time.timestamp()) or invoice_data.date transactions.append( { "type": "outgoing" if p.is_out else "incoming", @@ -345,8 +349,8 @@ async def _on_list_transactions( "payment_hash": p.payment_hash, "amount": abs(p.msat), "fees_paid": p.fee, - "created_at": p.time, - "settled_at": p.time if is_settled else None, + "created_at": timestamp, + "settled_at": timestamp if is_settled else None, "metadata": {}, } ) From 24c8ccd7def8b3b18602c0cfb61fa1887add8c89 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 09:59:45 +0000 Subject: [PATCH 23/90] fix integration test run --- .github/workflows/test.yml | 3 ++- tests/integration/start.sh | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4938526..7dcf534 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,7 +37,8 @@ jobs: pytest tests/unit/*.py -s - name: Setup integration tests - run: bash tests/integration/start.sh + run: | + bash tests/integration/start.sh & - name: Run integration tests run: | diff --git a/tests/integration/start.sh b/tests/integration/start.sh index bd510a5..454361c 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -45,7 +45,9 @@ docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ex docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_lnbits_test --alias lnbits|| true docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "curl -sSL https://install.python-poetry.org | python3 -" + +set +e docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && bash /setup.sh /nwcprovider" docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "ln -s /app/.env \$HOME/lnbits/.env" -docker exec -d lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" +docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" From 064e34c2ba93f67f0932ba1079a23b85cde455c1 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 10:08:23 +0000 Subject: [PATCH 24/90] fix integration test run? --- .github/workflows/test.yml | 3 ++- tests/integration/start.sh | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7dcf534..e720631 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,7 +38,8 @@ jobs: - name: Setup integration tests run: | - bash tests/integration/start.sh & + export HEADLESS=1 + bash tests/integration/start.sh - name: Run integration tests run: | diff --git a/tests/integration/start.sh b/tests/integration/start.sh index 454361c..866881d 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -49,5 +49,13 @@ docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "curl -sSL https://insta set +e docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && bash /setup.sh /nwcprovider" docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "ln -s /app/.env \$HOME/lnbits/.env" -docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" + + +ARGS="" +if [ "$HEADLESS" != "" ]; +then + ARGS="-d" +fi + +docker exec $ARGS lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" From d9462282e1cf2b22b6cc9095c0c938d711372881 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 10:55:21 +0000 Subject: [PATCH 25/90] fix integration test run? --- tests/integration/start.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/integration/start.sh b/tests/integration/start.sh index 866881d..e6ab1b5 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -28,10 +28,19 @@ ghcr.io/hoytech/strfry:latest rm -Rf lnbits_itest_data unzip data.zip +id=$(id -u) +gid=$(id -g) + +if [ "$(whoami)" == "root" ]; then + id=1000 + gid=1000 +fi + + docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -d \ --rm \ ---user $(id -u):$(id -g) \ +--user $id:$gid \ -p 5002:5000 \ -v ${PWD}/.env:/app/.env \ -v ${PWD}/lnbits_itest_data/:/data \ From d48f5a5989e4f2971f5fc659a0ae6ec2c592aeaa Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 11:29:52 +0000 Subject: [PATCH 26/90] fix integration test run? --- tests/integration/start.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/integration/start.sh b/tests/integration/start.sh index e6ab1b5..5893989 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -31,16 +31,12 @@ unzip data.zip id=$(id -u) gid=$(id -g) -if [ "$(whoami)" == "root" ]; then - id=1000 - gid=1000 -fi - docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -d \ --rm \ --user $id:$gid \ +-e HOME=/home/vscode \ -p 5002:5000 \ -v ${PWD}/.env:/app/.env \ -v ${PWD}/lnbits_itest_data/:/data \ From c4faac35c0022d0ba09c5c319284d74f6c1bbd91 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 12:35:30 +0100 Subject: [PATCH 27/90] fix integration test run? --- tests/integration/start.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/integration/start.sh b/tests/integration/start.sh index 5893989..974996e 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -31,6 +31,11 @@ unzip data.zip id=$(id -u) gid=$(id -g) +if [ "$(whoami)" == "root" ]; then + id=1000 + gid=1000 +fi + docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -d \ From e3957b51352f4cc4ea5eb96ee8c5f850ff3f9fb7 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 12:16:21 +0000 Subject: [PATCH 28/90] edges hardening --- crud.py | 84 +++++++++++++++++++++++++++++++++-- paranoia.py | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++ tasks.py | 83 +++++++++++++++++++++++++++++++++++ views_api.py | 36 +++++++++++++++ 4 files changed, 322 insertions(+), 3 deletions(-) create mode 100644 paranoia.py diff --git a/crud.py b/crud.py index 400b5d1..08d29e7 100644 --- a/crud.py +++ b/crud.py @@ -15,11 +15,28 @@ from .models import ( GetNWC, NWCNewBudget ) +from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_valid_timestamp_seconds, assert_valid_msats, assert_valid_positive_int db = Database("ext_nwcprovider") async def create_nwc(data: CreateNWCKey) -> NWCKey: + + # hardening # + assert_valid_pubkey(data.pubkey) + assert_valid_wallet_id(data.wallet) + assert_sane_string(data.description) + assert_valid_timestamp_seconds(data.expires_at) + for permission in data.permissions: + assert_sane_string(permission) + + if data.budgets: + for budget in data.budgets: + assert_valid_msats(budget.budget_msats) + assert_valid_positive_int(budget.refresh_window) + assert_valid_timestamp_seconds(budget.created_at) + # ## # + nwckey_entry = NWCKey( pubkey=data.pubkey, wallet=data.wallet, @@ -43,6 +60,12 @@ async def create_nwc(data: CreateNWCKey) -> NWCKey: async def delete_nwc(data: DeleteNWC) -> None: + + # hardening # + assert_valid_pubkey(data.pubkey) + assert_valid_wallet_id(data.wallet) + # ## # + await db.execute( "DELETE FROM nwcprovider.keys WHERE pubkey = :pubkey AND wallet = :wallet", {"pubkey": data.pubkey, "wallet": data.wallet}, @@ -50,6 +73,13 @@ async def delete_nwc(data: DeleteNWC) -> None: async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: + expires = int(time.time()) if not data.include_expired else -1 + + # hardening # + assert_valid_wallet_id(data.wallet) + assert_valid_timestamp_seconds(expires) + # ## # + return await db.fetchall( """ SELECT * FROM nwcprovider.keys @@ -57,15 +87,23 @@ async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: """, { "wallet": data.wallet, - "expires": int(time.time()) if not data.include_expired else -1, + "expires": expires, }, model=NWCKey, ) async def get_nwc(data: GetNWC) -> Optional[NWCKey]: + expires = int(time.time()) if not data.include_expired else -1 + + # hardening # + assert_valid_pubkey(data.pubkey) + assert_valid_timestamp_seconds(expires) + # ## # + # expires_at = 0 means it never expires if data.wallet: + assert_valid_wallet_id(data.wallet) row = await db.fetchone( """ SELECT * FROM nwcprovider.keys @@ -75,7 +113,7 @@ async def get_nwc(data: GetNWC) -> Optional[NWCKey]: { "pubkey": data.pubkey, "wallet": data.wallet, - "expires": int(time.time()) if not data.include_expired else -1, + "expires": expires, }, NWCKey, ) @@ -87,7 +125,7 @@ async def get_nwc(data: GetNWC) -> Optional[NWCKey]: """, { "pubkey": data.pubkey, - "expires": int(time.time()) if not data.include_expired else -1, + "expires": expires, }, NWCKey, ) @@ -105,6 +143,11 @@ async def get_nwc(data: GetNWC) -> Optional[NWCKey]: async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: + + # hardening # + assert_valid_pubkey(data.pubkey) + # ## # + rows = await db.fetchall( "SELECT * FROM nwcprovider.budgets WHERE pubkey = :pubkey", {"pubkey": data.pubkey}, @@ -113,6 +156,12 @@ async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: if data.calculate_spent: for budget in budgets: last_cycle, next_cycle = budget.get_timestamp_range() + + # hardening # + assert_valid_timestamp_seconds(last_cycle) + assert_valid_timestamp_seconds(next_cycle) + # ## # + tot_spent_in_range_msats = await db.fetchone( """ SELECT SUM(amount_msats) FROM nwcprovider.spent @@ -126,12 +175,23 @@ async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: }, ) tot_spent_in_range_msats = next(iter(tot_spent_in_range_msats.values())) or 0 + + # hardening # + assert_valid_msats(tot_spent_in_range_msats) + # ## # + budget.used_budget_msats = tot_spent_in_range_msats return budgets async def tracked_spend_nwc(data: TrackedSpendNWC, action): async def r(): + + # hardening # + assert_valid_pubkey(data.pubkey) + assert_valid_msats(data.amount_msats) + # ## # + created_at = int(time.time()) budgets = await get_budgets_nwc(GetBudgetsNWC( pubkey=data.pubkey @@ -139,6 +199,12 @@ async def tracked_spend_nwc(data: TrackedSpendNWC, action): in_budget = True for budget in budgets: last_cycle, next_cycle = budget.get_timestamp_range() + + # hardening # + assert_valid_timestamp_seconds(last_cycle) + assert_valid_timestamp_seconds(next_cycle) + # ## # + tot_spent_in_range_msats = ( next(iter((await db.fetchone( """ @@ -153,6 +219,12 @@ async def tracked_spend_nwc(data: TrackedSpendNWC, action): }, )).values())) or 0 ) + + # hardening # + assert_valid_msats(tot_spent_in_range_msats) + assert_valid_msats(budget.budget_msats) + # ## # + if tot_spent_in_range_msats + data.amount_msats > budget.budget_msats: in_budget = False break @@ -185,6 +257,12 @@ async def get_config_nwc(key: str): async def set_config_nwc(key: str, value: str): + + # hardening # + assert_sane_string(key) + assert_sane_string(value) + # ## # + await db.execute( """ INSERT OR REPLACE INTO nwcprovider.config (key, value) diff --git a/paranoia.py b/paranoia.py new file mode 100644 index 0000000..4e56e93 --- /dev/null +++ b/paranoia.py @@ -0,0 +1,122 @@ +# Run-time hardening to detect unexpected inputs at the edges +from loguru import logger + +ENABLE_HARDENING = True + +def panic(reason:str): + if not ENABLE_HARDENING: + return + logger.error(f"hardening error: {reason}") + raise ValueError(f"hardening error: {reason}") + +# Throw if string contains any non-printable characters +def assert_printable(v:str): + if not ENABLE_HARDENING: + return + if not isinstance(v, str): + panic("not a string "+str(v)) + if not v.isprintable(): + panic("string contains non-printable characters") + +# Check if number is valid int and not NaN +def assert_valid_int(v:int): + if not ENABLE_HARDENING: + return + if not isinstance(v, int): + panic("number is not a valid int") + +# Check if number is valid positive int +def assert_valid_positive_int(v:int): + if not ENABLE_HARDENING: + return + assert_valid_int(v) + if v < 0: + panic("number is not positive") + +# Check if number is a valid sats amount +def assert_valid_sats(v:int): + if not ENABLE_HARDENING: + return + assert_valid_positive_int(v) + max_sats_value = 10_000_000 + if v >= max_sats_value: + panic("sats amount looks too high") + +# Check if number is a valid msats amount +def assert_valid_msats(v:int): + if not ENABLE_HARDENING: + return + assert_valid_positive_int(v) + max_msats_value = 10_000_000 * 1000 + if v >= max_msats_value: + panic("msats amount looks too high") + + +# Check if string is a valid sha256 hash +def assert_valid_sha256(v:str): + if not ENABLE_HARDENING: + return + assert_printable(v) + if len(v) != 64 or not all(c in "0123456789abcdef" for c in v): + panic("string is not a valid sha256 hash") + +# Check if valid nostr pubkey +def assert_valid_pubkey(v:str): + if not ENABLE_HARDENING: + return + assert_valid_sha256(v) + + +# Check if valid wallet id +def assert_valid_wallet_id(v:str): + if not ENABLE_HARDENING: + return + assert_printable(v) + if not v.isalnum(): + panic("string is not a valid wallet id") + + +# Check if valid timestamp in seconds +def assert_valid_timestamp_seconds(v:int): + if not ENABLE_HARDENING: + return + assert_valid_int(v) + if v < 0: + panic("timestamp is negative") + if v > 2**31: + panic("timestamp is too high") + +# Check if string is within sane parameters +def assert_sane_string(v:str): + if not ENABLE_HARDENING: + return + assert_printable(v) + if len(v) > 1024: + panic("string is too long") + + +# Check if string is a non-empty string +def assert_non_empty_string(v:str): + if not ENABLE_HARDENING: + return + assert_printable(v) + if len(v.strip()) == 0: + panic("string is empty") + +# Assert valid json +def assert_valid_json(v:str): + if not ENABLE_HARDENING: + return + assert_non_empty_string(v) + try: + import json + json.loads(v) + except: + panic("string is not valid json") + +# Check if string is a valid bolt11 invoice +def assert_valid_bolt11(invoice:str): + if not ENABLE_HARDENING: + return + assert_printable(invoice) + diff --git a/tasks.py b/tasks.py index 9ca9bf7..4b89913 100644 --- a/tasks.py +++ b/tasks.py @@ -22,6 +22,7 @@ from .execution_queue import execution_queue from .models import NWCKey, TrackedSpendNWC, GetNWC from .nwcp import NWCServiceProvider from .permission import nwc_permissions +from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_valid_timestamp_seconds, assert_valid_msats, assert_valid_positive_int, assert_valid_bolt11, assert_valid_sha256 async def _check(nwc: Optional[NWCKey], method: str) -> Optional[Dict]: @@ -55,6 +56,16 @@ async def _process_invoice( amount_msats: int, description: Optional[str] = None, ): + + # hardening # + assert_valid_wallet_id(wallet_id) + assert_valid_pubkey(pubkey) + assert_valid_bolt11(invoice) + assert_valid_msats(amount_msats) + if description: + assert_sane_string(description) + # ## # + async def execute_payment() -> str : payment = await pay_invoice( wallet_id=wallet_id, @@ -114,6 +125,11 @@ async def _on_pay_invoice( pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + + # hardening # + assert_valid_pubkey(pubkey) + # ## # + nwc = await get_nwc(GetNWC( pubkey=pubkey, refresh_last_used=True @@ -130,6 +146,12 @@ async def _on_pay_invoice( raise Exception("Missing invoice") invoice_data = bolt11_decode(invoice) amount_msats = int(invoice_data.amount_msat or 0) + + # hardening # + assert_valid_bolt11(invoice) + assert_valid_msats(amount_msats) + # ## # + res = await _process_invoice( nwc.wallet, pubkey, invoice, amount_msats, invoice_data.description ) @@ -149,6 +171,11 @@ async def _on_multi_pay_invoice( pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + + # hardening # + assert_valid_pubkey(pubkey) + # ## # + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) error = await _check(nwc, "multi_pay_invoice") if error: @@ -171,6 +198,12 @@ async def _on_multi_pay_invoice( invoice = i.get("invoice", None) invoice_data = bolt11_decode(invoice) amount_msats = int(invoice_data.amount_msat or 0) + + # hardening # + assert_valid_bolt11(invoice) + assert_valid_msats(amount_msats) + # ## # + res = await _process_invoice( nwc.wallet, pubkey, invoice, amount_msats, invoice_data.description ) @@ -197,6 +230,11 @@ async def _on_make_invoice( pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + + # hardening # + assert_valid_pubkey(pubkey) + # ## # + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) error = await _check(nwc, "make_invoice") if error: @@ -211,6 +249,17 @@ async def _on_make_invoice( description = params.get("description", "") description_hash = params.get("description_hash", None) expiry = params.get("expiry", None) + + # hardening # + assert_valid_msats(amount_msats) + if description: + assert_sane_string(description) + if description_hash: + assert_valid_sha256(description_hash) + if expiry: + assert_valid_timestamp_seconds(expiry) + # ## # + payment = await create_invoice( wallet_id=nwc.wallet, amount=int(amount_msats / 1000), @@ -253,6 +302,11 @@ async def _on_lookup_invoice( pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + + # hardening # + assert_valid_pubkey(pubkey) + # ## # + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) error = await _check(nwc, "lookup_invoice") if error: @@ -269,6 +323,12 @@ async def _on_lookup_invoice( if not payment_hash: invoice_data = bolt11_decode(invoice) payment_hash = invoice_data.payment_hash + + # hardening # + assert_valid_sha256(payment_hash) + assert_valid_bolt11(invoice) + # ## # + # Get payment data payment = await get_wallet_payment(nwc.wallet, payment_hash) if not payment: @@ -304,6 +364,10 @@ async def _on_list_transactions( pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + # hardening # + assert_valid_pubkey(pubkey) + # ## # + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) error = await _check(nwc, "list_transactions") if error: @@ -316,6 +380,15 @@ async def _on_list_transactions( offset = payload.get("offset", 0) unpaid = payload.get("unpaid", False) tx_type = payload.get("type", None) + + # hardening # + assert_valid_positive_int(tfrom) + assert_valid_positive_int(tto) + assert_valid_positive_int(limit) + assert_valid_positive_int(offset) + assert_sane_string(tx_type) + # ## # + values = [] filters: Filters = Filters() filters.where(["time <= ?"]) @@ -363,6 +436,11 @@ async def _on_get_balance( pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + + # hardening # + assert_valid_pubkey(pubkey) + # ## # + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used= True)) error = await _check(nwc, "get_balance") if error: @@ -383,6 +461,11 @@ async def _on_get_info( pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + + # hardening # + assert_valid_pubkey(pubkey) + # ## # + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) error = await _check(nwc, "get_info") if error: diff --git a/views_api.py b/views_api.py index 2bd68fb..fcd755e 100644 --- a/views_api.py +++ b/views_api.py @@ -28,6 +28,7 @@ from .models import ( GetBudgetsNWC ) from .permission import nwc_permissions +from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string nwcprovider_api_router = APIRouter() @@ -53,6 +54,11 @@ async def api_get_nwcs( wallet: WalletTypeInfo = Depends(require_admin_key), ): wallet_id = wallet.wallet.id + + # hardening # + assert_valid_wallet_id(wallet_id) + # ## # + wallet_nwcs = GetWalletNWC( wallet=wallet_id, include_expired=include_expired @@ -82,6 +88,12 @@ async def api_get_nwc( wallet: WalletTypeInfo = Depends(require_admin_key) ) -> NWCGetResponse: wallet_id = wallet.wallet.id + + # hardening # + assert_valid_pubkey(pubkey) + assert_valid_wallet_id(wallet_id) + # ## # + nwc = await get_nwc(GetNWC(pubkey=pubkey, wallet=wallet_id, include_expired=include_expired)) if not nwc: raise Exception("Pubkey has no associated wallet") @@ -103,6 +115,11 @@ async def api_get_pairing_url( req: Request, secret: str ) -> str: + + # hardening # + assert_sane_string(secret) + # ## # + pprivkey: Optional[str] = await get_config_nwc("provider_key") if not pprivkey: raise Exception("Extension is not configured") @@ -147,6 +164,12 @@ async def api_register_nwc( wallet: WalletTypeInfo = Depends(require_admin_key), ): wallet_id = wallet.wallet.id + + # hardening # + assert_valid_pubkey(pubkey) + assert_valid_wallet_id(wallet_id) + # ## # + nwc = await create_nwc( CreateNWCKey( pubkey=pubkey, @@ -176,6 +199,12 @@ async def api_delete_nwc( wallet: WalletTypeInfo = Depends(require_admin_key) ): wallet_id = wallet.wallet.id + + # hardening # + assert_valid_pubkey(pubkey) + assert_valid_wallet_id(wallet_id) + # ## # + await delete_nwc(DeleteNWC( pubkey=pubkey, wallet=wallet_id @@ -217,6 +246,13 @@ async def api_get_config_nwc(key: str): ) async def api_set_config_nwc(req: Request): data = await req.json() + + # hardening # + for key, value in data.items(): + assert_sane_string(key) + assert_sane_string(value) + # ## # + for key, value in data.items(): await set_config_nwc(key, value) return await api_get_all_config_nwc() From 0b0efa0518ceaf7afb610eca5a516ca3c76df292 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 13:21:40 +0100 Subject: [PATCH 29/90] fix integration test run? --- tests/integration/start.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/integration/start.sh b/tests/integration/start.sh index 974996e..3311dea 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -54,11 +54,11 @@ docker network create lnbits_nwcprovider_ext_test_network || true docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_nostr_test --alias nostr|| true docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_lnbits_test --alias lnbits|| true -docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "curl -sSL https://install.python-poetry.org | python3 -" +docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "curl -sSL https://install.python-poetry.org | python3 -" set +e -docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && bash /setup.sh /nwcprovider" -docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "ln -s /app/.env \$HOME/lnbits/.env" +docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && bash /setup.sh /nwcprovider" +docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "ln -s /app/.env \$HOME/lnbits/.env" ARGS="" @@ -67,5 +67,5 @@ then ARGS="-d" fi -docker exec $ARGS lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" +docker exec --user $id:$gid $ARGS lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" From 686eda82b7256d8b9b139521747332b0b8a6c8b9 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 12:27:22 +0000 Subject: [PATCH 30/90] more hardening --- paranoia.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/paranoia.py b/paranoia.py index 4e56e93..7d1f584 100644 --- a/paranoia.py +++ b/paranoia.py @@ -6,8 +6,8 @@ ENABLE_HARDENING = True def panic(reason:str): if not ENABLE_HARDENING: return - logger.error(f"hardening error: {reason}") - raise ValueError(f"hardening error: {reason}") + logger.error(f"hardening: {reason}") + raise ValueError(f"hardening: {reason}") # Throw if string contains any non-printable characters def assert_printable(v:str): @@ -81,7 +81,7 @@ def assert_valid_timestamp_seconds(v:int): if not ENABLE_HARDENING: return assert_valid_int(v) - if v < 0: + if v < 0 and v != -1: panic("timestamp is negative") if v > 2**31: panic("timestamp is too high") From 171d2b128c1a65e90806435d4a121483b9a64712 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 12:29:25 +0000 Subject: [PATCH 31/90] fix for ghactions ? --- tests/integration/start.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/integration/start.sh b/tests/integration/start.sh index 3311dea..f00c494 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -31,17 +31,11 @@ unzip data.zip id=$(id -u) gid=$(id -g) -if [ "$(whoami)" == "root" ]; then - id=1000 - gid=1000 -fi - docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -d \ --rm \ --user $id:$gid \ --e HOME=/home/vscode \ -p 5002:5000 \ -v ${PWD}/.env:/app/.env \ -v ${PWD}/lnbits_itest_data/:/data \ @@ -50,6 +44,8 @@ docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -v ${PWD}/../../.devcontainer/setup.sh:/setup.sh:ro \ mcr.microsoft.com/devcontainers/python:1-3.12 bash -c "while true; do sleep 1000; done" +docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "id -u $id &>/dev/null || useradd -m -u $id tester" + docker network create lnbits_nwcprovider_ext_test_network || true docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_nostr_test --alias nostr|| true docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_lnbits_test --alias lnbits|| true @@ -57,7 +53,7 @@ docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ex docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "curl -sSL https://install.python-poetry.org | python3 -" set +e -docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && bash /setup.sh /nwcprovider" +docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"\$HOME/.local/bin:\$PATH\" && bash /setup.sh /nwcprovider" docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "ln -s /app/.env \$HOME/lnbits/.env" @@ -67,5 +63,5 @@ then ARGS="-d" fi -docker exec --user $id:$gid $ARGS lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"/home/vscode/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" +docker exec --user $id:$gid $ARGS lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"\$HOME/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" From c33fd1c2df01ac604e8f6dcdb70b5ab1e1bdfd2a Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 12:37:32 +0000 Subject: [PATCH 32/90] fix ghactions? --- tests/integration/start.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/integration/start.sh b/tests/integration/start.sh index f00c494..d6924d3 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -44,12 +44,11 @@ docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -v ${PWD}/../../.devcontainer/setup.sh:/setup.sh:ro \ mcr.microsoft.com/devcontainers/python:1-3.12 bash -c "while true; do sleep 1000; done" -docker exec lnbits_nwcprovider_ext_lnbits_test bash -c "id -u $id &>/dev/null || useradd -m -u $id tester" - docker network create lnbits_nwcprovider_ext_test_network || true docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_nostr_test --alias nostr|| true docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_lnbits_test --alias lnbits|| true +docker exec -u root lnbits_nwcprovider_ext_lnbits_test bash -c "id -u $id &>/dev/null || useradd -m -u $id tester" docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "curl -sSL https://install.python-poetry.org | python3 -" set +e From 404da582fe5604835fb3b126acdd014e7bb20d94 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 13:47:02 +0100 Subject: [PATCH 33/90] more ghaction fixes --- .devcontainer/devcontainer.json | 3 ++- .devcontainer/pre-setup.sh | 10 ++++++++++ .devcontainer/setup.sh | 8 +------- tests/integration/start.sh | 2 ++ 4 files changed, 15 insertions(+), 8 deletions(-) create mode 100644 .devcontainer/pre-setup.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5d69523..ab3aa91 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,12 +7,13 @@ "mounts": [ "source=${localWorkspaceFolder}/.devcontainer/start.sh,target=/start-lnbits.sh,type=bind", "source=${localWorkspaceFolder}/.devcontainer/setup.sh,target=/setup.sh,type=bind", + "source=${localWorkspaceFolder}/.devcontainer/pre-setup.sh,target=/pre-setup.sh,type=bind", "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ], "containerEnv": { "IS_DEV_CONTAINER": "true" }, - "postCreateCommand": "/bin/bash /setup.sh ${containerWorkspaceFolder}", + "postCreateCommand": "/bin/bash /pre-setup.sh && /bin/bash /setup.sh ${containerWorkspaceFolder}", "postStartCommand": "/bin/bash /start-lnbits.sh", "customizations": { "vscode": { diff --git a/.devcontainer/pre-setup.sh b/.devcontainer/pre-setup.sh new file mode 100644 index 0000000..367a1e1 --- /dev/null +++ b/.devcontainer/pre-setup.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +sudo apt update -y +sudo apt install -y curl +sudo apt-get install -y docker.io + +curl -fsSL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup.sh +sudo bash /tmp/nodesource_setup.sh +sudo apt-get install -y nodejs diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index 7a8da6d..aac5e84 100644 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -1,14 +1,8 @@ #!/bin/bash echo $PYTHONPATH +set -e CONTAINER_WORKSPACE_FOLDER=$1 cd $CONTAINER_WORKSPACE_FOLDER -sudo apt update -y -sudo apt install -y curl -sudo apt-get install -y docker.io - -curl -fsSL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup.sh -sudo bash /tmp/nodesource_setup.sh -sudo apt-get install -y nodejs cd $HOME echo $PWD diff --git a/tests/integration/start.sh b/tests/integration/start.sh index d6924d3..140f26a 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -42,6 +42,7 @@ docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -v ${PWD}/../../:/nwcprovider \ -v ${PWD}/../../.devcontainer/start.sh:/start-lnbits.sh:ro \ -v ${PWD}/../../.devcontainer/setup.sh:/setup.sh:ro \ +-v ${PWD}/../../.devcontainer/pre-setup.sh:/pre-setup.sh:ro \ mcr.microsoft.com/devcontainers/python:1-3.12 bash -c "while true; do sleep 1000; done" docker network create lnbits_nwcprovider_ext_test_network || true @@ -49,6 +50,7 @@ docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ex docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_lnbits_test --alias lnbits|| true docker exec -u root lnbits_nwcprovider_ext_lnbits_test bash -c "id -u $id &>/dev/null || useradd -m -u $id tester" +docker exec -u root lnbits_nwcprovider_ext_lnbits_test bash -c "bash /pre-setup.sh" docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "curl -sSL https://install.python-poetry.org | python3 -" set +e From 26a7dd821c8860b33b49c745e6c12b54ec5a81e8 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 13:48:59 +0100 Subject: [PATCH 34/90] fix integration test run? --- .devcontainer/setup.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index aac5e84..d2a2f72 100644 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -1,6 +1,5 @@ #!/bin/bash echo $PYTHONPATH -set -e CONTAINER_WORKSPACE_FOLDER=$1 cd $CONTAINER_WORKSPACE_FOLDER From fac130c49ce400700d1b15b1f88a0cf593c52b32 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 12:54:17 +0000 Subject: [PATCH 35/90] more hardening --- crud.py | 8 ++++---- paranoia.py | 18 +++++++++++++++--- tasks.py | 4 ++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/crud.py b/crud.py index 08d29e7..dd87609 100644 --- a/crud.py +++ b/crud.py @@ -15,7 +15,7 @@ from .models import ( GetNWC, NWCNewBudget ) -from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_valid_timestamp_seconds, assert_valid_msats, assert_valid_positive_int +from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_valid_timestamp_seconds, assert_valid_expiration_seconds, assert_valid_msats, assert_valid_positive_int db = Database("ext_nwcprovider") @@ -26,7 +26,7 @@ async def create_nwc(data: CreateNWCKey) -> NWCKey: assert_valid_pubkey(data.pubkey) assert_valid_wallet_id(data.wallet) assert_sane_string(data.description) - assert_valid_timestamp_seconds(data.expires_at) + assert_valid_expiration_seconds(data.expires_at) for permission in data.permissions: assert_sane_string(permission) @@ -77,7 +77,7 @@ async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: # hardening # assert_valid_wallet_id(data.wallet) - assert_valid_timestamp_seconds(expires) + assert_valid_expiration_seconds(expires) # ## # return await db.fetchall( @@ -98,7 +98,7 @@ async def get_nwc(data: GetNWC) -> Optional[NWCKey]: # hardening # assert_valid_pubkey(data.pubkey) - assert_valid_timestamp_seconds(expires) + assert_valid_expiration_seconds(expires) # ## # # expires_at = 0 means it never expires diff --git a/paranoia.py b/paranoia.py index 7d1f584..ed21a72 100644 --- a/paranoia.py +++ b/paranoia.py @@ -80,12 +80,24 @@ def assert_valid_wallet_id(v:str): def assert_valid_timestamp_seconds(v:int): if not ENABLE_HARDENING: return - assert_valid_int(v) - if v < 0 and v != -1: - panic("timestamp is negative") + assert_valid_positive_int(v) if v > 2**31: panic("timestamp is too high") + +# Check if valid expiration in seconds +def assert_valid_expiration_seconds(v: int): + if not ENABLE_HARDENING: + return + assert_valid_int(v) + if v == -1: + return + if v < 0: + panic("expiration is invalid") + if v > 2**31: + panic("expiration is too high") + + # Check if string is within sane parameters def assert_sane_string(v:str): if not ENABLE_HARDENING: diff --git a/tasks.py b/tasks.py index 4b89913..43175f2 100644 --- a/tasks.py +++ b/tasks.py @@ -22,7 +22,7 @@ from .execution_queue import execution_queue from .models import NWCKey, TrackedSpendNWC, GetNWC from .nwcp import NWCServiceProvider from .permission import nwc_permissions -from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_valid_timestamp_seconds, assert_valid_msats, assert_valid_positive_int, assert_valid_bolt11, assert_valid_sha256 +from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_valid_timestamp_seconds, assert_valid_expiration_seconds, assert_valid_msats, assert_valid_positive_int, assert_valid_bolt11, assert_valid_sha256 async def _check(nwc: Optional[NWCKey], method: str) -> Optional[Dict]: @@ -257,7 +257,7 @@ async def _on_make_invoice( if description_hash: assert_valid_sha256(description_hash) if expiry: - assert_valid_timestamp_seconds(expiry) + assert_valid_expiration_seconds(expiry) # ## # payment = await create_invoice( From 06fdb06d9ae3b5d26df371247ce16f54c1032587 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 13:05:53 +0000 Subject: [PATCH 36/90] garbage collect old tracked events --- nwcp.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/nwcp.py b/nwcp.py index ff8aff8..5aafbe8 100644 --- a/nwcp.py +++ b/nwcp.py @@ -47,6 +47,24 @@ class MainSubscription: if event_id not in self.responses: self.responses.append(event_id) + def gc(self, expire: int = 3 * 60 * 60): + """ + Garbage collection, remove all the events that have a response older than expire seconds. + """ + now = int(time.time()) + deleted_ids = [] + for [event_id, event] in self.events.items(): + if event_id in self.responses: + if now - event["created_at"] > expire: + del self.events[event_id] + deleted_ids.append(event_id) + self.responses = [event_id for event_id in self.responses if event_id not in deleted_ids] + + if len(deleted_ids) > 0: + logger.debug("Garbage collected " + str(len(deleted_ids)) + " events") + + + class Config: arbitrary_types_allowed = True @@ -92,6 +110,9 @@ class NWCServiceProvider: # Reconnect task (if the connection is lost) self.reconnect_task = None + # Garbage collection loop + self.gc_task = None + # Subscription self.sub = None self.rate_limit: Dict[str, RateLimit] = {} @@ -112,6 +133,13 @@ class NWCServiceProvider: + self.public_key_hex ) + async def _gc_loop(self): + while not self._is_shutting_down(): + if self.sub: + self.sub.gc() + await asyncio.sleep(60) + + def get_supported_methods(self): """ Returns the list of supported methods by this service provider. @@ -144,6 +172,7 @@ class NWCServiceProvider: Starts the NWC service provider. """ self.reconnect_task = asyncio.create_task(self._connect_to_relay()) + self.gc_task = asyncio.create_task(self._gc_loop()) def _json_dumps(self, data: Union[Dict, list]) -> str: """ @@ -602,6 +631,11 @@ class NWCServiceProvider: self.reconnect_task.cancel() except Exception as e: logger.warning("Error closing reconnection task: " + str(e)) + try: + if self.gc_task: + self.gc_task.cancel() + except Exception as e: + logger.warning("Error closing gc loop: " + str(e)) # close the websocket try: if self.ws: From 1f26e11e8b98cef3e06fae71cd4c7aa3601f09e7 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 13:41:44 +0000 Subject: [PATCH 37/90] configurable handle_missed_events --- README.md | 7 +++++++ migrations.py | 14 ++++++++++++++ nwcp.py | 20 +++++++++++++------- tasks.py | 3 ++- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 605ec9d..c1f3ec7 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,13 @@ Configure the extension from the "Settings" page in the top right menu when logg | relay | URL of the nostr relay for dispatching and receiving NWC events. Use public relays or a custom one. Specify `nostrclient` to connect to the [nostrclient extension](https://github.com/lnbits/nostrclient). | nostrclient | | provider_key | Nostr secret key of the NWC Service Provider. | Random key generated on install | | relay_alias | Relay URL to display in pairing URLs. Set if different from `relay`. | Empty (uses the `relay` value) | +| handle_missed_events | Number of seconds to look back for processing events missed while offline. Setting it to 0 disables this functionality. | 0 | + + +> [!WARNING] +> +> Do not change handle_missed_events from its default value of 0 unless you fully understand its implications. While a non-zero value may improve service quality under unstable conditions (e.g., poor connectivity or unreliable power), it can also lead to unexpected behavior. For example, in shared or community lnbits instances, where users are unaware of this functionality, they might assume a payment has failed and attempt to pay a new invoice with a different wallet, only for the instance to come back online and process the original payment request, potentially leading to duplicate payments. For this reason, unless you are trying to tackle this specific issue, it is recommended to leave this setting at 0. + ### Using Nostrclient diff --git a/migrations.py b/migrations.py index 98dd934..6046c3c 100644 --- a/migrations.py +++ b/migrations.py @@ -105,3 +105,17 @@ async def m005_key_last_used(db): ALTER TABLE nwcprovider.keys ADD COLUMN last_used INTEGER; """ ) + + +async def m006_default_config3(db): + """ + Default config + """ + + await db.execute( + """ + INSERT OR REPLACE INTO nwcprovider.config + (key, value) VALUES ('handle_missed_events', :value); + """, + {"value": "0"}, + ) diff --git a/nwcp.py b/nwcp.py index 5aafbe8..8af7716 100644 --- a/nwcp.py +++ b/nwcp.py @@ -47,10 +47,11 @@ class MainSubscription: if event_id not in self.responses: self.responses.append(event_id) - def gc(self, expire: int = 3 * 60 * 60): + def gc(self, expire: Optional[int] = None): """ - Garbage collection, remove all the events that have a response older than expire seconds. + Garbage collection, remove all the events that have a response older than expire seconds (defaults to 1 hour if 0 or None) """ + expire = expire or 1 * 60 * 60 now = int(time.time()) deleted_ids = [] for [event_id, event] in self.events.items(): @@ -70,7 +71,7 @@ class MainSubscription: class NWCServiceProvider: - def __init__(self, private_key: Optional[str] = None, relay: Optional[str] = None): + def __init__(self, private_key: Optional[str] = None, relay: Optional[str] = None, handle_missed_events: int = 3 * 60 * 60): if not relay: # Connect to nostrclient relay = "nostrclient" if relay == "nostrclient": @@ -125,6 +126,11 @@ class NWCServiceProvider: # if True the instance is shutting down self.shutdown = False + + # process missed events that are not older than + # handle_missed_events seconds (0 to disable) + # (handles reboots) + self.handle_missed_events = handle_missed_events logger.info( "NWC Service is ready. relay: " @@ -136,7 +142,7 @@ class NWCServiceProvider: async def _gc_loop(self): while not self._is_shutting_down(): if self.sub: - self.sub.gc() + self.sub.gc(self.handle_missed_events) await asyncio.sleep(60) @@ -263,15 +269,15 @@ class NWCServiceProvider: req_filter = { "kinds": [23194], "#p": [self.public_key_hex], - # Since the last 3 hours (handles reboots) - "since": int(time.time()) - 3 * 60 * 60, + # Since the last handle_missed_events seconds (handles reboots) + "since": int(time.time()) - self.handle_missed_events } self.sub.requests_sub_id = self._get_new_subid() # Create responses subscription (needed to track previosly responded requests) res_filter = { "kinds": [23195], "authors": [self.public_key_hex], - "since": int(time.time()) - 3 * 60 * 60, + "since": int(time.time()) - self.handle_missed_events, } self.sub.responses_sub_id = self._get_new_subid() # Subscribe diff --git a/tasks.py b/tasks.py index 43175f2..5091656 100644 --- a/tasks.py +++ b/tasks.py @@ -503,7 +503,8 @@ async def _on_get_info( async def handle_nwc(): priv_key = await get_config_nwc("provider_key") relay = await get_config_nwc("relay") - nwcsp = NWCServiceProvider(priv_key, relay) + handle_missed_events = int(await get_config_nwc("handle_missed_events") or 0) + nwcsp = NWCServiceProvider(priv_key, relay, handle_missed_events) nwcsp.add_request_listener("pay_invoice", _on_pay_invoice) nwcsp.add_request_listener("multi_pay_invoice", _on_multi_pay_invoice) nwcsp.add_request_listener("make_invoice", _on_make_invoice) From 79c01a0f34a0165867f9880f4a6dcfd860c6a8ac Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 13:43:07 +0000 Subject: [PATCH 38/90] readme format --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c1f3ec7..7e8ba03 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,11 @@ Configure the extension from the "Settings" page in the top right menu when logg > [!WARNING] > -> Do not change handle_missed_events from its default value of 0 unless you fully understand its implications. While a non-zero value may improve service quality under unstable conditions (e.g., poor connectivity or unreliable power), it can also lead to unexpected behavior. For example, in shared or community lnbits instances, where users are unaware of this functionality, they might assume a payment has failed and attempt to pay a new invoice with a different wallet, only for the instance to come back online and process the original payment request, potentially leading to duplicate payments. For this reason, unless you are trying to tackle this specific issue, it is recommended to leave this setting at 0. +> Do not change `handle_missed_events` from its default value of `0` unless you fully understand its implications. +> While a non-zero value may improve service quality under unstable conditions (e.g., poor connectivity or unreliable power), it can also lead to unexpected behavior. +> For example, in shared or community lnbits instances, where users are unaware of this functionality, they might assume a payment has failed and attempt to pay a new invoice with a different wallet, only for the instance to come back online and process the original payment request, potentially leading to duplicate payments. +> +> For this reason, unless you are trying to tackle this specific issue, it is recommended to leave this setting at `0`. ### Using Nostrclient From 49b3a0d4e9951befc8133eff521f712f1dc12367 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 13:44:07 +0000 Subject: [PATCH 39/90] default handle_missed_events to 0 --- nwcp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nwcp.py b/nwcp.py index 8af7716..e5d3bf0 100644 --- a/nwcp.py +++ b/nwcp.py @@ -71,7 +71,7 @@ class MainSubscription: class NWCServiceProvider: - def __init__(self, private_key: Optional[str] = None, relay: Optional[str] = None, handle_missed_events: int = 3 * 60 * 60): + def __init__(self, private_key: Optional[str] = None, relay: Optional[str] = None, handle_missed_events: int = 0): if not relay: # Connect to nostrclient relay = "nostrclient" if relay == "nostrclient": From a26cef75d7d1a6f61dbffb4fe334c9d311dcacaf Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 14:11:22 +0000 Subject: [PATCH 40/90] more hardening --- paranoia.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/paranoia.py b/paranoia.py index ed21a72..b1f905c 100644 --- a/paranoia.py +++ b/paranoia.py @@ -59,12 +59,25 @@ def assert_valid_sha256(v:str): assert_printable(v) if len(v) != 64 or not all(c in "0123456789abcdef" for c in v): panic("string is not a valid sha256 hash") + +# Check if value is an hash of an unexpected input (eg. empty strings, booleans etc) +def assert_no_badhash(v:str): + bad_hashes = [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", # empty string + "36a9e7f1c95b82ffb99743e0c5c4ce95d83c9a430aac59f84ef3cbfab6145068", # 1 space string + "c1c4b7fbd3e146bb14ec6258e5231c1ec703590721ff1e321b179a62b5857c9c", # None + "cdca0b9bb2325fc8ed7eba7734a3a1f876d919221399b6587ae7d26305adee9d", # True + "f9e08f8b038b1b401497f17da3adc120667ac742bf035657869a6ca1cd180e69", # False + ] + if v in bad_hashes: + panic("bad hash detected") # Check if valid nostr pubkey def assert_valid_pubkey(v:str): if not ENABLE_HARDENING: return assert_valid_sha256(v) + assert_no_badhash(v) # Check if valid wallet id From d6d679520c685146ec9850d2faec4bd09326c4a4 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 14:39:59 +0000 Subject: [PATCH 41/90] increase timeout --- tests/integration/test_all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index 0d4d38c..2f63f4c 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -335,7 +335,7 @@ class NWCWallet: await self.ws.send(self._json_dumps(["EVENT", event])) async def wait_for( - self, result_type, callback=None, on_error_callback=None, timeout=10 + self, result_type, callback=None, on_error_callback=None, timeout=21 ): now = time.time() while True: From abb6f888f15f63300acfbd71727106c4ca498167 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 22 Feb 2025 14:47:31 +0000 Subject: [PATCH 42/90] increase timeout --- tests/integration/test_all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index 2f63f4c..b48ed3a 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -335,7 +335,7 @@ class NWCWallet: await self.ws.send(self._json_dumps(["EVENT", event])) async def wait_for( - self, result_type, callback=None, on_error_callback=None, timeout=21 + self, result_type, callback=None, on_error_callback=None, timeout=60 ): now = time.time() while True: From 2fbc100da5e501a0623897061aa7dd3af9ddd9ff Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sun, 23 Feb 2025 16:19:34 +0000 Subject: [PATCH 43/90] Add more tests --- tests/integration/test_all.py | 134 ++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index b48ed3a..cc785b5 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -850,3 +850,137 @@ async def test_budget_refresh(): await wallet3.close() await wallet1.close() + + + +# Mostly AI generated pentests + + +@pytest.mark.asyncio +async def test_unauthorized_access(): + """Test accessing protected endpoints without valid API keys""" + async with httpx.AsyncClient() as client: + # privkey b758d3c535f8d089ce20473bafb33ee2f2f8deb94c97a0c5272cbf5bdc29f573 + # Try to create NWC without API key + resp = await client.put( + "http://localhost:5002/nwcprovider/api/v1/nwc/033c415d948f92aa7aa788ecfe49e49c3acae882d3dd2294574141bd786e18b6" + ) + assert resp.status_code == 401 + + # Try to access config endpoint without admin privileges + resp = await client.get("http://localhost:5002/nwcprovider/api/v1/config") + assert resp.status_code == 401 + + +@pytest.mark.asyncio +async def test_idor_vulnerability(): + """Test Insecure Direct Object Reference through pubkey manipulation""" + # Create NWC for wallet1 + nwc_wallet1 = await create_nwc("wallet1", "test_idor", ["pay"], [], 0) + + # Attempt to access wallet1's NWC using wallet2's credentials + async with httpx.AsyncClient() as client: + resp = await client.get( + f"http://localhost:5002/nwcprovider/api/v1/nwc/{nwc_wallet1['pubkey']}", + headers={"X-Api-Key": wallets["wallet2"]["admin_key"]} + ) + assert resp.status_code == 500 + assert "Pubkey has no associated wallet" in resp.text + + +@pytest.mark.asyncio +async def test_sql_injection(): + """Test for SQL injection vulnerabilities in parameters""" + malicious_pubkey = "'; DROP TABLE nwc;--" + async with httpx.AsyncClient() as client: + resp = await client.put( + f"http://localhost:5002/nwcprovider/api/v1/nwc/{malicious_pubkey}", + headers={"X-Api-Key": wallets["wallet1"]["admin_key"]}, + json={"permissions": ["pay"], "description": "test"} + ) + # Should be rejected by input validation + assert resp.status_code == 400 + + +@pytest.mark.asyncio +async def test_invalid_invoice_handling(): + """Test handling of malformed invoices""" + nwc = await create_nwc("wallet1", "test_invalid", ["pay"], [], 0) + wallet = NWCWallet(nwc["pairing"]) + await wallet.start() + + # Send invalid invoice + await wallet.send_event("pay_invoice", {"invoice": "invalid_lninvoice"}) + _, _, error = await wallet.wait_for("pay_invoice") + assert error["code"] == "INTERNAL" + + +@pytest.mark.asyncio +async def test_replay_attack(): + """Test message replay protection""" + nwc = await create_nwc("wallet1", "test_replay", ["pay", "invoice"], [], 0) + wallet = NWCWallet(nwc["pairing"]) + await wallet.start() + + # Capture valid payment request + valid_invoice = await create_valid_invoice(wallet) + await wallet.send_event("pay_invoice", {"invoice": valid_invoice}) + _, _, error = await wallet.wait_for("pay_invoice") + assert not error + + # Replay same message + await wallet.send_event("pay_invoice", {"invoice": valid_invoice}) + _, _, error = await wallet.wait_for("pay_invoice") + assert error["code"] == "PAYMENT_FAILED" + + +@pytest.mark.asyncio +async def test_budget_bypass(): + """Test budget limit enforcement""" + nwc = await create_nwc( + "wallet1", + "test_budget_bypass", + ["pay", "invoice"], + [{"budget_msats": 100000, "refresh_window": 3600, "created_at": int(time.time())}], + 0 + ) + wallet = NWCWallet(nwc["pairing"]) + await wallet.start() + + # First payment within budget + invoice1 = await create_valid_invoice(wallet, 50000) + await wallet.send_event("pay_invoice", {"invoice": invoice1}) + _, _, error = await wallet.wait_for("pay_invoice") + assert not error + + # Attempt to exceed budget + invoice2 = await create_valid_invoice(wallet, 60000) + await wallet.send_event("pay_invoice", {"invoice": invoice2}) + _, _, error = await wallet.wait_for("pay_invoice") + assert error["code"] == "QUOTA_EXCEEDED" + + +@pytest.mark.asyncio +async def test_unauthorized_config(): + """Test unauthorized access to config endpoint""" + malicious_relay = "ws://attacker-relay.example" + async def set_config_nwc(key: str, value: str): + async with httpx.AsyncClient() as client: + resp = await client.post( + "http://localhost:5002/nwcprovider/api/v1/config", + json={key: value}, + headers={"X-Api-Key": "lnbitsadmin"} # Assuming admin key + ) + assert resp.status_code == 401 + await set_config_nwc("relay", malicious_relay) + + +async def create_valid_invoice(wallet, amount=1000): + """Helper function to create valid test invoice""" + await wallet.send_event( + "make_invoice", {"amount": amount, "description": "test invoice"} + ) + result, tags, error = await wallet.wait_for("make_invoice") + if error: + raise Exception(f"Failed to create invoice: {error}") + return result["invoice"] \ No newline at end of file From ac69ae984622e127235e13d1b532e7d4a15b1bf9 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sun, 23 Feb 2025 16:51:26 +0000 Subject: [PATCH 44/90] more hardening --- paranoia.py | 8 ++++++++ tasks.py | 7 +++++-- views_api.py | 7 +++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/paranoia.py b/paranoia.py index b1f905c..17829e8 100644 --- a/paranoia.py +++ b/paranoia.py @@ -144,4 +144,12 @@ def assert_valid_bolt11(invoice:str): if not ENABLE_HARDENING: return assert_printable(invoice) + + +# Check if boolean +def assert_boolean(v:bool): + if not ENABLE_HARDENING: + return + if not isinstance(v, bool): + panic("not a boolean") diff --git a/tasks.py b/tasks.py index 5091656..1cc1f1a 100644 --- a/tasks.py +++ b/tasks.py @@ -22,7 +22,7 @@ from .execution_queue import execution_queue from .models import NWCKey, TrackedSpendNWC, GetNWC from .nwcp import NWCServiceProvider from .permission import nwc_permissions -from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_valid_timestamp_seconds, assert_valid_expiration_seconds, assert_valid_msats, assert_valid_positive_int, assert_valid_bolt11, assert_valid_sha256 +from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_boolean, assert_sane_string, assert_valid_expiration_seconds, assert_valid_msats, assert_valid_positive_int, assert_valid_bolt11, assert_valid_sha256 async def _check(nwc: Optional[NWCKey], method: str) -> Optional[Dict]: @@ -202,6 +202,8 @@ async def _on_multi_pay_invoice( # hardening # assert_valid_bolt11(invoice) assert_valid_msats(amount_msats) + if invoice_id: + assert_sane_string(invoice_id) # ## # res = await _process_invoice( @@ -379,13 +381,14 @@ async def _on_list_transactions( limit = payload.get("limit", 10) offset = payload.get("offset", 0) unpaid = payload.get("unpaid", False) - tx_type = payload.get("type", None) + tx_type = payload.get("type", "") # hardening # assert_valid_positive_int(tfrom) assert_valid_positive_int(tto) assert_valid_positive_int(limit) assert_valid_positive_int(offset) + assert_boolean(unpaid) assert_sane_string(tx_type) # ## # diff --git a/views_api.py b/views_api.py index fcd755e..b7ef1ad 100644 --- a/views_api.py +++ b/views_api.py @@ -28,7 +28,7 @@ from .models import ( GetBudgetsNWC ) from .permission import nwc_permissions -from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string +from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_boolean nwcprovider_api_router = APIRouter() @@ -57,6 +57,8 @@ async def api_get_nwcs( # hardening # assert_valid_wallet_id(wallet_id) + assert_boolean(include_expired) + assert_boolean(calculate_spent_budget) # ## # wallet_nwcs = GetWalletNWC( @@ -84,13 +86,14 @@ async def api_get_nwcs( ) async def api_get_nwc( pubkey: str, - include_expired: Optional[bool] = False, + include_expired: bool = False, wallet: WalletTypeInfo = Depends(require_admin_key) ) -> NWCGetResponse: wallet_id = wallet.wallet.id # hardening # assert_valid_pubkey(pubkey) + assert_boolean(include_expired) assert_valid_wallet_id(wallet_id) # ## # From 44d3e28182e7c551c718d63edde1fd999a2214ad Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sun, 23 Feb 2025 16:52:03 +0000 Subject: [PATCH 45/90] format --- README.md | 16 +- __init__.py | 1 + crud.py | 65 +-- models.py | 7 +- nwcp.py | 20 +- paranoia.py | 78 ++-- static/js/admin.js | 165 ++++---- static/js/index.js | 727 +++++++++++++++++----------------- tasks.py | 79 ++-- tests/integration/test_all.py | 25 +- views_api.py | 99 ++--- 11 files changed, 637 insertions(+), 645 deletions(-) diff --git a/README.md b/README.md index 7e8ba03..24eb404 100644 --- a/README.md +++ b/README.md @@ -12,23 +12,21 @@ Configure the extension from the "Settings" page in the top right menu when logg ### Configuration Options: -| Key | Description | Default | -| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| relay | URL of the nostr relay for dispatching and receiving NWC events. Use public relays or a custom one. Specify `nostrclient` to connect to the [nostrclient extension](https://github.com/lnbits/nostrclient). | nostrclient | -| provider_key | Nostr secret key of the NWC Service Provider. | Random key generated on install | -| relay_alias | Relay URL to display in pairing URLs. Set if different from `relay`. | Empty (uses the `relay` value) | -| handle_missed_events | Number of seconds to look back for processing events missed while offline. Setting it to 0 disables this functionality. | 0 | - +| Key | Description | Default | +| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | +| relay | URL of the nostr relay for dispatching and receiving NWC events. Use public relays or a custom one. Specify `nostrclient` to connect to the [nostrclient extension](https://github.com/lnbits/nostrclient). | nostrclient | +| provider_key | Nostr secret key of the NWC Service Provider. | Random key generated on install | +| relay_alias | Relay URL to display in pairing URLs. Set if different from `relay`. | Empty (uses the `relay` value) | +| handle_missed_events | Number of seconds to look back for processing events missed while offline. Setting it to 0 disables this functionality. | 0 | > [!WARNING] > > Do not change `handle_missed_events` from its default value of `0` unless you fully understand its implications. -> While a non-zero value may improve service quality under unstable conditions (e.g., poor connectivity or unreliable power), it can also lead to unexpected behavior. +> While a non-zero value may improve service quality under unstable conditions (e.g., poor connectivity or unreliable power), it can also lead to unexpected behavior. > For example, in shared or community lnbits instances, where users are unaware of this functionality, they might assume a payment has failed and attempt to pay a new invoice with a different wallet, only for the instance to come back online and process the original payment request, potentially leading to duplicate payments. > > For this reason, unless you are trying to tackle this specific issue, it is recommended to leave this setting at `0`. - ### Using Nostrclient The extension is preconfigured to connect to the nostrclient extension. Install it on the same LNbits instance and configure it to expose public websocket endpoints. Refer to the [nostrclient documentation](https://github.com/lnbits/nostrclient) for more information. diff --git a/__init__.py b/__init__.py index d7f2a3b..86e59d7 100644 --- a/__init__.py +++ b/__init__.py @@ -32,6 +32,7 @@ def nwcprovider_stop(): except Exception as ex: logger.warning(ex) + def nwcprovider_start(): task = create_permanent_unique_task("ext_nwcprovider", handle_nwc) scheduled_tasks.append(task) diff --git a/crud.py b/crud.py index dd87609..b41e71c 100644 --- a/crud.py +++ b/crud.py @@ -8,14 +8,22 @@ from .models import ( CreateNWCKey, DeleteNWC, GetBudgetsNWC, + GetNWC, GetWalletNWC, NWCBudget, NWCKey, + NWCNewBudget, TrackedSpendNWC, - GetNWC, - NWCNewBudget ) -from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_valid_timestamp_seconds, assert_valid_expiration_seconds, assert_valid_msats, assert_valid_positive_int +from .paranoia import ( + assert_sane_string, + assert_valid_expiration_seconds, + assert_valid_msats, + assert_valid_positive_int, + assert_valid_pubkey, + assert_valid_timestamp_seconds, + assert_valid_wallet_id, +) db = Database("ext_nwcprovider") @@ -73,8 +81,8 @@ async def delete_nwc(data: DeleteNWC) -> None: async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: - expires = int(time.time()) if not data.include_expired else -1 - + expires = int(time.time()) if not data.include_expired else -1 + # hardening # assert_valid_wallet_id(data.wallet) assert_valid_expiration_seconds(expires) @@ -94,7 +102,7 @@ async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: async def get_nwc(data: GetNWC) -> Optional[NWCKey]: - expires = int(time.time()) if not data.include_expired else -1 + expires = int(time.time()) if not data.include_expired else -1 # hardening # assert_valid_pubkey(data.pubkey) @@ -117,7 +125,7 @@ async def get_nwc(data: GetNWC) -> Optional[NWCKey]: }, NWCKey, ) - else: + else: row = await db.fetchone( """ SELECT * FROM nwcprovider.keys @@ -143,7 +151,7 @@ async def get_nwc(data: GetNWC) -> Optional[NWCKey]: async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: - + # hardening # assert_valid_pubkey(data.pubkey) # ## # @@ -156,7 +164,7 @@ async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: if data.calculate_spent: for budget in budgets: last_cycle, next_cycle = budget.get_timestamp_range() - + # hardening # assert_valid_timestamp_seconds(last_cycle) assert_valid_timestamp_seconds(next_cycle) @@ -173,8 +181,10 @@ async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: "last_cycle": last_cycle, "next_cycle": next_cycle, }, - ) - tot_spent_in_range_msats = next(iter(tot_spent_in_range_msats.values())) or 0 + ) + tot_spent_in_range_msats = ( + next(iter(tot_spent_in_range_msats.values())) or 0 + ) # hardening # assert_valid_msats(tot_spent_in_range_msats) @@ -193,9 +203,7 @@ async def tracked_spend_nwc(data: TrackedSpendNWC, action): # ## # created_at = int(time.time()) - budgets = await get_budgets_nwc(GetBudgetsNWC( - pubkey=data.pubkey - )) + budgets = await get_budgets_nwc(GetBudgetsNWC(pubkey=data.pubkey)) in_budget = True for budget in budgets: last_cycle, next_cycle = budget.get_timestamp_range() @@ -206,23 +214,30 @@ async def tracked_spend_nwc(data: TrackedSpendNWC, action): # ## # tot_spent_in_range_msats = ( - next(iter((await db.fetchone( - """ + next( + iter( + ( + await db.fetchone( + """ SELECT SUM(amount_msats) FROM nwcprovider.spent WHERE pubkey = :pubkey AND created_at >= :last_cycle AND created_at < :next_cycle """, - { - "pubkey": data.pubkey, - "last_cycle": last_cycle, - "next_cycle": next_cycle, - }, - )).values())) or 0 + { + "pubkey": data.pubkey, + "last_cycle": last_cycle, + "next_cycle": next_cycle, + }, + ) + ).values() + ) + ) + or 0 ) # hardening # assert_valid_msats(tot_spent_in_range_msats) - assert_valid_msats(budget.budget_msats) + assert_valid_msats(budget.budget_msats) # ## # if tot_spent_in_range_msats + data.amount_msats > budget.budget_msats: @@ -243,7 +258,7 @@ async def tracked_spend_nwc(data: TrackedSpendNWC, action): }, ) return True, out - + return await enqueue(r) @@ -262,7 +277,7 @@ async def set_config_nwc(key: str, value: str): assert_sane_string(key) assert_sane_string(value) # ## # - + await db.execute( """ INSERT OR REPLACE INTO nwcprovider.config (key, value) diff --git a/models.py b/models.py index 5884d4c..2208d98 100644 --- a/models.py +++ b/models.py @@ -6,8 +6,6 @@ from typing import Any, Dict, List, Optional from pydantic import BaseModel -from .nwcp import NWCServiceProvider - class NWCKey(BaseModel): pubkey: str @@ -29,8 +27,6 @@ class NWCKey(BaseModel): return cls(**row) - - class NWCBudget(BaseModel): id: int pubkey: str @@ -61,7 +57,7 @@ class NWCNewBudget(BaseModel): budget_msats: int refresh_window: int created_at: int - + # CRUD models class CreateNWCKey(BaseModel): @@ -111,4 +107,3 @@ class NWCRegistrationRequest(BaseModel): class NWCGetResponse(BaseModel): data: NWCKey budgets: List[NWCBudget] - diff --git a/nwcp.py b/nwcp.py index e5d3bf0..22358dc 100644 --- a/nwcp.py +++ b/nwcp.py @@ -59,19 +59,24 @@ class MainSubscription: if now - event["created_at"] > expire: del self.events[event_id] deleted_ids.append(event_id) - self.responses = [event_id for event_id in self.responses if event_id not in deleted_ids] + self.responses = [ + event_id for event_id in self.responses if event_id not in deleted_ids + ] if len(deleted_ids) > 0: logger.debug("Garbage collected " + str(len(deleted_ids)) + " events") - - class Config: arbitrary_types_allowed = True class NWCServiceProvider: - def __init__(self, private_key: Optional[str] = None, relay: Optional[str] = None, handle_missed_events: int = 0): + def __init__( + self, + private_key: Optional[str] = None, + relay: Optional[str] = None, + handle_missed_events: int = 0, + ): if not relay: # Connect to nostrclient relay = "nostrclient" if relay == "nostrclient": @@ -126,8 +131,8 @@ class NWCServiceProvider: # if True the instance is shutting down self.shutdown = False - - # process missed events that are not older than + + # process missed events that are not older than # handle_missed_events seconds (0 to disable) # (handles reboots) self.handle_missed_events = handle_missed_events @@ -145,7 +150,6 @@ class NWCServiceProvider: self.sub.gc(self.handle_missed_events) await asyncio.sleep(60) - def get_supported_methods(self): """ Returns the list of supported methods by this service provider. @@ -270,7 +274,7 @@ class NWCServiceProvider: "kinds": [23194], "#p": [self.public_key_hex], # Since the last handle_missed_events seconds (handles reboots) - "since": int(time.time()) - self.handle_missed_events + "since": int(time.time()) - self.handle_missed_events, } self.sub.requests_sub_id = self._get_new_subid() # Create responses subscription (needed to track previosly responded requests) diff --git a/paranoia.py b/paranoia.py index 17829e8..815ae4e 100644 --- a/paranoia.py +++ b/paranoia.py @@ -3,85 +3,93 @@ from loguru import logger ENABLE_HARDENING = True -def panic(reason:str): + +def panic(reason: str): if not ENABLE_HARDENING: return logger.error(f"hardening: {reason}") raise ValueError(f"hardening: {reason}") - + + # Throw if string contains any non-printable characters -def assert_printable(v:str): +def assert_printable(v: str): if not ENABLE_HARDENING: return if not isinstance(v, str): - panic("not a string "+str(v)) + panic("not a string " + str(v)) if not v.isprintable(): panic("string contains non-printable characters") - + + # Check if number is valid int and not NaN -def assert_valid_int(v:int): +def assert_valid_int(v: int): if not ENABLE_HARDENING: return if not isinstance(v, int): panic("number is not a valid int") - + + # Check if number is valid positive int -def assert_valid_positive_int(v:int): +def assert_valid_positive_int(v: int): if not ENABLE_HARDENING: return assert_valid_int(v) if v < 0: panic("number is not positive") - + + # Check if number is a valid sats amount -def assert_valid_sats(v:int): +def assert_valid_sats(v: int): if not ENABLE_HARDENING: return assert_valid_positive_int(v) - max_sats_value = 10_000_000 + max_sats_value = 10_000_000 if v >= max_sats_value: panic("sats amount looks too high") - + + # Check if number is a valid msats amount -def assert_valid_msats(v:int): +def assert_valid_msats(v: int): if not ENABLE_HARDENING: return assert_valid_positive_int(v) max_msats_value = 10_000_000 * 1000 if v >= max_msats_value: panic("msats amount looks too high") - + # Check if string is a valid sha256 hash -def assert_valid_sha256(v:str): +def assert_valid_sha256(v: str): if not ENABLE_HARDENING: return assert_printable(v) if len(v) != 64 or not all(c in "0123456789abcdef" for c in v): panic("string is not a valid sha256 hash") + # Check if value is an hash of an unexpected input (eg. empty strings, booleans etc) -def assert_no_badhash(v:str): +def assert_no_badhash(v: str): bad_hashes = [ - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", # empty string - "36a9e7f1c95b82ffb99743e0c5c4ce95d83c9a430aac59f84ef3cbfab6145068", # 1 space string - "c1c4b7fbd3e146bb14ec6258e5231c1ec703590721ff1e321b179a62b5857c9c", # None - "cdca0b9bb2325fc8ed7eba7734a3a1f876d919221399b6587ae7d26305adee9d", # True - "f9e08f8b038b1b401497f17da3adc120667ac742bf035657869a6ca1cd180e69", # False + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", # empty string + "36a9e7f1c95b82ffb99743e0c5c4ce95d83c9a430aac59f84ef3cbfab6145068", # 1 space string + "c1c4b7fbd3e146bb14ec6258e5231c1ec703590721ff1e321b179a62b5857c9c", # None + "cdca0b9bb2325fc8ed7eba7734a3a1f876d919221399b6587ae7d26305adee9d", # True + "f9e08f8b038b1b401497f17da3adc120667ac742bf035657869a6ca1cd180e69", # False ] if v in bad_hashes: panic("bad hash detected") - + + # Check if valid nostr pubkey -def assert_valid_pubkey(v:str): +def assert_valid_pubkey(v: str): if not ENABLE_HARDENING: return assert_valid_sha256(v) assert_no_badhash(v) - + # Check if valid wallet id -def assert_valid_wallet_id(v:str): +def assert_valid_wallet_id(v: str): if not ENABLE_HARDENING: return assert_printable(v) @@ -90,7 +98,7 @@ def assert_valid_wallet_id(v:str): # Check if valid timestamp in seconds -def assert_valid_timestamp_seconds(v:int): +def assert_valid_timestamp_seconds(v: int): if not ENABLE_HARDENING: return assert_valid_positive_int(v) @@ -112,44 +120,46 @@ def assert_valid_expiration_seconds(v: int): # Check if string is within sane parameters -def assert_sane_string(v:str): +def assert_sane_string(v: str): if not ENABLE_HARDENING: return assert_printable(v) if len(v) > 1024: panic("string is too long") - + # Check if string is a non-empty string -def assert_non_empty_string(v:str): +def assert_non_empty_string(v: str): if not ENABLE_HARDENING: return assert_printable(v) if len(v.strip()) == 0: panic("string is empty") - + + # Assert valid json -def assert_valid_json(v:str): +def assert_valid_json(v: str): if not ENABLE_HARDENING: return assert_non_empty_string(v) try: import json + json.loads(v) except: panic("string is not valid json") + # Check if string is a valid bolt11 invoice -def assert_valid_bolt11(invoice:str): +def assert_valid_bolt11(invoice: str): if not ENABLE_HARDENING: return assert_printable(invoice) # Check if boolean -def assert_boolean(v:bool): +def assert_boolean(v: bool): if not ENABLE_HARDENING: return if not isinstance(v, bool): panic("not a boolean") - diff --git a/static/js/admin.js b/static/js/admin.js index b6fc801..afacb7e 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -1,86 +1,87 @@ window.app = Vue.createApp({ - el: "#vue", - mixins: [windowMixin], - delimiters: ["${", "}"], - data: function () { - return { - entries: [], - columns: [ - { - name: "key", - required: true, - label: "Key", - align: "left", - field: (row) => row.key, - sortable: true, - }, - { - name: "value", - required: true, - label: "Value", - align: "left", - field: (row) => row.value, - sortable: true, - }, - ], - }; - }, + el: "#vue", + mixins: [windowMixin], + delimiters: ["${", "}"], + data: function () { + return { + entries: [], + columns: [ + { + name: "key", + required: true, + label: "Key", + align: "left", + field: (row) => row.key, + sortable: true, + }, + { + name: "value", + required: true, + label: "Value", + align: "left", + field: (row) => row.value, + sortable: true, + }, + ], + }; + }, - methods: { - fetchConfig() { - this.entries = []; - LNbits.api - .request( - "GET", - "/nwcprovider/api/v1/config", - this.g.user.wallets[0].adminkey, - ) - .then((response) => { - const newEntries = []; - for (const [key, value] of Object.entries(response.data)) { - newEntries.push({ - key: key, - value: value, - }); - } - this.entries.length = 0; - this.entries.push(...newEntries); - }) - .catch(function (error) { - console.error("Error fetching config:", error); - }); - }, - async saveConfig() { - const data = {}; - for (const entry of this.entries) { - data[entry.key] = entry.value; - } - try { - const response = await LNbits.api.request( - "POST", - "/nwcprovider/api/v1/config", - this.g.user.wallets[0].adminkey, - data, - ); - Quasar.Notify.create({ - type: 'positive', - message: 'Config saved!', - }); - Quasar.Notify.create({ - type: 'warning', - message: 'You need to restart the server for the changes to take effect!', - }); - } catch (error) { - Quasar.Notify.create({ - type: 'negative', - message: "Error saving config: "+String(error), - }) - console.error("Error saving config:", error); - } - }, + methods: { + fetchConfig() { + this.entries = []; + LNbits.api + .request( + "GET", + "/nwcprovider/api/v1/config", + this.g.user.wallets[0].adminkey, + ) + .then((response) => { + const newEntries = []; + for (const [key, value] of Object.entries(response.data)) { + newEntries.push({ + key: key, + value: value, + }); + } + this.entries.length = 0; + this.entries.push(...newEntries); + }) + .catch(function (error) { + console.error("Error fetching config:", error); + }); }, + async saveConfig() { + const data = {}; + for (const entry of this.entries) { + data[entry.key] = entry.value; + } + try { + const response = await LNbits.api.request( + "POST", + "/nwcprovider/api/v1/config", + this.g.user.wallets[0].adminkey, + data, + ); + Quasar.Notify.create({ + type: "positive", + message: "Config saved!", + }); + Quasar.Notify.create({ + type: "warning", + message: + "You need to restart the server for the changes to take effect!", + }); + } catch (error) { + Quasar.Notify.create({ + type: "negative", + message: "Error saving config: " + String(error), + }); + console.error("Error saving config:", error); + } + }, + }, - created: function () { - this.fetchConfig(); - }, - }); \ No newline at end of file + created: function () { + this.fetchConfig(); + }, +}); diff --git a/static/js/index.js b/static/js/index.js index 3141357..e8a4ec1 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -1,389 +1,386 @@ - window.app = Vue.createApp({ - el: "#vue", - mixins: [windowMixin], - delimiters: ["${", "}"], - data: function () { - return { - selectedWallet: null, - nodePermissions: [], - nwcEntries: [], - nwcsTable: { - columns: [ - { - name: "description", - align: "left", - label: "Description", - field: "description", - }, - { name: "status", align: "left", label: "Status", field: "status" }, - { - name: "last_used", - align: "left", - label: "Last used", - field: "last_used", - }, - { - name: "created_at", - align: "left", - label: "Created", - field: "created_at", - }, - { - name: "expires_at", - align: "left", - label: "Expires", - field: "expires_at", - }, - ], - pagination: { - rowsPerPage: 10, +window.app = Vue.createApp({ + el: "#vue", + mixins: [windowMixin], + delimiters: ["${", "}"], + data: function () { + return { + selectedWallet: null, + nodePermissions: [], + nwcEntries: [], + nwcsTable: { + columns: [ + { + name: "description", + align: "left", + label: "Description", + field: "description", }, - }, - connectDialog: { - show: false, - data: {}, - }, - pairingDialog: { - show: false, - data: { - pairingUrl: "", + { name: "status", align: "left", label: "Status", field: "status" }, + { + name: "last_used", + align: "left", + label: "Last used", + field: "last_used", }, - }, - pairingQrDialog: { - show: false, - data: { - pairingUrl: "", + { + name: "created_at", + align: "left", + label: "Created", + field: "created_at", }, + { + name: "expires_at", + align: "left", + label: "Expires", + field: "expires_at", + }, + ], + pagination: { + rowsPerPage: 10, }, - connectionInfoDialog: { - show: false, - data: {}, + }, + connectDialog: { + show: false, + data: {}, + }, + pairingDialog: { + show: false, + data: { + pairingUrl: "", }, - }; - }, + }, + pairingQrDialog: { + show: false, + data: { + pairingUrl: "", + }, + }, + connectionInfoDialog: { + show: false, + data: {}, + }, + }; + }, - methods: { - showConnectDialog() { - const wallet = this.getWallet(); - if (!wallet) { + methods: { + showConnectDialog() { + const wallet = this.getWallet(); + if (!wallet) { + Quasar.Notify.create({ + type: "negative", + message: "Please select a wallet first", + }); + return; + } else { + this.connectDialog.show = true; + } + }, + openConnectionInfoDialog(data) { + this.connectionInfoDialog.data = data; + this.connectionInfoDialog.show = true; + }, + closeConnectionInfoDialog() { + this.connectionInfoDialog.show = false; + }, + openPairingUrl() { + const url = this.pairingDialog.data.pairingUrl; + if (url) window.open(url, "_blank"); + }, + go(url) { + window.open(url, "_blank"); + }, + async copyPairingUrl() { + const url = this.pairingDialog.data.pairingUrl; + if (url) { + try { + await navigator.clipboard.writeText(url); Quasar.Notify.create({ - type: 'negative', - message: 'Please select a wallet first', + type: "positive", + message: "URL copied to clipboard", + }); + } catch (err) { + Quasar.Notify.create({ + type: "negative", + message: "Failed to copy URL.", }); - return; - } else { - this.connectDialog.show = true; } - }, - openConnectionInfoDialog(data) { - this.connectionInfoDialog.data = data; - this.connectionInfoDialog.show = true; - }, - closeConnectionInfoDialog() { - this.connectionInfoDialog.show = false; - }, - openPairingUrl() { - const url = this.pairingDialog.data.pairingUrl; - if (url) window.open(url, "_blank"); - }, - go(url) { - window.open(url, "_blank"); - }, - async copyPairingUrl() { - const url = this.pairingDialog.data.pairingUrl; - if (url) { + } + }, + showPairingQR() { + this.pairingQrDialog.data.pairingUrl = this.pairingDialog.data.pairingUrl; + this.pairingQrDialog.show = true; + }, + closePairingQrDialog() { + this.pairingQrDialog.show = false; + }, + loadConnectDialogData() { + this.connectDialog.data = { + description: "", + expires_at: Date.now() + 1000 * 60 * 60 * 24 * 7, + neverExpires: true, + permissions: [], + budgets: [], + }; + for (const permission of this.nodePermissions) { + this.connectDialog.data.permissions.push({ + key: permission.key, + name: permission.name, + value: permission.value, + }); + } + }, + deleteBudget(index) { + this.connectDialog.data.budgets.splice(index, 1); + }, + addBudget() { + this.connectDialog.data.budgets.push({ + budget_sats: 1000, + used_budget_sats: 0, + created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, + expiration: "never", + }); + }, + closeConnectDialog() { + this.connectDialog.show = false; + this.loadConnectDialogData(); + }, + getWallet: function () { + let wallet = undefined; + for (let i = 0; i < this.g.user.wallets.length; i++) { + if (this.g.user.wallets[i].id == this.selectedWallet) { + wallet = this.g.user.wallets[i]; + break; + } + } + return wallet; + }, + async generateKeyPair() { + while (!window.NobleSecp256k1) { + await new Promise((resolve) => setTimeout(resolve, 1)); + } + const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey(); + const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes); + const out = { + privKeyBytes: privKeyBytes, + pubKeyBytes: pubKeyBytes, + privKey: window.NobleSecp256k1.etc.bytesToHex(privKeyBytes), + pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)), + }; + return out; + }, + deleteNWC: async function (pubkey) { + Quasar.Dialog.create({ + title: "Confirm Deletion", + message: "Are you sure you want to delete this connection?", + cancel: true, + persistent: true, + }) + .onOk(async () => { try { - await navigator.clipboard.writeText(url); + const wallet = this.getWallet(); + const response = await LNbits.api.request( + "DELETE", + `/nwcprovider/api/v1/nwc/${pubkey}`, + wallet.adminkey, + ); + this.loadNwcs(); Quasar.Notify.create({ type: "positive", - message: "URL copied to clipboard" - }); - } catch (err) { - Quasar.Notify.create({ - type: "negative", - message: "Failed to copy URL." + message: "Deleted successfully", }); + } catch (error) { + LNbits.utils.notifyApiError(error); } - } - }, - showPairingQR() { - this.pairingQrDialog.data.pairingUrl = - this.pairingDialog.data.pairingUrl; - this.pairingQrDialog.show = true; - }, - closePairingQrDialog() { - this.pairingQrDialog.show = false; - }, - loadConnectDialogData() { - this.connectDialog.data = { - description: "", - expires_at: Date.now() + 1000 * 60 * 60 * 24 * 7, - neverExpires: true, - permissions: [], - budgets: [], - }; - for (const permission of this.nodePermissions) { - this.connectDialog.data.permissions.push({ - key: permission.key, - name: permission.name, - value: permission.value, + }) + .onCancel(() => { + // User canceled the operation + }); + }, + loadNwcs: async function () { + const wallet = this.getWallet(); + if (!wallet) { + this.nwcs = []; + return; + } + try { + const response = await LNbits.api.request( + "GET", + "/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true", + wallet.adminkey, + ); + this.nwcs = response.data; + } catch (error) { + this.nwcs = []; + } + try { + const response = await LNbits.api.request( + "GET", + "/nwcprovider/api/v1/permissions", + wallet.adminkey, + ); + const permissions = []; + for (const [key, value] of Object.entries(response.data)) { + permissions.push({ + key: key, + name: value.name, + value: value.default, }); } - }, - deleteBudget(index) { - this.connectDialog.data.budgets.splice(index, 1); - }, - addBudget() { - this.connectDialog.data.budgets.push({ - budget_sats: 1000, - used_budget_sats: 0, + this.nodePermissions = permissions; + } catch (error) { + Lnbits.utils.notifyApiError(error); + } + this.loadConnectDialogData(); + const newTableEntries = []; + for (const nwc of this.nwcs) { + const t = Quasar.date.formatDate( + new Date(nwc.data.created_at * 1000), + "YYYY-MM-DD HH:mm", + ); + const e = + nwc.data.expires_at > 0 + ? Quasar.date.formatDate( + new Date(nwc.data.expires_at * 1000), + "YYYY-MM-DD HH:mm", + ) + : "Never"; + const l = Quasar.date.formatDate( + new Date(nwc.data.last_used * 1000), + "YYYY-MM-DD HH:mm", + ); + const nwcTableEntry = { + description: nwc.data.description, + created_at: t, + expires_at: e, + last_used: l, + pubkey: nwc.data.pubkey, + permissions: nwc.data.permissions, + budgets: [], + status: "Active", + }; + if ( + nwc.data.expires_at > 0 && + nwc.data.expires_at < new Date().getTime() / 1000 + ) { + nwcTableEntry.status = "Expired"; + } + for (const budget of nwc.budgets) { + const createdAt = Quasar.date.formatDate( + new Date(budget.created_at * 1000), + "YYYY-MM-DD HH:mm", + ); + let refreshWindow = budget.refresh_window; + if (refreshWindow <= 0) { + refreshWindow = "Never"; + } else if (refreshWindow == 60 * 60 * 24) { + refreshWindow = "Daily"; + } else if (refreshWindow == 60 * 60 * 24 * 7) { + refreshWindow = "Weekly"; + } else if (refreshWindow == 60 * 60 * 24 * 30) { + refreshWindow = "Monthly"; + } else if (refreshWindow == 60 * 60 * 24 * 365) { + refreshWindow = "Yearly"; + } + nwcTableEntry.budgets.push({ + budget_sats: budget.budget_msats / 1000, + used_budget_sats: budget.used_budget_msats / 1000, + created_at: createdAt, + refresh_window: refreshWindow, + }); + } + newTableEntries.push(nwcTableEntry); + } + this.nwcEntries = newTableEntries; + }, + closePairingDialog() { + this.pairingDialog.show = false; + }, + async showPairingDialog(secret) { + let response = await LNbits.api.request( + "GET", + "/nwcprovider/api/v1/pairing/{SECRET}", + ); + response = response.data; + response = response.replace("{SECRET}", secret); + this.pairingDialog.data.pairingUrl = response; + this.pairingDialog.show = true; + }, + async confirmConnectDialog() { + const keyPair = await this.generateKeyPair(); + // timestamp + let expires_at = 0; + if (!this.connectDialog.data.neverExpires) { + expires_at = + new Date(this.connectDialog.data.expires_at).getTime() / 1000; + } + const data = { + permissions: [], + description: this.connectDialog.data.description, + expires_at: expires_at, + budgets: [], + }; + for (const permission of this.connectDialog.data.permissions) { + if (permission.value) data.permissions.push(permission.key); + } + for (const budget of this.connectDialog.data.budgets) { + const budget_msats = budget.budget_sats * 1000; + let refresh_window = 0; + switch (budget.expiry) { + case "Daily": + refresh_window = 60 * 60 * 24; + break; + case "Weekly": + refresh_window = 60 * 60 * 24 * 7; + break; + case "Monthly": + refresh_window = 60 * 60 * 24 * 30; + break; + case "Yearly": + refresh_window = 60 * 60 * 24 * 365; + break; + case "Never": + refresh_window = 0; + break; + } + data.budgets.push({ + budget_msats: budget_msats, + refresh_window: refresh_window, created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, - expiration: "never", }); - }, - closeConnectDialog() { - this.connectDialog.show = false; - this.loadConnectDialogData(); - }, - getWallet: function () { - let wallet = undefined; - for (let i = 0; i < this.g.user.wallets.length; i++) { - if (this.g.user.wallets[i].id == this.selectedWallet) { - wallet = this.g.user.wallets[i]; - break; - } - } - return wallet; - }, - async generateKeyPair() { - while (!window.NobleSecp256k1) { - await new Promise((resolve) => setTimeout(resolve, 1)); - } - const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey(); - const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes); - const out = { - privKeyBytes: privKeyBytes, - pubKeyBytes: pubKeyBytes, - privKey: window.NobleSecp256k1.etc.bytesToHex(privKeyBytes), - pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)), - }; - return out; - }, - deleteNWC: async function (pubkey) { - Quasar - .Dialog.create({ - title: "Confirm Deletion", - message: "Are you sure you want to delete this connection?", - cancel: true, - persistent: true, - }) - .onOk(async () => { - try { - const wallet = this.getWallet(); - const response = await LNbits.api.request( - "DELETE", - `/nwcprovider/api/v1/nwc/${pubkey}`, - wallet.adminkey, - ); - this.loadNwcs(); - Quasar.Notify.create({ - type: "positive", - message: "Deleted successfully" - }); - } catch (error) { - LNbits.utils.notifyApiError(error); - } - }) - .onCancel(() => { - // User canceled the operation - }); - }, - loadNwcs: async function () { - const wallet = this.getWallet(); - if (!wallet) { - this.nwcs = []; + } + const wallet = this.getWallet(); + + try { + const response = await LNbits.api.request( + "PUT", + "/nwcprovider/api/v1/nwc/" + keyPair.pubKey, + wallet.adminkey, + data, + ); + this.closeConnectDialog(); + if ( + !response.data || + !response.data.data || + !response.data.data.pubkey + ) { + LNbits.utils.notifyApiError("Error creating nwc pairing"); return; } - try { - const response = await LNbits.api.request( - "GET", - "/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true", - wallet.adminkey, - ); - this.nwcs = response.data; - } catch (error) { - this.nwcs = []; - } - try { - const response = await LNbits.api.request( - "GET", - "/nwcprovider/api/v1/permissions", - wallet.adminkey, - ); - const permissions = []; - for (const [key, value] of Object.entries(response.data)) { - permissions.push({ - key: key, - name: value.name, - value: value.default, - }); - } - this.nodePermissions = permissions; - } catch (error) { - Lnbits.utils.notifyApiError(error); - } - this.loadConnectDialogData(); - const newTableEntries = []; - for (const nwc of this.nwcs) { - const t = Quasar.date.formatDate( - new Date(nwc.data.created_at * 1000), - "YYYY-MM-DD HH:mm", - ); - const e = - nwc.data.expires_at > 0 - ? Quasar.date.formatDate( - new Date(nwc.data.expires_at * 1000), - "YYYY-MM-DD HH:mm", - ) - : "Never"; - const l = Quasar.date.formatDate( - new Date(nwc.data.last_used * 1000), - "YYYY-MM-DD HH:mm", - ); - const nwcTableEntry = { - description: nwc.data.description, - created_at: t, - expires_at: e, - last_used: l, - pubkey: nwc.data.pubkey, - permissions: nwc.data.permissions, - budgets: [], - status: "Active", - }; - if ( - nwc.data.expires_at > 0 && - nwc.data.expires_at < new Date().getTime() / 1000 - ) { - nwcTableEntry.status = "Expired"; - } - for (const budget of nwc.budgets) { - const createdAt = Quasar.date.formatDate( - new Date(budget.created_at * 1000), - "YYYY-MM-DD HH:mm", - ); - let refreshWindow = budget.refresh_window; - if (refreshWindow <= 0) { - refreshWindow = "Never"; - } else if (refreshWindow == 60 * 60 * 24) { - refreshWindow = "Daily"; - } else if (refreshWindow == 60 * 60 * 24 * 7) { - refreshWindow = "Weekly"; - } else if (refreshWindow == 60 * 60 * 24 * 30) { - refreshWindow = "Monthly"; - } else if (refreshWindow == 60 * 60 * 24 * 365) { - refreshWindow = "Yearly"; - } - nwcTableEntry.budgets.push({ - budget_sats: budget.budget_msats / 1000, - used_budget_sats: budget.used_budget_msats / 1000, - created_at: createdAt, - refresh_window: refreshWindow, - }); - } - newTableEntries.push(nwcTableEntry); - } - this.nwcEntries = newTableEntries; - }, - closePairingDialog() { - this.pairingDialog.show = false; - }, - async showPairingDialog(secret) { - let response = await LNbits.api.request( - "GET", - "/nwcprovider/api/v1/pairing/{SECRET}", - ); - response = response.data; - response = response.replace("{SECRET}", secret); - this.pairingDialog.data.pairingUrl = response; - this.pairingDialog.show = true; - }, - async confirmConnectDialog() { - const keyPair = await this.generateKeyPair(); - // timestamp - let expires_at = 0; - if (!this.connectDialog.data.neverExpires) { - expires_at = - new Date(this.connectDialog.data.expires_at).getTime() / 1000; - } - const data = { - permissions: [], - description: this.connectDialog.data.description, - expires_at: expires_at, - budgets: [], - }; - for (const permission of this.connectDialog.data.permissions) { - if (permission.value) data.permissions.push(permission.key); - } - for (const budget of this.connectDialog.data.budgets) { - const budget_msats = budget.budget_sats * 1000; - let refresh_window = 0; - switch (budget.expiry) { - case "Daily": - refresh_window = 60 * 60 * 24; - break; - case "Weekly": - refresh_window = 60 * 60 * 24 * 7; - break; - case "Monthly": - refresh_window = 60 * 60 * 24 * 30; - break; - case "Yearly": - refresh_window = 60 * 60 * 24 * 365; - break; - case "Never": - refresh_window = 0; - break; - } - data.budgets.push({ - budget_msats: budget_msats, - refresh_window: refresh_window, - created_at: - new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, - }); - } - const wallet = this.getWallet(); - - try { - const response = await LNbits.api.request( - "PUT", - "/nwcprovider/api/v1/nwc/" + keyPair.pubKey, - wallet.adminkey, - data, - ); - this.closeConnectDialog(); - if ( - !response.data || - !response.data.data || - !response.data.data.pubkey - ) { - LNbits.utils.notifyApiError("Error creating nwc pairing"); - return; - } - this.showPairingDialog(keyPair.privKey); - } catch (error) { - LNbits.utils.notifyApiError(error); - } - this.loadNwcs(); - }, - }, - - created: function () { + this.showPairingDialog(keyPair.privKey); + } catch (error) { + LNbits.utils.notifyApiError(error); + } this.loadNwcs(); }, - watch: { - selectedWallet(newValue, oldValue) { - this.loadNwcs(); - }, + }, + + created: function () { + this.loadNwcs(); + }, + watch: { + selectedWallet(newValue, oldValue) { + this.loadNwcs(); }, - }); \ No newline at end of file + }, +}); diff --git a/tasks.py b/tasks.py index 1cc1f1a..d06a80f 100644 --- a/tasks.py +++ b/tasks.py @@ -19,10 +19,20 @@ from loguru import logger from .crud import get_config_nwc, get_nwc, tracked_spend_nwc from .execution_queue import execution_queue -from .models import NWCKey, TrackedSpendNWC, GetNWC +from .models import GetNWC, NWCKey, TrackedSpendNWC from .nwcp import NWCServiceProvider +from .paranoia import ( + assert_boolean, + assert_sane_string, + assert_valid_bolt11, + assert_valid_expiration_seconds, + assert_valid_msats, + assert_valid_positive_int, + assert_valid_pubkey, + assert_valid_sha256, + assert_valid_wallet_id, +) from .permission import nwc_permissions -from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_boolean, assert_sane_string, assert_valid_expiration_seconds, assert_valid_msats, assert_valid_positive_int, assert_valid_bolt11, assert_valid_sha256 async def _check(nwc: Optional[NWCKey], method: str) -> Optional[Dict]: @@ -56,7 +66,7 @@ async def _process_invoice( amount_msats: int, description: Optional[str] = None, ): - + # hardening # assert_valid_wallet_id(wallet_id) assert_valid_pubkey(pubkey) @@ -66,7 +76,7 @@ async def _process_invoice( assert_sane_string(description) # ## # - async def execute_payment() -> str : + async def execute_payment() -> str: payment = await pay_invoice( wallet_id=wallet_id, payment_request=invoice, @@ -78,10 +88,7 @@ async def _process_invoice( payment_hash = None try: in_budget, payment_hash = await tracked_spend_nwc( - TrackedSpendNWC( - pubkey=pubkey, - amount_msats=amount_msats - ), execute_payment + TrackedSpendNWC(pubkey=pubkey, amount_msats=amount_msats), execute_payment ) if not in_budget: error = { @@ -121,19 +128,14 @@ async def _process_invoice( async def _on_pay_invoice( - sp: NWCServiceProvider, - pubkey: str, - payload: Dict + sp: NWCServiceProvider, pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - + # hardening # assert_valid_pubkey(pubkey) # ## # - nwc = await get_nwc(GetNWC( - pubkey=pubkey, - refresh_last_used=True - )) + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) error = await _check(nwc, "pay_invoice") if error: return [(None, error, [])] @@ -167,11 +169,9 @@ async def _on_pay_invoice( async def _on_multi_pay_invoice( - sp: NWCServiceProvider, - pubkey: str, - payload: Dict + sp: NWCServiceProvider, pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - + # hardening # assert_valid_pubkey(pubkey) # ## # @@ -228,11 +228,9 @@ async def _on_multi_pay_invoice( async def _on_make_invoice( - sp: NWCServiceProvider, - pubkey: str, - payload: Dict + sp: NWCServiceProvider, pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - + # hardening # assert_valid_pubkey(pubkey) # ## # @@ -261,7 +259,7 @@ async def _on_make_invoice( if expiry: assert_valid_expiration_seconds(expiry) # ## # - + payment = await create_invoice( wallet_id=nwc.wallet, amount=int(amount_msats / 1000), @@ -300,11 +298,9 @@ async def _on_make_invoice( async def _on_lookup_invoice( - sp: NWCServiceProvider, - pubkey: str, - payload: Dict + sp: NWCServiceProvider, pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - + # hardening # assert_valid_pubkey(pubkey) # ## # @@ -330,7 +326,7 @@ async def _on_lookup_invoice( assert_valid_sha256(payment_hash) assert_valid_bolt11(invoice) # ## # - + # Get payment data payment = await get_wallet_payment(nwc.wallet, payment_hash) if not payment: @@ -339,7 +335,10 @@ async def _on_lookup_invoice( is_settled = not payment.pending timestamp = int(payment.time.timestamp()) or int(invoice_data.date) expiry = int(payment.expiry.timestamp()) or timestamp + 3600 - preimage = payment.preimage or "0000000000000000000000000000000000000000000000000000000000000000" + preimage = ( + payment.preimage + or "0000000000000000000000000000000000000000000000000000000000000000" + ) res: Dict = { "type": "outgoing" if payment.is_out else "incoming", "invoice": payment.bolt11, @@ -362,9 +361,7 @@ async def _on_lookup_invoice( async def _on_list_transactions( - sp: NWCServiceProvider, - pubkey: str, - payload: Dict + sp: NWCServiceProvider, pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: # hardening # assert_valid_pubkey(pubkey) @@ -435,16 +432,14 @@ async def _on_list_transactions( async def _on_get_balance( - sp: NWCServiceProvider, - pubkey: str, - payload: Dict + sp: NWCServiceProvider, pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - + # hardening # assert_valid_pubkey(pubkey) # ## # - nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used= True)) + nwc = await get_nwc(GetNWC(pubkey=pubkey, refresh_last_used=True)) error = await _check(nwc, "get_balance") if error: return [(None, error, [])] @@ -460,11 +455,9 @@ async def _on_get_balance( async def _on_get_info( - sp: NWCServiceProvider, - pubkey: str, - payload: Dict + sp: NWCServiceProvider, pubkey: str, payload: Dict ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - + # hardening # assert_valid_pubkey(pubkey) # ## # diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index cc785b5..e965b0d 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -852,7 +852,6 @@ async def test_budget_refresh(): await wallet1.close() - # Mostly AI generated pentests @@ -882,7 +881,7 @@ async def test_idor_vulnerability(): async with httpx.AsyncClient() as client: resp = await client.get( f"http://localhost:5002/nwcprovider/api/v1/nwc/{nwc_wallet1['pubkey']}", - headers={"X-Api-Key": wallets["wallet2"]["admin_key"]} + headers={"X-Api-Key": wallets["wallet2"]["admin_key"]}, ) assert resp.status_code == 500 assert "Pubkey has no associated wallet" in resp.text @@ -896,7 +895,7 @@ async def test_sql_injection(): resp = await client.put( f"http://localhost:5002/nwcprovider/api/v1/nwc/{malicious_pubkey}", headers={"X-Api-Key": wallets["wallet1"]["admin_key"]}, - json={"permissions": ["pay"], "description": "test"} + json={"permissions": ["pay"], "description": "test"}, ) # Should be rejected by input validation assert resp.status_code == 400 @@ -941,8 +940,14 @@ async def test_budget_bypass(): "wallet1", "test_budget_bypass", ["pay", "invoice"], - [{"budget_msats": 100000, "refresh_window": 3600, "created_at": int(time.time())}], - 0 + [ + { + "budget_msats": 100000, + "refresh_window": 3600, + "created_at": int(time.time()), + } + ], + 0, ) wallet = NWCWallet(nwc["pairing"]) await wallet.start() @@ -963,17 +968,19 @@ async def test_budget_bypass(): @pytest.mark.asyncio async def test_unauthorized_config(): """Test unauthorized access to config endpoint""" - malicious_relay = "ws://attacker-relay.example" + malicious_relay = "ws://attacker-relay.example" + async def set_config_nwc(key: str, value: str): async with httpx.AsyncClient() as client: resp = await client.post( "http://localhost:5002/nwcprovider/api/v1/config", json={key: value}, - headers={"X-Api-Key": "lnbitsadmin"} # Assuming admin key + headers={"X-Api-Key": "lnbitsadmin"}, # Assuming admin key ) assert resp.status_code == 401 + await set_config_nwc("relay", malicious_relay) - + async def create_valid_invoice(wallet, amount=1000): """Helper function to create valid test invoice""" @@ -983,4 +990,4 @@ async def create_valid_invoice(wallet, amount=1000): result, tags, error = await wallet.wait_for("make_invoice") if error: raise Exception(f"Failed to create invoice: {error}") - return result["invoice"] \ No newline at end of file + return result["invoice"] diff --git a/views_api.py b/views_api.py index b7ef1ad..c29c60c 100644 --- a/views_api.py +++ b/views_api.py @@ -2,7 +2,7 @@ from http import HTTPStatus from typing import Dict, List, Optional import secp256k1 -from fastapi import APIRouter, Depends, Request, Query +from fastapi import APIRouter, Depends, Request from fastapi.responses import JSONResponse from lnbits.core.models import WalletTypeInfo from lnbits.decorators import check_admin, require_admin_key @@ -18,35 +18,34 @@ from .crud import ( set_config_nwc, ) from .models import ( - NWCRegistrationRequest, - GetBudgetsNWC, - GetWalletNWC, - NWCGetResponse, CreateNWCKey, DeleteNWC, + GetBudgetsNWC, GetNWC, - GetBudgetsNWC + GetWalletNWC, + NWCGetResponse, + NWCRegistrationRequest, +) +from .paranoia import ( + assert_boolean, + assert_sane_string, + assert_valid_pubkey, + assert_valid_wallet_id, ) from .permission import nwc_permissions -from .paranoia import assert_valid_wallet_id, assert_valid_pubkey, assert_sane_string, assert_boolean nwcprovider_api_router = APIRouter() # Get supported permissions -@nwcprovider_api_router.get( - "/api/v1/permissions", - status_code=HTTPStatus.OK -) +@nwcprovider_api_router.get("/api/v1/permissions", status_code=HTTPStatus.OK) async def api_get_permissions() -> Dict: return nwc_permissions ## Get nwc keys associated with the wallet @nwcprovider_api_router.get( - "/api/v1/nwc", - status_code=HTTPStatus.OK, - response_model=List[NWCGetResponse] + "/api/v1/nwc", status_code=HTTPStatus.OK, response_model=List[NWCGetResponse] ) async def api_get_nwcs( include_expired: bool = False, @@ -59,18 +58,14 @@ async def api_get_nwcs( assert_valid_wallet_id(wallet_id) assert_boolean(include_expired) assert_boolean(calculate_spent_budget) - # ## # + # ## # - wallet_nwcs = GetWalletNWC( - wallet=wallet_id, - include_expired=include_expired - ) + wallet_nwcs = GetWalletNWC(wallet=wallet_id, include_expired=include_expired) nwcs = await get_wallet_nwcs(wallet_nwcs) out = [] for nwc in nwcs: budgets_nwc = GetBudgetsNWC( - pubkey=nwc.pubkey, - calculate_spent=calculate_spent_budget + pubkey=nwc.pubkey, calculate_spent=calculate_spent_budget ) budgets = await get_budgets_nwc(budgets_nwc) res = NWCGetResponse(data=nwc, budgets=budgets) @@ -80,14 +75,12 @@ async def api_get_nwcs( # Get a nwc key @nwcprovider_api_router.get( - "/api/v1/nwc/{pubkey}", - status_code=HTTPStatus.OK, - response_model=NWCGetResponse + "/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK, response_model=NWCGetResponse ) async def api_get_nwc( pubkey: str, include_expired: bool = False, - wallet: WalletTypeInfo = Depends(require_admin_key) + wallet: WalletTypeInfo = Depends(require_admin_key), ) -> NWCGetResponse: wallet_id = wallet.wallet.id @@ -97,28 +90,23 @@ async def api_get_nwc( assert_valid_wallet_id(wallet_id) # ## # - nwc = await get_nwc(GetNWC(pubkey=pubkey, wallet=wallet_id, include_expired=include_expired)) + nwc = await get_nwc( + GetNWC(pubkey=pubkey, wallet=wallet_id, include_expired=include_expired) + ) if not nwc: raise Exception("Pubkey has no associated wallet") - res = NWCGetResponse(data=nwc, budgets=await get_budgets_nwc( - GetBudgetsNWC( - pubkey=pubkey - ) - )) + res = NWCGetResponse( + data=nwc, budgets=await get_budgets_nwc(GetBudgetsNWC(pubkey=pubkey)) + ) return res # Get pairing url for given secret @nwcprovider_api_router.get( - "/api/v1/pairing/{secret}", - status_code=HTTPStatus.OK, - response_model=str + "/api/v1/pairing/{secret}", status_code=HTTPStatus.OK, response_model=str ) -async def api_get_pairing_url( - req: Request, - secret: str -) -> str: - +async def api_get_pairing_url(req: Request, secret: str) -> str: + # hardening # assert_sane_string(secret) # ## # @@ -163,7 +151,7 @@ async def api_get_pairing_url( ) async def api_register_nwc( pubkey: str, - data: NWCRegistrationRequest, + data: NWCRegistrationRequest, wallet: WalletTypeInfo = Depends(require_admin_key), ): wallet_id = wallet.wallet.id @@ -183,23 +171,15 @@ async def api_register_nwc( budgets=data.budgets, ) ) - budgets = await get_budgets_nwc( - GetBudgetsNWC( - pubkey=pubkey - ) - ) + budgets = await get_budgets_nwc(GetBudgetsNWC(pubkey=pubkey)) res = NWCGetResponse(data=nwc, budgets=budgets) return res # Delete a nwc key -@nwcprovider_api_router.delete( - "/api/v1/nwc/{pubkey}", - status_code=HTTPStatus.OK -) +@nwcprovider_api_router.delete("/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK) async def api_delete_nwc( - pubkey: str, - wallet: WalletTypeInfo = Depends(require_admin_key) + pubkey: str, wallet: WalletTypeInfo = Depends(require_admin_key) ): wallet_id = wallet.wallet.id @@ -208,20 +188,13 @@ async def api_delete_nwc( assert_valid_wallet_id(wallet_id) # ## # - await delete_nwc(DeleteNWC( - pubkey=pubkey, - wallet=wallet_id - )) - return JSONResponse( - content={"message": f"NWC key {pubkey} deleted successfully."} - ) + await delete_nwc(DeleteNWC(pubkey=pubkey, wallet=wallet_id)) + return JSONResponse(content={"message": f"NWC key {pubkey} deleted successfully."}) # Get config @nwcprovider_api_router.get( - "/api/v1/config", - status_code=HTTPStatus.OK, - dependencies=[Depends(check_admin)] + "/api/v1/config", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] ) async def api_get_all_config_nwc(): config = await get_all_config_nwc() @@ -243,9 +216,7 @@ async def api_get_config_nwc(key: str): # Set config @nwcprovider_api_router.post( - "/api/v1/config", - status_code=HTTPStatus.OK, - dependencies=[Depends(check_admin)] + "/api/v1/config", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] ) async def api_set_config_nwc(req: Request): data = await req.json() From 9dcaf125b0cf91cfcbe8c5b17b511a70911a2a53 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sun, 23 Feb 2025 16:53:06 +0000 Subject: [PATCH 46/90] lint --- nwcp.py | 3 ++- paranoia.py | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/nwcp.py b/nwcp.py index 22358dc..4a5023a 100644 --- a/nwcp.py +++ b/nwcp.py @@ -49,7 +49,8 @@ class MainSubscription: def gc(self, expire: Optional[int] = None): """ - Garbage collection, remove all the events that have a response older than expire seconds (defaults to 1 hour if 0 or None) + Garbage collection, remove all the events that have a response older + than expire seconds (defaults to 1 hour if 0 or None) """ expire = expire or 1 * 60 * 60 now = int(time.time()) diff --git a/paranoia.py b/paranoia.py index 815ae4e..5ebca7c 100644 --- a/paranoia.py +++ b/paranoia.py @@ -70,11 +70,16 @@ def assert_valid_sha256(v: str): # Check if value is an hash of an unexpected input (eg. empty strings, booleans etc) def assert_no_badhash(v: str): bad_hashes = [ - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", # empty string - "36a9e7f1c95b82ffb99743e0c5c4ce95d83c9a430aac59f84ef3cbfab6145068", # 1 space string - "c1c4b7fbd3e146bb14ec6258e5231c1ec703590721ff1e321b179a62b5857c9c", # None - "cdca0b9bb2325fc8ed7eba7734a3a1f876d919221399b6587ae7d26305adee9d", # True - "f9e08f8b038b1b401497f17da3adc120667ac742bf035657869a6ca1cd180e69", # False + # empty string + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + # 1 space string + "36a9e7f1c95b82ffb99743e0c5c4ce95d83c9a430aac59f84ef3cbfab6145068", + # None + "c1c4b7fbd3e146bb14ec6258e5231c1ec703590721ff1e321b179a62b5857c9c", + # True + "cdca0b9bb2325fc8ed7eba7734a3a1f876d919221399b6587ae7d26305adee9d", + # False + "f9e08f8b038b1b401497f17da3adc120667ac742bf035657869a6ca1cd180e69", ] if v in bad_hashes: panic("bad hash detected") @@ -146,8 +151,8 @@ def assert_valid_json(v: str): import json json.loads(v) - except: - panic("string is not valid json") + except Exception as e: + panic("string is not valid json " + str(e)) # Check if string is a valid bolt11 invoice From a6e0a18a066d7cb0e4052a0c920c43905d99c951 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Mon, 3 Mar 2025 20:20:08 +0000 Subject: [PATCH 47/90] postgres fix --- crud.py | 3 ++- migrations.py | 25 +++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/crud.py b/crud.py index b41e71c..ee50849 100644 --- a/crud.py +++ b/crud.py @@ -280,8 +280,9 @@ async def set_config_nwc(key: str, value: str): await db.execute( """ - INSERT OR REPLACE INTO nwcprovider.config (key, value) + INSERT INTO nwcprovider.config (key, value) VALUES (:key, :value) + ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, {"key": key, "value": value}, ) diff --git a/migrations.py b/migrations.py index 6046c3c..fd12650 100644 --- a/migrations.py +++ b/migrations.py @@ -68,15 +68,15 @@ async def m003_default_config(db): """ await db.execute( """ - INSERT OR REPLACE INTO nwcprovider.config - (key, value) VALUES ('relay', 'nostrclient'); + INSERT INTO nwcprovider.config (key, value) VALUES ('relay', 'nostrclient') + ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """ ) new_private_key = bytes.hex(secp256k1._gen_private_key()) await db.execute( """ - INSERT OR REPLACE INTO nwcprovider.config - (key, value) VALUES ('provider_key', :provider_key); + INSERT INTO nwcprovider.config (key, value) VALUES ('provider_key', :provider_key) + ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, {"provider_key": new_private_key}, ) @@ -86,15 +86,13 @@ async def m004_default_config2(db): """ Default config """ - await db.execute( - """ - INSERT OR REPLACE INTO nwcprovider.config - (key, value) VALUES ('relay_alias', :value); + """ + INSERT INTO nwcprovider.config (key, value) VALUES ('relay_alias', :value) + ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, - {"value": ""}, - ) - + {"value": ""}, + ) async def m005_key_last_used(db): """ @@ -111,11 +109,10 @@ async def m006_default_config3(db): """ Default config """ - await db.execute( """ - INSERT OR REPLACE INTO nwcprovider.config - (key, value) VALUES ('handle_missed_events', :value); + INSERT INTO nwcprovider.config (key, value) VALUES ('handle_missed_events', :value) + ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, {"value": "0"}, ) From eb0ac9d13d73ffac8124e3a8d878b5a2e24d57c6 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Mon, 9 Jun 2025 14:16:15 +0200 Subject: [PATCH 48/90] fix test_multi_pay_invoices --- tests/integration/test_all.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index e965b0d..8b82297 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -627,6 +627,7 @@ async def test_multi_pay_invoices(): assert not error assert result["invoice"] invoice3 = result["invoice"] + invoice3_payhash = result["payment_hash"] await wallet3.send_event( "multi_pay_invoice", @@ -645,7 +646,7 @@ async def test_multi_pay_invoices(): assert result["preimage"] elif d_tag == "invoice2": assert result["preimage"] - elif d_tag == invoice3: + elif d_tag == invoice3_payhash: assert result["preimage"] else: raise AssertionError("Unexpected d tag") From b851920eb398b8f0bebd23e8e05ad086c073151c Mon Sep 17 00:00:00 2001 From: 21M4TW <134294118+21M4TW@users.noreply.github.com> Date: Mon, 9 Jun 2025 12:51:50 +0000 Subject: [PATCH 49/90] -Two issues identified with the list_transactions command: (#11) -Was accessing the arguments from payload instead of from params -Was using "to" instead of "until" defined in NIP-47 --- tasks.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tasks.py b/tasks.py index d06a80f..f09d1c3 100644 --- a/tasks.py +++ b/tasks.py @@ -373,16 +373,17 @@ async def _on_list_transactions( return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - tfrom = payload.get("from", 0) - tto = payload.get("to", int(time.time())) - limit = payload.get("limit", 10) - offset = payload.get("offset", 0) - unpaid = payload.get("unpaid", False) - tx_type = payload.get("type", "") + params = payload.get("params", 0) + tfrom = params.get("from", 0) + tuntil = params.get("until", int(time.time())) + limit = params.get("limit", 10) + offset = params.get("offset", 0) + unpaid = params.get("unpaid", False) + tx_type = params.get("type", "") # hardening # assert_valid_positive_int(tfrom) - assert_valid_positive_int(tto) + assert_valid_positive_int(tuntil) assert_valid_positive_int(limit) assert_valid_positive_int(offset) assert_boolean(unpaid) @@ -392,7 +393,7 @@ async def _on_list_transactions( values = [] filters: Filters = Filters() filters.where(["time <= ?"]) - values.append(tto) + values.append(tuntil) filters.values(values) history = await get_payments( wallet_id=nwc.wallet, From fb1c3b87ebe4b1b6d9a3f2a0d4660d9fed669f81 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Mon, 9 Jun 2025 14:27:01 +0200 Subject: [PATCH 50/90] add list_transactions test --- tests/integration/test_all.py | 135 +++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index 8b82297..86f12c6 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -183,7 +183,11 @@ class NWCWallet: async def _wait_for_connection(self): while not self.connected: - await asyncio.sleep(0.2) + try: + await asyncio.sleep(0.2) + except asyncio.CancelledError: + logger.debug("Connection wait cancelled") + return async def start(self): self.task = asyncio.create_task(self._run()) @@ -335,7 +339,7 @@ class NWCWallet: await self.ws.send(self._json_dumps(["EVENT", event])) async def wait_for( - self, result_type, callback=None, on_error_callback=None, timeout=60 + self, result_type, callback=None, on_error_callback=None, timeout=60000 ): now = time.time() while True: @@ -992,3 +996,130 @@ async def create_valid_invoice(wallet, amount=1000): if error: raise Exception(f"Failed to create invoice: {error}") return result["invoice"] + +@pytest.mark.asyncio +async def test_list_transactions(): + # Create wallets with required permissions + nwc1 = await create_nwc( + "wallet1", "test_list_transactions", ["invoice", "pay", "balance", "history"], [], 0 + ) + nwc2 = await create_nwc( + "wallet2", "test_list_transactions", ["invoice", "pay", "balance", "history"], [], 0 + ) + + wallet1 = NWCWallet(nwc1["pairing"]) + wallet2 = NWCWallet(nwc2["pairing"]) + + await wallet1.start() + await wallet2.start() + + # Create some transactions with different timestamps + start_time = int(time.time()) + + # First invoice + await wallet1.send_event( + "make_invoice", {"amount": 100000, "description": "test invoice 1"} + ) + result1, _, error = await wallet1.wait_for("make_invoice") + assert not error + invoice1 = result1["invoice"] + + # Pay first invoice + await wallet2.send_event("pay_invoice", {"invoice": invoice1}) + _, _, error = await wallet2.wait_for("pay_invoice") + assert not error + + mid_timestamp = int(time.time()) + + # Second invoice + await wallet1.send_event( + "make_invoice", {"amount": 200000, "description": "test invoice 2"} + ) + result2, _, error = await wallet1.wait_for("make_invoice") + assert not error + invoice2 = result2["invoice"] + + # Pay second invoice + await wallet2.send_event("pay_invoice", {"invoice": invoice2}) + _, _, error = await wallet2.wait_for("pay_invoice") + assert not error + + # Create an unpaid invoice + await wallet1.send_event( + "make_invoice", {"amount": 300000, "description": "test invoice 3 (unpaid)"} + ) + _, _, error = await wallet1.wait_for("make_invoice") + assert not error + + end_time = int(time.time()) + + # Test 1: List all transactions + await wallet1.send_event("list_transactions", {}) + result, _, error = await wallet1.wait_for("list_transactions") + assert not error + assert "transactions" in result + transactions = result["transactions"] + + # Should have at least 2 paid invoices + assert len(transactions) >= 2 + + # Verify transaction structure + for tx in transactions: + assert "type" in tx + assert "amount" in tx + assert "created_at" in tx + assert "payment_hash" in tx + + # Test 2: Filter by type (incoming) + await wallet1.send_event("list_transactions", {"type": "incoming"}) + result, _, error = await wallet1.wait_for("list_transactions") + assert not error + incoming_txs = result["transactions"] + assert all(tx["type"] == "incoming" for tx in incoming_txs) + + # Test 3: Filter by time range + await wallet1.send_event( + "list_transactions", {"from": start_time, "until": mid_timestamp} + ) + result, _, error = await wallet1.wait_for("list_transactions") + assert not error + early_txs = result["transactions"] + # Should only include transactions from the first time period + for tx in early_txs: + assert tx["created_at"] >= start_time + assert tx["created_at"] <= mid_timestamp + + # Test 4: Test limit and offset + await wallet1.send_event("list_transactions", {"limit": 1}) + result, _, error = await wallet1.wait_for("list_transactions") + assert not error + limited_txs = result["transactions"] + assert len(limited_txs) == 1 + + await wallet1.send_event("list_transactions", {"limit": 1, "offset": 1}) + result, _, error = await wallet1.wait_for("list_transactions") + assert not error + offset_txs = result["transactions"] + assert len(offset_txs) == 1 + # Should be different transactions + assert offset_txs[0]["payment_hash"] != limited_txs[0]["payment_hash"] + + # Test 5: Include unpaid invoices + await wallet1.send_event("list_transactions", {"unpaid": True}) + result, _, error = await wallet1.wait_for("list_transactions") + assert not error + all_txs = result["transactions"] + # Should find at least one unpaid invoice + assert any(tx.get("settled_at") is None for tx in all_txs) + + # Test 6: Check outgoing transactions from wallet2 + await wallet2.send_event("list_transactions", {"type": "outgoing"}) + result, _, error = await wallet2.wait_for("list_transactions") + assert not error + outgoing_txs = result["transactions"] + assert all(tx["type"] == "outgoing" for tx in outgoing_txs) + assert len(outgoing_txs) >= 2 + + # Cleanup + await wallet1.close() + await wallet2.close() \ No newline at end of file From 0baeaadb24460c3ab6b3ca4e930c29098423155c Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Mon, 9 Jun 2025 17:24:41 +0200 Subject: [PATCH 51/90] update dev container --- .devcontainer/devcontainer.json | 4 +--- .devcontainer/pre-setup.sh | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ab3aa91..a1bd5a1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,9 +1,7 @@ { "name": "lnbits_nwc_provider", "image": "mcr.microsoft.com/devcontainers/python:1-3.12", - "features": { - "ghcr.io/devcontainers-contrib/features/poetry:2": {} - }, + "mounts": [ "source=${localWorkspaceFolder}/.devcontainer/start.sh,target=/start-lnbits.sh,type=bind", "source=${localWorkspaceFolder}/.devcontainer/setup.sh,target=/setup.sh,type=bind", diff --git a/.devcontainer/pre-setup.sh b/.devcontainer/pre-setup.sh index 367a1e1..6a2b99e 100644 --- a/.devcontainer/pre-setup.sh +++ b/.devcontainer/pre-setup.sh @@ -5,6 +5,7 @@ sudo apt update -y sudo apt install -y curl sudo apt-get install -y docker.io +curl -sSL https://install.python-poetry.org | python3 - curl -fsSL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup.sh sudo bash /tmp/nodesource_setup.sh sudo apt-get install -y nodejs From dd1d35b99daf01686b770ee6e840a181b0185888 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Mon, 9 Jun 2025 18:18:44 +0200 Subject: [PATCH 52/90] make list_transactions simpler to avoid timeouts --- tests/integration/test_all.py | 161 ++++++++++------------------------ 1 file changed, 48 insertions(+), 113 deletions(-) diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index 86f12c6..854aef4 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -1010,116 +1010,51 @@ async def test_list_transactions(): wallet1 = NWCWallet(nwc1["pairing"]) wallet2 = NWCWallet(nwc2["pairing"]) - await wallet1.start() - await wallet2.start() - - # Create some transactions with different timestamps - start_time = int(time.time()) - - # First invoice - await wallet1.send_event( - "make_invoice", {"amount": 100000, "description": "test invoice 1"} - ) - result1, _, error = await wallet1.wait_for("make_invoice") - assert not error - invoice1 = result1["invoice"] - - # Pay first invoice - await wallet2.send_event("pay_invoice", {"invoice": invoice1}) - _, _, error = await wallet2.wait_for("pay_invoice") - assert not error - - mid_timestamp = int(time.time()) - - # Second invoice - await wallet1.send_event( - "make_invoice", {"amount": 200000, "description": "test invoice 2"} - ) - result2, _, error = await wallet1.wait_for("make_invoice") - assert not error - invoice2 = result2["invoice"] - - # Pay second invoice - await wallet2.send_event("pay_invoice", {"invoice": invoice2}) - _, _, error = await wallet2.wait_for("pay_invoice") - assert not error - - # Create an unpaid invoice - await wallet1.send_event( - "make_invoice", {"amount": 300000, "description": "test invoice 3 (unpaid)"} - ) - _, _, error = await wallet1.wait_for("make_invoice") - assert not error - - end_time = int(time.time()) - - # Test 1: List all transactions - await wallet1.send_event("list_transactions", {}) - result, _, error = await wallet1.wait_for("list_transactions") - assert not error - assert "transactions" in result - transactions = result["transactions"] - - # Should have at least 2 paid invoices - assert len(transactions) >= 2 - - # Verify transaction structure - for tx in transactions: - assert "type" in tx - assert "amount" in tx - assert "created_at" in tx - assert "payment_hash" in tx - - # Test 2: Filter by type (incoming) - await wallet1.send_event("list_transactions", {"type": "incoming"}) - result, _, error = await wallet1.wait_for("list_transactions") - assert not error - incoming_txs = result["transactions"] - assert all(tx["type"] == "incoming" for tx in incoming_txs) - - # Test 3: Filter by time range - await wallet1.send_event( - "list_transactions", {"from": start_time, "until": mid_timestamp} - ) - result, _, error = await wallet1.wait_for("list_transactions") - assert not error - early_txs = result["transactions"] - # Should only include transactions from the first time period - for tx in early_txs: - assert tx["created_at"] >= start_time - assert tx["created_at"] <= mid_timestamp - - # Test 4: Test limit and offset - await wallet1.send_event("list_transactions", {"limit": 1}) - result, _, error = await wallet1.wait_for("list_transactions") - assert not error - limited_txs = result["transactions"] - assert len(limited_txs) == 1 - - await wallet1.send_event("list_transactions", {"limit": 1, "offset": 1}) - result, _, error = await wallet1.wait_for("list_transactions") - assert not error - offset_txs = result["transactions"] - assert len(offset_txs) == 1 - # Should be different transactions - assert offset_txs[0]["payment_hash"] != limited_txs[0]["payment_hash"] - - # Test 5: Include unpaid invoices - await wallet1.send_event("list_transactions", {"unpaid": True}) - result, _, error = await wallet1.wait_for("list_transactions") - assert not error - all_txs = result["transactions"] - # Should find at least one unpaid invoice - assert any(tx.get("settled_at") is None for tx in all_txs) - - # Test 6: Check outgoing transactions from wallet2 - await wallet2.send_event("list_transactions", {"type": "outgoing"}) - result, _, error = await wallet2.wait_for("list_transactions") - assert not error - outgoing_txs = result["transactions"] - assert all(tx["type"] == "outgoing" for tx in outgoing_txs) - assert len(outgoing_txs) >= 2 - - # Cleanup - await wallet1.close() - await wallet2.close() \ No newline at end of file + try: + await wallet1.start() + await wallet2.start() + + # First invoice + await wallet1.send_event( + "make_invoice", {"amount": 1000, "description": "test invoice 1"} + ) + result1, _, error = await wallet1.wait_for("make_invoice") + assert not error + invoice1 = result1["invoice"] + + # Pay first invoice + await wallet2.send_event("pay_invoice", {"invoice": invoice1}) + _, _, error = await wallet2.wait_for("pay_invoice") + assert not error + + # Second invoice + await wallet1.send_event( + "make_invoice", {"amount": 2000, "description": "test invoice 2"} + ) + result2, _, error = await wallet1.wait_for("make_invoice") + assert not error + invoice2 = result2["invoice"] + + # Pay second invoice + await wallet2.send_event("pay_invoice", {"invoice": invoice2}) + _, _, error = await wallet2.wait_for("pay_invoice") + assert not error + + # Test basic transaction listing + await wallet1.send_event("list_transactions", {}) + result, _, error = await wallet1.wait_for("list_transactions") + assert not error + assert "transactions" in result + transactions = result["transactions"] + assert len(transactions) >= 2 + + # Test limit + await wallet1.send_event("list_transactions", {"limit": 1}) + result, _, error = await wallet1.wait_for("list_transactions") + assert not error + limited_txs = result["transactions"] + assert len(limited_txs) == 1 + + finally: + await wallet1.close() + await wallet2.close() \ No newline at end of file From 59bdc8cc537bc57c566fc525905c84bfb9073e78 Mon Sep 17 00:00:00 2001 From: blackcoffeexbt <87530449+blackcoffeexbt@users.noreply.github.com> Date: Wed, 18 Jun 2025 13:15:38 +0100 Subject: [PATCH 53/90] Add extension images for extension preview modal --- static/image/nwcprovimage/1.png | Bin 0 -> 38427 bytes static/image/nwcprovimage/2.png | Bin 0 -> 34425 bytes static/image/nwcprovimage/3.png | Bin 0 -> 33475 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 static/image/nwcprovimage/1.png create mode 100644 static/image/nwcprovimage/2.png create mode 100644 static/image/nwcprovimage/3.png diff --git a/static/image/nwcprovimage/1.png b/static/image/nwcprovimage/1.png new file mode 100644 index 0000000000000000000000000000000000000000..4e04c6dadf5e5b18bde125e4cee69b67d7980412 GIT binary patch literal 38427 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

89F^eu4h|2Z51!3MxOHwvX)GIAhfGE-`l0# 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 literal 0 HcmV?d00001 diff --git a/static/image/nwcprovimage/2.png b/static/image/nwcprovimage/2.png new file mode 100644 index 0000000000000000000000000000000000000000..ee4c1389bb0e808c00d062b4bb94d3d19459bb94 GIT binary patch literal 34425 zcmeAS@N?(olHy`uVBq!ia0y~yV5?$aU=iYAW?*30f9uLd1_lPn64!{5;QX|b^2DN4 z2FH~Aq*MjZ+{EX{)CB@w}FfdWj%4dKI|^3?N`*Ur~^l zoSj;tkd&I9nP;o?e)oPQh0GLNrEpVU1K$GY)Qn7zs-o23D!-8As_bOT6eW8*1)B=1 zirj+S)RIJnirk#MVyg;UC9t_xdBs*BVSOb9u#%E&TP292B76fBob!uP6)g1(b(0MY z3>C~R^$bnSj4UiI&CShq6pRdvjP(u7^o>k)jf|~K&8-Yg6re!KPQj)qCCw_x#SLm- zQA(PvQbtKhft9{~d3m{Bxv^e;QM$gNrKP35fswwEk#12+nr?ArUP)qwZeFo6%mkOz z;^d;tf|AVqJOz-6iAnjTCALaRP-81{3*g4)6+?q6IX_pwBC$Z+nYporB~J68dQ-5u1)|pxr(S(K1si=(%p%1!Oeo034a5W| zOi&`VQ$VEt)Vvg1r6MJJyDjQB7cwv~HU#*Dxc*Q6FUl-xtz+$K;c6vl^`GJYwq@HC zxD{SKeKnI|=KufyS504)?w#J#)g#R*ot>P0`^s%)LFKZ@vZ8__M=8hH;Mhs2ax-Vn zJi7B}xLLS|vWJ$GR!U6D=Z~MKPMunqRe0shl@x{)308^!tN)vEnKfrLD~AaEzw*Db zq_VTM^U}ym|kv{}(qG=lY8!h9`!4g{m;C_}KeI z`bO4O*1do8J~J+}tFS9OF#GJGvz|G=zkdGe@9m%2Jaf{7Nt0_P2f7CS{r&g9`2Trb z^A=B7{Quqmh?0!|hyPdQR3*41Oqn#LCZT3}W42+ewZD#k&%_>eG4+zw!$t=mqz&T+`|KzEYm3Wmp`r8fU4dgiGbU1V*m?Y-Rp0j@5 z`svfB>oe<%Gl~l{2yfBeo5R4+7~|>U7*cWT&EEgTvro)>U&|hIP+hoX-K6RCBra;&u-b4@8{VsN|y|12}^JwL)&0GCtgLa>Ox9PaR1{-D^IVFVayB%zBlVhNBL*1@wPRz?B83J zUzw*JtyVa(SyfJZb4iQGlxs}v^Tik#YWP`}eQ;i0Dt+a$=d{(!Z}wC&iOP#JFx;s< z78>?&cbnIVC#Rjdx_R>+f4*=&od2b6xc@|kSBwk|?;GS+zccl6w^K~ZwSBddOZ-Z5 z+vis&d7Q=O+Du$y{zUKN(~i9y&Fda&{CLB_@E|Yf@!DLW=nEAeHrv$fbo^?ynMeEcULb|S>&-pnaoTaV;Fyv)qdVC{Jz`=j2{&Qs!I?h{Q{E$S;@w_@JTjk>P->tMJ4l2MSx2RjMx9&VR+YYlYlr zoA3bt4584OE7K2L>kC=u7PxKCdUd5|9hcVJK3b5?z_4TT4ep00E6*ByuPJ(SFiQH) zu08Kp+6DU`3IFa{?Pz<(?`)mTp>%czhVm&^`TVbsCSD0Wy*f+mj&iM0yXk86mjaix zuPV0*xg3cP;P17OTN!%sIx_=9xv;wYxibftfTX|E)ouHNhV z)j(0|TMJM2j~@&S5A+uOcF}7|{P?Sm_tno;iEM8&50sz0s+_b=PrlN8`8=IR2P0oh zw6n7VId#J?y9ejHd~N>DUUB>~%ibW{mFB_yrw?t&Il&#VB7MdOhu-+#&bKRfGBPmS zvE8-j)BD?MAD8Oi`oH>j71yezRY$BA%3ThBeQkn?c578s%NE^L)oTviHT&pXQ^CMc z;6Cxno>$lR=Y0RVx}ATw@T-q57jxn^?D@Dh?~}Kev7yfSb001;G8~w@bfV?o7v0Vs z*?Z&9TXc)J+bv0I%H4bQkgF{NLqYw)wT~DW7ziZkhAL9jylbseVPIf*;I@-L@cey{ z-_*dlC4e84eIO*mt45HS5YoXGlzSi~ET4S^=Qa@8PzBNrAsHaLAtWeOGcbGwyB$I< zkOSq?1@mru2c(}Ul$~z`@)^YJ&8Kc9@^8GB)ZZ7pZi?)z(({+D9D46zYtO(ittp;o z$G-O$E5CZg82W{$_1~>%t&;hj`O9!f%uBpy<{n|3iDbvJ4i3>@?pY`KEqt>GG?G>)n4uF>IK1)QWk(#D>227rDNAu)R$U;mR;i zu1*Q`*S@+qo3Gi`HO6-1wf?;S8O{DH+3OE77QDQ_`uUaSc%C1xKw4hRGFowA!@R6N zh7+>x2H7rDD?U^+qw(C5lGp9hG0Wt>S+9Cv&3GU+48h;OvlzkYeD_FKgB{-lbp zYYwhm`0`Dv&8fw5-&CitZLghkQ2ol}N7{@BQkQhUI;hW9^Ywei(yBR*A$C@bODA5_ zYL~QdOx2ORaG1l@2i&&@N+i! zhf4O!f9Pg>{YUQZZ_7I$oS7J2F$SDBW%|m%@ReZ&`zuBeACv$asu->?Ba4EQB0`km zYmBSyNe{*c^NhR}$T57a;r^1tn&z`2oe zV%3%=$5z)ZRm`k?`2Kg!`2)_T{9o^UU9o)mmMUh~i%zyhi=1p1%Dk)!5I^_wYj8;D zgMF*pC0eVF)lJuR5k4e*(=6J2W0LD7kANk)<&V5pdsk_%R@eS>sVjGz`W5D{cPhWO zFdv=xD{}3+FU>o&Ils1)YQB2q7ry0Ss;O+K=#KZVGG}j%vAvSDxpm#s%@5Qizh$^? zt!OaL`~9RILAbpkeX2C^GQuZnteP%=#Dk+J00itd=@>Q^pHzuJ>|Zl>zVtIEH+ zU;Wd#fAF1(%?7Rrg{w)cb2lzG^wE@EDJNTLvoX#1>yD1f1@o*|%-e7)X_2AG(rk&n zy8`@gy_V_|%3^$_!SGe&mE_9Og>vh<^|}*mX0FnS*?5P}{A;(hRwW62o_N(S_}g)tkdsq|McE8KEzH&AoZ%egr+QLVXvG!2qOV(CJK4O{ z@w|B5Sj?*H2%mBxqu|yYIgZxa)i;U{gd6?#R1w*&CZsRCWAdw?Paix`KX~w5bEy*Z&-26aB=$W<2=QovIWf!J>wtcN7fB0=x$ovl`6WtchvtBi?aN*oZnM_|9 z3Z9=$4k=z!k^5?4t*&Pd9&#qVE<*;^1QJ7|S_ujt9mU9u^cybo*1PjIOAEuQi|a(2eTJc0fo->D*=r3*lo z6+aT($bW_TK>4G2OP~D=`f4(3(X98+wJx4owoOfOiRJ6p{HFI&B0y&0#?B8|F&+l5!9~#A7-Lq+pP1C+jg09!~RXA&Iafp{)aQFV^bNbBj8HvBw ztxErOnQNJLk=`?oHJt}1)$HhU>avfBX}`AU=aQK>F6DGTc`6{{ym*q8_of|(w+Hoy z^DO*!YfoT|(ymKopG;%D1Lw3>u1-D_ze@Jo1*Nq~sZTV2yKTtmAS{MTLBC z7Mztc^3F|OWKqETE;4ambk${+WpV}jS2ka=(Y|XO+<$)ggtuo`s`IVfY;d6d%<~E^ z+sXW`GjFB^+V)kizGD1lez1SHr^{6Fx-)jSr&Ol(dOC+rTYdc1y#I4gyA^MWv0a-s zd2M+0T92b&S10^^7nvxxg1yH3YfRF-(04Oes=qMd`s%VSKYdD8V7%$=$e{0SWqHck z2c9gt>Em##A?@3R>sm{z4z0>}4|!A2edY4^=+>&L(D|>IUthcR|E()iR^(1gTao2s zHS4rl)GVRRlQ(^tSykm5dU@)q_gl~ZJ*T{L{%ZHU-+JqL7Hx}vDs?HgeWiQS!KsTf zS7;vWEwsM6xMjtj_svyxKVJsb?F_NaysB~K@yWHn0+z3ve06r3}Ul{y7 zVcYvwwLf(2QTD}8UP-QW6XP-7cvv^6|4#Yk7~5rvU)48V+FEk+z1Pb7y|TtaomD=f zp~n;E1ohOtMa!j%d#>tU z5iT$B};5`d#L`E$-i_$ z->$zoiEaDLs;V~|b2UPn?XA0FLb<;FSkh%}%&>y}4)fPD{j2_+pA>I*@k!Y-xm(%l zPPR2Hje)vXC;vRVF67Sq3*C>*eE-b4v#dmh{o0a{{%dkPY-P`{t!!^qo*BR&FFbQ; zmB{P$SL1H_K0X=b?)f+DLf{mWSJ9J$Y$Y#BIHxa@J6n3UBG7h^^NQ%ukl9Of__EGM zt(04u79J?iw1U0n`zy)+TYPM}6VLw$`l|BwU(O82`+8TMgO3}<7V5{YD*esYUCOl9 zdurKk`OKwNI@c4v|(r7E4Cg6K1$kr<)|KHXO*UhioVgpy%u3gvicAMh)Me}Bq zSYGn6_1k}cz3!^^-={Z--hZSy*UGrys(gy1`J@!3H;e)NKi*v}-r!@qzvk7YOO{_R zOk3HR$o8|N$;md*_l%8pkY#RN@rnakURNG&jz1%Hho|mik=k9SuPyVAT@5~8UCQbiB_o35Lcb?QNaFPo>>bEy;`=6?7`C`hi85*h% zl&_mNf7;6DllR(Y>8C7lvfbjhqsq!^>X{j<-Se~_S8Y9XWpezn;Mp@ozh!K4cMpwN zRkd*5EX}~Z!kw~tja5B8fx@o>We#06o-)P9w54iRdY!9 zRU`JN2F$1VE-#p@HA`$=kpJ>!F7;EVEVvn@5^wVGBir^FU%p%@n_6&SN!piB{}~)? zAN&qJuYdZ==hN!!J69&n`joX!&h_c5m%sPPcX)dpR_iRi9r8DB<}E$>%iCUtR|~I{ zh|#UycWY@vSNzq>S=)qu+}jXa_HD(siWJ9y6Mm=6)B+dI z+mQ8Z-4cyW{$VSROZ>9C>~+iZZ<<_o=e~Id%+<@5UGazyv?}{2&#;2Mrv8;>#Ikw% zv(K#E_`^2z(9+=a50Zw@+=7-rer@sbtM8J@x+e8YBX^jD`ih(X)Vz4uKXtV@lXteb zF{thOJ zVtp+470=PUQ04NutGafdXe~)N?s+LIEHgm=Qe5iomDNs{ zRe2$uby?y(UzX>z`zPBSdT#~Ud8eAb-c|GaW+uy?lvK{ljcZrjJFhC(9=`YB3!TWo zo_)zHwC4X;eX*j{PHD$0^Xl}^(MDgl{E$6VxpS3|ZQrS~E~_PPr{qiAj?tTT(#7Y5 z-{B1rb$LPaD%Q>WGg%-~Wd6ghM_qFtt-AAZ&6hX19k-WBt%~=N+2^}% z7oK9j8$)$uC)l-y}7w;mfz{1qX8>!>P%ggYTcE- zHRb#X|HaQw>z?)R7V7KHZLJcU-0`_&>59b{jUpp^cHPSTdQ)1&Wa*5lejm3^JACg} zQQhf12X()`(mfu$(q_v~zeI;8Q9s)@o_(4$(`SqKriKakZ<%g5Ev$cKa=nmJ_aoz& zs5?o^J9cW8-QK)i@nf%#+2gG%mv1QkKDMIkeqB-{Nve>$l z)hT_aZmL@Uxx~Nd`76z|l_75p-REB}*xb6vLq)e^nxkjB%uzq@w<#@h z%Fz|YiK~hp9k&tVsovwM`{KO$j*UF6p}SwLd9!EhnwrBcRiBO;NvbEU4vk(E763{T zpC&(uoHGC6q({@NUH|xPS*bZS-}%)0X1(p#*3M%FCyJF-U6InV7w=x+o6@)b^E1C~FByY`66zF`S8~3svO8gh_9{bfsn1t}u|l=Tx0id9+q@SLUgdRKr() zN@ve)IL2o?geFv}ZtPR_8E{_NGubCX^= zx2DB;h`jp2?5=fHcty=EH)UPkAmyL(=duExE&nVv=lZ(2d&+dxs?MCqSXp%_@yyl7 zTOOOuU(@X$_~u8ijozt@*x9`WtG~XfDUp+1(RSuh(6zu=DgyRqKm$ zs=6YzcKWVe7ZB1tz0I{`k&&KvMBeOR|CuRu1qn0P=(sJM*VAFXB31JA73FKE(m`JQ z;$!fmV{upEXR9&%6QUnsEA3df9?Y6I$&d4b_lX3Rd&zJXBurm~d zetojp%*{D2^=F`1a8%~E;;(1icCL(#ORf4d(VcT^kgd>r3(u#U8$)sfzo)Bcf3{vf zFKLl`t990sb5eIIc2DI{sPeu2fPIB@&AysArn^&IW#9K_ZjE1&{^kRt;A9t#m1>7J zRes&_J825T+ijm6g`U2d#Qo~w*EOaBtOhxOEQtZGK1YMrPFL00es<+@A0?>+J0u>z z(&;XKCE2;+kmv5Jsl0iyyE6)Q$JnNBs@btHEnV5(AWePV>g9h_D#V_q?^v?qso%wx z)VUQ!Kh0k3@%7uh-^q4=Ovw5FpCik=jeqD^ZcHsdx;_uI7#8U3sbGg@g3jmF~vBA5APj%uWoTR#9{4N5<8so*KPM zJifFqoGmJG`Q`<3$MZKz=q`vA>TwUPF1x_`Rb+EW(bp?#e7>>T`n}h#tvutjW>L%2 zZ9%r5JuBSzrK{|^J73j$x!kJIsYf#VqbGNyW!cQWziGzTA|-Q`{5adKDVGc1h@K$O6=U1BQRaaK$9DkGJ z9<8^_H_FL&*3B8Vm*(a3weL0bZQB}TTX^|aET=Cpg7tx0Yz zG(fsyl&+eez8qk3IsEBnA+g(DU(cuuK7Gq$Ter`3)8|*7x|g^Ay#0*7QYPqJeq>CL zl&N~|a?9J9IsR4NSAx|}zudsE>b3f2VSTq9qVrkKFZ#nXU3B{m&7jxMCj89)W@fR^ zyyWou!1F)Fws$AAKTbg?IS$<@HA8t&}_Ldt{c&Yoo6&Ycl$@&t=HmD2q+^ z4-L=0xGOuGcWL(Rzbvm9ADml}-neM>3ZXtd-($rq=copr`>#9eniTiX*fn{dI_0#v z+b6y~-6z>rBfrzCKC8+ye#s%NjHfYYjm4sOGtcT1CaOPX-?l>1Lc_0)2BpCy*}lQmdjb~ zy}aT39KQuk<2QQn>fzo<-8w-7-K)YoOK+AfzQJd_Y~Gf4QF#hyRCl}SuDKXBM`PM- z^Bt1w)?8ord^hh`h7Yx?+r17h54zH``kCaHuso@o+aI2t5c{=QZOQL5Dd7s&)_pOn znO5~;`4#8zRm~^WZyDN5;Eu1&& z>8>bVQ1guO{@d>vTdV4J-m%%gCahoiSJ5HMuPtj^)_SsUd%J6$&4bB&Pjj=n=DBT~ zU2->Uaoh^^&_f5-I@^NU>T;{v{q&8`Pgxh{|Ki%`k2y}Z$mXS4Up%||;{p4@7({gBU-u!`o{t!(BD3*-vyuWr6&d)Z$`ai)B{_~&bz zFCJ3Zdn(64S@va3Nc_?piVq+Ey7Xn1pA6WN?QyoNe^uA*y!3EObg})drLTT6+N&_w zg{J;t_}U;Ha{khR=MT=!vj7iIziX<>DDtyof4sZ;(dsL~2g{inu7)g-D|q}W@lR1e zOngdN8jY7yHtAi-CsV*L59FfW*Ay0ZPa?NqM3E}jEM zT2p_{0IS?}a{|o`=x2|Mo_z>w}i!lK1 z0E!(HQP4m*LX-hChIwt3T#N+=gPta9!1>-)>{q!N=4;BYV81h?YD$>*&%Ue8l6M$> zyotQCK&~M9Rc7ewweQ1iV{CQ=%P?q5m`m-*WNN6owpK1ru11|9!k2k_7jwXQ(-rK7 z{0!5N*@DeqEmt?+0yIm|^KBe*}Kr5x4yCBH5Em7p*@&HRI-WW4=3m(JR{5rXErhcAM)Kwff%V z>b@IOR(bATx>d(Zd3W;kR})==BwsN;Fk9))^niOu8{75^&rj}A$=)Q+)?Jn2rCoVN zdADZiv#ZXv+x8hPTAZeE{A*Uk4sSUVE8Ce*r)*4E9^ilM_J=7fuNWBu`FEHHo{#zR zxigXNuT_1>Vwc_shRaL)ZZFsyW1ABkboJTQ#a}hvUs+gYol|m0sXgv?qIQW^>5WZM zE7UWOndEA1;ROx$GOTzm<0EKuXJf{l9P_n$zHC|530z-OR^5L0`{taglHHddK3>n< z&uZ;9(b+BQN`m9L6?YR)&P|%ZczWGorWNbzYn7ohK;^-<#UkPvW^PZrTGm=#_cQm> zJFPJD{=RdXn-|J4ERg$9yXv_Z%G?cjY7ssg)bM-7y!SuZZvIeYWcb<;y>i}r))njw zpu8Et56%UksmUwM;CV;5D0q_c!1nNdCFyO~FE)wYGXzgk-sz}PnJU5~vL_v!wRV(! z?RoWt$Mo22Hjws)*J1rfrzX#CtyYt~XA0I3v%V@tPeyy9*Y^@B?_#NTNvX#lY@0x{ zq1P75-A&)M(&+A)JIOkyHM02HCs#c_?Ik!#tNv0&KxpZ)EpbQHnZG*NGTcf2TEhML z%+7SrlF2hKRm@p=S6{m|(A0U|yex@pO7U$~V7q^>m5aV{Y}v<~0nMt)yo)&Rn|7}_ zn6zlc+6xDxbJAnNkmn>UE%Q=?01AH_ty_zQR+v zG-k!}hpeC=|H@FX{;Ke#nN@F=T0Rz~hO90)bI!r`|Xn z`egap{gBzL`C`ALY;S!~T{bUmZ{E*kd|$z{#{v9;w`RK9-MX~qSmgQg<5x;WLN~2E zx@Ylew{{J`+3v0?b8M@d4>~CC3QJq;|EuqDRE+H`vlrJju0X;n`>P0V9(Qk^x6~b_ zPWxjji*0>3Y1JLRyz()>Os9t9!Z|lLXB7mkm6?3u^DQ1R;it8>BCi@j@$qhF)tl~D zkw#|@Y;eu-K9Y@vz{uvU3OT$@;yJqMhDv% zt=5WXY!UjhF?ZKrxai8x6>y$yXjlhm?eS8nyRsLuO#Tv_bXlvka;6X#z9 zSqMsl>i!SU?{uG${!?}7+|I09H5*E5Ez%D9b_X5*ViUPF^Q`IBju)GsugU!tW)MU6?Z|U=EAKqv!c5@RJ6YV{nzRfZ7!Q6I`j{;I_vVH~h zW!IhjvXIw4AnRMgHy%(@VF;1DUVFJ^&8ls^7jGJaC*}7=^VR)&$=@@-&gzHN*9T#R z;N<;7Mrh&ON%JSI58}_8zzfpa;O}lzZ*lzKk8E&l`IX@VXWg&EtaVM03E6_h&mten zK{L_yw0Te8LFZLBu<`xd(4_j;Hh_PJ=GPL_!m}TDtgdxeezQ=Hfoqce8kNSX1KWfB zZ6EnZ{=K(K{Y*hF(~r8JnOm#sepz2(-Z!%B$gcqLna zXTNm0f0%pvim-{VWW0TWbi|vNm77<9dhIpVUtQLSO>LU6(!J}ZT~w=-QGM8oGfPyy zW?CdL26}rRFZ~uJxn%qQBlgj@j&?s2U8=G}{deal&MGg^j>yTc{`}>WV;=XbpNy{< z<5$g-w{y15-0Rrev$|btV@|=>EfF>c+T~wNiZPGaaQIU1mXPZ*Zh!fF=6$^R>SNdM zgX})rJomr7Em-~VnA_#YyXNX%So3PP%^mNaa~Gzrcrt03^`ggh$1hi$j?So@cX9Sg zb!F4aL;PtHMyDtHZ^$_97QD4&UUOENOpWbKPH^#-@6<;*yC$0;oMukB~uy!yY_&CmaQ{Oa7i&#zWK;AIJ4{%Pi`&gxA*JF9l3Hb<|U7jpUM38q=R zH}1R5oM!eTTk3w}#De*&=T*Gh_G#mV2}{jZy!^!a%^-Tkr`xJlhrN6vLZ+B(-E(lQ ztI;<*)8AJlHgOa#nfA)lMon||+3!y^CzVZI-M%+har5-En=didSReFV{rvyGuj}jQ z3Vi$U`uVEm6P4aD#tVH}(tAG0KRJNE_^Zbj!3?jJaf>ucPIU z;_0nNt)~dR>fC;I(@Mja+k|S&51w7^ZnDGn|KX+1cf@wJ-}G1GnQC~?xj^)omxP{l z>IN6vD~VqhNu(L9xc)fr{hEWh0p>}%i>m4`HaYICXTNoO-Gv8XUv`~fyjn5C z$yw}r$Hh!1+oMhqcjg?qc&EsJot$p`>%h>8RI@V&l$K@sc}&;MT-s$*sId6t@2V3Y z^mwi^++SREuD9U#;rsfb(B^6Z>!Yw8CNFlDD9v?A{QrENhvdfn@3kMREJ>E)`w?${ z@@~fOzcF8XYPI7tqOSz}baH#t{Yp~M@@dE}*?DTb#a|_4H<~TYEu4P8Xhvfa-;V;G z+uj*==X}+aUv(;$FfZJ`#(qnnYSZkW!e8zfG;8-12=BG+lDo#RgK6P9o!2jaPO`i+ zX_v{R-{qMh*V6k7UQZ6YcjlRa?aXQBt0$W}U3ZH^^UT%fce+apIlZ!}xwu-`$YfILtA&mJHFd21XH{Kdd~eAM zwYHfl=Kk}_5=wfWEReBQW<#ub@M$TZj`O!~*)%T=ow>Q>o6jAAQl%XW?;n!ad-#5S zNdE+WhVTdP>)WgB(tlkjTpPw#((B!`K>Y9}w}*c^=0{F@c}delw_B@nUYx^MrL{sy zyMhXm|2!A>m*+YV)mW9scUo(@P0UH=eS*_jzzz2Wat!PCZ%^O1{P}wk&?=eo6>_y@ zE+(5A^S@>Pcv(FAHmEaEBMxeC{*kJS%7c~p<}c?heFiJ@*WEvS@Mzt<{lTyb;YV}C zoPg&Fk#Oa&f4ly9Uhh{g^y}x#tCIynU6q#iD4PT;!e%2e8tZ`Bf^bs~EkTKphT-9eQ6) zrp;*IxttNA-1k*x==4iaIoVf%oeAHf_`++uc_E$f1ld5Aim z{+?U?GoM_$mA2V0^FrWjQOI1#g$-6;ZUiR;Y0eZiP1MRO5@KrTxzsl@r*aGQ+{*KnE~!LYDhkU+uj7*XE4Pik|nYu5eq_mU;P#QLXhnPPM#Wa@=hd%+X7JEt@*;KGWAbsb52;2$+8S z%N+ivA>aB;f+cV2$3rHyHj|^0uZpdB-nUA9?Lwt}^;bkzu&)WV4VQ_jRd1+Tw|TGc z`2fND&R>^EWH4M?CFdj0wLtEJ<|dK3whwk)3107P`{44c%!Nw(`d>Mw^Y4)RDxtY_ zB_n8=Tucc6G0BG4f&F2E%zP%GyvOj0(R_)VWxb}eEdwa`>`41M#r%Yx-u8(F%{kz# z60^B#MM`W)ziJ><{q?1Cw=xPZ{c+WbGtmHLHHNPZuY=EjX9umj1E~S!K~Nz8%CL-( zj0zG4w;LhqL9Ka6Ck(8H;nmLOS1Uoj1aWuzzw+c%T=sg+xpQ(;yuIv~{C&2oJ9|b; zi0G`Z>Df&`v^V#7ygjsQ=b!2C7lG6>2AuC*dHjUR;Wul~=*pvBxhn0y)D`3D_7IzEvcG=lSZ6Q`st zQJXz6=iB}em~Efq+Fu@D{MGM{`o|Niy|;P4-Y4?|6xa+`iVwe<=&{VO*P_m2*FvG7 zsjV!V?kF%{yzcyJ%|0{Xdk>CXS!^V3F}dww@5+UBwT0QGQ)g_-5a`Y}k+IryaBT?x zL{ZznL0_NT6ip8?*&+JsV#rFtKABP<=Sh`sTEGKW46k-3em&t*e)i!76|UdE_X~%5 z9NBK#F=utV?NOKWS1&)fJwvR^>rb|1s7CJAzb&g5hK5>CuKa3ZGWo{M>8qBX@SAhd z@@tEkq3KbD!w)B%_|tOXIx{H2+}TpK$~Q{3$F1w$g~`)W`+T+;b+x4KsA7sU@9$c1 zoWEkqk~N;T+s;-ebR4>3@NE~@*~Rl_v}|$B>N1*S^-g@%@)PSU7CYJ2w8WiX{L-Vm z&27Di9TcBC~mf;>`acbzuPoxuD`}#OD;`(8#MO>=jvTs z|6HAQ<+5_0&@ErNa?Ld&LYHHf&nx&|>bcgO=j8+ME5a^;S59r#KG*ToUQD-pYuD?* z+iOj%+}u=N%~*LgY>F8qk=^-IYRj9OWM&+t{?A~+!t7toAAM}6<*$;I-M!@amBqJ( zH^)X#uR2yb`NP5VgksRzhhMtibQuTz46wSjV%EH8 z7sD=_#Li_~_VTnzj{g}(s5LXHo~>xH(UWL>q__6voxM?=cQ}qZZS?cJ9(m78S3jy% z)@11)56?qJam(Eh1vG-h- z_G(#Y&{zhj0#4w4H8J?yo6-%xn5OCcy>~^qakcPCMy;e3><#Nf`~^>)u=To}w|0GI zteT|r>&;cWrhna1bu6xIt>ck3SA?Q@{)rqZ)%D1Dlre3g@+(KM*VoB>?OAb1=E{4+ ztzV+HEc0AwoN=KlcGXvtSs6tV(USQEt0RjfHXe<5eLZQLd&v6MT4vA?#uerRQ-4=6 zoyrl)T)gMt+Vj$PcNwm=p7Ls%QPR4H=CaAJUT$u=VwjPmsk8F1*m09ysApqbZ6_Xj zQ0)F~ZP>-@i@!E2B-~qhe2SUQT(&TKucHRcz2_I+xs(y}oQo@C1@D|39?-bVE5--h zzp7?L>g){h_fI=w{Pn__mC+jm__qhAoxS2Lx-wmo6H;0>=m+?RoL^%Q-Y?-gw{>Zi zh}^3$Jo|QOcTX|?x+Nl4E=m%rZZ)5=$I5dokFE$yvG8i~mPln~uADa|SL%CJjO`?` zO}ZC-Y#sL>ys{V+pAA(EJ6;(uuTEr{5@s@Un@M+Hs`u*6Czj_FOg1_D>Q#(wO}A=) z`l~=5@5_1j*XBU{`M_*-x-0MIiuF%aWY11Jf7i8giW+GA1F|std0(;XSC5^3(TmP& zovARNt`MfD61v1;Uz?|F)brh^r^)>4(l9Obf8*x+#6)cS1G&!^drs~YDS60tr_%Az z&Qk8|ma3GHBjBWVeO0RDN~-72P{-p%1PQ{2`6 z?UI??c>SA_SL*(^(q~e#Zg18KF$xXs?NW)|)~V|r=U$rj+toKtX7|mUw9nax%8qBh zZmpWLe~}V+MEBZKxvjfa%sV#Y8{212=gHS^e^iMnu9Q7J_wr2LZs+>gzPDVxZJkNS zLcT9?nVNa{?Z?EfVlm&9CLvDi-Lm5@&eMuk6Yo8EuRX7{uJ>5knrp39PhS0R1&y36 zn74JMdd8`pRXwZjr%hV9jpuxR@bb)UpGCgbwB@TWUfj6qn)_?5_0p_n)vInEUUs-i zf9pBEyQ%-Y?@VCx-CFnc-4?6vYi=q%RymakEpp(p3d zO#U+NKTuKE8z}s{eQww!S2j=*VEDSm*VgaNODEejlddy8Wl4LpTQxIP`?P|#r0WKU zh4Sa-`W`*IN5#}R>SL8x&as8kFWy|(v(Wq1g#*07tN*#)JoPFoBh=Fr0%{gv%dL9>f4p~S5~Y`^)%`Nr3!`>>9wyOCh~^!=ch`S zRJMEPJGiIm%Rcwb*)xAh{;XvSh3j;6BQG~F%Qb}XYHhE~j#HDmV^w(ge8ygP>q(2Q zwDsy|7JpWi`jBQUc;H2u>BGr^OWxY8O^pm&wfvR0XG$Aa^wepKPR^S4>}2<=!Y#`} zzCZ{1&Rbnwydv=Cb>WECs*If3vdc3jJzjh=c&+qjF`cY+=~C@&?^mx{-`8!n&dGMm zJ^9s&bAQM^el^#->T2rJ;x~J~cb$q`pRsjvY*emU?5eMo-t&_)ADvm8HhH_*vqc+k z{ye_)9oN?Ysg=()?|jX%^BAKskhHF@uaP9{*v;9#2_+#iz2@ipLd%BzprCMjR_!~5Ng~`!rDbBO{AoB+O%)`k&HSK9> z-rtX|)OPOFdYkkk?o5)|@$4;sCTu%X;AlH-=>-Sb^J_D&yC*O9ovP3RNw{BEv=?MK z+3q@jCE0X#ojt#;&3vi4W)_m!-gxOikP4}y1 z^V@EB%XR@3{|pP}ZC#Nb8GiClscG+qqHQrgj1KOLvo(HfD&+26Z#`k&nyRTUwE3-e zZSXtko|>#A3+miFzjcLq8hFSSRJ(u+d~mX80Ck-}$r7ms0@W`8{3taLNCViI*H;lW z4Z{ldK>kH?;1(^UE&y#4xs(6Zrf$oD-N)zeer!GMS3>Hv<)9)8G<>_}!PUdXd+t>2 z|7&UeZu6GYwqNJuR>G>h^UqhcZ?5J7#V2Tlc%F3V`NPxIL8%GkyjMH@zW({K?ZM-Z z53?W6`+FQA?)Ek3%-S23zbCD)`oB{4{`+_D-s#-^)Rg-Z+|6sOS}^Z?==qYWUp?!q zTM93O{Ix)C#q(uXl%vkb?Q04JwUHcbLCxLts*?3p*)YCtz+uZlh9zQcX-)mR#CoOnQ{kMdCtG{#K zZe#z-uwwa=kJJCJ`0)Hoetqx)xdQ$xpBvU%Yq87P%-sLr`OU@M&8xTHxOA}OafHf` z4F)@Ybv)nv@j=f2$3IWJ+&(>BT)H$OlB|BvJLZ6#;UeBQoaHGu!e zzpICHKQGD9ydAUWM#-~z#jkGOtlHsZ%YOXx@BDLpr61}PA3p~L&@+#^f6DIHcUJ!U z=IWc5Sdq4-aE2ym$Ia@in-98&*Pjt@4djcTyQg~l-)8|k9w)4<^6HNXIWH~uW{+)U z`KK_RTl2Q=EWBz{^Y_WyZ{6m{b^cWTWC4w9B%S%J{%ybNmC5UJrYbKvKF{P)iRav) z&KaU!)-H=W9|}MEeyq|cQne*Qd)2Q73GeH>bL20*>9gB7-Cbk_`>V+2D!X}_kHYs= zY!X;*6SZt!uHI5}^`rv_7FER={}%Z?ao(pX?ybAzKJMw`x;`iG+!5BV3@h3%otpnY z;*)&+?lnhyS03kStx~$Q@QT72E341`M^(2amYi@{(&cGfU~(yLp8IO`wE_ND4RRjU zCFz4K?5>*Eb#8i%!@+kobBt^s?5o`6W9uWkc_**f)x+D){wn|WBcr+ea^$)8&4Jwg z{0rq6zRuaYZSKtF9o3hvzM6T%$@Wysk}bKLB3#tW-U@X~uemH@{ms*Kp{GDd#^T!{ zrmbmt_XBySANR~t*v;78eJAmFqUYRg@n^lhZV)}$(h|EpH1|?SaH#L{#?#ln-I?)z zYRT2UGglW!$1Oi!R{RO}Ggs)oeow80YtxH37)_bG3Uv6+$>V^7rMD_ou*r`=` zTc@wnvwgw=6YUa*MGh}ct>?RGXM1T&r~JH?%iTJXHeZQb>=`qAg>q+SubDd6{ndUp zr{@c}2C9cn-TUry&O*5r&yBAZM-+vW{gQunHmTa(-QEA3>CwGWtLE)I-EeMY`s+I@ z-o~dlznC{i{uZd*a5va|?)>H*>05$qS3X}JV_SP^YG?4=o?A;?ZH4qp&dg{L&|f5U zQDbYzk(evtLftMQvSvG6LMCnO-DZ?ymbTYIFEe|Z|Eeo$XV*OXV3Fle)oCA?5C7x#n|4~zG`f*d_KQsR?fyRMTRo7 z{I-K)FDAhM$8-Dtb9Sr8uAFy7Q7YWu=T_;YuN>S7$F>|^b12}F+dRLCTNMot%VkD~ z&6Y3>{P}?S(%BgSGh9mU1*#lUzPc$#?)sF&JRNI|zgpa}5)^%PsbY@EhrLls3y&XG zy1gkx>Fds$pyKEBmCtXkKP}%^SN^A9Y8Bsd?W@H_ezr+3?mTXP{(k2NiC2sP{wL#$ zKK}XHZ?7Km-!i{AdhNWz*(+?`7^ttZf99Jh)}OO0=XHjM%YNSr{F+y1A2HlfrE|Ko z)#Q@r$p z&i?|6war&QR~_4Y`0n=e`hGJue}4G#_T5FMc`K{r)`XpJPkr_CK>sd{9oIo+gV^2A z^7TKtmv%<{i;Q0@ckkKJ$CI=YwO05XDRTMK(^q{&-1+e;Cr-18sdCd=0%xpl-@e3G zL~r7;l!%3dT~*?O9> zSI%8#Z~ts~G3e`_$hGq>r@pd$sC-|nznJ4I!;18<#ZUGL{#DbA|KnZMSry@O==Hyb z53}y8s)+0|c&n!QL{T{D>*^!d-B)E=ob_Beui*Z6(!TJiA*r)hE_c1MAieBZ0RNTEYF};6>9d^8kNx%Suhv(a{fnyVZ0#L2 zL90f%3;oy0?fW91Ts5=GDY!-U&my^7s=gZ?V}hb~G+X_d6f~XHICA!cG8gWzFIqS8 zSV{SKEVo~#`Ppl;|MV5@UT0FWrgX2F_I|1H`ApeG0XLJEtquegH2qb6-#_1*ug+h0 z-_CZ%zSyPn#KS|*U)~w{h-;psEyF8I@$Y};^c=5ws2?Aq+xjr3Y;$MHlu%|dF2NY3 zmM@Q%ZP_y?B>%yrpcUz{uTG{H{Qj}x&D6-1^UA|R&hKtdI(PA>bK(rfhAOeg^XAX2 z{`cqk{QsY(@9%kE!O96LLxTAC_odh8-T89sit@3|x_9if zdKgyu+j9DpxKP_gm2av#SZRk^|p+5#%Q{`@lTxshqMuPTe) zB`Fw2gZl3CDutfSoB#h4_Z8-M)2qIni~aHQ;lo>3HvcWSn6*EV&z#|_PG|MII(tw9 zAtuz;x;ywuPKP6V{b=|jy$=*2 zAl>O}KWxlBKX01z-EHT5U$TMBs}4WU530RCzv=9*GP^&|=2l&`4qL%{s9zXf?Y!2= zHk;d6)#lF*Mv#WOmCKpR9c<0dJ?=k$?nv>EcYX6%LAL3K_$#~KVE$UeZ8mRT{idJ4 zUi^5x{x&;!!r{B8ZOt4<39aN8%pk`#ROR{D>b&8M-pI1AO{41xgQy{B*#C3otB2s3 zrvu>=w+6jFpSpCT*+=Qyip-g!^0dAWze)qApdGT|*z2WyiH8ZQ`q?s&Ayw7dFbY6v`>xCzm0$;xgESR|i8Zq@Vqb_?fS=sB`EEjUx5{EuVvr4zE-RF}fUz}a<@#B3GnUO;u=tvG)$N>X3&Ha}58_rnpa1WpfBmoR^}n}2od54j z|Nnhawii|A|BC#!5;Emr^KvWC=4F%pRJNK%&HiH4E_t*xWBJQ1I-ze2zNO4El}d1MA8t{6JEi7NBira$1MhD{-^zUfAtmTl|`1l8k=Try0Oe} zwN1oDrMcx#EM%q1Z+hDcy?XgcLH)hhrdL~zU$UyT@JyS8+0V=H+ zzx&zx*i8QaQ~hAp*Ar=ie`h4mEWa-y6}ouQ`gTjTq%HANM+$?vK z6O&(q*4zsV;GTg|6#@R{r_s0R&7d(X}GwsNIm>~fR%LGfh&_M z!vxHWzq+KqS}9n&VneTD;EKomGAlzs6BpdCe!jc9dE@p%?d+?~%rjVDG2Scmw zEQ1qI;=}q2vb#4jDC^Hyx%{rS)SaTQ9UCv-WBnSi_4Oy-KNI^4S5JK<$vM+f^UCMB ztDoP!_WE!8d-?czFU~e^{vvRmqH;PmakHrRN# zvS|8-(oZ|{S@iE84XS6&KFjlp@xH>Vhp&Equb(x+`--yfFU_?(&z|zJZItR$t~Uwp zH!x@=+h>0VcQMcIM7F3<&pF>_n9XIo^7-$o=PAY2$yLAViXRteUu4f0 zH~)Bj{?d8N{l((!>MDLJmdDM1#ywl#&fQk$YWS-5>F-POd&45K(*pQ^n1Mske)ja0 z?Z+NX3Ti!fvKGn?+zZav@KkviY-M`)aPo?%%)c&aX ze)F33w6p!Qqxa8UnO^<+soLo$cPCGuz27%J*Y37Z>Bq-+)7|Cy<8o~8RGpgky?>^0 zUG>+r&mVjPRi=HPEPmNN$y)otwbO_Dt@*capC@ZSZ`w=OEviMSzvc4kYy?(DoLqjn zdF^rOXr1oIi|*a8(mR)s-+l7+gU*P^c~>TVvaL6+{Zd%nJ+(i#w&=@)pR0cw`QEpw z-KFaH`{%>cx@8-B`)9k$&vcB>-Di{1bmx}!z4WCz#S!yvu2FHFxBvgC?k`EZc7OlI zd4)MI_KNer*ZWT_eHCdm(Qi|MVWyB;$(*=VZC&U7^{44ebE#eWdGG4yhdSSWe0`Df z{@}lJUkX0Iyf^vm_xJPcZRY0LR&V`&`?YwCiu||v@BUWo`1s<--?E)LTB-kjeR%P+ z{rl`Q&b#Hena`j8%Ch$F>wA~mm$U!Q_w%2(H`zL;`$lSc`TM&MS06twKW|Q6&c2(~ z`}UjH{(fV7+mL_xy}kcx-(R2JFK3^6yR!ZKw~MpOt@*dd+1#o!(7pWmYvsB#HvM)o z`^8tfeAxQ&!^dNX7fu`FXQt$NlB@TGSZS?%Kci`(wfGv-3KFrdh5zu|~sl=JVt7 zH+QM~FQ2{p`1yr$1-BQ?`){Z|`DFe7`Wbd2Yr<{S&!^4(_1i|^MwO{;O8p%B+LKu~ z7Q0_w`+d*lr!%fE+P(kz+3-D$Yh&h_?%4Q$Ie+=LZ#Uy^w=b=_S2$f}?~Te6kD4d% zjcmRx#+`4M)6KU1eqZG``Q`cMkqI9j%`CX7w|+srP1^19XHs_}Dn5KEm^RPdxpE!* zZ=D;rDt|_p>^OVn@aqril?RNhn`5WFzTFz?ed>7b$4Ro^5B6V<-B+r;-8E7zFYTOJ z{lC)m_om!O>N;H^D`)l>JK1^P_=bU(MT>rd}Q6*Vn2%J}omy4wzaeE3CoeH*`AS3%n3?F{>F*e{pc z_P_gVWL06z#Mdtmv*%p>_ia&?U$@k}>)($`&M}&q_fB_BRFGXB_dHwe3xfK``&}0V zO?i3ncT&fZYyX-j_rAQmcGJyIPu?nq`^TL!Y8Ra;s;c>U&dTSSSD5pnuQ;py|7zd! zU;GtgcG&sMxcmO*^WS$aGY?DDU-8_<#QbAa$^XC7$F>Fd?zFK#({T0YdGnvI%$HVu z>np3TK0fusySEQdzulb3wtT;weU0{&&;L06|7Q!H*i(00{(EKoxy93;U)ijz_0_2M z9@nwryVXCYt^c)Qg`C~3w^u*jG+-`cyR5D*zik=!>S>=YNQ=U|$ny>#BX>-r>Ex zfuG<1+p%Ka_C@}4uP^d~@6zm*Rj0l@O_Y<#?{C{QdfKL)S$G?X!%|`CE6*Eo|CLM?;aMe*TpfHCy+dcRI$uTPeYEZ;0(@aA^OT zIQ=unE5_}#dYLIVv zxw+ZB;;%WjX&+tc{svaEU7q{*@S{ufi>^-kboS<>pBLME@6WT1&zFs&{QNim`JeQ@UEln4&*{IVE9bqucWv|E@77DJ>}1}) z-(UMb=kd>f7ynH@zGhp!M$U(a1^+v)Z$7@hetw?(+kB(Yy?1TvzJ1zZaQOZ2-{&pO^XQ2=6F-m2%D<}H}~($}Dy{hE{AnFoI=x+X8~)t-B0eRQ?7|NOb@mV11j zd3GwxW=YU#JdIU)pFUpfUGecFqhG#&ll=J!~A3rK{ zt=p!m{-)p2xlTvd6vQ8S`7OzfRob8bljP-Tg^B-~imkcJrujA%^p(q>TU)XF|AUvU zzoX=BY-}rb(@6T(?89BSNkyV^sKt{LO+H&{_9?T=x5dfT&9S>NZ|T3kKWCpkd%x(bjeX6|ss7=c zH-3F_@}J@7Gv}HYrypN_ng96ZTCX`{d)2E+cm-YAyvOmUTl8;^Y5Dbwv{_I zy$W`m+@4c&$L7}#!`jbZUS7+r`w~9;{I-^@5pJ7#mR%N)=HEUqFW>gQ$oiX#<=rcq zWy?NWhWpQZe6XK;sYd_i@;^D*y94;6@6{I={C#_M_SwVc#p(xc+_kS#DypBf`n90_ zt8Vsm*2=9vKYeKJsM;ns-+ua{3E+0n+5NM@KA%^;c3$t|e))NJ)-(TAm2CQ+P@i5^ z@#D|o-@f0z3uMm@^*H&XWCVK%6R|7Hvg4X?atp11otmKfZRUVp)d7-@7w)3 z^K7b*XT5fpk9hR*<79VzzMpgJ`ReQE$k)Cva@?Y7HcmLDh*Ug!=L-<(#VwWeJj)IRJniLi%a(PU=k-1+>f@_h+ zygxIZ9XNP#ThQ~oC(DXI&*}GTRQ>c+8XCwx%YXc$EKS(O~;>HJ^xPq zrqlb9&!JbQKl{DiJp9({FI%?fKD+haja&Hj?7MHdtM@znnREH|-HVt0oIdn-Cd;)) z0TtH_c(V6QSorUq)A5wr_S+BdFa4+V`Q|$2|Fd2QR$VCG^s>@S>VHM#tN!o)rFXmC z#2;ec&4SD$1YIaFn`Yto!X1xt>g%>G-uwr$_O+ZS?$j zkL}T?#J<%vTG@84oBEIWi%FbEU25VM$MXyCr}oc-#l@kQFMatJwg1oazn}A3T|ReC zZE@{~z!!B@<&)<Yre~$HS7`sPdt76IVPP=+WO9{?Dvb83y7t1B60I9U6-R5m0#|(-Z`_aRbI-(RepHmkY+Vphlte+A90$!~Vtsb>XLKR*PES+|{^jefJORr1YD4r&|{KDr))Mv+bI9GCeTOcDDaZ z%P+f4;+{OL_x-|Q`@-_(mzMIY|0>o@ik$zlzdu7}k@~B7Z}Q)FESEU*<$Igq(Zw@g z&X{%V*6;Eix#zd|Zt~JAZ%8WNQ|lyjTBuG56lf!p4`6?u}QNYi}s;s{i}9y4=*hMbFffiM=kD*n{qwh9(D`%Q>tDY7`QZ1j*6rf|g!$He z`x@)YUsYn`+;1mnTmSpf?)^Mh_`m*neE7?kyOJ|rOUC8it1Ev!|Lp6z4;P+(?l1py z$L-?H*2Vl6n&lR{zgT(s^Y;CJYwPQO-)?{LGyVD7)w@?8PCm=J+V=go7d!Xv`t|ML zxmSYyyG<``uU@zHIcwDgzHS5yY{2q_G_zm=eJLPer|rX;XUIr z?E^*zVr{3$Io<2yYJNYJ{j$LQ#l@47UwLY_|G8VvoM~_T>gHaH4^LkgKm4@(+~@25<@cg$ zFI>J=Uc2Dy+oey7HEr{&?_GQUd!?~K=`Lfl^zUEK&5b^p@#5E=wcDq=-&@NUV^ja@ z)6|5U=UU6>PQPatQMdbcW$F(xkUw5Lk$L^{=jr=w`|f$#U-?{oyz1UvxtEeVE^Yt) z?9c4GceUfytnb9>?7#W<Sq}@|l0(u(h)MQnUYa|9-wd$`>|o{`_`({r`9J z_Qr>E%fDXxap%=L|Ml`QH$7ikTHBTH`+E0X-t)PipX=LO?7qEYeg1Oo|nJ>r}w4p%<+FDzSqky zdR}$t@a~=L>Bo=d?YEeJX>;}0qgUR%$-3Nktaf*K)cXGA-Eu1T`wFVd%HN$@8X)m? zPH(%_^!4XrZ|p5nkNa{p?>RRlIu<_f-v3AW-TM2rAOHUU_qRR&|NGzkW?d!XDJ15@ut&;lw_TDZb7tdY7@6&JR&i(z;Z_l}x+gICuEL> zPww8`y(M;bE+tjlKburtD2_SBGxbq^hI9Xy)qP*z{P}SBz<2BVzaQ)WfBbqqzW)2s ze)$E@@1B^-z5D+j(+}Ump5J_M;i-fFefwzZ@bdG0cW$}+SKWU%d*{SoKCjuC6FoLt zmD$Zqt*w3M-@<24)BXo6Og0hr<$tENIQQu8 zn^S+}*aYT>=VcaHol0ld-nq`~i-)|k|M~Cn$NzpfD$dL}FTd``hZWD0qjKj~KY#6f zvDilIYx(iz99s9}d6nn9>-72VW7l=dYSFRO{Gz_gQxDZh+%-IZ|~f>4(Gnd*MB~H-@ana^Tof4{(RA^x=?JhD(!N9UtYI= z(u9*@yOQ0-ZY?^NTK)dpw{IE81FqlOIM2aC1acjq$_~rz%Z;v)Z};%f~NY-rl_Y`R@PP-}TlX!=Em2SMQv+qTFgS=ev;S?Th|As4AH; zZy~5E)=yKDpZe*tKC|uBpasiKcExIyZkaCiCB>@f#l$*A+xl&P*7wZ&pK#-{_2v7~ z9gE(5`#1CJpXx6z{c6A551&XcE=ek~wlKE+Z#3^=nCzSxFSJ~Et3KUKe=+fb@|Qo4 zjAmLnE#-eu^5kx>`%jOREucbNunL_2UpV%IOJ@kZ!2N|_Rf`-b2SeqZ`u|V82r9l| z3hLvkKDmZ0aDU;*U-hqBx3{lv+xkC?LcQJV9!7nAVZ3i`x%%t-^FQj5{rB?Efr-EGJ<0g6!ocEYSl6Q6i~r^>ee|Lx{8L+f!BvOzWvV^%Zavx^W_3ud zebJ?aOvUMI>g%hkl6L)bT_ihMI5AnaeD|;G#(|}OFQ$Z-Z~F6Y@sBI^OEWS`Ht7nB z9%}n^xijt~o0)Z++v0T}q^i0D^Geb-%-Y8TYRO#OxHNr>;k}*a5o^kLUB9ar|GZay z@!65he-^*gxIFK4PQLrjZ%&23;xaeykE*J_>Tv$<*9WKWrf^)5OZ|0y@!6Ldd#xk? z*VS(dIusOccz9=cL zK0mB0P7E;));jWB|E)*) zao#+)+`EC%5)DtE8&`i(kv?%$-E8e;<0}2&Rm=2~ub40|WVf|i_oXCs(oVLiL1vSA z>>ni?YoA?seDTj6j}r3!FP!eY`q=TRYuc^%N~*b?zlT?K@4c#K`_k*=VewtN+?Z`Y z8vBKDf3$r1ZrS%cu^PS879IT3clb-oY~Cua%f^>W8LKZUe_7yueCoWnZ&R#pZC&y8GAMNM9zhSR{4PnZKPupNzsTK&?6CB9Z-sNiA14 zF!S$4#i~_rfBx9}|7M9p@(R!M2SbyqycRcqP1b)HC9$GJ#`Szj#3ehCwfxf-?QRZK zye*sRrv3FKU!s99Z)>iNbk8c`nJ+FXR^6Ju$ZK2FEDg7rGkuH>=c@LDdKgyAzPRlC z_HEs_7@L(jB_+1S9rIq~RbNj~)Y`hW|CsPyHucGwjO^jQYT^0o&6l59>pt_Rmy`dV ze|A-2YV6Cm-(LK6+r@PkokAquzRikXVV|M8Y}u8I_pXZ0Tadfyb*h*Dp2n7WyM<$O zAFkW|wt2DsU*z$Jylt=T>hEoGRZ5kJME+XPX5~s z$>Vl~N7Lm$GM-;ra`((Vi%jFC6>PN)Vg{3@CD(_(9Do4v@AB$_r7- zA5gIamlmwLpuCXX7G6GqN;VEq$pJAPRBSC|x2BK=zY||t%nd)u*jF#APv!>|fqxFZ{ODKr z=a&rFEPdPgi=Xef^w|<51ui8)Cb`31=Lqrz-1X15zkfD4=hjT)&%N4C{TG_$zSJC& z`m_LS(}mCRTC;2Sl|O!%4k}VXa#dA)CqCbt_{C=b&p-BcP3`;NY&4f&E~?xzMs9jXJ)O`;ZHZyUv_;qKPMAY^z7N?oU(tn zK5y8ey6@-B%U?Erp1;+`zF7C(k#zGzZS(JQaL+%Mt#bNMu+5tHY&CakRy{fOSY7w* z^sAFDgeuSN@%KOdXX~`ty7O&oCH_=gx^$^XH|;^D z_npJDZ@%fR{gRSg^-aIh;{TIpXQgkdpZ|VY*#4Va#Oo-teV=}uocY{;-nN#ja`!DJ z>t+AcsW$#Ir$0Q$F0|_Dtv|iTUjKTNS)rIdE4uRDq`iXnUp_j6%U#2T>QkSe`Sa(Y zY}#l4OWoNgSEw;Q`}z3T0=3^M|DG)jJpWHsx6_$%!n7Q3BZ(@R7oP99?ANEttCiU7 z5#-_geoXx3rfDpzzI00ahwd*@{-{>@YTAued)F@E_o`py{=%`pkI}ZYvd@AexL&{h zlZE8fC39@*s*LsaeLgwadGWlz-g4(s)^D}BbKA@4RpXKX5+f!)6K2z;5z5A!})!N=c~V5`Cf3ey?mDS z?sIQsUuRl={_t^Y^Wu56-cfm1`p;iETJfvo{=wN_G|t|eI_((Wc4PLk9kMppE=#mr zwdeX>kgxs!?_wK}dCl|w&zSf8_qT0(?GNkDH5S{y(cDdj{UvAlS$UbSZ*)D?SzG4w zPo8;!|M9~!zrQS*EI7};_SYWEvk#uJzo`6i^UUFr{kOLoh-7&l^L!ch>Nu#pSm1s< z`ATu}dyDhGzuY-vm%Fnv*>1;%{41Y-xZOF+GAm*oGbl0-B}dDtFN?{}temy?=O2!$ zLjuo^ot>usa^mdoX*;gY*P0ho`}o-7U3FhO^UhWlxq)(e$(_EhHuj$rt0whNIj1hK zc~|W%Dm45l*0vV*=;J` zy>UCzpMmVC$cEhy~;_lyVMI3_?oHX1Onrg0NZciwCG# z)&i=D)O+Xs|L9kD=a)PvUs)dea^%||`)@MlmH+PVp9n6A{=N88^Y4Gj8E6q_Y};x3 z!LsbbpFQA6`+R(v`d0VjYrsbL8QZ@3`T1ls$l&^tsu!Qti@`?pvD*Hc+zJwfIB0=8 zxWx(9gVnu|(hw%^@#5otqbjg-A^JINkraSy8AniI3@P_jzJN+lP~imeFN(Yqs2PhS zF9d7eg7kCRI{7d5+4$q$rlgHur0tyd%>dO=3)9!%%h^^`aWiGx4{5u@Rb{NULRBsE z_A;KUG27h-3e*>l=j+!`zuDLM(*~UA*lquBy|wx3wl}q)7BZ*-9Q|}tbD*mAtvi3W zUAkDdf5wH&wjsXLOZkuTiN4QYpMT%C&3)&>8qMd7_po%`#4E^v^^$V|M`>oxi2(l6IextN)36uNvl(4J+A=eOf~=k&in=_fX+lXLd# zkG((BPyRjm_05sHKipO-?=+m{5F+85r?bG_ssF;}{Cl5$-gvoh)19h5`|XL)@LkW+ znQU9%xEQJLvc4_-|3&>w?PqL{UpLNMcXFXqo~^Yoe>>aex6ZAn%FJ%hy<-}&@>!K| z^(x_;FW+T-uPS2#heletu(w%os@LM1(@$EY8A!{&e(7bv`FPR0AIAe~_Rf0iUo%r< zS$k(&(v(}1rE_n-)L50m?)@@3?wEJgWNAm$FCH%htE8@0N}fHo`?S{0e_s@QRTn;w z+;n`ciJ-oWSO3$H%{N=-^`&fWeY3aX!sK&-8f7{z7fZ~h-#f9*edfki*Tm1ZuSi0V&H=F&vdFbEF!t-sD zer>+$RJLhfi4@oyZntlywf>lJ-l_OlsiERB>wCG=d>l`#^>3TX_WDbS`OA|jo2&0n zntcCuOxb4ZhdOt~+vPxsruI{Dec2Z6mG<}Azpb!5;AwyTvaFlq(tqD74(@&9bNfQj zz7i4J>iO=xiRL5<@zP&+T7NVMRe>zcy!z(e_or))E6;nI z6TU~mJaB)q@$K985%c>5-iNL3OWVBE`Abe(`lINhDM@98X-faZ-drkqbJ1&Cz2;ta za4@Z~v#i=xxz}2{&HU)PocjFZ5B?<7-(9l6&8X<)mh{`!VpZvEw>RfrZT`}-Hig}q zZSza@s(0twrCe znqGi=;NYSQT%rlWN-mH#NC~eDD*28tz7+Sv0bKmm{90CZs`}}VMsUgd^GfLHR9JyD z`)L6rOuz-_mlx;#&tExq&u)9KW*ev>%wJ_^YJ0V)a&_d+7~7<+HTx=cKhHk5PCE^h z^wcNJ^V+#-`-20$yZAq@$jDn+n7d72o$fK^CFiyVZM6|wzbULw+|B#rrJYA>HaTsY zd$dT?>sZL?kC%EsK8Q)TX|GOE`J>U-ZXNej+CPTJ-uUU!676VZ?~mWOUIk zGL!8SHB0kSUVRaHWnUb9wP>N^d5^9DwWZImhS@D#F7lvjW2DX=cmF*q@$R=`gkI#vM_h;<~`HozDagVec2NgEv?fl97GedqMGNHSQm+&UHio0-0I$ATP0e)MEKub_DpUko9NQHPmG=B{w~`w^;_8v*O|RX z9sHNsnI~56`FG@Mip$ot_SqMj<>ppYaXtMJyzJ-N@UPiR&po}ge_{IOJs~<`(w7Ba zUFO*~>r2bmZA>mFYnnGC?D=Oh^~=PsYmX#rf8nrwaq;95^{UXg)nZoLyS`>W{%AOB z{_^yk#Zw+^+}1yD>oK0~6<&utY?QR}&gzOzpSC@y%4>7G|4+exY+E}#TH z*PzNP*!t4Ksf=e|a+bCHup^xtHW@Kk{u+v%NZF-V^1e(Nkl*{C_cCo|u)a zy>#BhFNc>tonZxb!~C{+-?vyc&CB?I{rR73@k=)U|57sZ@!zdhpmf+g@BSpv02rvt z2F@ywPTT@^+x=Ub)lb@eTEYoV7GM4>^L_i~;O566gE6EhE|d zs-mX>@0`scjkcdGUvhGD-!4|aqZMA!1WJW3eop!F6VtZDqOt*xV zFm}4O(Hl*tdO7(Q&AeUpKEhvfzW(0tCw%@Ljy{{-7dJ06Z}}AW{ua5p0acS4{eNr} zy)3NPFZJmO+o`9$F?*6s)0WzZ*5#dRO-;P(wNpZWR_~+LS3{<*>@BL?Ca^B|$l(=F zkG2_oOy0IEsisT$Y0>$l9ot00Zb(IP2Z^4}1Vx1M7njygAzODvoO`=GJ!^T;+Go?m z7iZP1(O?j&ki6~jRC0doDzRl%hd%Y*bXqtedY75J=5p>>Xi4<6)%GJyj^j{SnS2jO^1D7IQIMT z+5TQGDP#JIvw2F;rbkhEn&zTCE2d1Io3Zp$(ig3s(z0oBM<35GIbyVLPRtQ=;VL8P zxhI=`CBG^^+L{>T<^Lt?_2;C@jZ&u;gZiz047UHboxNFfVR?x8Dw!9NI?FG!PIEtW zC~4!I^*ZL6k#e5tQY}}_s@&Y%P8FZjSn+eliif^?meiT@^t?J=bq!o5yy(<^=5~ld zJv>fJth+VgRMgy=Yr_LK?g^R6%{=qZ>XHKC-ZR(Q&8B7~LkpOF_w{OhG@-aOCW@BHuhyaU3ZWa@ZceQsp!i;zNCWpDR(R0Whf2zMP1oeA9Yu}!uJ$?H!ufUBq zTk}u4sqUL5&2haba7&0^RjVAQ?F+~A>+`_{McFaC{7aMdBI9}%IaRKTiq(0}WSi~1 zkf{n>e(vAp)SxQ&LMKh?%a!Rz#Iv6^_-b}+4zc5W1!+0`(+)k=d)SJ%>Xox7abIVoDS#s2r|)ygJz630Q>Qc8KAsw&7`rJVu6t3;&(N(Ao@G09k9~g% z88-c?Teeeo`f2N(75vecqIRkL^mzGvYHv|x_D0LI3xvTzKJR|o^5}of-d;Z!>0ctc zrXn0;phO0WIdGM90TNR1CwhjRG02owtcP_V?XzMTFslo+x_~s2j^YgzTW@!kuSgAzKWd8(<1lf&%JMRs*4jt z)t7O9Os_hj{AI!O@@>zrTwVRVBx#q_1I7Le&GYOT?5qNR&K9q_pzQg=v0sJLc9P1M z1@4nBG|PDkAp~Dc1dF!Feeu8}>cn5A!fA`H7B0Gw-F6blgh>~aJ+TNj%Yj8bUrba% zsDukT_Jc)LzIcG$2GS39Fi0ubZ4ei$U=t+LZ}>dy1PU75K63|q3>-8dmw^KT= z3ylkqsd&5wvI{8`;2ws%cu@LnP(~#*k>ZL=Xo5tGVW=ol3}N+Kjg0N{s(VMp-&e`C z%-3(r-nz5+;%^ygh5X-uzv5*UMLx{CN+kx2LD? z-}CCc>!b^xJzrE_ue4s4zBR1c_S%ByuU6i=y>b1YogP9}cAU0bqnQnDr)O{dJUyxE zp6>Om?T6QTPtRH|`);Djmp^4+cy#pju{H#p9Ca ztAht#&bw@AoBVO@&5yNTj!a)(op=4%vq`o#k2i1H>j{PcgmmFJv#ciF*i^#WRIkPj#nL%`yzYq z_BM5YhwKN_Z#T<%S~J}{Kngjt#4Ou+*&qc-qVNXw!x)Q>-N9M^j#O% z+s`+*y0C7+^SAA6ps7<8*_&6N&fD?v*v5Ic605?Rt&1OjWljHGrFZ;#+;^Lb+G^97 zOyBh5vYF?P%Ydzz6IGoTyT9&l(fP0Z7m8oioPT+1`bnFXeRH+9-ntQEv;IMm&A-m` zvnu~C(5n`{<74d5uTs0<;m(Tdk?}TLD(BBzFIQuEt$1TtwXyYw2Vd9TY}{vX@1|sC zZSBhEUT>GxTA>EpzY zA%8;ueRTKY_c2~^`?2!U7ZaD-FCpm-qiMyU5+ksj&R=#Fslyi|7A#o~-gk=3VKhhj(w! zb?lxP^}6}i%BZ(jT5ok%uvC7~cJ{woKaZ<>{k&|w8__SndHk|`uzC9Q;F)^1D`NA$ zPFM4MVL5AFbn^S8sy2PT`cUiYr-yEw=zd+kj_3HgFR?4HwymEhx36O5wyJ+guh%~8 zj=vUXvtsVP;-{ys-um#g`|$F6%Z|U%TQZxg$kyZK&f;y~s!qkvQd#&sqbe$XPXEi! znUS{DhH_u;{Cjof<&)Q+-pzSE+p6?=NbalL`)_97`tbGE+Jf&ZKNfFg=g(3W&wBpb zZ?3QT)~bE`&PHq6K3*=gUB&Z-<)nGHeqKJwxBb@A%bK?D_w6aRv$Vd{d~JPP{EWR7 zA0NGxn6&S6x!&BWk5^kCM!o$NqT5rhXU@+pyDa@p%-dg;^_i1e=J8+roVI53HL1Lq zH{LHZ_Xg~it#8}@?b)fLw^nWpPIQdl@!Rq3l@GTot`u+m_F(mtdBM-Wz3^Oj{L7qO zQU=}O6IB*I7qH!Y`0(ND%(h#vJ&k%jS6f{FDwA#PWBs`MGo}2NZ;Ia;vU;zCUH#5! z7mREEJ-VuJx!d}={yguOmDZcw{flguJ$H<#eRFDV`M*mloVND&ukMx1?sc~4t(Kbp toKN@1%yU1jCsV!2@Y4S6e{KT?#v^+d#0nN=F)%PNc)I$ztaD0e0stH~>3#qJ literal 0 HcmV?d00001 diff --git a/static/image/nwcprovimage/3.png b/static/image/nwcprovimage/3.png new file mode 100644 index 0000000000000000000000000000000000000000..138c963e79086d67b7e22fc74731c3fda70ced6d GIT binary patch literal 33475 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 N-P6_2Wt~$(697=kw@Cm1 literal 0 HcmV?d00001 From af130015e1afa4046a70d12d6e2c5a93f9abb464 Mon Sep 17 00:00:00 2001 From: blackcoffeexbt <87530449+blackcoffeexbt@users.noreply.github.com> Date: Wed, 18 Jun 2025 13:18:56 +0100 Subject: [PATCH 54/90] Move images --- static/image/{nwcprovimage => }/1.png | Bin static/image/{nwcprovimage => }/2.png | Bin static/image/{nwcprovimage => }/3.png | Bin 3 files changed, 0 insertions(+), 0 deletions(-) rename static/image/{nwcprovimage => }/1.png (100%) rename static/image/{nwcprovimage => }/2.png (100%) rename static/image/{nwcprovimage => }/3.png (100%) diff --git a/static/image/nwcprovimage/1.png b/static/image/1.png similarity index 100% rename from static/image/nwcprovimage/1.png rename to static/image/1.png diff --git a/static/image/nwcprovimage/2.png b/static/image/2.png similarity index 100% rename from static/image/nwcprovimage/2.png rename to static/image/2.png diff --git a/static/image/nwcprovimage/3.png b/static/image/3.png similarity index 100% rename from static/image/nwcprovimage/3.png rename to static/image/3.png From 25852e98d91e6b541fbbce910bf2b492ba2a56c6 Mon Sep 17 00:00:00 2001 From: blackcoffeexbt <87530449+blackcoffeexbt@users.noreply.github.com> Date: Wed, 18 Jun 2025 13:25:33 +0100 Subject: [PATCH 55/90] Update image paths in config.json and added BC as contributor --- config.json | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/config.json b/config.json index 92b27df..f853b33 100644 --- a/config.json +++ b/config.json @@ -13,20 +13,25 @@ "name": "Ben Arc", "uri": "https://github.com/arcbtc", "role": "Dev" + }, + { + "name": "BlackCoffee", + "uri": "https://github.com/blackcoffeexbt", + "role": "Dev" } ], "images": [ { - "uri": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/static/image/1.png" + "uri": "https://raw.githubusercontent.com/lnbits/nwcprovider/main/static/image/1.png" }, { - "uri": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/static/image/2.png" + "uri": "https://raw.githubusercontent.com/lnbits/nwcprovider/main/static/image/2.png" }, { - "uri": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/static/image/3.png" + "uri": "https://raw.githubusercontent.com/lnbits/nwcprovider/main/static/image/3.png" } ], - "description_md": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/description.md", - "terms_and_conditions_md": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/toc.md", + "description_md": "https://raw.githubusercontent.com/lnbits/nwcprovider/main/description.md", + "terms_and_conditions_md": "https://raw.githubusercontent.com/lnbits/nwcprovider/main/toc.md", "license": "MIT" } From ce4b4a55309c61dff3057c71a23e0e51df21d32c Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Mon, 23 Jun 2025 12:10:19 +0200 Subject: [PATCH 56/90] relax hardening: don't block lookup calls without payment_hash or invoice --- tasks.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tasks.py b/tasks.py index d06a80f..5749751 100644 --- a/tasks.py +++ b/tasks.py @@ -323,8 +323,10 @@ async def _on_lookup_invoice( payment_hash = invoice_data.payment_hash # hardening # - assert_valid_sha256(payment_hash) - assert_valid_bolt11(invoice) + if payment_hash: + assert_valid_sha256(payment_hash) + if invoice: + assert_valid_bolt11(invoice) # ## # # Get payment data From abdd7a781b24d17d0f8342fcdb5e1beafb8690bd Mon Sep 17 00:00:00 2001 From: blackcoffeexbt <87530449+blackcoffeexbt@users.noreply.github.com> Date: Wed, 10 Sep 2025 12:00:45 +0100 Subject: [PATCH 57/90] Improve configuration form for readability and UX --- .github/workflows/main.yml | 16 +- .github/workflows/release.yml | 16 +- .github/workflows/test.yml | 2 +- __init__.py | 2 +- migrations.py | 7 +- nwcp.py | 3 +- static/js/admin.js | 100 +++---- static/js/index.js | 355 ++++++++++++----------- static/js/noble-secp256k1.min.js | 479 ++++++++++++++++--------------- templates/nwcprovider/admin.html | 47 ++- templates/nwcprovider/index.html | 4 +- tests/integration/test_all.py | 33 ++- 12 files changed, 552 insertions(+), 512 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ed44344..c428ddd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,7 +1,7 @@ on: push: tags: - - "v[0-9]+.[0-9]+.[0-9]+" + - 'v[0-9]+.[0-9]+.[0-9]+' jobs: release: @@ -22,7 +22,7 @@ jobs: with: token: ${{ secrets.EXT_GITHUB }} repository: lnbits/lnbits-extensions - path: "./lnbits-extensions" + path: './lnbits-extensions' - name: setup git user run: | @@ -31,12 +31,12 @@ jobs: - name: Create pull request in extensions repo env: GH_TOKEN: ${{ secrets.EXT_GITHUB }} - repo_name: "${{ github.event.repository.name }}" - tag: "${{ github.ref_name }}" - branch: "update-${{ github.event.repository.name }}-${{ github.ref_name }}" - title: "[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}" - body: "https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}" - archive: "https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip" + repo_name: '${{ github.event.repository.name }}' + tag: '${{ github.ref_name }}' + branch: 'update-${{ github.event.repository.name }}-${{ github.ref_name }}' + title: '[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}' + body: 'https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}' + archive: 'https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip' run: | cd lnbits-extensions git checkout -b $branch diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ed44344..c428ddd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,7 @@ on: push: tags: - - "v[0-9]+.[0-9]+.[0-9]+" + - 'v[0-9]+.[0-9]+.[0-9]+' jobs: release: @@ -22,7 +22,7 @@ jobs: with: token: ${{ secrets.EXT_GITHUB }} repository: lnbits/lnbits-extensions - path: "./lnbits-extensions" + path: './lnbits-extensions' - name: setup git user run: | @@ -31,12 +31,12 @@ jobs: - name: Create pull request in extensions repo env: GH_TOKEN: ${{ secrets.EXT_GITHUB }} - repo_name: "${{ github.event.repository.name }}" - tag: "${{ github.ref_name }}" - branch: "update-${{ github.event.repository.name }}-${{ github.ref_name }}" - title: "[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}" - body: "https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}" - archive: "https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip" + repo_name: '${{ github.event.repository.name }}' + tag: '${{ github.ref_name }}' + branch: 'update-${{ github.event.repository.name }}-${{ github.ref_name }}' + title: '[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}' + body: 'https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}' + archive: 'https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip' run: | cd lnbits-extensions git checkout -b $branch diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e720631..1537439 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: "3.9" + python-version: '3.9' - name: Install dependencies run: | diff --git a/__init__.py b/__init__.py index 86e59d7..3cfa20c 100644 --- a/__init__.py +++ b/__init__.py @@ -45,7 +45,7 @@ def nwcprovider_start(): __all__ = [ "db", "nwcprovider_ext", - "nwcprovider_static_files", "nwcprovider_start", + "nwcprovider_static_files", "nwcprovider_stop", ] diff --git a/migrations.py b/migrations.py index fd12650..da5fdd8 100644 --- a/migrations.py +++ b/migrations.py @@ -87,12 +87,13 @@ async def m004_default_config2(db): Default config """ await db.execute( - """ + """ INSERT INTO nwcprovider.config (key, value) VALUES ('relay_alias', :value) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, - {"value": ""}, - ) + {"value": ""}, + ) + async def m005_key_last_used(db): """ diff --git a/nwcp.py b/nwcp.py index 4a5023a..ded5999 100644 --- a/nwcp.py +++ b/nwcp.py @@ -4,7 +4,8 @@ import hashlib import json import random import time -from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, Union +from collections.abc import Awaitable +from typing import Any, Callable, Dict, List, Optional, Tuple, Union import secp256k1 import websockets.client as websockets diff --git a/static/js/admin.js b/static/js/admin.js index afacb7e..3e88718 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -1,87 +1,81 @@ window.app = Vue.createApp({ - el: "#vue", + el: '#vue', mixins: [windowMixin], - delimiters: ["${", "}"], + delimiters: ['${', '}'], data: function () { return { - entries: [], + config: {}, columns: [ { - name: "key", + name: 'key', required: true, - label: "Key", - align: "left", - field: (row) => row.key, - sortable: true, + label: 'Key', + align: 'left', + field: row => row.key, + sortable: true }, { - name: "value", + name: 'value', required: true, - label: "Value", - align: "left", - field: (row) => row.value, - sortable: true, - }, - ], - }; + label: 'Value', + align: 'left', + field: row => row.value, + sortable: true + } + ] + } }, methods: { fetchConfig() { - this.entries = []; + this.config = {} LNbits.api .request( - "GET", - "/nwcprovider/api/v1/config", - this.g.user.wallets[0].adminkey, + 'GET', + '/nwcprovider/api/v1/config', + this.g.user.wallets[0].adminkey ) - .then((response) => { - const newEntries = []; - for (const [key, value] of Object.entries(response.data)) { - newEntries.push({ - key: key, - value: value, - }); - } - this.entries.length = 0; - this.entries.push(...newEntries); + .then(response => { + this.config = response.data + console.log('Config fetched:', this.config) }) .catch(function (error) { - console.error("Error fetching config:", error); - }); + console.error('Error fetching config:', error) + }) }, async saveConfig() { - const data = {}; - for (const entry of this.entries) { - data[entry.key] = entry.value; + const data = {} + for (const [key, value] of Object.entries(this.config)) { + data[key] = value } + console.log('Saving config:', data) try { const response = await LNbits.api.request( - "POST", - "/nwcprovider/api/v1/config", + 'POST', + '/nwcprovider/api/v1/config', this.g.user.wallets[0].adminkey, - data, - ); + data + ) Quasar.Notify.create({ - type: "positive", - message: "Config saved!", - }); + type: 'positive', + message: 'Config saved!' + }) Quasar.Notify.create({ - type: "warning", + type: 'warning', message: - "You need to restart the server for the changes to take effect!", - }); + 'You need to restart the server for the changes to take effect!' + }) } catch (error) { Quasar.Notify.create({ - type: "negative", - message: "Error saving config: " + String(error), - }); - console.error("Error saving config:", error); + type: 'negative', + message: 'Error saving config: ' + String(error) + }) + console.error('Error saving config:', error) } - }, + } }, created: function () { - this.fetchConfig(); - }, -}); + this.fetchConfig() + } +}) diff --git a/static/js/index.js b/static/js/index.js index e8a4ec1..d593469 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -1,7 +1,7 @@ window.app = Vue.createApp({ - el: "#vue", + el: '#vue', mixins: [windowMixin], - delimiters: ["${", "}"], + delimiters: ['${', '}'], data: function () { return { selectedWallet: null, @@ -10,244 +10,244 @@ window.app = Vue.createApp({ nwcsTable: { columns: [ { - name: "description", - align: "left", - label: "Description", - field: "description", + name: 'description', + align: 'left', + label: 'Description', + field: 'description' }, - { name: "status", align: "left", label: "Status", field: "status" }, + {name: 'status', align: 'left', label: 'Status', field: 'status'}, { - name: "last_used", - align: "left", - label: "Last used", - field: "last_used", + name: 'last_used', + align: 'left', + label: 'Last used', + field: 'last_used' }, { - name: "created_at", - align: "left", - label: "Created", - field: "created_at", + name: 'created_at', + align: 'left', + label: 'Created', + field: 'created_at' }, { - name: "expires_at", - align: "left", - label: "Expires", - field: "expires_at", - }, + name: 'expires_at', + align: 'left', + label: 'Expires', + field: 'expires_at' + } ], pagination: { - rowsPerPage: 10, - }, + rowsPerPage: 10 + } }, connectDialog: { show: false, - data: {}, + data: {} }, pairingDialog: { show: false, data: { - pairingUrl: "", - }, + pairingUrl: '' + } }, pairingQrDialog: { show: false, data: { - pairingUrl: "", - }, + pairingUrl: '' + } }, connectionInfoDialog: { show: false, - data: {}, - }, - }; + data: {} + } + } }, methods: { showConnectDialog() { - const wallet = this.getWallet(); + const wallet = this.getWallet() if (!wallet) { Quasar.Notify.create({ - type: "negative", - message: "Please select a wallet first", - }); - return; + type: 'negative', + message: 'Please select a wallet first' + }) + return } else { - this.connectDialog.show = true; + this.connectDialog.show = true } }, openConnectionInfoDialog(data) { - this.connectionInfoDialog.data = data; - this.connectionInfoDialog.show = true; + this.connectionInfoDialog.data = data + this.connectionInfoDialog.show = true }, closeConnectionInfoDialog() { - this.connectionInfoDialog.show = false; + this.connectionInfoDialog.show = false }, openPairingUrl() { - const url = this.pairingDialog.data.pairingUrl; - if (url) window.open(url, "_blank"); + const url = this.pairingDialog.data.pairingUrl + if (url) window.open(url, '_blank') }, go(url) { - window.open(url, "_blank"); + window.open(url, '_blank') }, async copyPairingUrl() { - const url = this.pairingDialog.data.pairingUrl; + const url = this.pairingDialog.data.pairingUrl if (url) { try { - await navigator.clipboard.writeText(url); + await navigator.clipboard.writeText(url) Quasar.Notify.create({ - type: "positive", - message: "URL copied to clipboard", - }); + type: 'positive', + message: 'URL copied to clipboard' + }) } catch (err) { Quasar.Notify.create({ - type: "negative", - message: "Failed to copy URL.", - }); + type: 'negative', + message: 'Failed to copy URL.' + }) } } }, showPairingQR() { - this.pairingQrDialog.data.pairingUrl = this.pairingDialog.data.pairingUrl; - this.pairingQrDialog.show = true; + this.pairingQrDialog.data.pairingUrl = this.pairingDialog.data.pairingUrl + this.pairingQrDialog.show = true }, closePairingQrDialog() { - this.pairingQrDialog.show = false; + this.pairingQrDialog.show = false }, loadConnectDialogData() { this.connectDialog.data = { - description: "", + description: '', expires_at: Date.now() + 1000 * 60 * 60 * 24 * 7, neverExpires: true, permissions: [], - budgets: [], - }; + budgets: [] + } for (const permission of this.nodePermissions) { this.connectDialog.data.permissions.push({ key: permission.key, name: permission.name, - value: permission.value, - }); + value: permission.value + }) } }, deleteBudget(index) { - this.connectDialog.data.budgets.splice(index, 1); + this.connectDialog.data.budgets.splice(index, 1) }, addBudget() { this.connectDialog.data.budgets.push({ budget_sats: 1000, used_budget_sats: 0, created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, - expiration: "never", - }); + expiration: 'never' + }) }, closeConnectDialog() { - this.connectDialog.show = false; - this.loadConnectDialogData(); + this.connectDialog.show = false + this.loadConnectDialogData() }, getWallet: function () { - let wallet = undefined; + let wallet = undefined for (let i = 0; i < this.g.user.wallets.length; i++) { if (this.g.user.wallets[i].id == this.selectedWallet) { - wallet = this.g.user.wallets[i]; - break; + wallet = this.g.user.wallets[i] + break } } - return wallet; + return wallet }, async generateKeyPair() { while (!window.NobleSecp256k1) { - await new Promise((resolve) => setTimeout(resolve, 1)); + await new Promise(resolve => setTimeout(resolve, 1)) } - const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey(); - const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes); + const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey() + const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes) const out = { privKeyBytes: privKeyBytes, pubKeyBytes: pubKeyBytes, privKey: window.NobleSecp256k1.etc.bytesToHex(privKeyBytes), - pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)), - }; - return out; + pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)) + } + return out }, deleteNWC: async function (pubkey) { Quasar.Dialog.create({ - title: "Confirm Deletion", - message: "Are you sure you want to delete this connection?", + title: 'Confirm Deletion', + message: 'Are you sure you want to delete this connection?', cancel: true, - persistent: true, + persistent: true }) .onOk(async () => { try { - const wallet = this.getWallet(); + const wallet = this.getWallet() const response = await LNbits.api.request( - "DELETE", + 'DELETE', `/nwcprovider/api/v1/nwc/${pubkey}`, - wallet.adminkey, - ); - this.loadNwcs(); + wallet.adminkey + ) + this.loadNwcs() Quasar.Notify.create({ - type: "positive", - message: "Deleted successfully", - }); + type: 'positive', + message: 'Deleted successfully' + }) } catch (error) { - LNbits.utils.notifyApiError(error); + LNbits.utils.notifyApiError(error) } }) .onCancel(() => { // User canceled the operation - }); + }) }, loadNwcs: async function () { - const wallet = this.getWallet(); + const wallet = this.getWallet() if (!wallet) { - this.nwcs = []; - return; + this.nwcs = [] + return } try { const response = await LNbits.api.request( - "GET", - "/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true", - wallet.adminkey, - ); - this.nwcs = response.data; + 'GET', + '/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true', + wallet.adminkey + ) + this.nwcs = response.data } catch (error) { - this.nwcs = []; + this.nwcs = [] } try { const response = await LNbits.api.request( - "GET", - "/nwcprovider/api/v1/permissions", - wallet.adminkey, - ); - const permissions = []; + 'GET', + '/nwcprovider/api/v1/permissions', + wallet.adminkey + ) + const permissions = [] for (const [key, value] of Object.entries(response.data)) { permissions.push({ key: key, name: value.name, - value: value.default, - }); + value: value.default + }) } - this.nodePermissions = permissions; + this.nodePermissions = permissions } catch (error) { - Lnbits.utils.notifyApiError(error); + Lnbits.utils.notifyApiError(error) } - this.loadConnectDialogData(); - const newTableEntries = []; + this.loadConnectDialogData() + const newTableEntries = [] for (const nwc of this.nwcs) { const t = Quasar.date.formatDate( new Date(nwc.data.created_at * 1000), - "YYYY-MM-DD HH:mm", - ); + 'YYYY-MM-DD HH:mm' + ) const e = nwc.data.expires_at > 0 ? Quasar.date.formatDate( new Date(nwc.data.expires_at * 1000), - "YYYY-MM-DD HH:mm", + 'YYYY-MM-DD HH:mm' ) - : "Never"; + : 'Never' const l = Quasar.date.formatDate( new Date(nwc.data.last_used * 1000), - "YYYY-MM-DD HH:mm", - ); + 'YYYY-MM-DD HH:mm' + ) const nwcTableEntry = { description: nwc.data.description, created_at: t, @@ -256,131 +256,130 @@ window.app = Vue.createApp({ pubkey: nwc.data.pubkey, permissions: nwc.data.permissions, budgets: [], - status: "Active", - }; + status: 'Active' + } if ( nwc.data.expires_at > 0 && nwc.data.expires_at < new Date().getTime() / 1000 ) { - nwcTableEntry.status = "Expired"; + nwcTableEntry.status = 'Expired' } for (const budget of nwc.budgets) { const createdAt = Quasar.date.formatDate( new Date(budget.created_at * 1000), - "YYYY-MM-DD HH:mm", - ); - let refreshWindow = budget.refresh_window; + 'YYYY-MM-DD HH:mm' + ) + let refreshWindow = budget.refresh_window if (refreshWindow <= 0) { - refreshWindow = "Never"; + refreshWindow = 'Never' } else if (refreshWindow == 60 * 60 * 24) { - refreshWindow = "Daily"; + refreshWindow = 'Daily' } else if (refreshWindow == 60 * 60 * 24 * 7) { - refreshWindow = "Weekly"; + refreshWindow = 'Weekly' } else if (refreshWindow == 60 * 60 * 24 * 30) { - refreshWindow = "Monthly"; + refreshWindow = 'Monthly' } else if (refreshWindow == 60 * 60 * 24 * 365) { - refreshWindow = "Yearly"; + refreshWindow = 'Yearly' } nwcTableEntry.budgets.push({ budget_sats: budget.budget_msats / 1000, used_budget_sats: budget.used_budget_msats / 1000, created_at: createdAt, - refresh_window: refreshWindow, - }); + refresh_window: refreshWindow + }) } - newTableEntries.push(nwcTableEntry); + newTableEntries.push(nwcTableEntry) } - this.nwcEntries = newTableEntries; + this.nwcEntries = newTableEntries }, closePairingDialog() { - this.pairingDialog.show = false; + this.pairingDialog.show = false }, async showPairingDialog(secret) { let response = await LNbits.api.request( - "GET", - "/nwcprovider/api/v1/pairing/{SECRET}", - ); - response = response.data; - response = response.replace("{SECRET}", secret); - this.pairingDialog.data.pairingUrl = response; - this.pairingDialog.show = true; + 'GET', + '/nwcprovider/api/v1/pairing/{SECRET}' + ) + response = response.data + response = response.replace('{SECRET}', secret) + this.pairingDialog.data.pairingUrl = response + this.pairingDialog.show = true }, async confirmConnectDialog() { - const keyPair = await this.generateKeyPair(); + const keyPair = await this.generateKeyPair() // timestamp - let expires_at = 0; + let expires_at = 0 if (!this.connectDialog.data.neverExpires) { expires_at = - new Date(this.connectDialog.data.expires_at).getTime() / 1000; + new Date(this.connectDialog.data.expires_at).getTime() / 1000 } const data = { permissions: [], description: this.connectDialog.data.description, expires_at: expires_at, - budgets: [], - }; + budgets: [] + } for (const permission of this.connectDialog.data.permissions) { - if (permission.value) data.permissions.push(permission.key); + if (permission.value) data.permissions.push(permission.key) } for (const budget of this.connectDialog.data.budgets) { - const budget_msats = budget.budget_sats * 1000; - let refresh_window = 0; + const budget_msats = budget.budget_sats * 1000 + let refresh_window = 0 switch (budget.expiry) { - case "Daily": - refresh_window = 60 * 60 * 24; - break; - case "Weekly": - refresh_window = 60 * 60 * 24 * 7; - break; - case "Monthly": - refresh_window = 60 * 60 * 24 * 30; - break; - case "Yearly": - refresh_window = 60 * 60 * 24 * 365; - break; - case "Never": - refresh_window = 0; - break; + case 'Daily': + refresh_window = 60 * 60 * 24 + break + case 'Weekly': + refresh_window = 60 * 60 * 24 * 7 + break + case 'Monthly': + refresh_window = 60 * 60 * 24 * 30 + break + case 'Yearly': + refresh_window = 60 * 60 * 24 * 365 + break + case 'Never': + refresh_window = 0 + break } data.budgets.push({ budget_msats: budget_msats, refresh_window: refresh_window, - created_at: - new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, - }); + created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000 + }) } - const wallet = this.getWallet(); + const wallet = this.getWallet() try { const response = await LNbits.api.request( - "PUT", - "/nwcprovider/api/v1/nwc/" + keyPair.pubKey, + 'PUT', + '/nwcprovider/api/v1/nwc/' + keyPair.pubKey, wallet.adminkey, - data, - ); - this.closeConnectDialog(); + data + ) + this.closeConnectDialog() if ( !response.data || !response.data.data || !response.data.data.pubkey ) { - LNbits.utils.notifyApiError("Error creating nwc pairing"); - return; + LNbits.utils.notifyApiError('Error creating nwc pairing') + return } - this.showPairingDialog(keyPair.privKey); + this.showPairingDialog(keyPair.privKey) } catch (error) { - LNbits.utils.notifyApiError(error); + LNbits.utils.notifyApiError(error) } - this.loadNwcs(); - }, + this.loadNwcs() + } }, created: function () { - this.loadNwcs(); + this.loadNwcs() }, watch: { selectedWallet(newValue, oldValue) { - this.loadNwcs(); - }, - }, -}); + this.loadNwcs() + } + } +}) diff --git a/static/js/noble-secp256k1.min.js b/static/js/noble-secp256k1.min.js index af328c8..c996cd2 100644 --- a/static/js/noble-secp256k1.min.js +++ b/static/js/noble-secp256k1.min.js @@ -4,93 +4,93 @@ const B256 = 2n ** 256n, N = B256 - 0x14551231950b75fc4402da1732fc9bebfn, Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n, Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n, - CURVE = { p: P, n: N, a: 0n, b: 7n, Gx, Gy }, + CURVE = {p: P, n: N, a: 0n, b: 7n, Gx, Gy}, fLen = 32, - crv = (t) => mod(mod(t * t) * t + CURVE.b), - err = (t = "") => { - throw new Error(t); + crv = t => mod(mod(t * t) * t + CURVE.b), + err = (t = '') => { + throw new Error(t) }, - big = (t) => "bigint" == typeof t, - str = (t) => "string" == typeof t, - fe = (t) => big(t) && 0n < t && t < P, - ge = (t) => big(t) && 0n < t && t < N, - isu8 = (t) => + big = t => 'bigint' == typeof t, + str = t => 'string' == typeof t, + fe = t => big(t) && 0n < t && t < P, + ge = t => big(t) && 0n < t && t < N, + isu8 = t => t instanceof Uint8Array || - (null != t && "object" == typeof t && "Uint8Array" === t.constructor.name), + (null != t && 'object' == typeof t && 'Uint8Array' === t.constructor.name), au8 = (t, n) => - !isu8(t) || ("number" == typeof n && n > 0 && t.length !== n) - ? err("Uint8Array expected") + !isu8(t) || ('number' == typeof n && n > 0 && t.length !== n) + ? err('Uint8Array expected') : t, - u8n = (t) => new Uint8Array(t), + u8n = t => new Uint8Array(t), toU8 = (t, n) => au8(str(t) ? h2b(t) : u8n(au8(t)), n), mod = (t, n = P) => { - let e = t % n; - return e >= 0n ? e : n + e; + let e = t % n + return e >= 0n ? e : n + e }, - isPoint = (t) => (t instanceof Point ? t : err("Point expected")); + isPoint = t => (t instanceof Point ? t : err('Point expected')) class Point { constructor(t, n, e) { - (this.px = t), (this.py = n), (this.pz = e); + ;((this.px = t), (this.py = n), (this.pz = e)) } static fromAffine(t) { - return 0n === t.x && 0n === t.y ? Point.ZERO : new Point(t.x, t.y, 1n); + return 0n === t.x && 0n === t.y ? Point.ZERO : new Point(t.x, t.y, 1n) } static fromHex(t) { - let n; + let n const e = (t = toU8(t))[0], r = t.subarray(1), o = slcNum(r, 0, 32), - i = t.length; + i = t.length if (33 === i && [2, 3].includes(e)) { - fe(o) || err("Point hex invalid: x not FE"); - let t = sqrt(crv(o)); - !(1 & ~e) !== (1n === (1n & t)) && (t = mod(-t)), - (n = new Point(o, t, 1n)); + fe(o) || err('Point hex invalid: x not FE') + let t = sqrt(crv(o)) + ;(!(1 & ~e) !== (1n === (1n & t)) && (t = mod(-t)), + (n = new Point(o, t, 1n))) } return ( 65 === i && 4 === e && (n = new Point(o, slcNum(r, 32, 64), 1n)), - n ? n.ok() : err("Point is not on curve") - ); + n ? n.ok() : err('Point is not on curve') + ) } static fromPrivateKey(t) { - return G.mul(toPriv(t)); + return G.mul(toPriv(t)) } get x() { - return this.aff().x; + return this.aff().x } get y() { - return this.aff().y; + return this.aff().y } equals(t) { - const { px: n, py: e, pz: r } = this, - { px: o, py: i, pz: s } = isPoint(t), + const {px: n, py: e, pz: r} = this, + {px: o, py: i, pz: s} = isPoint(t), a = mod(n * s), c = mod(o * r), d = mod(e * s), - u = mod(i * r); - return a === c && d === u; + u = mod(i * r) + return a === c && d === u } negate() { - return new Point(this.px, mod(-this.py), this.pz); + return new Point(this.px, mod(-this.py), this.pz) } double() { - return this.add(this); + return this.add(this) } add(t) { - const { px: n, py: e, pz: r } = this, - { px: o, py: i, pz: s } = isPoint(t), - { a, b: c } = CURVE; + const {px: n, py: e, pz: r} = this, + {px: o, py: i, pz: s} = isPoint(t), + {a, b: c} = CURVE let d = 0n, u = 0n, - m = 0n; - const h = mod(3n * c); + m = 0n + const h = mod(3n * c) let l = mod(n * o), y = mod(e * i), f = mod(r * s), p = mod(n + e), - b = mod(o + i); - (p = mod(p * b)), (b = mod(l + y)), (p = mod(p - b)), (b = mod(n + r)); - let g = mod(o + s); + b = mod(o + i) + ;((p = mod(p * b)), (b = mod(l + y)), (p = mod(p - b)), (b = mod(n + r))) + let g = mod(o + s) return ( (b = mod(b * g)), (g = mod(l + f)), @@ -123,300 +123,301 @@ class Point { (m = mod(g * m)), (m = mod(m + l)), new Point(d, u, m) - ); + ) } mul(t, n = !0) { - if (!n && 0n === t) return I; - if ((ge(t) || err("invalid scalar"), this.equals(G))) return wNAF(t).p; + if (!n && 0n === t) return I + if ((ge(t) || err('invalid scalar'), this.equals(G))) return wNAF(t).p let e = I, - r = G; + r = G for (let o = this; t > 0n; o = o.double(), t >>= 1n) - 1n & t ? (e = e.add(o)) : n && (r = r.add(o)); - return e; + 1n & t ? (e = e.add(o)) : n && (r = r.add(o)) + return e } mulAddQUns(t, n, e) { - return this.mul(n, !1).add(t.mul(e, !1)).ok(); + return this.mul(n, !1).add(t.mul(e, !1)).ok() } toAffine() { - const { px: t, py: n, pz: e } = this; - if (this.equals(I)) return { x: 0n, y: 0n }; - if (1n === e) return { x: t, y: n }; - const r = inv(e); + const {px: t, py: n, pz: e} = this + if (this.equals(I)) return {x: 0n, y: 0n} + if (1n === e) return {x: t, y: n} + const r = inv(e) return ( - 1n !== mod(e * r) && err("invalid inverse"), - { x: mod(t * r), y: mod(n * r) } - ); + 1n !== mod(e * r) && err('invalid inverse'), + {x: mod(t * r), y: mod(n * r)} + ) } assertValidity() { - const { x: t, y: n } = this.aff(); + const {x: t, y: n} = this.aff() return ( - (fe(t) && fe(n)) || err("Point invalid: x or y"), - mod(n * n) === crv(t) ? this : err("Point invalid: not on curve") - ); + (fe(t) && fe(n)) || err('Point invalid: x or y'), + mod(n * n) === crv(t) ? this : err('Point invalid: not on curve') + ) } multiply(t) { - return this.mul(t); + return this.mul(t) } aff() { - return this.toAffine(); + return this.toAffine() } ok() { - return this.assertValidity(); + return this.assertValidity() } toHex(t = !0) { - const { x: n, y: e } = this.aff(); + const {x: n, y: e} = this.aff() return ( - (t ? (0n === (1n & e) ? "02" : "03") : "04") + n2h(n) + (t ? "" : n2h(e)) - ); + (t ? (0n === (1n & e) ? '02' : '03') : '04') + n2h(n) + (t ? '' : n2h(e)) + ) } toRawBytes(t = !0) { - return h2b(this.toHex(t)); + return h2b(this.toHex(t)) } } -(Point.BASE = new Point(Gx, Gy, 1n)), (Point.ZERO = new Point(0n, 1n, 0n)); -const { BASE: G, ZERO: I } = Point, - padh = (t, n) => t.toString(16).padStart(n, "0"), - b2h = (t) => +;((Point.BASE = new Point(Gx, Gy, 1n)), (Point.ZERO = new Point(0n, 1n, 0n))) +const {BASE: G, ZERO: I} = Point, + padh = (t, n) => t.toString(16).padStart(n, '0'), + b2h = t => Array.from(t) - .map((t) => padh(t, 2)) - .join(""), - h2b = (t) => { - const n = t.length; - (!str(t) || n % 2) && err("hex invalid 1"); - const e = u8n(n / 2); + .map(t => padh(t, 2)) + .join(''), + h2b = t => { + const n = t.length + ;(!str(t) || n % 2) && err('hex invalid 1') + const e = u8n(n / 2) for (let n = 0; n < e.length; n++) { const r = 2 * n, o = t.slice(r, r + 2), - i = Number.parseInt(o, 16); - (Number.isNaN(i) || i < 0) && err("hex invalid 2"), (e[n] = i); + i = Number.parseInt(o, 16) + ;((Number.isNaN(i) || i < 0) && err('hex invalid 2'), (e[n] = i)) } - return e; + return e }, - b2n = (t) => BigInt("0x" + (b2h(t) || "0")), + b2n = t => BigInt('0x' + (b2h(t) || '0')), slcNum = (t, n, e) => b2n(t.slice(n, e)), - n2b = (t) => - big(t) && t >= 0n && t < B256 ? h2b(padh(t, 64)) : err("bigint expected"), - n2h = (t) => b2h(n2b(t)), + n2b = t => + big(t) && t >= 0n && t < B256 ? h2b(padh(t, 64)) : err('bigint expected'), + n2h = t => b2h(n2b(t)), concatB = (...t) => { - const n = u8n(t.reduce((t, n) => t + au8(n).length, 0)); - let e = 0; + const n = u8n(t.reduce((t, n) => t + au8(n).length, 0)) + let e = 0 return ( - t.forEach((t) => { - n.set(t, e), (e += t.length); + t.forEach(t => { + ;(n.set(t, e), (e += t.length)) }), n - ); + ) }, inv = (t, n = P) => { - (0n === t || n <= 0n) && err("no inverse n=" + t + " mod=" + n); + ;(0n === t || n <= 0n) && err('no inverse n=' + t + ' mod=' + n) let e = mod(t, n), r = n, o = 0n, i = 1n, s = 1n, - a = 0n; + a = 0n for (; 0n !== e; ) { const t = r / e, n = r % e, c = o - s * t, - d = i - a * t; - (r = e), (e = n), (o = s), (i = a), (s = c), (a = d); + d = i - a * t + ;((r = e), (e = n), (o = s), (i = a), (s = c), (a = d)) } - return 1n === r ? mod(o, n) : err("no inverse"); + return 1n === r ? mod(o, n) : err('no inverse') }, - sqrt = (t) => { - let n = 1n; + sqrt = t => { + let n = 1n for (let e = t, r = (P + 1n) / 4n; r > 0n; r >>= 1n) - 1n & r && (n = (n * e) % P), (e = (e * e) % P); - return mod(n * n) === t ? n : err("sqrt invalid"); + (1n & r && (n = (n * e) % P), (e = (e * e) % P)) + return mod(n * n) === t ? n : err('sqrt invalid') }, - toPriv = (t) => ( + toPriv = t => ( big(t) || (t = b2n(toU8(t, 32))), - ge(t) ? t : err("private key out of range") + ge(t) ? t : err('private key out of range') ), - moreThanHalfN = (t) => t > N >> 1n, - getPublicKey = (t, n = !0) => Point.fromPrivateKey(t).toRawBytes(n); + moreThanHalfN = t => t > N >> 1n, + getPublicKey = (t, n = !0) => Point.fromPrivateKey(t).toRawBytes(n) class Signature { constructor(t, n, e) { - (this.r = t), (this.s = n), (this.recovery = e), this.assertValidity(); + ;((this.r = t), (this.s = n), (this.recovery = e), this.assertValidity()) } static fromCompact(t) { return ( - (t = toU8(t, 64)), new Signature(slcNum(t, 0, 32), slcNum(t, 32, 64)) - ); + (t = toU8(t, 64)), + new Signature(slcNum(t, 0, 32), slcNum(t, 32, 64)) + ) } assertValidity() { - return ge(this.r) && ge(this.s) ? this : err(); + return ge(this.r) && ge(this.s) ? this : err() } addRecoveryBit(t) { - return new Signature(this.r, this.s, t); + return new Signature(this.r, this.s, t) } hasHighS() { - return moreThanHalfN(this.s); + return moreThanHalfN(this.s) } normalizeS() { return this.hasHighS() ? new Signature(this.r, mod(this.s, N), this.recovery) - : this; + : this } recoverPublicKey(t) { - const { r: n, s: e, recovery: r } = this; - [0, 1, 2, 3].includes(r) || err("recovery id invalid"); + const {r: n, s: e, recovery: r} = this + ;[0, 1, 2, 3].includes(r) || err('recovery id invalid') const o = bits2int_modN(toU8(t, 32)), - i = 2 === r || 3 === r ? n + N : n; - i >= P && err("q.x invalid"); - const s = 1 & r ? "03" : "02", + i = 2 === r || 3 === r ? n + N : n + i >= P && err('q.x invalid') + const s = 1 & r ? '03' : '02', a = Point.fromHex(s + n2h(i)), c = inv(i, N), d = mod(-o * c, N), - u = mod(e * c, N); - return G.mulAddQUns(a, d, u); + u = mod(e * c, N) + return G.mulAddQUns(a, d, u) } toCompactRawBytes() { - return h2b(this.toCompactHex()); + return h2b(this.toCompactHex()) } toCompactHex() { - return n2h(this.r) + n2h(this.s); + return n2h(this.r) + n2h(this.s) } } -const bits2int = (t) => { +const bits2int = t => { const n = 8 * t.length - 256, - e = b2n(t); - return n > 0 ? e >> BigInt(n) : e; + e = b2n(t) + return n > 0 ? e >> BigInt(n) : e }, - bits2int_modN = (t) => mod(bits2int(t), N), - i2o = (t) => n2b(t), + bits2int_modN = t => mod(bits2int(t), N), + i2o = t => n2b(t), cr = () => - "object" == typeof globalThis && "crypto" in globalThis + 'object' == typeof globalThis && 'crypto' in globalThis ? globalThis.crypto - : void 0; -let _hmacSync; -const optS = { lowS: !0 }, - optV = { lowS: !0 }, + : void 0 +let _hmacSync +const optS = {lowS: !0}, + optV = {lowS: !0}, prepSig = (t, n, e = optS) => { - ["der", "recovered", "canonical"].some((t) => t in e) && - err("sign() legacy options not supported"); - let { lowS: r } = e; - null == r && (r = !0); + ;['der', 'recovered', 'canonical'].some(t => t in e) && + err('sign() legacy options not supported') + let {lowS: r} = e + null == r && (r = !0) const o = bits2int_modN(toU8(t)), i = i2o(o), s = toPriv(n), - a = [i2o(s), i]; - let c = e.extraEntropy; + a = [i2o(s), i] + let c = e.extraEntropy if (c) { - !0 === c && (c = etc.randomBytes(32)); - const t = toU8(c); - 32 !== t.length && err(), a.push(t); + !0 === c && (c = etc.randomBytes(32)) + const t = toU8(c) + ;(32 !== t.length && err(), a.push(t)) } - const d = o; + const d = o return { seed: concatB(...a), - k2sig: (t) => { - const n = bits2int(t); - if (!ge(n)) return; + k2sig: t => { + const n = bits2int(t) + if (!ge(n)) return const e = inv(n, N), o = G.mul(n).aff(), - i = mod(o.x, N); - if (0n === i) return; - const a = mod(e * mod(d + mod(s * i, N), N), N); - if (0n === a) return; + i = mod(o.x, N) + if (0n === i) return + const a = mod(e * mod(d + mod(s * i, N), N), N) + if (0n === a) return let c = a, - u = (o.x === i ? 0 : 2) | Number(1n & o.y); + u = (o.x === i ? 0 : 2) | Number(1n & o.y) return ( r && moreThanHalfN(a) && ((c = mod(-a, N)), (u ^= 1)), new Signature(i, c, u) - ); - }, - }; - }; + ) + } + } + } function hmacDrbg(t) { let n = u8n(32), e = u8n(32), - r = 0; + r = 0 const o = () => { - n.fill(1), e.fill(0), (r = 0); + ;(n.fill(1), e.fill(0), (r = 0)) }, - i = "drbg: tried 1000 values"; + i = 'drbg: tried 1000 values' if (t) { const t = (...t) => etc.hmacSha256Async(e, n, ...t), s = async (r = u8n()) => { - (e = await t(u8n([0]), r)), + ;((e = await t(u8n([0]), r)), (n = await t()), - 0 !== r.length && ((e = await t(u8n([1]), r)), (n = await t())); + 0 !== r.length && ((e = await t(u8n([1]), r)), (n = await t()))) }, - a = async () => (r++ >= 1e3 && err(i), (n = await t()), n); + a = async () => (r++ >= 1e3 && err(i), (n = await t()), n) return async (t, n) => { - let e; - for (o(), await s(t); !(e = n(await a())); ) await s(); - return o(), e; - }; + let e + for (o(), await s(t); !(e = n(await a())); ) await s() + return (o(), e) + } } { const t = (...t) => { - const r = _hmacSync; - return r || err("etc.hmacSha256Sync not set"), r(e, n, ...t); + const r = _hmacSync + return (r || err('etc.hmacSha256Sync not set'), r(e, n, ...t)) }, s = (r = u8n()) => { - (e = t(u8n([0]), r)), + ;((e = t(u8n([0]), r)), (n = t()), - 0 !== r.length && ((e = t(u8n([1]), r)), (n = t())); + 0 !== r.length && ((e = t(u8n([1]), r)), (n = t()))) }, - a = () => (r++ >= 1e3 && err(i), (n = t()), n); + a = () => (r++ >= 1e3 && err(i), (n = t()), n) return (t, n) => { - let e; - for (o(), s(t); !(e = n(a())); ) s(); - return o(), e; - }; + let e + for (o(), s(t); !(e = n(a())); ) s() + return (o(), e) + } } } const signAsync = async (t, n, e = optS) => { - const { seed: r, k2sig: o } = prepSig(t, n, e); - return hmacDrbg(!0)(r, o); + const {seed: r, k2sig: o} = prepSig(t, n, e) + return hmacDrbg(!0)(r, o) }, sign = (t, n, e = optS) => { - const { seed: r, k2sig: o } = prepSig(t, n, e); - return hmacDrbg(!1)(r, o); + const {seed: r, k2sig: o} = prepSig(t, n, e) + return hmacDrbg(!1)(r, o) }, verify = (t, n, e, r = optV) => { let o, i, s, - { lowS: a } = r; - null == a && (a = !0), - "strict" in r && err("verify() legacy options not supported"); - const c = t && "object" == typeof t && "r" in t; - c || 64 === toU8(t).length || err("signature must be 64 bytes"); + {lowS: a} = r + ;(null == a && (a = !0), + 'strict' in r && err('verify() legacy options not supported')) + const c = t && 'object' == typeof t && 'r' in t + c || 64 === toU8(t).length || err('signature must be 64 bytes') try { - (o = c + ;((o = c ? new Signature(t.r, t.s).assertValidity() : Signature.fromCompact(t)), (i = bits2int_modN(toU8(n))), - (s = e instanceof Point ? e.ok() : Point.fromHex(e)); + (s = e instanceof Point ? e.ok() : Point.fromHex(e))) } catch (t) { - return !1; + return !1 } - if (!o) return !1; - const { r: d, s: u } = o; - if (a && moreThanHalfN(u)) return !1; - let m; + if (!o) return !1 + const {r: d, s: u} = o + if (a && moreThanHalfN(u)) return !1 + let m try { const t = inv(u, N), n = mod(i * t, N), - e = mod(d * t, N); - m = G.mulAddQUns(s, n, e).aff(); + e = mod(d * t, N) + m = G.mulAddQUns(s, n, e).aff() } catch (t) { - return !1; + return !1 } - if (!m) return !1; - return mod(m.x, N) === d; + if (!m) return !1 + return mod(m.x, N) === d }, getSharedSecret = (t, n, e = !0) => Point.fromHex(n).mul(toPriv(t)).toRawBytes(e), - hashToPrivateKey = (t) => { - ((t = toU8(t)).length < 40 || t.length > 1024) && - err("expected proper params"); - const n = mod(b2n(t), N - 1n) + 1n; - return n2b(n); + hashToPrivateKey = t => { + ;((t = toU8(t)).length < 40 || t.length > 1024) && + err('expected proper params') + const n = mod(b2n(t), N - 1n) + 1n + return n2b(n) }, etc = { hexToBytes: h2b, @@ -428,84 +429,84 @@ const signAsync = async (t, n, e = optS) => { invert: inv, hmacSha256Async: async (t, ...n) => { const e = cr(), - r = e && e.subtle; - if (!r) return err("etc.hmacSha256Async not set"); + r = e && e.subtle + if (!r) return err('etc.hmacSha256Async not set') const o = await r.importKey( - "raw", + 'raw', t, - { name: "HMAC", hash: { name: "SHA-256" } }, + {name: 'HMAC', hash: {name: 'SHA-256'}}, !1, - ["sign"], - ); - return u8n(await r.sign("HMAC", o, concatB(...n))); + ['sign'] + ) + return u8n(await r.sign('HMAC', o, concatB(...n))) }, hmacSha256Sync: _hmacSync, hashToPrivateKey, randomBytes: (t = 32) => { - const n = cr(); + const n = cr() return ( (n && n.getRandomValues) || - err("crypto.getRandomValues must be defined"), + err('crypto.getRandomValues must be defined'), n.getRandomValues(u8n(t)) - ); - }, + ) + } }, utils = { normPrivateKeyToScalar: toPriv, - isValidPrivateKey: (t) => { + isValidPrivateKey: t => { try { - return !!toPriv(t); + return !!toPriv(t) } catch (t) { - return !1; + return !1 } }, randomPrivateKey: () => hashToPrivateKey(etc.randomBytes(48)), - precompute: (t = 8, n = G) => (n.multiply(3n), n), - }; + precompute: (t = 8, n = G) => (n.multiply(3n), n) + } Object.defineProperties(etc, { hmacSha256Sync: { configurable: !1, get: () => _hmacSync, set(t) { - _hmacSync || (_hmacSync = t); - }, - }, -}); + _hmacSync || (_hmacSync = t) + } + } +}) const W = 8, precompute = () => { - const t = []; + const t = [] let n = G, - e = n; + e = n for (let r = 0; r < 33; r++) { - (e = n), t.push(e); - for (let r = 1; r < 128; r++) (e = e.add(n)), t.push(e); - n = e.double(); + ;((e = n), t.push(e)) + for (let r = 1; r < 128; r++) ((e = e.add(n)), t.push(e)) + n = e.double() } - return t; - }; -let Gpows; -const wNAF = (t) => { + return t + } +let Gpows +const wNAF = t => { const n = Gpows || (Gpows = precompute()), e = (t, n) => { - let e = n.negate(); - return t ? e : n; - }; + let e = n.negate() + return t ? e : n + } let r = I, - o = G; + o = G const i = BigInt(255), - s = BigInt(8); + s = BigInt(8) for (let a = 0; a < 33; a++) { - const c = 128 * a; - let d = Number(t & i); - (t >>= s), d > 128 && ((d -= 256), (t += 1n)); + const c = 128 * a + let d = Number(t & i) + ;((t >>= s), d > 128 && ((d -= 256), (t += 1n))) const u = c, m = c + Math.abs(d) - 1, h = a % 2 != 0, - l = d < 0; - 0 === d ? (o = o.add(e(h, n[u]))) : (r = r.add(e(l, n[m]))); + l = d < 0 + 0 === d ? (o = o.add(e(h, n[u]))) : (r = r.add(e(l, n[m]))) } - return { p: r, f: o }; -}; + return {p: r, f: o} +} export { getPublicKey, sign, @@ -516,5 +517,5 @@ export { etc, utils, Point as ProjectivePoint, - Signature, -}; + Signature +} diff --git a/templates/nwcprovider/admin.html b/templates/nwcprovider/admin.html index 171a6d0..81576b4 100644 --- a/templates/nwcprovider/admin.html +++ b/templates/nwcprovider/admin.html @@ -6,21 +6,56 @@

-
+
- NWC Service Provider - Config + NWC Service Provider Configuration
- + - + - ${entry.key} + + + + - + + + + + + + + + + + diff --git a/templates/nwcprovider/index.html b/templates/nwcprovider/index.html index 143c7af..3c6ecf1 100644 --- a/templates/nwcprovider/index.html +++ b/templates/nwcprovider/index.html @@ -1,8 +1,8 @@ {% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} {% block scripts %} {{ window_vars(user) }} {% endblock %} {% block page %} diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index 854aef4..ba6178e 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -997,23 +997,32 @@ async def create_valid_invoice(wallet, amount=1000): raise Exception(f"Failed to create invoice: {error}") return result["invoice"] + @pytest.mark.asyncio async def test_list_transactions(): # Create wallets with required permissions nwc1 = await create_nwc( - "wallet1", "test_list_transactions", ["invoice", "pay", "balance", "history"], [], 0 + "wallet1", + "test_list_transactions", + ["invoice", "pay", "balance", "history"], + [], + 0, ) nwc2 = await create_nwc( - "wallet2", "test_list_transactions", ["invoice", "pay", "balance", "history"], [], 0 + "wallet2", + "test_list_transactions", + ["invoice", "pay", "balance", "history"], + [], + 0, ) - + wallet1 = NWCWallet(nwc1["pairing"]) wallet2 = NWCWallet(nwc2["pairing"]) - + try: await wallet1.start() await wallet2.start() - + # First invoice await wallet1.send_event( "make_invoice", {"amount": 1000, "description": "test invoice 1"} @@ -1021,12 +1030,12 @@ async def test_list_transactions(): result1, _, error = await wallet1.wait_for("make_invoice") assert not error invoice1 = result1["invoice"] - + # Pay first invoice await wallet2.send_event("pay_invoice", {"invoice": invoice1}) _, _, error = await wallet2.wait_for("pay_invoice") assert not error - + # Second invoice await wallet1.send_event( "make_invoice", {"amount": 2000, "description": "test invoice 2"} @@ -1034,12 +1043,12 @@ async def test_list_transactions(): result2, _, error = await wallet1.wait_for("make_invoice") assert not error invoice2 = result2["invoice"] - + # Pay second invoice await wallet2.send_event("pay_invoice", {"invoice": invoice2}) _, _, error = await wallet2.wait_for("pay_invoice") assert not error - + # Test basic transaction listing await wallet1.send_event("list_transactions", {}) result, _, error = await wallet1.wait_for("list_transactions") @@ -1047,14 +1056,14 @@ async def test_list_transactions(): assert "transactions" in result transactions = result["transactions"] assert len(transactions) >= 2 - + # Test limit await wallet1.send_event("list_transactions", {"limit": 1}) result, _, error = await wallet1.wait_for("list_transactions") assert not error limited_txs = result["transactions"] assert len(limited_txs) == 1 - + finally: await wallet1.close() - await wallet2.close() \ No newline at end of file + await wallet2.close() From 93ba3ba628b6a0254c34e041625e35fc4f98b79c Mon Sep 17 00:00:00 2001 From: Arc <33088785+arcbtc@users.noreply.github.com> Date: Thu, 11 Sep 2025 05:15:23 +0100 Subject: [PATCH 58/90] Revert "Improve configuration form for readability and UX" --- .github/workflows/main.yml | 16 +- .github/workflows/release.yml | 16 +- .github/workflows/test.yml | 2 +- __init__.py | 2 +- migrations.py | 7 +- nwcp.py | 3 +- static/js/admin.js | 100 ++++--- static/js/index.js | 355 +++++++++++------------ static/js/noble-secp256k1.min.js | 479 +++++++++++++++---------------- templates/nwcprovider/admin.html | 47 +-- templates/nwcprovider/index.html | 4 +- tests/integration/test_all.py | 33 +-- 12 files changed, 512 insertions(+), 552 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c428ddd..ed44344 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,7 +1,7 @@ on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+' + - "v[0-9]+.[0-9]+.[0-9]+" jobs: release: @@ -22,7 +22,7 @@ jobs: with: token: ${{ secrets.EXT_GITHUB }} repository: lnbits/lnbits-extensions - path: './lnbits-extensions' + path: "./lnbits-extensions" - name: setup git user run: | @@ -31,12 +31,12 @@ jobs: - name: Create pull request in extensions repo env: GH_TOKEN: ${{ secrets.EXT_GITHUB }} - repo_name: '${{ github.event.repository.name }}' - tag: '${{ github.ref_name }}' - branch: 'update-${{ github.event.repository.name }}-${{ github.ref_name }}' - title: '[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}' - body: 'https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}' - archive: 'https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip' + repo_name: "${{ github.event.repository.name }}" + tag: "${{ github.ref_name }}" + branch: "update-${{ github.event.repository.name }}-${{ github.ref_name }}" + title: "[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}" + body: "https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}" + archive: "https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip" run: | cd lnbits-extensions git checkout -b $branch diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c428ddd..ed44344 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,7 @@ on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+' + - "v[0-9]+.[0-9]+.[0-9]+" jobs: release: @@ -22,7 +22,7 @@ jobs: with: token: ${{ secrets.EXT_GITHUB }} repository: lnbits/lnbits-extensions - path: './lnbits-extensions' + path: "./lnbits-extensions" - name: setup git user run: | @@ -31,12 +31,12 @@ jobs: - name: Create pull request in extensions repo env: GH_TOKEN: ${{ secrets.EXT_GITHUB }} - repo_name: '${{ github.event.repository.name }}' - tag: '${{ github.ref_name }}' - branch: 'update-${{ github.event.repository.name }}-${{ github.ref_name }}' - title: '[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}' - body: 'https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}' - archive: 'https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip' + repo_name: "${{ github.event.repository.name }}" + tag: "${{ github.ref_name }}" + branch: "update-${{ github.event.repository.name }}-${{ github.ref_name }}" + title: "[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}" + body: "https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}" + archive: "https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip" run: | cd lnbits-extensions git checkout -b $branch diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1537439..e720631 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.9' + python-version: "3.9" - name: Install dependencies run: | diff --git a/__init__.py b/__init__.py index 3cfa20c..86e59d7 100644 --- a/__init__.py +++ b/__init__.py @@ -45,7 +45,7 @@ def nwcprovider_start(): __all__ = [ "db", "nwcprovider_ext", - "nwcprovider_start", "nwcprovider_static_files", + "nwcprovider_start", "nwcprovider_stop", ] diff --git a/migrations.py b/migrations.py index da5fdd8..fd12650 100644 --- a/migrations.py +++ b/migrations.py @@ -87,13 +87,12 @@ async def m004_default_config2(db): Default config """ await db.execute( - """ + """ INSERT INTO nwcprovider.config (key, value) VALUES ('relay_alias', :value) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, - {"value": ""}, - ) - + {"value": ""}, + ) async def m005_key_last_used(db): """ diff --git a/nwcp.py b/nwcp.py index ded5999..4a5023a 100644 --- a/nwcp.py +++ b/nwcp.py @@ -4,8 +4,7 @@ import hashlib import json import random import time -from collections.abc import Awaitable -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, Union import secp256k1 import websockets.client as websockets diff --git a/static/js/admin.js b/static/js/admin.js index 3e88718..afacb7e 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -1,81 +1,87 @@ window.app = Vue.createApp({ - el: '#vue', + el: "#vue", mixins: [windowMixin], - delimiters: ['${', '}'], + delimiters: ["${", "}"], data: function () { return { - config: {}, + entries: [], columns: [ { - name: 'key', + name: "key", required: true, - label: 'Key', - align: 'left', - field: row => row.key, - sortable: true + label: "Key", + align: "left", + field: (row) => row.key, + sortable: true, }, { - name: 'value', + name: "value", required: true, - label: 'Value', - align: 'left', - field: row => row.value, - sortable: true - } - ] - } + label: "Value", + align: "left", + field: (row) => row.value, + sortable: true, + }, + ], + }; }, methods: { fetchConfig() { - this.config = {} + this.entries = []; LNbits.api .request( - 'GET', - '/nwcprovider/api/v1/config', - this.g.user.wallets[0].adminkey + "GET", + "/nwcprovider/api/v1/config", + this.g.user.wallets[0].adminkey, ) - .then(response => { - this.config = response.data - console.log('Config fetched:', this.config) + .then((response) => { + const newEntries = []; + for (const [key, value] of Object.entries(response.data)) { + newEntries.push({ + key: key, + value: value, + }); + } + this.entries.length = 0; + this.entries.push(...newEntries); }) .catch(function (error) { - console.error('Error fetching config:', error) - }) + console.error("Error fetching config:", error); + }); }, async saveConfig() { - const data = {} - for (const [key, value] of Object.entries(this.config)) { - data[key] = value + const data = {}; + for (const entry of this.entries) { + data[entry.key] = entry.value; } - console.log('Saving config:', data) try { const response = await LNbits.api.request( - 'POST', - '/nwcprovider/api/v1/config', + "POST", + "/nwcprovider/api/v1/config", this.g.user.wallets[0].adminkey, - data - ) + data, + ); Quasar.Notify.create({ - type: 'positive', - message: 'Config saved!' - }) + type: "positive", + message: "Config saved!", + }); Quasar.Notify.create({ - type: 'warning', + type: "warning", message: - 'You need to restart the server for the changes to take effect!' - }) + "You need to restart the server for the changes to take effect!", + }); } catch (error) { Quasar.Notify.create({ - type: 'negative', - message: 'Error saving config: ' + String(error) - }) - console.error('Error saving config:', error) + type: "negative", + message: "Error saving config: " + String(error), + }); + console.error("Error saving config:", error); } - } + }, }, created: function () { - this.fetchConfig() - } -}) + this.fetchConfig(); + }, +}); diff --git a/static/js/index.js b/static/js/index.js index d593469..e8a4ec1 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -1,7 +1,7 @@ window.app = Vue.createApp({ - el: '#vue', + el: "#vue", mixins: [windowMixin], - delimiters: ['${', '}'], + delimiters: ["${", "}"], data: function () { return { selectedWallet: null, @@ -10,244 +10,244 @@ window.app = Vue.createApp({ nwcsTable: { columns: [ { - name: 'description', - align: 'left', - label: 'Description', - field: 'description' + name: "description", + align: "left", + label: "Description", + field: "description", }, - {name: 'status', align: 'left', label: 'Status', field: 'status'}, + { name: "status", align: "left", label: "Status", field: "status" }, { - name: 'last_used', - align: 'left', - label: 'Last used', - field: 'last_used' + name: "last_used", + align: "left", + label: "Last used", + field: "last_used", }, { - name: 'created_at', - align: 'left', - label: 'Created', - field: 'created_at' + name: "created_at", + align: "left", + label: "Created", + field: "created_at", }, { - name: 'expires_at', - align: 'left', - label: 'Expires', - field: 'expires_at' - } + name: "expires_at", + align: "left", + label: "Expires", + field: "expires_at", + }, ], pagination: { - rowsPerPage: 10 - } + rowsPerPage: 10, + }, }, connectDialog: { show: false, - data: {} + data: {}, }, pairingDialog: { show: false, data: { - pairingUrl: '' - } + pairingUrl: "", + }, }, pairingQrDialog: { show: false, data: { - pairingUrl: '' - } + pairingUrl: "", + }, }, connectionInfoDialog: { show: false, - data: {} - } - } + data: {}, + }, + }; }, methods: { showConnectDialog() { - const wallet = this.getWallet() + const wallet = this.getWallet(); if (!wallet) { Quasar.Notify.create({ - type: 'negative', - message: 'Please select a wallet first' - }) - return + type: "negative", + message: "Please select a wallet first", + }); + return; } else { - this.connectDialog.show = true + this.connectDialog.show = true; } }, openConnectionInfoDialog(data) { - this.connectionInfoDialog.data = data - this.connectionInfoDialog.show = true + this.connectionInfoDialog.data = data; + this.connectionInfoDialog.show = true; }, closeConnectionInfoDialog() { - this.connectionInfoDialog.show = false + this.connectionInfoDialog.show = false; }, openPairingUrl() { - const url = this.pairingDialog.data.pairingUrl - if (url) window.open(url, '_blank') + const url = this.pairingDialog.data.pairingUrl; + if (url) window.open(url, "_blank"); }, go(url) { - window.open(url, '_blank') + window.open(url, "_blank"); }, async copyPairingUrl() { - const url = this.pairingDialog.data.pairingUrl + const url = this.pairingDialog.data.pairingUrl; if (url) { try { - await navigator.clipboard.writeText(url) + await navigator.clipboard.writeText(url); Quasar.Notify.create({ - type: 'positive', - message: 'URL copied to clipboard' - }) + type: "positive", + message: "URL copied to clipboard", + }); } catch (err) { Quasar.Notify.create({ - type: 'negative', - message: 'Failed to copy URL.' - }) + type: "negative", + message: "Failed to copy URL.", + }); } } }, showPairingQR() { - this.pairingQrDialog.data.pairingUrl = this.pairingDialog.data.pairingUrl - this.pairingQrDialog.show = true + this.pairingQrDialog.data.pairingUrl = this.pairingDialog.data.pairingUrl; + this.pairingQrDialog.show = true; }, closePairingQrDialog() { - this.pairingQrDialog.show = false + this.pairingQrDialog.show = false; }, loadConnectDialogData() { this.connectDialog.data = { - description: '', + description: "", expires_at: Date.now() + 1000 * 60 * 60 * 24 * 7, neverExpires: true, permissions: [], - budgets: [] - } + budgets: [], + }; for (const permission of this.nodePermissions) { this.connectDialog.data.permissions.push({ key: permission.key, name: permission.name, - value: permission.value - }) + value: permission.value, + }); } }, deleteBudget(index) { - this.connectDialog.data.budgets.splice(index, 1) + this.connectDialog.data.budgets.splice(index, 1); }, addBudget() { this.connectDialog.data.budgets.push({ budget_sats: 1000, used_budget_sats: 0, created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, - expiration: 'never' - }) + expiration: "never", + }); }, closeConnectDialog() { - this.connectDialog.show = false - this.loadConnectDialogData() + this.connectDialog.show = false; + this.loadConnectDialogData(); }, getWallet: function () { - let wallet = undefined + let wallet = undefined; for (let i = 0; i < this.g.user.wallets.length; i++) { if (this.g.user.wallets[i].id == this.selectedWallet) { - wallet = this.g.user.wallets[i] - break + wallet = this.g.user.wallets[i]; + break; } } - return wallet + return wallet; }, async generateKeyPair() { while (!window.NobleSecp256k1) { - await new Promise(resolve => setTimeout(resolve, 1)) + await new Promise((resolve) => setTimeout(resolve, 1)); } - const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey() - const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes) + const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey(); + const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes); const out = { privKeyBytes: privKeyBytes, pubKeyBytes: pubKeyBytes, privKey: window.NobleSecp256k1.etc.bytesToHex(privKeyBytes), - pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)) - } - return out + pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)), + }; + return out; }, deleteNWC: async function (pubkey) { Quasar.Dialog.create({ - title: 'Confirm Deletion', - message: 'Are you sure you want to delete this connection?', + title: "Confirm Deletion", + message: "Are you sure you want to delete this connection?", cancel: true, - persistent: true + persistent: true, }) .onOk(async () => { try { - const wallet = this.getWallet() + const wallet = this.getWallet(); const response = await LNbits.api.request( - 'DELETE', + "DELETE", `/nwcprovider/api/v1/nwc/${pubkey}`, - wallet.adminkey - ) - this.loadNwcs() + wallet.adminkey, + ); + this.loadNwcs(); Quasar.Notify.create({ - type: 'positive', - message: 'Deleted successfully' - }) + type: "positive", + message: "Deleted successfully", + }); } catch (error) { - LNbits.utils.notifyApiError(error) + LNbits.utils.notifyApiError(error); } }) .onCancel(() => { // User canceled the operation - }) + }); }, loadNwcs: async function () { - const wallet = this.getWallet() + const wallet = this.getWallet(); if (!wallet) { - this.nwcs = [] - return + this.nwcs = []; + return; } try { const response = await LNbits.api.request( - 'GET', - '/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true', - wallet.adminkey - ) - this.nwcs = response.data + "GET", + "/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true", + wallet.adminkey, + ); + this.nwcs = response.data; } catch (error) { - this.nwcs = [] + this.nwcs = []; } try { const response = await LNbits.api.request( - 'GET', - '/nwcprovider/api/v1/permissions', - wallet.adminkey - ) - const permissions = [] + "GET", + "/nwcprovider/api/v1/permissions", + wallet.adminkey, + ); + const permissions = []; for (const [key, value] of Object.entries(response.data)) { permissions.push({ key: key, name: value.name, - value: value.default - }) + value: value.default, + }); } - this.nodePermissions = permissions + this.nodePermissions = permissions; } catch (error) { - Lnbits.utils.notifyApiError(error) + Lnbits.utils.notifyApiError(error); } - this.loadConnectDialogData() - const newTableEntries = [] + this.loadConnectDialogData(); + const newTableEntries = []; for (const nwc of this.nwcs) { const t = Quasar.date.formatDate( new Date(nwc.data.created_at * 1000), - 'YYYY-MM-DD HH:mm' - ) + "YYYY-MM-DD HH:mm", + ); const e = nwc.data.expires_at > 0 ? Quasar.date.formatDate( new Date(nwc.data.expires_at * 1000), - 'YYYY-MM-DD HH:mm' + "YYYY-MM-DD HH:mm", ) - : 'Never' + : "Never"; const l = Quasar.date.formatDate( new Date(nwc.data.last_used * 1000), - 'YYYY-MM-DD HH:mm' - ) + "YYYY-MM-DD HH:mm", + ); const nwcTableEntry = { description: nwc.data.description, created_at: t, @@ -256,130 +256,131 @@ window.app = Vue.createApp({ pubkey: nwc.data.pubkey, permissions: nwc.data.permissions, budgets: [], - status: 'Active' - } + status: "Active", + }; if ( nwc.data.expires_at > 0 && nwc.data.expires_at < new Date().getTime() / 1000 ) { - nwcTableEntry.status = 'Expired' + nwcTableEntry.status = "Expired"; } for (const budget of nwc.budgets) { const createdAt = Quasar.date.formatDate( new Date(budget.created_at * 1000), - 'YYYY-MM-DD HH:mm' - ) - let refreshWindow = budget.refresh_window + "YYYY-MM-DD HH:mm", + ); + let refreshWindow = budget.refresh_window; if (refreshWindow <= 0) { - refreshWindow = 'Never' + refreshWindow = "Never"; } else if (refreshWindow == 60 * 60 * 24) { - refreshWindow = 'Daily' + refreshWindow = "Daily"; } else if (refreshWindow == 60 * 60 * 24 * 7) { - refreshWindow = 'Weekly' + refreshWindow = "Weekly"; } else if (refreshWindow == 60 * 60 * 24 * 30) { - refreshWindow = 'Monthly' + refreshWindow = "Monthly"; } else if (refreshWindow == 60 * 60 * 24 * 365) { - refreshWindow = 'Yearly' + refreshWindow = "Yearly"; } nwcTableEntry.budgets.push({ budget_sats: budget.budget_msats / 1000, used_budget_sats: budget.used_budget_msats / 1000, created_at: createdAt, - refresh_window: refreshWindow - }) + refresh_window: refreshWindow, + }); } - newTableEntries.push(nwcTableEntry) + newTableEntries.push(nwcTableEntry); } - this.nwcEntries = newTableEntries + this.nwcEntries = newTableEntries; }, closePairingDialog() { - this.pairingDialog.show = false + this.pairingDialog.show = false; }, async showPairingDialog(secret) { let response = await LNbits.api.request( - 'GET', - '/nwcprovider/api/v1/pairing/{SECRET}' - ) - response = response.data - response = response.replace('{SECRET}', secret) - this.pairingDialog.data.pairingUrl = response - this.pairingDialog.show = true + "GET", + "/nwcprovider/api/v1/pairing/{SECRET}", + ); + response = response.data; + response = response.replace("{SECRET}", secret); + this.pairingDialog.data.pairingUrl = response; + this.pairingDialog.show = true; }, async confirmConnectDialog() { - const keyPair = await this.generateKeyPair() + const keyPair = await this.generateKeyPair(); // timestamp - let expires_at = 0 + let expires_at = 0; if (!this.connectDialog.data.neverExpires) { expires_at = - new Date(this.connectDialog.data.expires_at).getTime() / 1000 + new Date(this.connectDialog.data.expires_at).getTime() / 1000; } const data = { permissions: [], description: this.connectDialog.data.description, expires_at: expires_at, - budgets: [] - } + budgets: [], + }; for (const permission of this.connectDialog.data.permissions) { - if (permission.value) data.permissions.push(permission.key) + if (permission.value) data.permissions.push(permission.key); } for (const budget of this.connectDialog.data.budgets) { - const budget_msats = budget.budget_sats * 1000 - let refresh_window = 0 + const budget_msats = budget.budget_sats * 1000; + let refresh_window = 0; switch (budget.expiry) { - case 'Daily': - refresh_window = 60 * 60 * 24 - break - case 'Weekly': - refresh_window = 60 * 60 * 24 * 7 - break - case 'Monthly': - refresh_window = 60 * 60 * 24 * 30 - break - case 'Yearly': - refresh_window = 60 * 60 * 24 * 365 - break - case 'Never': - refresh_window = 0 - break + case "Daily": + refresh_window = 60 * 60 * 24; + break; + case "Weekly": + refresh_window = 60 * 60 * 24 * 7; + break; + case "Monthly": + refresh_window = 60 * 60 * 24 * 30; + break; + case "Yearly": + refresh_window = 60 * 60 * 24 * 365; + break; + case "Never": + refresh_window = 0; + break; } data.budgets.push({ budget_msats: budget_msats, refresh_window: refresh_window, - created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000 - }) + created_at: + new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, + }); } - const wallet = this.getWallet() + const wallet = this.getWallet(); try { const response = await LNbits.api.request( - 'PUT', - '/nwcprovider/api/v1/nwc/' + keyPair.pubKey, + "PUT", + "/nwcprovider/api/v1/nwc/" + keyPair.pubKey, wallet.adminkey, - data - ) - this.closeConnectDialog() + data, + ); + this.closeConnectDialog(); if ( !response.data || !response.data.data || !response.data.data.pubkey ) { - LNbits.utils.notifyApiError('Error creating nwc pairing') - return + LNbits.utils.notifyApiError("Error creating nwc pairing"); + return; } - this.showPairingDialog(keyPair.privKey) + this.showPairingDialog(keyPair.privKey); } catch (error) { - LNbits.utils.notifyApiError(error) + LNbits.utils.notifyApiError(error); } - this.loadNwcs() - } + this.loadNwcs(); + }, }, created: function () { - this.loadNwcs() + this.loadNwcs(); }, watch: { selectedWallet(newValue, oldValue) { - this.loadNwcs() - } - } -}) + this.loadNwcs(); + }, + }, +}); diff --git a/static/js/noble-secp256k1.min.js b/static/js/noble-secp256k1.min.js index c996cd2..af328c8 100644 --- a/static/js/noble-secp256k1.min.js +++ b/static/js/noble-secp256k1.min.js @@ -4,93 +4,93 @@ const B256 = 2n ** 256n, N = B256 - 0x14551231950b75fc4402da1732fc9bebfn, Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n, Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n, - CURVE = {p: P, n: N, a: 0n, b: 7n, Gx, Gy}, + CURVE = { p: P, n: N, a: 0n, b: 7n, Gx, Gy }, fLen = 32, - crv = t => mod(mod(t * t) * t + CURVE.b), - err = (t = '') => { - throw new Error(t) + crv = (t) => mod(mod(t * t) * t + CURVE.b), + err = (t = "") => { + throw new Error(t); }, - big = t => 'bigint' == typeof t, - str = t => 'string' == typeof t, - fe = t => big(t) && 0n < t && t < P, - ge = t => big(t) && 0n < t && t < N, - isu8 = t => + big = (t) => "bigint" == typeof t, + str = (t) => "string" == typeof t, + fe = (t) => big(t) && 0n < t && t < P, + ge = (t) => big(t) && 0n < t && t < N, + isu8 = (t) => t instanceof Uint8Array || - (null != t && 'object' == typeof t && 'Uint8Array' === t.constructor.name), + (null != t && "object" == typeof t && "Uint8Array" === t.constructor.name), au8 = (t, n) => - !isu8(t) || ('number' == typeof n && n > 0 && t.length !== n) - ? err('Uint8Array expected') + !isu8(t) || ("number" == typeof n && n > 0 && t.length !== n) + ? err("Uint8Array expected") : t, - u8n = t => new Uint8Array(t), + u8n = (t) => new Uint8Array(t), toU8 = (t, n) => au8(str(t) ? h2b(t) : u8n(au8(t)), n), mod = (t, n = P) => { - let e = t % n - return e >= 0n ? e : n + e + let e = t % n; + return e >= 0n ? e : n + e; }, - isPoint = t => (t instanceof Point ? t : err('Point expected')) + isPoint = (t) => (t instanceof Point ? t : err("Point expected")); class Point { constructor(t, n, e) { - ;((this.px = t), (this.py = n), (this.pz = e)) + (this.px = t), (this.py = n), (this.pz = e); } static fromAffine(t) { - return 0n === t.x && 0n === t.y ? Point.ZERO : new Point(t.x, t.y, 1n) + return 0n === t.x && 0n === t.y ? Point.ZERO : new Point(t.x, t.y, 1n); } static fromHex(t) { - let n + let n; const e = (t = toU8(t))[0], r = t.subarray(1), o = slcNum(r, 0, 32), - i = t.length + i = t.length; if (33 === i && [2, 3].includes(e)) { - fe(o) || err('Point hex invalid: x not FE') - let t = sqrt(crv(o)) - ;(!(1 & ~e) !== (1n === (1n & t)) && (t = mod(-t)), - (n = new Point(o, t, 1n))) + fe(o) || err("Point hex invalid: x not FE"); + let t = sqrt(crv(o)); + !(1 & ~e) !== (1n === (1n & t)) && (t = mod(-t)), + (n = new Point(o, t, 1n)); } return ( 65 === i && 4 === e && (n = new Point(o, slcNum(r, 32, 64), 1n)), - n ? n.ok() : err('Point is not on curve') - ) + n ? n.ok() : err("Point is not on curve") + ); } static fromPrivateKey(t) { - return G.mul(toPriv(t)) + return G.mul(toPriv(t)); } get x() { - return this.aff().x + return this.aff().x; } get y() { - return this.aff().y + return this.aff().y; } equals(t) { - const {px: n, py: e, pz: r} = this, - {px: o, py: i, pz: s} = isPoint(t), + const { px: n, py: e, pz: r } = this, + { px: o, py: i, pz: s } = isPoint(t), a = mod(n * s), c = mod(o * r), d = mod(e * s), - u = mod(i * r) - return a === c && d === u + u = mod(i * r); + return a === c && d === u; } negate() { - return new Point(this.px, mod(-this.py), this.pz) + return new Point(this.px, mod(-this.py), this.pz); } double() { - return this.add(this) + return this.add(this); } add(t) { - const {px: n, py: e, pz: r} = this, - {px: o, py: i, pz: s} = isPoint(t), - {a, b: c} = CURVE + const { px: n, py: e, pz: r } = this, + { px: o, py: i, pz: s } = isPoint(t), + { a, b: c } = CURVE; let d = 0n, u = 0n, - m = 0n - const h = mod(3n * c) + m = 0n; + const h = mod(3n * c); let l = mod(n * o), y = mod(e * i), f = mod(r * s), p = mod(n + e), - b = mod(o + i) - ;((p = mod(p * b)), (b = mod(l + y)), (p = mod(p - b)), (b = mod(n + r))) - let g = mod(o + s) + b = mod(o + i); + (p = mod(p * b)), (b = mod(l + y)), (p = mod(p - b)), (b = mod(n + r)); + let g = mod(o + s); return ( (b = mod(b * g)), (g = mod(l + f)), @@ -123,301 +123,300 @@ class Point { (m = mod(g * m)), (m = mod(m + l)), new Point(d, u, m) - ) + ); } mul(t, n = !0) { - if (!n && 0n === t) return I - if ((ge(t) || err('invalid scalar'), this.equals(G))) return wNAF(t).p + if (!n && 0n === t) return I; + if ((ge(t) || err("invalid scalar"), this.equals(G))) return wNAF(t).p; let e = I, - r = G + r = G; for (let o = this; t > 0n; o = o.double(), t >>= 1n) - 1n & t ? (e = e.add(o)) : n && (r = r.add(o)) - return e + 1n & t ? (e = e.add(o)) : n && (r = r.add(o)); + return e; } mulAddQUns(t, n, e) { - return this.mul(n, !1).add(t.mul(e, !1)).ok() + return this.mul(n, !1).add(t.mul(e, !1)).ok(); } toAffine() { - const {px: t, py: n, pz: e} = this - if (this.equals(I)) return {x: 0n, y: 0n} - if (1n === e) return {x: t, y: n} - const r = inv(e) + const { px: t, py: n, pz: e } = this; + if (this.equals(I)) return { x: 0n, y: 0n }; + if (1n === e) return { x: t, y: n }; + const r = inv(e); return ( - 1n !== mod(e * r) && err('invalid inverse'), - {x: mod(t * r), y: mod(n * r)} - ) + 1n !== mod(e * r) && err("invalid inverse"), + { x: mod(t * r), y: mod(n * r) } + ); } assertValidity() { - const {x: t, y: n} = this.aff() + const { x: t, y: n } = this.aff(); return ( - (fe(t) && fe(n)) || err('Point invalid: x or y'), - mod(n * n) === crv(t) ? this : err('Point invalid: not on curve') - ) + (fe(t) && fe(n)) || err("Point invalid: x or y"), + mod(n * n) === crv(t) ? this : err("Point invalid: not on curve") + ); } multiply(t) { - return this.mul(t) + return this.mul(t); } aff() { - return this.toAffine() + return this.toAffine(); } ok() { - return this.assertValidity() + return this.assertValidity(); } toHex(t = !0) { - const {x: n, y: e} = this.aff() + const { x: n, y: e } = this.aff(); return ( - (t ? (0n === (1n & e) ? '02' : '03') : '04') + n2h(n) + (t ? '' : n2h(e)) - ) + (t ? (0n === (1n & e) ? "02" : "03") : "04") + n2h(n) + (t ? "" : n2h(e)) + ); } toRawBytes(t = !0) { - return h2b(this.toHex(t)) + return h2b(this.toHex(t)); } } -;((Point.BASE = new Point(Gx, Gy, 1n)), (Point.ZERO = new Point(0n, 1n, 0n))) -const {BASE: G, ZERO: I} = Point, - padh = (t, n) => t.toString(16).padStart(n, '0'), - b2h = t => +(Point.BASE = new Point(Gx, Gy, 1n)), (Point.ZERO = new Point(0n, 1n, 0n)); +const { BASE: G, ZERO: I } = Point, + padh = (t, n) => t.toString(16).padStart(n, "0"), + b2h = (t) => Array.from(t) - .map(t => padh(t, 2)) - .join(''), - h2b = t => { - const n = t.length - ;(!str(t) || n % 2) && err('hex invalid 1') - const e = u8n(n / 2) + .map((t) => padh(t, 2)) + .join(""), + h2b = (t) => { + const n = t.length; + (!str(t) || n % 2) && err("hex invalid 1"); + const e = u8n(n / 2); for (let n = 0; n < e.length; n++) { const r = 2 * n, o = t.slice(r, r + 2), - i = Number.parseInt(o, 16) - ;((Number.isNaN(i) || i < 0) && err('hex invalid 2'), (e[n] = i)) + i = Number.parseInt(o, 16); + (Number.isNaN(i) || i < 0) && err("hex invalid 2"), (e[n] = i); } - return e + return e; }, - b2n = t => BigInt('0x' + (b2h(t) || '0')), + b2n = (t) => BigInt("0x" + (b2h(t) || "0")), slcNum = (t, n, e) => b2n(t.slice(n, e)), - n2b = t => - big(t) && t >= 0n && t < B256 ? h2b(padh(t, 64)) : err('bigint expected'), - n2h = t => b2h(n2b(t)), + n2b = (t) => + big(t) && t >= 0n && t < B256 ? h2b(padh(t, 64)) : err("bigint expected"), + n2h = (t) => b2h(n2b(t)), concatB = (...t) => { - const n = u8n(t.reduce((t, n) => t + au8(n).length, 0)) - let e = 0 + const n = u8n(t.reduce((t, n) => t + au8(n).length, 0)); + let e = 0; return ( - t.forEach(t => { - ;(n.set(t, e), (e += t.length)) + t.forEach((t) => { + n.set(t, e), (e += t.length); }), n - ) + ); }, inv = (t, n = P) => { - ;(0n === t || n <= 0n) && err('no inverse n=' + t + ' mod=' + n) + (0n === t || n <= 0n) && err("no inverse n=" + t + " mod=" + n); let e = mod(t, n), r = n, o = 0n, i = 1n, s = 1n, - a = 0n + a = 0n; for (; 0n !== e; ) { const t = r / e, n = r % e, c = o - s * t, - d = i - a * t - ;((r = e), (e = n), (o = s), (i = a), (s = c), (a = d)) + d = i - a * t; + (r = e), (e = n), (o = s), (i = a), (s = c), (a = d); } - return 1n === r ? mod(o, n) : err('no inverse') + return 1n === r ? mod(o, n) : err("no inverse"); }, - sqrt = t => { - let n = 1n + sqrt = (t) => { + let n = 1n; for (let e = t, r = (P + 1n) / 4n; r > 0n; r >>= 1n) - (1n & r && (n = (n * e) % P), (e = (e * e) % P)) - return mod(n * n) === t ? n : err('sqrt invalid') + 1n & r && (n = (n * e) % P), (e = (e * e) % P); + return mod(n * n) === t ? n : err("sqrt invalid"); }, - toPriv = t => ( + toPriv = (t) => ( big(t) || (t = b2n(toU8(t, 32))), - ge(t) ? t : err('private key out of range') + ge(t) ? t : err("private key out of range") ), - moreThanHalfN = t => t > N >> 1n, - getPublicKey = (t, n = !0) => Point.fromPrivateKey(t).toRawBytes(n) + moreThanHalfN = (t) => t > N >> 1n, + getPublicKey = (t, n = !0) => Point.fromPrivateKey(t).toRawBytes(n); class Signature { constructor(t, n, e) { - ;((this.r = t), (this.s = n), (this.recovery = e), this.assertValidity()) + (this.r = t), (this.s = n), (this.recovery = e), this.assertValidity(); } static fromCompact(t) { return ( - (t = toU8(t, 64)), - new Signature(slcNum(t, 0, 32), slcNum(t, 32, 64)) - ) + (t = toU8(t, 64)), new Signature(slcNum(t, 0, 32), slcNum(t, 32, 64)) + ); } assertValidity() { - return ge(this.r) && ge(this.s) ? this : err() + return ge(this.r) && ge(this.s) ? this : err(); } addRecoveryBit(t) { - return new Signature(this.r, this.s, t) + return new Signature(this.r, this.s, t); } hasHighS() { - return moreThanHalfN(this.s) + return moreThanHalfN(this.s); } normalizeS() { return this.hasHighS() ? new Signature(this.r, mod(this.s, N), this.recovery) - : this + : this; } recoverPublicKey(t) { - const {r: n, s: e, recovery: r} = this - ;[0, 1, 2, 3].includes(r) || err('recovery id invalid') + const { r: n, s: e, recovery: r } = this; + [0, 1, 2, 3].includes(r) || err("recovery id invalid"); const o = bits2int_modN(toU8(t, 32)), - i = 2 === r || 3 === r ? n + N : n - i >= P && err('q.x invalid') - const s = 1 & r ? '03' : '02', + i = 2 === r || 3 === r ? n + N : n; + i >= P && err("q.x invalid"); + const s = 1 & r ? "03" : "02", a = Point.fromHex(s + n2h(i)), c = inv(i, N), d = mod(-o * c, N), - u = mod(e * c, N) - return G.mulAddQUns(a, d, u) + u = mod(e * c, N); + return G.mulAddQUns(a, d, u); } toCompactRawBytes() { - return h2b(this.toCompactHex()) + return h2b(this.toCompactHex()); } toCompactHex() { - return n2h(this.r) + n2h(this.s) + return n2h(this.r) + n2h(this.s); } } -const bits2int = t => { +const bits2int = (t) => { const n = 8 * t.length - 256, - e = b2n(t) - return n > 0 ? e >> BigInt(n) : e + e = b2n(t); + return n > 0 ? e >> BigInt(n) : e; }, - bits2int_modN = t => mod(bits2int(t), N), - i2o = t => n2b(t), + bits2int_modN = (t) => mod(bits2int(t), N), + i2o = (t) => n2b(t), cr = () => - 'object' == typeof globalThis && 'crypto' in globalThis + "object" == typeof globalThis && "crypto" in globalThis ? globalThis.crypto - : void 0 -let _hmacSync -const optS = {lowS: !0}, - optV = {lowS: !0}, + : void 0; +let _hmacSync; +const optS = { lowS: !0 }, + optV = { lowS: !0 }, prepSig = (t, n, e = optS) => { - ;['der', 'recovered', 'canonical'].some(t => t in e) && - err('sign() legacy options not supported') - let {lowS: r} = e - null == r && (r = !0) + ["der", "recovered", "canonical"].some((t) => t in e) && + err("sign() legacy options not supported"); + let { lowS: r } = e; + null == r && (r = !0); const o = bits2int_modN(toU8(t)), i = i2o(o), s = toPriv(n), - a = [i2o(s), i] - let c = e.extraEntropy + a = [i2o(s), i]; + let c = e.extraEntropy; if (c) { - !0 === c && (c = etc.randomBytes(32)) - const t = toU8(c) - ;(32 !== t.length && err(), a.push(t)) + !0 === c && (c = etc.randomBytes(32)); + const t = toU8(c); + 32 !== t.length && err(), a.push(t); } - const d = o + const d = o; return { seed: concatB(...a), - k2sig: t => { - const n = bits2int(t) - if (!ge(n)) return + k2sig: (t) => { + const n = bits2int(t); + if (!ge(n)) return; const e = inv(n, N), o = G.mul(n).aff(), - i = mod(o.x, N) - if (0n === i) return - const a = mod(e * mod(d + mod(s * i, N), N), N) - if (0n === a) return + i = mod(o.x, N); + if (0n === i) return; + const a = mod(e * mod(d + mod(s * i, N), N), N); + if (0n === a) return; let c = a, - u = (o.x === i ? 0 : 2) | Number(1n & o.y) + u = (o.x === i ? 0 : 2) | Number(1n & o.y); return ( r && moreThanHalfN(a) && ((c = mod(-a, N)), (u ^= 1)), new Signature(i, c, u) - ) - } - } - } + ); + }, + }; + }; function hmacDrbg(t) { let n = u8n(32), e = u8n(32), - r = 0 + r = 0; const o = () => { - ;(n.fill(1), e.fill(0), (r = 0)) + n.fill(1), e.fill(0), (r = 0); }, - i = 'drbg: tried 1000 values' + i = "drbg: tried 1000 values"; if (t) { const t = (...t) => etc.hmacSha256Async(e, n, ...t), s = async (r = u8n()) => { - ;((e = await t(u8n([0]), r)), + (e = await t(u8n([0]), r)), (n = await t()), - 0 !== r.length && ((e = await t(u8n([1]), r)), (n = await t()))) + 0 !== r.length && ((e = await t(u8n([1]), r)), (n = await t())); }, - a = async () => (r++ >= 1e3 && err(i), (n = await t()), n) + a = async () => (r++ >= 1e3 && err(i), (n = await t()), n); return async (t, n) => { - let e - for (o(), await s(t); !(e = n(await a())); ) await s() - return (o(), e) - } + let e; + for (o(), await s(t); !(e = n(await a())); ) await s(); + return o(), e; + }; } { const t = (...t) => { - const r = _hmacSync - return (r || err('etc.hmacSha256Sync not set'), r(e, n, ...t)) + const r = _hmacSync; + return r || err("etc.hmacSha256Sync not set"), r(e, n, ...t); }, s = (r = u8n()) => { - ;((e = t(u8n([0]), r)), + (e = t(u8n([0]), r)), (n = t()), - 0 !== r.length && ((e = t(u8n([1]), r)), (n = t()))) + 0 !== r.length && ((e = t(u8n([1]), r)), (n = t())); }, - a = () => (r++ >= 1e3 && err(i), (n = t()), n) + a = () => (r++ >= 1e3 && err(i), (n = t()), n); return (t, n) => { - let e - for (o(), s(t); !(e = n(a())); ) s() - return (o(), e) - } + let e; + for (o(), s(t); !(e = n(a())); ) s(); + return o(), e; + }; } } const signAsync = async (t, n, e = optS) => { - const {seed: r, k2sig: o} = prepSig(t, n, e) - return hmacDrbg(!0)(r, o) + const { seed: r, k2sig: o } = prepSig(t, n, e); + return hmacDrbg(!0)(r, o); }, sign = (t, n, e = optS) => { - const {seed: r, k2sig: o} = prepSig(t, n, e) - return hmacDrbg(!1)(r, o) + const { seed: r, k2sig: o } = prepSig(t, n, e); + return hmacDrbg(!1)(r, o); }, verify = (t, n, e, r = optV) => { let o, i, s, - {lowS: a} = r - ;(null == a && (a = !0), - 'strict' in r && err('verify() legacy options not supported')) - const c = t && 'object' == typeof t && 'r' in t - c || 64 === toU8(t).length || err('signature must be 64 bytes') + { lowS: a } = r; + null == a && (a = !0), + "strict" in r && err("verify() legacy options not supported"); + const c = t && "object" == typeof t && "r" in t; + c || 64 === toU8(t).length || err("signature must be 64 bytes"); try { - ;((o = c + (o = c ? new Signature(t.r, t.s).assertValidity() : Signature.fromCompact(t)), (i = bits2int_modN(toU8(n))), - (s = e instanceof Point ? e.ok() : Point.fromHex(e))) + (s = e instanceof Point ? e.ok() : Point.fromHex(e)); } catch (t) { - return !1 + return !1; } - if (!o) return !1 - const {r: d, s: u} = o - if (a && moreThanHalfN(u)) return !1 - let m + if (!o) return !1; + const { r: d, s: u } = o; + if (a && moreThanHalfN(u)) return !1; + let m; try { const t = inv(u, N), n = mod(i * t, N), - e = mod(d * t, N) - m = G.mulAddQUns(s, n, e).aff() + e = mod(d * t, N); + m = G.mulAddQUns(s, n, e).aff(); } catch (t) { - return !1 + return !1; } - if (!m) return !1 - return mod(m.x, N) === d + if (!m) return !1; + return mod(m.x, N) === d; }, getSharedSecret = (t, n, e = !0) => Point.fromHex(n).mul(toPriv(t)).toRawBytes(e), - hashToPrivateKey = t => { - ;((t = toU8(t)).length < 40 || t.length > 1024) && - err('expected proper params') - const n = mod(b2n(t), N - 1n) + 1n - return n2b(n) + hashToPrivateKey = (t) => { + ((t = toU8(t)).length < 40 || t.length > 1024) && + err("expected proper params"); + const n = mod(b2n(t), N - 1n) + 1n; + return n2b(n); }, etc = { hexToBytes: h2b, @@ -429,84 +428,84 @@ const signAsync = async (t, n, e = optS) => { invert: inv, hmacSha256Async: async (t, ...n) => { const e = cr(), - r = e && e.subtle - if (!r) return err('etc.hmacSha256Async not set') + r = e && e.subtle; + if (!r) return err("etc.hmacSha256Async not set"); const o = await r.importKey( - 'raw', + "raw", t, - {name: 'HMAC', hash: {name: 'SHA-256'}}, + { name: "HMAC", hash: { name: "SHA-256" } }, !1, - ['sign'] - ) - return u8n(await r.sign('HMAC', o, concatB(...n))) + ["sign"], + ); + return u8n(await r.sign("HMAC", o, concatB(...n))); }, hmacSha256Sync: _hmacSync, hashToPrivateKey, randomBytes: (t = 32) => { - const n = cr() + const n = cr(); return ( (n && n.getRandomValues) || - err('crypto.getRandomValues must be defined'), + err("crypto.getRandomValues must be defined"), n.getRandomValues(u8n(t)) - ) - } + ); + }, }, utils = { normPrivateKeyToScalar: toPriv, - isValidPrivateKey: t => { + isValidPrivateKey: (t) => { try { - return !!toPriv(t) + return !!toPriv(t); } catch (t) { - return !1 + return !1; } }, randomPrivateKey: () => hashToPrivateKey(etc.randomBytes(48)), - precompute: (t = 8, n = G) => (n.multiply(3n), n) - } + precompute: (t = 8, n = G) => (n.multiply(3n), n), + }; Object.defineProperties(etc, { hmacSha256Sync: { configurable: !1, get: () => _hmacSync, set(t) { - _hmacSync || (_hmacSync = t) - } - } -}) + _hmacSync || (_hmacSync = t); + }, + }, +}); const W = 8, precompute = () => { - const t = [] + const t = []; let n = G, - e = n + e = n; for (let r = 0; r < 33; r++) { - ;((e = n), t.push(e)) - for (let r = 1; r < 128; r++) ((e = e.add(n)), t.push(e)) - n = e.double() + (e = n), t.push(e); + for (let r = 1; r < 128; r++) (e = e.add(n)), t.push(e); + n = e.double(); } - return t - } -let Gpows -const wNAF = t => { + return t; + }; +let Gpows; +const wNAF = (t) => { const n = Gpows || (Gpows = precompute()), e = (t, n) => { - let e = n.negate() - return t ? e : n - } + let e = n.negate(); + return t ? e : n; + }; let r = I, - o = G + o = G; const i = BigInt(255), - s = BigInt(8) + s = BigInt(8); for (let a = 0; a < 33; a++) { - const c = 128 * a - let d = Number(t & i) - ;((t >>= s), d > 128 && ((d -= 256), (t += 1n))) + const c = 128 * a; + let d = Number(t & i); + (t >>= s), d > 128 && ((d -= 256), (t += 1n)); const u = c, m = c + Math.abs(d) - 1, h = a % 2 != 0, - l = d < 0 - 0 === d ? (o = o.add(e(h, n[u]))) : (r = r.add(e(l, n[m]))) + l = d < 0; + 0 === d ? (o = o.add(e(h, n[u]))) : (r = r.add(e(l, n[m]))); } - return {p: r, f: o} -} + return { p: r, f: o }; +}; export { getPublicKey, sign, @@ -517,5 +516,5 @@ export { etc, utils, Point as ProjectivePoint, - Signature -} + Signature, +}; diff --git a/templates/nwcprovider/admin.html b/templates/nwcprovider/admin.html index 81576b4..171a6d0 100644 --- a/templates/nwcprovider/admin.html +++ b/templates/nwcprovider/admin.html @@ -6,56 +6,21 @@
-
+
- NWC Service Provider Configuration + NWC Service Provider - Config
- + - + - - + ${entry.key} - - - - - - - - - - - - - + diff --git a/templates/nwcprovider/index.html b/templates/nwcprovider/index.html index 3c6ecf1..143c7af 100644 --- a/templates/nwcprovider/index.html +++ b/templates/nwcprovider/index.html @@ -1,8 +1,8 @@ {% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} {% block scripts %} {{ window_vars(user) }} {% endblock %} {% block page %} diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index ba6178e..854aef4 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -997,32 +997,23 @@ async def create_valid_invoice(wallet, amount=1000): raise Exception(f"Failed to create invoice: {error}") return result["invoice"] - @pytest.mark.asyncio async def test_list_transactions(): # Create wallets with required permissions nwc1 = await create_nwc( - "wallet1", - "test_list_transactions", - ["invoice", "pay", "balance", "history"], - [], - 0, + "wallet1", "test_list_transactions", ["invoice", "pay", "balance", "history"], [], 0 ) nwc2 = await create_nwc( - "wallet2", - "test_list_transactions", - ["invoice", "pay", "balance", "history"], - [], - 0, + "wallet2", "test_list_transactions", ["invoice", "pay", "balance", "history"], [], 0 ) - + wallet1 = NWCWallet(nwc1["pairing"]) wallet2 = NWCWallet(nwc2["pairing"]) - + try: await wallet1.start() await wallet2.start() - + # First invoice await wallet1.send_event( "make_invoice", {"amount": 1000, "description": "test invoice 1"} @@ -1030,12 +1021,12 @@ async def test_list_transactions(): result1, _, error = await wallet1.wait_for("make_invoice") assert not error invoice1 = result1["invoice"] - + # Pay first invoice await wallet2.send_event("pay_invoice", {"invoice": invoice1}) _, _, error = await wallet2.wait_for("pay_invoice") assert not error - + # Second invoice await wallet1.send_event( "make_invoice", {"amount": 2000, "description": "test invoice 2"} @@ -1043,12 +1034,12 @@ async def test_list_transactions(): result2, _, error = await wallet1.wait_for("make_invoice") assert not error invoice2 = result2["invoice"] - + # Pay second invoice await wallet2.send_event("pay_invoice", {"invoice": invoice2}) _, _, error = await wallet2.wait_for("pay_invoice") assert not error - + # Test basic transaction listing await wallet1.send_event("list_transactions", {}) result, _, error = await wallet1.wait_for("list_transactions") @@ -1056,14 +1047,14 @@ async def test_list_transactions(): assert "transactions" in result transactions = result["transactions"] assert len(transactions) >= 2 - + # Test limit await wallet1.send_event("list_transactions", {"limit": 1}) result, _, error = await wallet1.wait_for("list_transactions") assert not error limited_txs = result["transactions"] assert len(limited_txs) == 1 - + finally: await wallet1.close() - await wallet2.close() + await wallet2.close() \ No newline at end of file From 603b34507320a607a5a425af7c1d4b97de5ac90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Fri, 12 Sep 2025 09:30:16 +0200 Subject: [PATCH 59/90] fix: use lnbits linting, change to uv (#9) * fix: use lnbits linting, change to uv - formatting - prettier - pyright * dont ignore packagejson * readd poetry lock for integration tests * fix pyright * fix mypy * fix test? * fix lnbits version * fixup tests * fixup! --- .github/workflows/lint.yml | 10 + .github/workflows/main.yml | 52 - .github/workflows/release.yml | 26 +- .github/workflows/test.yml | 4 +- .gitignore | 5 +- .prettierrc | 12 + Makefile | 24 +- __init__.py | 2 +- crud.py | 38 +- execution_queue.py | 4 +- migrations.py | 13 +- models.py | 37 +- nwcp.py | 61 +- package-lock.json | 62 + package.json | 15 + poetry.lock | 3385 +++++++++++++++++------------- pyproject.toml | 48 +- static/js/admin.js | 94 +- static/js/index.js | 355 ++-- static/js/noble-secp256k1.min.js | 479 ++--- tasks.py | 60 +- templates/nwcprovider/index.html | 4 +- tests/__init__.py | 0 tests/integration/test_all.py | 116 +- tests/unit/__init__.py | 0 tests/unit/test_nwcp.py | 11 +- uv.lock | 2276 ++++++++++++++++++++ views_api.py | 37 +- 28 files changed, 5045 insertions(+), 2185 deletions(-) create mode 100644 .github/workflows/lint.yml delete mode 100644 .github/workflows/main.yml create mode 100644 .prettierrc create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 tests/__init__.py create mode 100644 tests/unit/__init__.py create mode 100644 uv.lock diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..4e02f97 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,10 @@ +name: lint +on: + push: + branches: + - main + pull_request: + +jobs: + lint: + uses: lnbits/lnbits/.github/workflows/lint.yml@dev diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index ed44344..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,52 +0,0 @@ -on: - push: - tags: - - "v[0-9]+.[0-9]+.[0-9]+" - -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Create github release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - tag: ${{ github.ref_name }} - run: | - gh release create "$tag" --generate-notes - pullrequest: - needs: [release] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - token: ${{ secrets.EXT_GITHUB }} - repository: lnbits/lnbits-extensions - path: "./lnbits-extensions" - - - name: setup git user - run: | - git config --global user.name "alan" - git config --global user.email "alan@lnbits.com" - - name: Create pull request in extensions repo - env: - GH_TOKEN: ${{ secrets.EXT_GITHUB }} - repo_name: "${{ github.event.repository.name }}" - tag: "${{ github.ref_name }}" - branch: "update-${{ github.event.repository.name }}-${{ github.ref_name }}" - title: "[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}" - body: "https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}" - archive: "https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip" - run: | - cd lnbits-extensions - git checkout -b $branch - # if there is another open PR - git pull origin $branch || echo "branch does not exist" - sh util.sh update_extension $repo_name $tag - git add -A - git commit -am "$title" - git push origin $branch - # check if pr exists before creating it - gh config set pager cat - check=$(gh pr list -H $branch | wc -l) - test $check -ne 0 || gh pr create --title "$title" --body "$body" --repo lnbits/lnbits-extensions diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ed44344..b76c725 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,51 +1,57 @@ on: push: tags: - - "v[0-9]+.[0-9]+.[0-9]+" + - 'v[0-9]+.[0-9]+.[0-9]+' jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Create github release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} tag: ${{ github.ref_name }} run: | gh release create "$tag" --generate-notes + pullrequest: needs: [release] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: token: ${{ secrets.EXT_GITHUB }} repository: lnbits/lnbits-extensions - path: "./lnbits-extensions" + path: './lnbits-extensions' - name: setup git user run: | git config --global user.name "alan" git config --global user.email "alan@lnbits.com" + - name: Create pull request in extensions repo env: GH_TOKEN: ${{ secrets.EXT_GITHUB }} - repo_name: "${{ github.event.repository.name }}" - tag: "${{ github.ref_name }}" - branch: "update-${{ github.event.repository.name }}-${{ github.ref_name }}" - title: "[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}" - body: "https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}" - archive: "https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip" + repo_name: '${{ github.event.repository.name }}' + tag: '${{ github.ref_name }}' + branch: 'update-${{ github.event.repository.name }}-${{ github.ref_name }}' + title: '[UPDATE] ${{ github.event.repository.name }} to ${{ github.ref_name }}' + body: 'https://github.com/lnbits/${{ github.event.repository.name }}/releases/${{ github.ref_name }}' + archive: 'https://github.com/lnbits/${{ github.event.repository.name }}/archive/refs/tags/${{ github.ref_name }}.zip' run: | cd lnbits-extensions git checkout -b $branch + # if there is another open PR git pull origin $branch || echo "branch does not exist" + sh util.sh update_extension $repo_name $tag + git add -A git commit -am "$title" git push origin $branch + # check if pr exists before creating it gh config set pager cat check=$(gh pr list -H $branch | wc -l) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e720631..7fa81f8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,12 +10,12 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v2 with: - python-version: "3.9" + python-version: '3.10' - name: Install dependencies run: | diff --git a/.gitignore b/.gitignore index 118a873..acd0773 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,5 @@ node_modules .mypy_cache data .vscode -package.json -package-lock.json -dump \ No newline at end of file +dump +.venv diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..725c398 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,12 @@ +{ + "semi": false, + "arrowParens": "avoid", + "insertPragma": false, + "printWidth": 80, + "proseWrap": "preserve", + "singleQuote": true, + "trailingComma": "none", + "useTabs": false, + "bracketSameLine": false, + "bracketSpacing": false +} diff --git a/Makefile b/Makefile index 9a08146..0fac253 100644 --- a/Makefile +++ b/Makefile @@ -5,27 +5,27 @@ format: prettier black ruff check: mypy pyright checkblack checkruff checkprettier prettier: - poetry run ./node_modules/.bin/prettier --write . + uv run ./node_modules/.bin/prettier --write . pyright: - poetry run ./node_modules/.bin/pyright + uv run ./node_modules/.bin/pyright mypy: - poetry run mypy . + uv run mypy . black: - poetry run black . + uv run black . ruff: - poetry run ruff check . --fix + uv run ruff check . --fix checkruff: - poetry run ruff check . + uv run ruff check . checkprettier: - poetry run ./node_modules/.bin/prettier --check . + uv run ./node_modules/.bin/prettier --check . checkblack: - poetry run black --check . + uv run black --check . checkeditorconfig: editorconfig-checker @@ -33,14 +33,14 @@ checkeditorconfig: test: PYTHONUNBUFFERED=1 \ DEBUG=true \ - poetry run pytest + uv run pytest install-pre-commit-hook: @echo "Installing pre-commit hook to git" - @echo "Uninstall the hook with poetry run pre-commit uninstall" - poetry run pre-commit install + @echo "Uninstall the hook with uv run pre-commit uninstall" + uv run pre-commit install pre-commit: - poetry run pre-commit run --all-files + uv run pre-commit run --all-files checkbundle: diff --git a/__init__.py b/__init__.py index 86e59d7..3cfa20c 100644 --- a/__init__.py +++ b/__init__.py @@ -45,7 +45,7 @@ def nwcprovider_start(): __all__ = [ "db", "nwcprovider_ext", - "nwcprovider_static_files", "nwcprovider_start", + "nwcprovider_static_files", "nwcprovider_stop", ] diff --git a/crud.py b/crud.py index ee50849..872d0d6 100644 --- a/crud.py +++ b/crud.py @@ -1,5 +1,4 @@ import time -from typing import List, Optional from lnbits.db import Database @@ -11,6 +10,7 @@ from .models import ( GetNWC, GetWalletNWC, NWCBudget, + NWCConfig, NWCKey, NWCNewBudget, TrackedSpendNWC, @@ -71,7 +71,8 @@ async def delete_nwc(data: DeleteNWC) -> None: # hardening # assert_valid_pubkey(data.pubkey) - assert_valid_wallet_id(data.wallet) + if data.wallet: + assert_valid_wallet_id(data.wallet) # ## # await db.execute( @@ -80,9 +81,12 @@ async def delete_nwc(data: DeleteNWC) -> None: ) -async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: +async def get_wallet_nwcs(data: GetWalletNWC) -> list[NWCKey]: expires = int(time.time()) if not data.include_expired else -1 + if not data.wallet: + return [] + # hardening # assert_valid_wallet_id(data.wallet) assert_valid_expiration_seconds(expires) @@ -101,7 +105,7 @@ async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: ) -async def get_nwc(data: GetNWC) -> Optional[NWCKey]: +async def get_nwc(data: GetNWC) -> NWCKey | None: expires = int(time.time()) if not data.include_expired else -1 # hardening # @@ -150,17 +154,17 @@ async def get_nwc(data: GetNWC) -> Optional[NWCKey]: return row -async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: +async def get_budgets_nwc(data: GetBudgetsNWC) -> list[NWCBudget]: # hardening # assert_valid_pubkey(data.pubkey) # ## # - rows = await db.fetchall( + budgets = await db.fetchall( "SELECT * FROM nwcprovider.budgets WHERE pubkey = :pubkey", {"pubkey": data.pubkey}, + model=NWCBudget, ) - budgets = [NWCBudget(**row) for row in rows] if data.calculate_spent: for budget in budgets: last_cycle, next_cycle = budget.get_timestamp_range() @@ -170,7 +174,7 @@ async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: assert_valid_timestamp_seconds(next_cycle) # ## # - tot_spent_in_range_msats = await db.fetchone( + result: dict = await db.fetchone( """ SELECT SUM(amount_msats) FROM nwcprovider.spent WHERE pubkey = :pubkey AND created_at >= @@ -182,9 +186,7 @@ async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: "next_cycle": next_cycle, }, ) - tot_spent_in_range_msats = ( - next(iter(tot_spent_in_range_msats.values())) or 0 - ) + tot_spent_in_range_msats = next(iter(result.values())) or 0 # hardening # assert_valid_msats(tot_spent_in_range_msats) @@ -263,12 +265,14 @@ async def tracked_spend_nwc(data: TrackedSpendNWC, action): async def get_config_nwc(key: str): - row = await db.fetchone( - "SELECT * FROM nwcprovider.config WHERE key = :key", {"key": key} + config = await db.fetchone( + "SELECT * FROM nwcprovider.config WHERE key = :key", + {"key": key}, + model=NWCConfig, ) - if not row: + if not config: return None - return row["value"] + return config.value async def set_config_nwc(key: str, value: str): @@ -289,5 +293,5 @@ async def set_config_nwc(key: str, value: str): async def get_all_config_nwc(): - rows = await db.fetchall("SELECT * FROM nwcprovider.config") - return {row["key"]: row["value"] for row in rows} + rows = await db.fetchall("SELECT * FROM nwcprovider.config", model=NWCConfig) + return {row.key: row.value for row in rows} diff --git a/execution_queue.py b/execution_queue.py index 972e9a6..607113d 100644 --- a/execution_queue.py +++ b/execution_queue.py @@ -1,7 +1,7 @@ import asyncio -from typing import Any, Dict +from typing import Any -execution_queue: asyncio.Queue[Dict[str, Any]] = asyncio.Queue() +execution_queue: asyncio.Queue[dict[str, Any]] = asyncio.Queue() async def enqueue(action): diff --git a/migrations.py b/migrations.py index fd12650..cb816db 100644 --- a/migrations.py +++ b/migrations.py @@ -75,7 +75,8 @@ async def m003_default_config(db): new_private_key = bytes.hex(secp256k1._gen_private_key()) await db.execute( """ - INSERT INTO nwcprovider.config (key, value) VALUES ('provider_key', :provider_key) + INSERT INTO nwcprovider.config (key, value) + VALUES ('provider_key', :provider_key) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, {"provider_key": new_private_key}, @@ -87,12 +88,13 @@ async def m004_default_config2(db): Default config """ await db.execute( - """ + """ INSERT INTO nwcprovider.config (key, value) VALUES ('relay_alias', :value) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, - {"value": ""}, - ) + {"value": ""}, + ) + async def m005_key_last_used(db): """ @@ -111,7 +113,8 @@ async def m006_default_config3(db): """ await db.execute( """ - INSERT INTO nwcprovider.config (key, value) VALUES ('handle_missed_events', :value) + INSERT INTO nwcprovider.config (key, value) + VALUES ('handle_missed_events', :value) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, {"value": "0"}, diff --git a/models.py b/models.py index 2208d98..a84c46f 100644 --- a/models.py +++ b/models.py @@ -2,7 +2,7 @@ import time from sqlite3 import Row -from typing import Any, Dict, List, Optional +from typing import Any from pydantic import BaseModel @@ -16,14 +16,14 @@ class NWCKey(BaseModel): created_at: int last_used: int - def get_permissions(self) -> List[str]: + def get_permissions(self) -> list[str]: try: return self.permissions.split(" ") except Exception: return [] @classmethod - def from_row(cls, row: Dict[str, Any]) -> "NWCKey": + def from_row(cls, row: dict[str, Any]) -> "NWCKey": return cls(**row) @@ -53,7 +53,7 @@ class NWCBudget(BaseModel): class NWCNewBudget(BaseModel): - pubkey: Optional[str] + pubkey: str | None budget_msats: int refresh_window: int created_at: int @@ -65,30 +65,30 @@ class CreateNWCKey(BaseModel): wallet: str description: str expires_at: int - permissions: List[str] - budgets: Optional[List[NWCNewBudget]] = None + permissions: list[str] + budgets: list[NWCNewBudget] | None = None class DeleteNWC(BaseModel): pubkey: str - wallet: Optional[str] = None + wallet: str | None = None class GetWalletNWC(BaseModel): - wallet: Optional[str] = None - include_expired: Optional[bool] = False + wallet: str | None = None + include_expired: bool | None = False class GetNWC(BaseModel): pubkey: str - wallet: Optional[str] = None - include_expired: Optional[bool] = False - refresh_last_used: Optional[bool] = False + wallet: str | None = None + include_expired: bool | None = False + refresh_last_used: bool | None = False class GetBudgetsNWC(BaseModel): pubkey: str - calculate_spent: Optional[bool] = False + calculate_spent: bool | None = False class TrackedSpendNWC(BaseModel): @@ -98,12 +98,17 @@ class TrackedSpendNWC(BaseModel): # API models class NWCRegistrationRequest(BaseModel): - permissions: List[str] + permissions: list[str] description: str expires_at: int - budgets: List[NWCNewBudget] + budgets: list[NWCNewBudget] class NWCGetResponse(BaseModel): data: NWCKey - budgets: List[NWCBudget] + budgets: list[NWCBudget] + + +class NWCConfig(BaseModel): + key: str + value: str diff --git a/nwcp.py b/nwcp.py index 4a5023a..378acbd 100644 --- a/nwcp.py +++ b/nwcp.py @@ -4,16 +4,17 @@ import hashlib import json import random import time -from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, Union +from collections.abc import Awaitable, Callable +from typing import Any, Union import secp256k1 -import websockets.client as websockets from Cryptodome import Random from Cryptodome.Cipher import AES from Cryptodome.Util.Padding import pad, unpad from lnbits.helpers import encrypt_internal_message from lnbits.settings import settings from loguru import logger +from websockets.legacy.client import connect class RateLimit: @@ -23,14 +24,14 @@ class RateLimit: class MainSubscription: def __init__(self): - self.requests_sub_id: Optional[str] = None - self.responses_sub_id: Optional[str] = None + self.requests_sub_id: str | None = None + self.responses_sub_id: str | None = None self.requests_eose = False self.responses_eose = False - self.events: Dict[str, Dict] = {} - self.responses: List[str] = [] + self.events: dict[str, dict] = {} + self.responses: list[str] = [] - def get_stale(self) -> List[Dict]: + def get_stale(self) -> list[dict]: """ Get all the pending events that do not have a response yet. """ @@ -47,7 +48,7 @@ class MainSubscription: if event_id not in self.responses: self.responses.append(event_id) - def gc(self, expire: Optional[int] = None): + def gc(self, expire: int | None = None): """ Garbage collection, remove all the events that have a response older than expire seconds (defaults to 1 hour if 0 or None) @@ -74,8 +75,8 @@ class MainSubscription: class NWCServiceProvider: def __init__( self, - private_key: Optional[str] = None, - relay: Optional[str] = None, + private_key: str | None = None, + relay: str | None = None, handle_missed_events: int = 0, ): if not relay: # Connect to nostrclient @@ -100,17 +101,17 @@ class NWCServiceProvider: self.public_key_hex = self.public_key.serialize().hex()[2:] # List of supported methods - self.supported_methods: List[str] = [] + self.supported_methods: list[str] = [] # Keep track of the number of subscriptions (used for unique subid) self.subscriptions_count: int = 0 # Request listeners, listen to specific methods - self.request_listeners: Dict[ + self.request_listeners: dict[ str, Callable[ - [NWCServiceProvider, str, Dict], - Awaitable[List[Tuple[Optional[Dict], Optional[Dict], List]]], + [NWCServiceProvider, str, dict], + Awaitable[list[tuple[dict | None, dict | None, list]]], ], ] = {} @@ -122,7 +123,7 @@ class NWCServiceProvider: # Subscription self.sub = None - self.rate_limit: Dict[str, RateLimit] = {} + self.rate_limit: dict[str, RateLimit] = {} # websocket connection self.ws = None @@ -161,8 +162,8 @@ class NWCServiceProvider: self, method: str, listener: Callable[ - ["NWCServiceProvider", str, Dict], - Awaitable[List[Tuple[Optional[Dict], Optional[Dict], List]]], + ["NWCServiceProvider", str, dict], + Awaitable[list[tuple[dict | None, dict | None, list]]], ], ): """ @@ -185,7 +186,7 @@ class NWCServiceProvider: self.reconnect_task = asyncio.create_task(self._connect_to_relay()) self.gc_task = asyncio.create_task(self._gc_loop()) - def _json_dumps(self, data: Union[Dict, list]) -> str: + def _json_dumps(self, data: Union[dict, list]) -> str: """ Converts a Python dictionary to a JSON string with compact encoding. @@ -195,7 +196,7 @@ class NWCServiceProvider: Returns: str: The compact JSON string. """ - if isinstance(data, Dict): + if isinstance(data, dict): data = {k: v for k, v in data.items() if v is not None} return json.dumps(data, separators=(",", ":"), ensure_ascii=False) @@ -205,7 +206,7 @@ class NWCServiceProvider: """ return self.shutdown or not settings.lnbits_running - async def _send(self, data: List[Any]): + async def _send(self, data: list[Any]): """ Sends data to the relay. @@ -249,7 +250,7 @@ class NWCServiceProvider: await asyncio.sleep(1) async def _ratelimit(self, unit: str, max_sleep_time: int = 120) -> None: - limit: Optional[RateLimit] = self.rate_limit.get(unit) + limit: RateLimit | None = self.rate_limit.get(unit) if not limit: self.rate_limit[unit] = limit = RateLimit() @@ -289,7 +290,7 @@ class NWCServiceProvider: await self._send(["REQ", self.sub.requests_sub_id, req_filter]) await self._send(["REQ", self.sub.responses_sub_id, res_filter]) - async def _on_connection(self, ws): + async def _on_connection(self, _): """ On connection callback, announce the service provider methods and subscribe to nip67 events. @@ -306,7 +307,7 @@ class NWCServiceProvider: # Resubscribe to nwc events await self._subscribe() - async def _handle_request(self, event: Dict) -> List[Dict]: + async def _handle_request(self, event: dict) -> list[dict]: """ Handle a nwc request """ @@ -319,7 +320,7 @@ class NWCServiceProvider: # Handle request method = content["method"] listener = self.request_listeners.get(method, None) - outs: List[Dict[str, Any]] = [] + outs: list[dict[str, Any]] = [] if not listener: outs.append( { @@ -352,7 +353,7 @@ class NWCServiceProvider: if "error" in out: content["error"] = out["error"] # Prepare response event - res: Dict = { + res: dict = { "kind": 23195, "created_at": int(time.time()), "tags": out.get("tags", []), @@ -451,7 +452,7 @@ class NWCServiceProvider: await self._ratelimit("subscribing") await self._subscribe() - async def _on_message(self, ws, message: str): + async def _on_message(self, _, message: str): """ Handle incoming messages from the relay. """ @@ -484,7 +485,7 @@ class NWCServiceProvider: ): # Reconnect until the instance is shutting down logger.debug("Creating new connection...") try: - async with websockets.connect(self.relay) as ws: + async with connect(self.relay) as ws: self.ws = ws self.connected = True await self._on_connection(ws) @@ -513,7 +514,7 @@ class NWCServiceProvider: await self._ratelimit("connecting") def _encrypt_content( - self, content: str, pubkey_hex: str, iv_seed: Optional[int] = None + self, content: str, pubkey_hex: str, iv_seed: int | None = None ) -> str: """ Encrypts the content for the given public key @@ -571,7 +572,7 @@ class NWCServiceProvider: decrypted = decrypted_bytes.decode("utf-8") return decrypted - def _verify_event(self, event: Dict) -> bool: + def _verify_event(self, event: dict) -> bool: """ Verify the event signature @@ -602,7 +603,7 @@ class NWCServiceProvider: return False return True - def _sign_event(self, event: Dict) -> Dict: + def _sign_event(self, event: dict) -> dict: """ Signs the event (in place) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..06a81d1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,62 @@ +{ + "name": "nwcprovider", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nwcprovider", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "prettier": "^3.2.5", + "pyright": "^1.1.358" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pyright": { + "version": "1.1.405", + "resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.405.tgz", + "integrity": "sha512-hgy12kLZ1oAMtl9LTsByHftg3AD6Pouwu5rBsQlqYQqCCdGBgaQm9XDAPDap7ayWe9W+NWrUwO7Zy1K7uXoE2A==", + "license": "MIT", + "bin": { + "pyright": "index.js", + "pyright-langserver": "langserver.index.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..97f219d --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "nwcprovider", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "prettier": "^3.2.5", + "pyright": "^1.1.358" + } +} diff --git a/poetry.lock b/poetry.lock index f25ce14..4248c68 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,43 +1,180 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +description = "Happy Eyeballs for asyncio" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8"}, + {file = "aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558"}, +] + +[[package]] +name = "aiohttp" +version = "3.12.15" +description = "Async http client/server framework (asyncio)" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "aiohttp-3.12.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b6fc902bff74d9b1879ad55f5404153e2b33a82e72a95c89cec5eb6cc9e92fbc"}, + {file = "aiohttp-3.12.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:098e92835b8119b54c693f2f88a1dec690e20798ca5f5fe5f0520245253ee0af"}, + {file = "aiohttp-3.12.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:40b3fee496a47c3b4a39a731954c06f0bd9bd3e8258c059a4beb76ac23f8e421"}, + {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ce13fcfb0bb2f259fb42106cdc63fa5515fb85b7e87177267d89a771a660b79"}, + {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3beb14f053222b391bf9cf92ae82e0171067cc9c8f52453a0f1ec7c37df12a77"}, + {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c39e87afe48aa3e814cac5f535bc6199180a53e38d3f51c5e2530f5aa4ec58c"}, + {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5f1b4ce5bc528a6ee38dbf5f39bbf11dd127048726323b72b8e85769319ffc4"}, + {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1004e67962efabbaf3f03b11b4c43b834081c9e3f9b32b16a7d97d4708a9abe6"}, + {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8faa08fcc2e411f7ab91d1541d9d597d3a90e9004180edb2072238c085eac8c2"}, + {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fe086edf38b2222328cdf89af0dde2439ee173b8ad7cb659b4e4c6f385b2be3d"}, + {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:79b26fe467219add81d5e47b4a4ba0f2394e8b7c7c3198ed36609f9ba161aecb"}, + {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b761bac1192ef24e16706d761aefcb581438b34b13a2f069a6d343ec8fb693a5"}, + {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e153e8adacfe2af562861b72f8bc47f8a5c08e010ac94eebbe33dc21d677cd5b"}, + {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fc49c4de44977aa8601a00edbf157e9a421f227aa7eb477d9e3df48343311065"}, + {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2776c7ec89c54a47029940177e75c8c07c29c66f73464784971d6a81904ce9d1"}, + {file = "aiohttp-3.12.15-cp310-cp310-win32.whl", hash = "sha256:2c7d81a277fa78b2203ab626ced1487420e8c11a8e373707ab72d189fcdad20a"}, + {file = "aiohttp-3.12.15-cp310-cp310-win_amd64.whl", hash = "sha256:83603f881e11f0f710f8e2327817c82e79431ec976448839f3cd05d7afe8f830"}, + {file = "aiohttp-3.12.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d3ce17ce0220383a0f9ea07175eeaa6aa13ae5a41f30bc61d84df17f0e9b1117"}, + {file = "aiohttp-3.12.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:010cc9bbd06db80fe234d9003f67e97a10fe003bfbedb40da7d71c1008eda0fe"}, + {file = "aiohttp-3.12.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f9d7c55b41ed687b9d7165b17672340187f87a773c98236c987f08c858145a9"}, + {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc4fbc61bb3548d3b482f9ac7ddd0f18c67e4225aaa4e8552b9f1ac7e6bda9e5"}, + {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbc8a7c410bb3ad5d595bb7118147dfbb6449d862cc1125cf8867cb337e8728"}, + {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74dad41b3458dbb0511e760fb355bb0b6689e0630de8a22b1b62a98777136e16"}, + {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b6f0af863cf17e6222b1735a756d664159e58855da99cfe965134a3ff63b0b0"}, + {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5b7fe4972d48a4da367043b8e023fb70a04d1490aa7d68800e465d1b97e493b"}, + {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6443cca89553b7a5485331bc9bedb2342b08d073fa10b8c7d1c60579c4a7b9bd"}, + {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c5f40ec615e5264f44b4282ee27628cea221fcad52f27405b80abb346d9f3f8"}, + {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:2abbb216a1d3a2fe86dbd2edce20cdc5e9ad0be6378455b05ec7f77361b3ab50"}, + {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:db71ce547012a5420a39c1b744d485cfb823564d01d5d20805977f5ea1345676"}, + {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ced339d7c9b5030abad5854aa5413a77565e5b6e6248ff927d3e174baf3badf7"}, + {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7c7dd29c7b5bda137464dc9bfc738d7ceea46ff70309859ffde8c022e9b08ba7"}, + {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:421da6fd326460517873274875c6c5a18ff225b40da2616083c5a34a7570b685"}, + {file = "aiohttp-3.12.15-cp311-cp311-win32.whl", hash = "sha256:4420cf9d179ec8dfe4be10e7d0fe47d6d606485512ea2265b0d8c5113372771b"}, + {file = "aiohttp-3.12.15-cp311-cp311-win_amd64.whl", hash = "sha256:edd533a07da85baa4b423ee8839e3e91681c7bfa19b04260a469ee94b778bf6d"}, + {file = "aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7"}, + {file = "aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444"}, + {file = "aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d"}, + {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c"}, + {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0"}, + {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab"}, + {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb"}, + {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545"}, + {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c"}, + {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd"}, + {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f"}, + {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d"}, + {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519"}, + {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea"}, + {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3"}, + {file = "aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1"}, + {file = "aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34"}, + {file = "aiohttp-3.12.15-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9f922ffd05034d439dde1c77a20461cf4a1b0831e6caa26151fe7aa8aaebc315"}, + {file = "aiohttp-3.12.15-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ee8a8ac39ce45f3e55663891d4b1d15598c157b4d494a4613e704c8b43112cd"}, + {file = "aiohttp-3.12.15-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3eae49032c29d356b94eee45a3f39fdf4b0814b397638c2f718e96cfadf4c4e4"}, + {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97752ff12cc12f46a9b20327104448042fce5c33a624f88c18f66f9368091c7"}, + {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:894261472691d6fe76ebb7fcf2e5870a2ac284c7406ddc95823c8598a1390f0d"}, + {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5fa5d9eb82ce98959fc1031c28198b431b4d9396894f385cb63f1e2f3f20ca6b"}, + {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0fa751efb11a541f57db59c1dd821bec09031e01452b2b6217319b3a1f34f3d"}, + {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5346b93e62ab51ee2a9d68e8f73c7cf96ffb73568a23e683f931e52450e4148d"}, + {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:049ec0360f939cd164ecbfd2873eaa432613d5e77d6b04535e3d1fbae5a9e645"}, + {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b52dcf013b57464b6d1e51b627adfd69a8053e84b7103a7cd49c030f9ca44461"}, + {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9b2af240143dd2765e0fb661fd0361a1b469cab235039ea57663cda087250ea9"}, + {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ac77f709a2cde2cc71257ab2d8c74dd157c67a0558a0d2799d5d571b4c63d44d"}, + {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:47f6b962246f0a774fbd3b6b7be25d59b06fdb2f164cf2513097998fc6a29693"}, + {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:760fb7db442f284996e39cf9915a94492e1896baac44f06ae551974907922b64"}, + {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad702e57dc385cae679c39d318def49aef754455f237499d5b99bea4ef582e51"}, + {file = "aiohttp-3.12.15-cp313-cp313-win32.whl", hash = "sha256:f813c3e9032331024de2eb2e32a88d86afb69291fbc37a3a3ae81cc9917fb3d0"}, + {file = "aiohttp-3.12.15-cp313-cp313-win_amd64.whl", hash = "sha256:1a649001580bdb37c6fdb1bebbd7e3bc688e8ec2b5c6f52edbb664662b17dc84"}, + {file = "aiohttp-3.12.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:691d203c2bdf4f4637792efbbcdcd157ae11e55eaeb5e9c360c1206fb03d4d98"}, + {file = "aiohttp-3.12.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e995e1abc4ed2a454c731385bf4082be06f875822adc4c6d9eaadf96e20d406"}, + {file = "aiohttp-3.12.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bd44d5936ab3193c617bfd6c9a7d8d1085a8dc8c3f44d5f1dcf554d17d04cf7d"}, + {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46749be6e89cd78d6068cdf7da51dbcfa4321147ab8e4116ee6678d9a056a0cf"}, + {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0c643f4d75adea39e92c0f01b3fb83d57abdec8c9279b3078b68a3a52b3933b6"}, + {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a23918fedc05806966a2438489dcffccbdf83e921a1170773b6178d04ade142"}, + {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74bdd8c864b36c3673741023343565d95bfbd778ffe1eb4d412c135a28a8dc89"}, + {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a146708808c9b7a988a4af3821379e379e0f0e5e466ca31a73dbdd0325b0263"}, + {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7011a70b56facde58d6d26da4fec3280cc8e2a78c714c96b7a01a87930a9530"}, + {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3bdd6e17e16e1dbd3db74d7f989e8af29c4d2e025f9828e6ef45fbdee158ec75"}, + {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:57d16590a351dfc914670bd72530fd78344b885a00b250e992faea565b7fdc05"}, + {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:bc9a0f6569ff990e0bbd75506c8d8fe7214c8f6579cca32f0546e54372a3bb54"}, + {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:536ad7234747a37e50e7b6794ea868833d5220b49c92806ae2d7e8a9d6b5de02"}, + {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f0adb4177fa748072546fb650d9bd7398caaf0e15b370ed3317280b13f4083b0"}, + {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:14954a2988feae3987f1eb49c706bff39947605f4b6fa4027c1d75743723eb09"}, + {file = "aiohttp-3.12.15-cp39-cp39-win32.whl", hash = "sha256:b784d6ed757f27574dca1c336f968f4e81130b27595e458e69457e6878251f5d"}, + {file = "aiohttp-3.12.15-cp39-cp39-win_amd64.whl", hash = "sha256:86ceded4e78a992f835209e236617bffae649371c4a50d5e5a3987f237db84b8"}, + {file = "aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2"}, +] + +[package.dependencies] +aiohappyeyeballs = ">=2.5.0" +aiosignal = ">=1.4.0" +async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""} +attrs = ">=17.3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +propcache = ">=0.2.0" +yarl = ">=1.17.0,<2.0" + +[package.extras] +speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns (>=3.3.0)", "brotlicffi ; platform_python_implementation != \"CPython\""] + +[[package]] +name = "aiosignal" +version = "1.4.0" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e"}, + {file = "aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" +typing-extensions = {version = ">=4.2", markers = "python_version < \"3.13\""} [[package]] name = "aiosqlite" -version = "0.20.0" +version = "0.21.0" description = "asyncio bridge to the standard sqlite3 module" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6"}, - {file = "aiosqlite-0.20.0.tar.gz", hash = "sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7"}, + {file = "aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0"}, + {file = "aiosqlite-0.21.0.tar.gz", hash = "sha256:131bb8056daa3bc875608c631c678cda73922a2d4ba8aec373b19f18c17e7aa3"}, ] [package.dependencies] typing_extensions = ">=4.0" [package.extras] -dev = ["attribution (==1.7.0)", "black (==24.2.0)", "coverage[toml] (==7.4.1)", "flake8 (==7.0.0)", "flake8-bugbear (==24.2.6)", "flit (==3.9.0)", "mypy (==1.8.0)", "ufmt (==2.3.0)", "usort (==1.0.8.post1)"] -docs = ["sphinx (==7.2.6)", "sphinx-mdinclude (==0.5.3)"] +dev = ["attribution (==1.7.1)", "black (==24.3.0)", "build (>=1.2)", "coverage[toml] (==7.6.10)", "flake8 (==7.0.0)", "flake8-bugbear (==24.12.12)", "flit (==3.10.1)", "mypy (==1.14.1)", "ufmt (==2.5.1)", "usort (==1.0.8.post1)"] +docs = ["sphinx (==8.1.3)", "sphinx-mdinclude (==0.6.1)"] [[package]] name = "anyio" -version = "4.6.2.post1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" +version = "4.10.0" +description = "High-level concurrency and networking framework on top of asyncio or Trio" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, + {file = "anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1"}, + {file = "anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -46,6 +183,7 @@ version = "1.5.1" description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"}, {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, @@ -57,6 +195,8 @@ version = "5.0.1" description = "Timeout context manager for asyncio programs" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "python_version == \"3.10\"" files = [ {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, @@ -64,60 +204,148 @@ files = [ [[package]] name = "asyncpg" -version = "0.29.0" +version = "0.30.0" description = "An asyncio PostgreSQL driver" optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ - {file = "asyncpg-0.29.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72fd0ef9f00aeed37179c62282a3d14262dbbafb74ec0ba16e1b1864d8a12169"}, - {file = "asyncpg-0.29.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52e8f8f9ff6e21f9b39ca9f8e3e33a5fcdceaf5667a8c5c32bee158e313be385"}, - {file = "asyncpg-0.29.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9e6823a7012be8b68301342ba33b4740e5a166f6bbda0aee32bc01638491a22"}, - {file = "asyncpg-0.29.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:746e80d83ad5d5464cfbf94315eb6744222ab00aa4e522b704322fb182b83610"}, - {file = "asyncpg-0.29.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ff8e8109cd6a46ff852a5e6bab8b0a047d7ea42fcb7ca5ae6eaae97d8eacf397"}, - {file = "asyncpg-0.29.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:97eb024685b1d7e72b1972863de527c11ff87960837919dac6e34754768098eb"}, - {file = "asyncpg-0.29.0-cp310-cp310-win32.whl", hash = "sha256:5bbb7f2cafd8d1fa3e65431833de2642f4b2124be61a449fa064e1a08d27e449"}, - {file = "asyncpg-0.29.0-cp310-cp310-win_amd64.whl", hash = "sha256:76c3ac6530904838a4b650b2880f8e7af938ee049e769ec2fba7cd66469d7772"}, - {file = "asyncpg-0.29.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4900ee08e85af01adb207519bb4e14b1cae8fd21e0ccf80fac6aa60b6da37b4"}, - {file = "asyncpg-0.29.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a65c1dcd820d5aea7c7d82a3fdcb70e096f8f70d1a8bf93eb458e49bfad036ac"}, - {file = "asyncpg-0.29.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b52e46f165585fd6af4863f268566668407c76b2c72d366bb8b522fa66f1870"}, - {file = "asyncpg-0.29.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc600ee8ef3dd38b8d67421359779f8ccec30b463e7aec7ed481c8346decf99f"}, - {file = "asyncpg-0.29.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:039a261af4f38f949095e1e780bae84a25ffe3e370175193174eb08d3cecab23"}, - {file = "asyncpg-0.29.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6feaf2d8f9138d190e5ec4390c1715c3e87b37715cd69b2c3dfca616134efd2b"}, - {file = "asyncpg-0.29.0-cp311-cp311-win32.whl", hash = "sha256:1e186427c88225ef730555f5fdda6c1812daa884064bfe6bc462fd3a71c4b675"}, - {file = "asyncpg-0.29.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfe73ffae35f518cfd6e4e5f5abb2618ceb5ef02a2365ce64f132601000587d3"}, - {file = "asyncpg-0.29.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6011b0dc29886ab424dc042bf9eeb507670a3b40aece3439944006aafe023178"}, - {file = "asyncpg-0.29.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b544ffc66b039d5ec5a7454667f855f7fec08e0dfaf5a5490dfafbb7abbd2cfb"}, - {file = "asyncpg-0.29.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d84156d5fb530b06c493f9e7635aa18f518fa1d1395ef240d211cb563c4e2364"}, - {file = "asyncpg-0.29.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54858bc25b49d1114178d65a88e48ad50cb2b6f3e475caa0f0c092d5f527c106"}, - {file = "asyncpg-0.29.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bde17a1861cf10d5afce80a36fca736a86769ab3579532c03e45f83ba8a09c59"}, - {file = "asyncpg-0.29.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:37a2ec1b9ff88d8773d3eb6d3784dc7e3fee7756a5317b67f923172a4748a175"}, - {file = "asyncpg-0.29.0-cp312-cp312-win32.whl", hash = "sha256:bb1292d9fad43112a85e98ecdc2e051602bce97c199920586be83254d9dafc02"}, - {file = "asyncpg-0.29.0-cp312-cp312-win_amd64.whl", hash = "sha256:2245be8ec5047a605e0b454c894e54bf2ec787ac04b1cb7e0d3c67aa1e32f0fe"}, - {file = "asyncpg-0.29.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0009a300cae37b8c525e5b449233d59cd9868fd35431abc470a3e364d2b85cb9"}, - {file = "asyncpg-0.29.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cad1324dbb33f3ca0cd2074d5114354ed3be2b94d48ddfd88af75ebda7c43cc"}, - {file = "asyncpg-0.29.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:012d01df61e009015944ac7543d6ee30c2dc1eb2f6b10b62a3f598beb6531548"}, - {file = "asyncpg-0.29.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000c996c53c04770798053e1730d34e30cb645ad95a63265aec82da9093d88e7"}, - {file = "asyncpg-0.29.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e0bfe9c4d3429706cf70d3249089de14d6a01192d617e9093a8e941fea8ee775"}, - {file = "asyncpg-0.29.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:642a36eb41b6313ffa328e8a5c5c2b5bea6ee138546c9c3cf1bffaad8ee36dd9"}, - {file = "asyncpg-0.29.0-cp38-cp38-win32.whl", hash = "sha256:a921372bbd0aa3a5822dd0409da61b4cd50df89ae85150149f8c119f23e8c408"}, - {file = "asyncpg-0.29.0-cp38-cp38-win_amd64.whl", hash = "sha256:103aad2b92d1506700cbf51cd8bb5441e7e72e87a7b3a2ca4e32c840f051a6a3"}, - {file = "asyncpg-0.29.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5340dd515d7e52f4c11ada32171d87c05570479dc01dc66d03ee3e150fb695da"}, - {file = "asyncpg-0.29.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e17b52c6cf83e170d3d865571ba574577ab8e533e7361a2b8ce6157d02c665d3"}, - {file = "asyncpg-0.29.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f100d23f273555f4b19b74a96840aa27b85e99ba4b1f18d4ebff0734e78dc090"}, - {file = "asyncpg-0.29.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48e7c58b516057126b363cec8ca02b804644fd012ef8e6c7e23386b7d5e6ce83"}, - {file = "asyncpg-0.29.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f9ea3f24eb4c49a615573724d88a48bd1b7821c890c2effe04f05382ed9e8810"}, - {file = "asyncpg-0.29.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8d36c7f14a22ec9e928f15f92a48207546ffe68bc412f3be718eedccdf10dc5c"}, - {file = "asyncpg-0.29.0-cp39-cp39-win32.whl", hash = "sha256:797ab8123ebaed304a1fad4d7576d5376c3a006a4100380fb9d517f0b59c1ab2"}, - {file = "asyncpg-0.29.0-cp39-cp39-win_amd64.whl", hash = "sha256:cce08a178858b426ae1aa8409b5cc171def45d4293626e7aa6510696d46decd8"}, - {file = "asyncpg-0.29.0.tar.gz", hash = "sha256:d1c49e1f44fffafd9a55e1a9b101590859d881d639ea2922516f5d9c512d354e"}, + {file = "asyncpg-0.30.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfb4dd5ae0699bad2b233672c8fc5ccbd9ad24b89afded02341786887e37927e"}, + {file = "asyncpg-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc1f62c792752a49f88b7e6f774c26077091b44caceb1983509edc18a2222ec0"}, + {file = "asyncpg-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3152fef2e265c9c24eec4ee3d22b4f4d2703d30614b0b6753e9ed4115c8a146f"}, + {file = "asyncpg-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7255812ac85099a0e1ffb81b10dc477b9973345793776b128a23e60148dd1af"}, + {file = "asyncpg-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:578445f09f45d1ad7abddbff2a3c7f7c291738fdae0abffbeb737d3fc3ab8b75"}, + {file = "asyncpg-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c42f6bb65a277ce4d93f3fba46b91a265631c8df7250592dd4f11f8b0152150f"}, + {file = "asyncpg-0.30.0-cp310-cp310-win32.whl", hash = "sha256:aa403147d3e07a267ada2ae34dfc9324e67ccc4cdca35261c8c22792ba2b10cf"}, + {file = "asyncpg-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb622c94db4e13137c4c7f98834185049cc50ee01d8f657ef898b6407c7b9c50"}, + {file = "asyncpg-0.30.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5e0511ad3dec5f6b4f7a9e063591d407eee66b88c14e2ea636f187da1dcfff6a"}, + {file = "asyncpg-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:915aeb9f79316b43c3207363af12d0e6fd10776641a7de8a01212afd95bdf0ed"}, + {file = "asyncpg-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c198a00cce9506fcd0bf219a799f38ac7a237745e1d27f0e1f66d3707c84a5a"}, + {file = "asyncpg-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3326e6d7381799e9735ca2ec9fd7be4d5fef5dcbc3cb555d8a463d8460607956"}, + {file = "asyncpg-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51da377487e249e35bd0859661f6ee2b81db11ad1f4fc036194bc9cb2ead5056"}, + {file = "asyncpg-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc6d84136f9c4d24d358f3b02be4b6ba358abd09f80737d1ac7c444f36108454"}, + {file = "asyncpg-0.30.0-cp311-cp311-win32.whl", hash = "sha256:574156480df14f64c2d76450a3f3aaaf26105869cad3865041156b38459e935d"}, + {file = "asyncpg-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:3356637f0bd830407b5597317b3cb3571387ae52ddc3bca6233682be88bbbc1f"}, + {file = "asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e"}, + {file = "asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a"}, + {file = "asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3"}, + {file = "asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737"}, + {file = "asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a"}, + {file = "asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af"}, + {file = "asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e"}, + {file = "asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305"}, + {file = "asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70"}, + {file = "asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3"}, + {file = "asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33"}, + {file = "asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4"}, + {file = "asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4"}, + {file = "asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba"}, + {file = "asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590"}, + {file = "asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e"}, + {file = "asyncpg-0.30.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:29ff1fc8b5bf724273782ff8b4f57b0f8220a1b2324184846b39d1ab4122031d"}, + {file = "asyncpg-0.30.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:64e899bce0600871b55368b8483e5e3e7f1860c9482e7f12e0a771e747988168"}, + {file = "asyncpg-0.30.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b290f4726a887f75dcd1b3006f484252db37602313f806e9ffc4e5996cfe5cb"}, + {file = "asyncpg-0.30.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f86b0e2cd3f1249d6fe6fd6cfe0cd4538ba994e2d8249c0491925629b9104d0f"}, + {file = "asyncpg-0.30.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:393af4e3214c8fa4c7b86da6364384c0d1b3298d45803375572f415b6f673f38"}, + {file = "asyncpg-0.30.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:fd4406d09208d5b4a14db9a9dbb311b6d7aeeab57bded7ed2f8ea41aeef39b34"}, + {file = "asyncpg-0.30.0-cp38-cp38-win32.whl", hash = "sha256:0b448f0150e1c3b96cb0438a0d0aa4871f1472e58de14a3ec320dbb2798fb0d4"}, + {file = "asyncpg-0.30.0-cp38-cp38-win_amd64.whl", hash = "sha256:f23b836dd90bea21104f69547923a02b167d999ce053f3d502081acea2fba15b"}, + {file = "asyncpg-0.30.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f4e83f067b35ab5e6371f8a4c93296e0439857b4569850b178a01385e82e9ad"}, + {file = "asyncpg-0.30.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5df69d55add4efcd25ea2a3b02025b669a285b767bfbf06e356d68dbce4234ff"}, + {file = "asyncpg-0.30.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3479a0d9a852c7c84e822c073622baca862d1217b10a02dd57ee4a7a081f708"}, + {file = "asyncpg-0.30.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26683d3b9a62836fad771a18ecf4659a30f348a561279d6227dab96182f46144"}, + {file = "asyncpg-0.30.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1b982daf2441a0ed314bd10817f1606f1c28b1136abd9e4f11335358c2c631cb"}, + {file = "asyncpg-0.30.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1c06a3a50d014b303e5f6fc1e5f95eb28d2cee89cf58384b700da621e5d5e547"}, + {file = "asyncpg-0.30.0-cp39-cp39-win32.whl", hash = "sha256:1b11a555a198b08f5c4baa8f8231c74a366d190755aa4f99aacec5970afe929a"}, + {file = "asyncpg-0.30.0-cp39-cp39-win_amd64.whl", hash = "sha256:8b684a3c858a83cd876f05958823b68e8d14ec01bb0c0d14a6704c5bf9711773"}, + {file = "asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851"}, ] [package.dependencies] -async-timeout = {version = ">=4.0.3", markers = "python_version < \"3.12.0\""} +async-timeout = {version = ">=4.0.3", markers = "python_version < \"3.11.0\""} [package.extras] -docs = ["Sphinx (>=5.3.0,<5.4.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -test = ["flake8 (>=6.1,<7.0)", "uvloop (>=0.15.3)"] +docs = ["Sphinx (>=8.1.3,<8.2.0)", "sphinx-rtd-theme (>=1.2.2)"] +gssauth = ["gssapi ; platform_system != \"Windows\"", "sspilib ; platform_system == \"Windows\""] +test = ["distro (>=1.9.0,<1.10.0)", "flake8 (>=6.1,<7.0)", "flake8-pyi (>=24.1.0,<24.2.0)", "gssapi ; platform_system == \"Linux\"", "k5test ; platform_system == \"Linux\"", "mypy (>=1.8.0,<1.9.0)", "sspilib ; platform_system == \"Windows\"", "uvloop (>=0.15.3) ; platform_system != \"Windows\" and python_version < \"3.14.0\""] + +[[package]] +name = "attrs" +version = "25.3.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, + {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, +] + +[package.extras] +benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] +tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""] + +[[package]] +name = "backports-datetime-fromisoformat" +version = "2.0.3" +description = "Backport of Python 3.11's datetime.fromisoformat" +optional = false +python-versions = ">3" +groups = ["main"] +markers = "python_version == \"3.10\"" +files = [ + {file = "backports_datetime_fromisoformat-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f681f638f10588fa3c101ee9ae2b63d3734713202ddfcfb6ec6cea0778a29d4"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:cd681460e9142f1249408e5aee6d178c6d89b49e06d44913c8fdfb6defda8d1c"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:ee68bc8735ae5058695b76d3bb2aee1d137c052a11c8303f1e966aa23b72b65b"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8273fe7932db65d952a43e238318966eab9e49e8dd546550a41df12175cc2be4"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39d57ea50aa5a524bb239688adc1d1d824c31b6094ebd39aa164d6cadb85de22"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ac6272f87693e78209dc72e84cf9ab58052027733cd0721c55356d3c881791cf"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:44c497a71f80cd2bcfc26faae8857cf8e79388e3d5fbf79d2354b8c360547d58"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:6335a4c9e8af329cb1ded5ab41a666e1448116161905a94e054f205aa6d263bc"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2e4b66e017253cdbe5a1de49e0eecff3f66cd72bcb1229d7db6e6b1832c0443"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:43e2d648e150777e13bbc2549cc960373e37bf65bd8a5d2e0cef40e16e5d8dd0"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:4ce6326fd86d5bae37813c7bf1543bae9e4c215ec6f5afe4c518be2635e2e005"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7c8fac333bf860208fd522a5394369ee3c790d0aa4311f515fcc4b6c5ef8d75"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24a4da5ab3aa0cc293dc0662a0c6d1da1a011dc1edcbc3122a288cfed13a0b45"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:58ea11e3bf912bd0a36b0519eae2c5b560b3cb972ea756e66b73fb9be460af01"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8a375c7dbee4734318714a799b6c697223e4bbb57232af37fbfff88fb48a14c6"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:ac677b1664c4585c2e014739f6678137c8336815406052349c85898206ec7061"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66ce47ee1ba91e146149cf40565c3d750ea1be94faf660ca733d8601e0848147"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:8b7e069910a66b3bba61df35b5f879e5253ff0821a70375b9daf06444d046fa4"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:a3b5d1d04a9e0f7b15aa1e647c750631a873b298cdd1255687bb68779fe8eb35"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec1b95986430e789c076610aea704db20874f0781b8624f648ca9fb6ef67c6e1"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffe5f793db59e2f1d45ec35a1cf51404fdd69df9f6952a0c87c3060af4c00e32"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:620e8e73bd2595dfff1b4d256a12b67fce90ece3de87b38e1dde46b910f46f4d"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4cf9c0a985d68476c1cabd6385c691201dda2337d7453fb4da9679ce9f23f4e7"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:d144868a73002e6e2e6fef72333e7b0129cecdd121aa8f1edba7107fd067255d"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e81b26497a17c29595bc7df20bc6a872ceea5f8c9d6537283945d4b6396aec10"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:5ba00ead8d9d82fd6123eb4891c566d30a293454e54e32ff7ead7644f5f7e575"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:24d574cb4072e1640b00864e94c4c89858033936ece3fc0e1c6f7179f120d0a8"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9735695a66aad654500b0193525e590c693ab3368478ce07b34b443a1ea5e824"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63d39709e17eb72685d052ac82acf0763e047f57c86af1b791505b1fec96915d"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:1ea2cc84224937d6b9b4c07f5cb7c667f2bde28c255645ba27f8a675a7af8234"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4024e6d35a9fdc1b3fd6ac7a673bd16cb176c7e0b952af6428b7129a70f72cce"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5e2dcc94dc9c9ab8704409d86fcb5236316e9dcef6feed8162287634e3568f4c"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fa2de871801d824c255fac7e5e7e50f2be6c9c376fd9268b40c54b5e9da91f42"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:1314d4923c1509aa9696712a7bc0c7160d3b7acf72adafbbe6c558d523f5d491"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:b750ecba3a8815ad8bc48311552f3f8ab99dd2326d29df7ff670d9c49321f48f"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d5117dce805d8a2f78baeddc8c6127281fa0a5e2c40c6dd992ba6b2b367876"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb35f607bd1cbe37b896379d5f5ed4dc298b536f4b959cb63180e05cacc0539d"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:61c74710900602637d2d145dda9720c94e303380803bf68811b2a151deec75c2"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ece59af54ebf67ecbfbbf3ca9066f5687879e36527ad69d8b6e3ac565d565a62"}, + {file = "backports_datetime_fromisoformat-2.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:d0a7c5f875068efe106f62233bc712d50db4d07c13c7db570175c7857a7b5dbd"}, + {file = "backports_datetime_fromisoformat-2.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90e202e72a3d5aae673fcc8c9a4267d56b2f532beeb9173361293625fe4d2039"}, + {file = "backports_datetime_fromisoformat-2.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2df98ef1b76f5a58bb493dda552259ba60c3a37557d848e039524203951c9f06"}, + {file = "backports_datetime_fromisoformat-2.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7100adcda5e818b5a894ad0626e38118bb896a347f40ebed8981155675b9ba7b"}, + {file = "backports_datetime_fromisoformat-2.0.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e410383f5d6a449a529d074e88af8bc80020bb42b402265f9c02c8358c11da5"}, + {file = "backports_datetime_fromisoformat-2.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2797593760da6bcc32c4a13fa825af183cd4bfd333c60b3dbf84711afca26ef"}, + {file = "backports_datetime_fromisoformat-2.0.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35a144fd681a0bea1013ccc4cd3fd4dc758ea17ee23dca019c02b82ec46fc0c4"}, + {file = "backports_datetime_fromisoformat-2.0.3.tar.gz", hash = "sha256:b58edc8f517b66b397abc250ecc737969486703a66eb97e01e6d51291b1a139d"}, +] [[package]] name = "base58" @@ -125,6 +353,7 @@ version = "2.1.1" description = "Base58 and Base58Check implementation." optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "base58-2.1.1-py3-none-any.whl", hash = "sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2"}, {file = "base58-2.1.1.tar.gz", hash = "sha256:c5d0cb3f5b6e81e8e35da5754388ddcc6d0d14b6c6a132cb93d69ed580a7278c"}, @@ -133,52 +362,13 @@ files = [ [package.extras] tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", "pytest-cov", "pytest-flake8"] -[[package]] -name = "bcrypt" -version = "4.2.0" -description = "Modern password hashing for your software and your servers" -optional = false -python-versions = ">=3.7" -files = [ - {file = "bcrypt-4.2.0-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:096a15d26ed6ce37a14c1ac1e48119660f21b24cba457f160a4b830f3fe6b5cb"}, - {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c02d944ca89d9b1922ceb8a46460dd17df1ba37ab66feac4870f6862a1533c00"}, - {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d84cf6d877918620b687b8fd1bf7781d11e8a0998f576c7aa939776b512b98d"}, - {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:1bb429fedbe0249465cdd85a58e8376f31bb315e484f16e68ca4c786dcc04291"}, - {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:655ea221910bcac76ea08aaa76df427ef8625f92e55a8ee44fbf7753dbabb328"}, - {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:1ee38e858bf5d0287c39b7a1fc59eec64bbf880c7d504d3a06a96c16e14058e7"}, - {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:0da52759f7f30e83f1e30a888d9163a81353ef224d82dc58eb5bb52efcabc399"}, - {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3698393a1b1f1fd5714524193849d0c6d524d33523acca37cd28f02899285060"}, - {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:762a2c5fb35f89606a9fde5e51392dad0cd1ab7ae64149a8b935fe8d79dd5ed7"}, - {file = "bcrypt-4.2.0-cp37-abi3-win32.whl", hash = "sha256:5a1e8aa9b28ae28020a3ac4b053117fb51c57a010b9f969603ed885f23841458"}, - {file = "bcrypt-4.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:8f6ede91359e5df88d1f5c1ef47428a4420136f3ce97763e31b86dd8280fbdf5"}, - {file = "bcrypt-4.2.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:c52aac18ea1f4a4f65963ea4f9530c306b56ccd0c6f8c8da0c06976e34a6e841"}, - {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bbbfb2734f0e4f37c5136130405332640a1e46e6b23e000eeff2ba8d005da68"}, - {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3413bd60460f76097ee2e0a493ccebe4a7601918219c02f503984f0a7ee0aebe"}, - {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8d7bb9c42801035e61c109c345a28ed7e84426ae4865511eb82e913df18f58c2"}, - {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3d3a6d28cb2305b43feac298774b997e372e56c7c7afd90a12b3dc49b189151c"}, - {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:9c1c4ad86351339c5f320ca372dfba6cb6beb25e8efc659bedd918d921956bae"}, - {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:27fe0f57bb5573104b5a6de5e4153c60814c711b29364c10a75a54bb6d7ff48d"}, - {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8ac68872c82f1add6a20bd489870c71b00ebacd2e9134a8aa3f98a0052ab4b0e"}, - {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:cb2a8ec2bc07d3553ccebf0746bbf3d19426d1c6d1adbd4fa48925f66af7b9e8"}, - {file = "bcrypt-4.2.0-cp39-abi3-win32.whl", hash = "sha256:77800b7147c9dc905db1cba26abe31e504d8247ac73580b4aa179f98e6608f34"}, - {file = "bcrypt-4.2.0-cp39-abi3-win_amd64.whl", hash = "sha256:61ed14326ee023917ecd093ee6ef422a72f3aec6f07e21ea5f10622b735538a9"}, - {file = "bcrypt-4.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:39e1d30c7233cfc54f5c3f2c825156fe044efdd3e0b9d309512cc514a263ec2a"}, - {file = "bcrypt-4.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f4f4acf526fcd1c34e7ce851147deedd4e26e6402369304220250598b26448db"}, - {file = "bcrypt-4.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:1ff39b78a52cf03fdf902635e4c81e544714861ba3f0efc56558979dd4f09170"}, - {file = "bcrypt-4.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:373db9abe198e8e2c70d12b479464e0d5092cc122b20ec504097b5f2297ed184"}, - {file = "bcrypt-4.2.0.tar.gz", hash = "sha256:cf69eaf5185fd58f268f805b505ce31f9b9fc2d64b376642164e9244540c1221"}, -] - -[package.extras] -tests = ["pytest (>=3.2.1,!=3.3.0)"] -typecheck = ["mypy"] - [[package]] name = "bech32" version = "1.2.0" description = "Reference implementation for Bech32 and segwit addresses." optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "bech32-1.2.0-py3-none-any.whl", hash = "sha256:990dc8e5a5e4feabbdf55207b5315fdd9b73db40be294a19b3752cde9e79d981"}, {file = "bech32-1.2.0.tar.gz", hash = "sha256:7d6db8214603bd7871fcfa6c0826ef68b85b0abd90fa21c285a9c5e21d2bd899"}, @@ -186,219 +376,173 @@ files = [ [[package]] name = "bitarray" -version = "2.9.3" +version = "3.7.1" description = "efficient arrays of booleans -- C extension" optional = false python-versions = "*" +groups = ["main"] files = [ - {file = "bitarray-2.9.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2cf5f5400636c7dda797fd681795ce63932458620fe8c40955890380acba9f62"}, - {file = "bitarray-2.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3487b4718ffa5942fab777835ee36085f8dda7ec4bd0b28433efb117f84852b6"}, - {file = "bitarray-2.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:10f44b1e4994035408bea54d7bf0aec79744cad709706bedf28091a48bb7f1a4"}, - {file = "bitarray-2.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb5c16f97c65add6535748a9c98c70e7ca79759c38a2eb990127fef72f76111a"}, - {file = "bitarray-2.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:13dbfc42971ba84e9c4ba070f720df6570285a3f89187f07ef422efcb611c19f"}, - {file = "bitarray-2.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c28076acfbe7f9a5494d7ae98094a6e209c390c340938845f294818ebf5e4d3"}, - {file = "bitarray-2.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b7cdd21835936d9a66477836ca23b2cb63295142cb9d9158883e2c0f1f8f6bd"}, - {file = "bitarray-2.9.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9f60887ab3a46e507fa6f8544d8d4b0748da48718591dfe3fe80c62bdea60f10"}, - {file = "bitarray-2.9.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f75e1abd4a37cba3002521d3f5e2b50ef4f4a74342207cad3f52468411d5d8ba"}, - {file = "bitarray-2.9.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dc63da9695383c048b83f5ab77eab35a55bbb2e77c7b6e762eba219929b45b84"}, - {file = "bitarray-2.9.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6fe5a57b859d9bc9c2fd27c78c4b7b83158faf984202de6fb44618caeebfff10"}, - {file = "bitarray-2.9.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1fe5a37bd9441a5ecc2f6e71b43df7176fa376a542ef97484310b8b46a45649a"}, - {file = "bitarray-2.9.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8a16e42c169ca818d6a15b5dd5acd5d2a26af0fa0588e1036e0e58d01f8387d4"}, - {file = "bitarray-2.9.3-cp310-cp310-win32.whl", hash = "sha256:5e6b5e7940af3474ffaa930cd1ce8215181cbe864d6b5ddb67a15d3c15e935cd"}, - {file = "bitarray-2.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:c63dbb99ef2ab1281871678624f9c9a5f1682b826e668ce559275ec488b3fa8b"}, - {file = "bitarray-2.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:49fb93b488d180f5c84b79fe687c585a84bf0295ff035d63e09ee24ce1da0558"}, - {file = "bitarray-2.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c2944fb83bbc2aa7f29a713bc4f8c1318e54fa0d06a72bedd350a3fb4a4b91d8"}, - {file = "bitarray-2.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3612d9d3788dc62f1922c917b1539f1cdf02cecc9faef8ae213a8b36093136ca"}, - {file = "bitarray-2.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90a9300cdb7c99b1e692bb790cba8acecee1a345a83e58e28c94a0d87c522237"}, - {file = "bitarray-2.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1211ed66acbbb221fd7554abf4206a384d79e6192d5cb95325c5c361bbb52a74"}, - {file = "bitarray-2.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67757279386accf93eba76b8f97b5acf1664a3e350cbea5f300f53490f8764fd"}, - {file = "bitarray-2.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64e19c6a99c32f460c2613f797f77aa37d8e298891d00ea5355158cce80e11ec"}, - {file = "bitarray-2.9.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72734bd3775f43c5a75385730abb9f84fee6c627eb14f579de4be478f1615c8c"}, - {file = "bitarray-2.9.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a92703471b5d3316c7481bc1852f620f42f7a1b62be27f39d13694827635786f"}, - {file = "bitarray-2.9.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d5d77c81300ca430d4b195ccfbb629d6858258f541b6e96c6b11ec1563cd2681"}, - {file = "bitarray-2.9.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3ba8a29c0d091c952ced1607ce715f5e0524899f24333a493807d00f5938463d"}, - {file = "bitarray-2.9.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:418171d035b191dbe5e86cd2bfb5c3e1ae7d947edc22857a897d1c7251674ae5"}, - {file = "bitarray-2.9.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e0bd272eba256183be2a17488f9cb096d2e6d3435ecf2e28c1e0857c6d20749"}, - {file = "bitarray-2.9.3-cp311-cp311-win32.whl", hash = "sha256:cc3fd2b0637a619cf13e122bbcf4729ae214d5f25623675597e67c25f9edfe61"}, - {file = "bitarray-2.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1fc2a81a585dbe5e367682156e6350d908a56e2ffd6ca651b0af01994db596f"}, - {file = "bitarray-2.9.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc47be026f76f1728af00dc7140cec8483fe2f0c476bbf2a59ef47865e00ff96"}, - {file = "bitarray-2.9.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:82b091742ff511cdb06f90af0d2c22e7af3dbff9b8212e2e0d88dfef6a8570b3"}, - {file = "bitarray-2.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d5edb4302a0e3a3d1d0eeb891de3c615d4cb7a446fb41c21eecdcfb29400a6f"}, - {file = "bitarray-2.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb4786c5525069c19820549dd2f42d33632bc42959ad167138bd8ee5024b922b"}, - {file = "bitarray-2.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bfe2de2b4df61ccb9244871a0fdf1fff83be0c1bd7187048c3cf7f81c5fe631"}, - {file = "bitarray-2.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31e4f69538f95d2934587d957eea0d283162322dd1af29e57122b20b8cd60f92"}, - {file = "bitarray-2.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca44908b2bc08d8995770018638d62626706864f9c599b7818225a12f3dbc2c"}, - {file = "bitarray-2.9.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:279f8de5d251ee521e365df29c927d9b5732f1ed4f373d2dbbd278fcbad94ff5"}, - {file = "bitarray-2.9.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49bb631b38431c09ecd534d56ef04264397d24d18c4ee6653c84e14ae09d92d"}, - {file = "bitarray-2.9.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:192bffc93ee9a5b6c833c98d1dcc81f5633ddd726b85e18341387d0c1d51f691"}, - {file = "bitarray-2.9.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c516cec28c6511df51d87033f40ec420324a2247469b0c989d344f4d27ea37d2"}, - {file = "bitarray-2.9.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:66241cb9a1c1db294f46cd440141e57e8242874e38f3f61877f72d92ae14768a"}, - {file = "bitarray-2.9.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ab1f0e7631110c89bea7b605c0c35832333eb9cc97e5de05d71c76d42a1858c9"}, - {file = "bitarray-2.9.3-cp312-cp312-win32.whl", hash = "sha256:42aa5bee6fe8ad3385eaf5c6585016bbc38a7b75efb52ce5c6f8e00e05237dfa"}, - {file = "bitarray-2.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:dc3fd647d845b94fac3652390866f921f914a17f3807a031c826f68dae3f43e3"}, - {file = "bitarray-2.9.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fcfcc1989e3e021a282624017b7fb754210f5332e933b1c3ebc79643727b6551"}, - {file = "bitarray-2.9.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:71b1e229a706798a9e106ca7b03d4c63455deb40b18c92950ec073a05a8f8285"}, - {file = "bitarray-2.9.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4bb49556d3d505d24c942a4206ad4d0d40e89fa3016a7ea6edc994d5c08d4a8e"}, - {file = "bitarray-2.9.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4466aa1e533a59d5f7fd37219d154ec3f2ba73fce3d8a2e11080ec475bc15fb"}, - {file = "bitarray-2.9.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a9b75adc0fd0bf278bea89dc3d679d74e10d2df98d3d074b7f3d36f323138818"}, - {file = "bitarray-2.9.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:701582bbbeac372b1cd8a3c9daf6c2336dc2d22e14373a6271d788bc4f2b6edc"}, - {file = "bitarray-2.9.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea1f119668bbdbd68008031491515e84441e505163918819994b28f295f762c"}, - {file = "bitarray-2.9.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9f400bc18a70bfdb073532c3054ecd78a0e64f96ff7b6140adde5b122580ec2b"}, - {file = "bitarray-2.9.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:aacff5656fb3e15cede7d02903da2634d376aa928d7a81ec8df19b0724d7972a"}, - {file = "bitarray-2.9.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8a2ae42a14cbf766d4478d7101da6359b0648dd813e60eb3486ac56ad2f5add3"}, - {file = "bitarray-2.9.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:616698edb547d10f0b960cb9f2e8629c55a420dd4c2b1ab46706f49a1815621d"}, - {file = "bitarray-2.9.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f277c50ba184929dfeed39b6cf9468e3446093521b0aeb52bd54a21ca08f5473"}, - {file = "bitarray-2.9.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:661237739b385c90d8837d5e96b06de093cc6e610236977e198f88f5a979686e"}, - {file = "bitarray-2.9.3-cp313-cp313-win32.whl", hash = "sha256:68acec6c19d798051f178a1197b76f891985f683f95a4b12811b68e58b080f5a"}, - {file = "bitarray-2.9.3-cp313-cp313-win_amd64.whl", hash = "sha256:3055720afdcfd7e8f630fa16db7bed7e55c9d0a1f4756195e3b250e203f3b436"}, - {file = "bitarray-2.9.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:72bf17d0e7d8a4f645655a07999d23e42472cbf2100b8dad7ce26586075241d7"}, - {file = "bitarray-2.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cfd332b5f1ad8c4dc3cc79ecef33c19b42d8d8e6a39fd5c9ecb5855be0b9723"}, - {file = "bitarray-2.9.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5b466ef1e48f25621c9d27e95deb5e33b8656827ed8aa530b972de73870bd1f"}, - {file = "bitarray-2.9.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:938cf26fdaf4d0adfac82d830c025523c5d36ddead0470b735286028231c1784"}, - {file = "bitarray-2.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0f766669e768ef9a2b23ecfa710b38b6a48da3f91755113c79320b207ae255d"}, - {file = "bitarray-2.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6337c0c64044f35ddfb241143244aac707a68f34ae31a71dad115f773ccc8b"}, - {file = "bitarray-2.9.3-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:731b59540167f8b2b20f69f487ecee2339fc4657059906a16cb51acac17f89c3"}, - {file = "bitarray-2.9.3-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:4feed0539a9d6432361fc4d3820eea3a81fa631d542f166cf8430aad81a971da"}, - {file = "bitarray-2.9.3-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:eb65c96a42e73f35175ec738d67992ffdf054c20abee3933cfcfa2343fa1187d"}, - {file = "bitarray-2.9.3-cp36-cp36m-musllinux_1_2_s390x.whl", hash = "sha256:4f40ceac94d182de6135759d81289683ff3e4cf0da709bc5826a7fe00d754114"}, - {file = "bitarray-2.9.3-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:5b29f7844080a281635a231a37e99f0bd6f567af6cf19f4f6d212137f99a9cdf"}, - {file = "bitarray-2.9.3-cp36-cp36m-win32.whl", hash = "sha256:947cf522a3b339b73114d12417fd848fa01303dbaa7883ced4c87688dba5637c"}, - {file = "bitarray-2.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:ea794ea60d514d68777a87a74106110db7a4bbc2c46720e67010e3071afefb95"}, - {file = "bitarray-2.9.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c7bc7cb79dcac8bdce23b305e671c06eaeffb012fa065b8c33bc51df7e1733f0"}, - {file = "bitarray-2.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d6380ad0f929ad9220abadd1c9b7234271c4b6ea9c753a88611d489e93a8f2e"}, - {file = "bitarray-2.9.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05f4e2451e2ad450b41ede8440e52c1fd798e81027e1dc2256292ec0787d3bf1"}, - {file = "bitarray-2.9.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7267885c98138f3707c710d5b08eedef150a3e5112c760cfe1200f3366fd7064"}, - {file = "bitarray-2.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:976957423cb41df8fe0eb811dbb53d8c5ab1ca3beec7a3ca7ff679be44a72714"}, - {file = "bitarray-2.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0ec5141a69f73ed6ff17ea7344d5cc166e087095bfe3661dbb42b519e76aa16"}, - {file = "bitarray-2.9.3-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:218a1b7c0652a3c1020f903ded0f9768c3719fb6d43a6e9d346e985292992d35"}, - {file = "bitarray-2.9.3-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:cf0c9ebf2df280794244e1e12ed626357506ddaa2f0d6f69efe493ae7bbf4bf7"}, - {file = "bitarray-2.9.3-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:c450a04a7e091b57d4c0bd1531648522cd0ef26913ad0e5dea0432ea29b0e5c1"}, - {file = "bitarray-2.9.3-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:a212eb89a50e32ef4969387e44a7410447dc59587615e3966d090edc338a1b85"}, - {file = "bitarray-2.9.3-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:4269232026212ee6b73379b88a578107a6b36a6182307a49d5509686c7495261"}, - {file = "bitarray-2.9.3-cp37-cp37m-win32.whl", hash = "sha256:8a0fb358e6a43f216c3fb0871e2ac14c16563aec363c23bc2fbbb18f6201285d"}, - {file = "bitarray-2.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:a8368774cdc737eec8fce6f28d0abc095fbc0edccf8fab8d29fddc264b68def9"}, - {file = "bitarray-2.9.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7d0724a4fef6ded914075a3385ea2d05afdeed567902f83490ed4e7e7e75d9bf"}, - {file = "bitarray-2.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0e11b37c6dff6f41ebc49914628824ceb8c8d6ebd0fda2ebe3c0fe0c63e8621e"}, - {file = "bitarray-2.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:085f4081d72c7468f82f722a9f113e03a1f7a4c132ef4c2a4e680c5d78b7db00"}, - {file = "bitarray-2.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b530b5fbed2900634fbc43f546e384abd72ad9c49795ff5bd6a93cac1aa9c4d8"}, - {file = "bitarray-2.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09ff88e4385967571146fb0d270442de39393d44198f4d108f3350cfd6486f0b"}, - {file = "bitarray-2.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a344bb212ddf87db4976a6711d274660a5d887da4fd3faafcdaa092152f85a6d"}, - {file = "bitarray-2.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc569c96b990f92fd5946d5b50501fee48b01a116a286d1de7961ebd9c6f06f3"}, - {file = "bitarray-2.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2fbbe7938ef8a7abe3e8519fa0578b51d2787f7171d3144e7d373551b5851fd"}, - {file = "bitarray-2.9.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0b5912fab904507b47217509b01aa903d7f98b6e725e490a7f01661f4d9a4fa7"}, - {file = "bitarray-2.9.3-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:0c836ccfca9cf60927256738ef234dfe500565492eff269610cdd1bca56801d0"}, - {file = "bitarray-2.9.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:af0e4441ebf51c18fc450962f1e201c96f444d63b17cc8dcf7c0b05111bd4486"}, - {file = "bitarray-2.9.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:9e9b57175fb6fe76d7ddd0647e06a25f6e23f4b54b5febf337c5a840ab37dc3b"}, - {file = "bitarray-2.9.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7f7de81721ae9492926bd067007ac974692182bb83fc8f0ba330a67f37a018bd"}, - {file = "bitarray-2.9.3-cp38-cp38-win32.whl", hash = "sha256:4beafb6b6e344385480df6611fdebfcb3579bbb40636ce1ddf5e72fb744e095f"}, - {file = "bitarray-2.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:d8eaeca98900bd6f06a29cdef57999813a67d314f661d14901d71e04f4cf9f00"}, - {file = "bitarray-2.9.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:413965d9d384aef90e58b959f4a39f1d5060b145c26080297b7b4cf23cf38faa"}, - {file = "bitarray-2.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2fbb56f2bb89c3a15304a6c0ea56013dc340a98337d9bbd7fc5c21451dc05f8c"}, - {file = "bitarray-2.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b8a84f39f7885627711473872d8fc58fc7a0a1e4ecd9ddf42daf9a3643432742"}, - {file = "bitarray-2.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45147a9c8580e857c1344d15bd49d2b4387777bd582a2ede11be2ba740653f28"}, - {file = "bitarray-2.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed255423dc60c6b2d5c0d90c13dea2962a31929767fdf1c525ab3210269e75c5"}, - {file = "bitarray-2.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4f5bd02671ea5c4ad52bbfe0e8e8197b6e8fa85dec1e93a4a05448c19354cc65"}, - {file = "bitarray-2.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1c99c58f044549c93fb6d4cda22678deccaed19845eaa2e6917b5b7ca058f2d"}, - {file = "bitarray-2.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:921ee87681e32e17d1849e11c96eb6a8a7edaa1269dd26831013daf8546bde05"}, - {file = "bitarray-2.9.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ed97d8ec40c4658d9f9aa8f26cb473f44fa1dbccba3fa3fbe4a102e38c6a8d7"}, - {file = "bitarray-2.9.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9d7f7db37edb9c50c9aad6a18f2e87dd7dc5ff2a33406821804a03263fedb2ca"}, - {file = "bitarray-2.9.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:292f726cdb9efc744ed0a1d7453c44151526648148a28d9a2495cc7c7b2c62a8"}, - {file = "bitarray-2.9.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2cc94784238782a9376f307b1aa9a85ce77b6eded9f82d2fe062db7fdb02c645"}, - {file = "bitarray-2.9.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5051436b1d318f6ce0df3b2f8a60bfa66a54c1d9e8719d6cb6b448140e7061f2"}, - {file = "bitarray-2.9.3-cp39-cp39-win32.whl", hash = "sha256:a3d436c686ce59fd0b93438ed2c0e1d3e1716e56bce64b874d05b9f49f1ca5d1"}, - {file = "bitarray-2.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:f168fc45664266a560f2cb28a327041b7f69d4a7faad8ab89e0a1dd7c270a70d"}, - {file = "bitarray-2.9.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ae36787299cff41f212aee33cfe1defee13979a41552665a412b6ca3fa8f7eb8"}, - {file = "bitarray-2.9.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42afe48abb8eeb386d93e7f1165ace1dd027f136a8a31edd2b20bc57a0c071d7"}, - {file = "bitarray-2.9.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:451ceecdb86bb95ae101b0d65c8c4524d692ae3666662fef8c89877ce17748c5"}, - {file = "bitarray-2.9.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4d67d3e3de2aede737b12cd75a84963700c941b77b579c14bd05517e05d7a9f"}, - {file = "bitarray-2.9.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2406d13ded84049b4238815a5821e44d6f58ba00fbb6b705b6ef8ccd88be8f03"}, - {file = "bitarray-2.9.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0db944fc2a048020fc940841ef46c0295b045d45a5a582cba69f78962a49a384"}, - {file = "bitarray-2.9.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25c603f141171a7d108773d5136d14e572c473e4cdb3fb464c39c8a138522eb2"}, - {file = "bitarray-2.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86c06b02705305cab0914d209caa24effda81316e2f2555a71a9aa399b75c5a5"}, - {file = "bitarray-2.9.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ddda45b24a802eaaca8f794e6267ff2b62de5fe7b900b76d6f662d95192bebf"}, - {file = "bitarray-2.9.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:81490623950d04870c6dd4d7e6df2eb68dd04eca8bec327895ebee8bbe0cc3c7"}, - {file = "bitarray-2.9.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a9e69ac6a514cc574891c24a50847022dac2fef8c3f4df530f92820a07337755"}, - {file = "bitarray-2.9.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:545c695ee69d26b41351ced4c76244d8b6225669fc0af3652ff8ed5a6b28325d"}, - {file = "bitarray-2.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbb2e6daabd2a64d091ac7460b0c5c5f9268199ae9a8ce32737cf5273987f1fa"}, - {file = "bitarray-2.9.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a969e5cf63144b944ee8d0a0739f53ef1ae54725b5e01258d690a8995d880526"}, - {file = "bitarray-2.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:73bbb9301ac9000f869c51db2cc5fcc6541985d3fcdcfe6e02f90c9e672a00be"}, - {file = "bitarray-2.9.3-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c07e346926488a85a48542d898f4168f3587ec42379fef0d18be301e08a3f27"}, - {file = "bitarray-2.9.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a26d8a14cd8ee496306f2afac34833502dd1ae826355af309333b6f252b23fe"}, - {file = "bitarray-2.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cef148ed37c892395ca182d6a235524165a9f765f4283d0a1ced891e7c43c67a"}, - {file = "bitarray-2.9.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94f35a8f0c8a50ee98a8bef9a070d0b68ecf623f20a2148cc039aba5557346a6"}, - {file = "bitarray-2.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b03207460daae828e2743874c84264e8d96a8c6156490279092b624cd5d2de08"}, - {file = "bitarray-2.9.3.tar.gz", hash = "sha256:9eff55cf189b0c37ba97156a00d640eb7392db58a8049be6f26ff2712b93fa89"}, + {file = "bitarray-3.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a05982bb49c73463cb0f0f4bed2d8da82631708a2c2d1926107ba99651b419ec"}, + {file = "bitarray-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d30e7daaf228e3d69cdd8b02c0dd4199cec034c4b93c80109f56f4675a6db957"}, + {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:160f449bb91686f8fc9984200e78b8d793b79e382decf7eb1dc9948d7c21b36f"}, + {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6542e1cfe060badd160cd383ad93a84871595c14bb05fb8129f963248affd946"}, + {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b723f9d10f7d8259f010b87fa66e924bb4d67927d9dcff4526a755e9ee84fef4"}, + {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca4b6298c89b92d6b0a67dfc5f98d68ae92b08101d227263ef2033b9c9a03a72"}, + {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:567d6891cb1ddbfd0051fcff3cb1bb86efc82ec818d9c5f98c37d59c1d23cc96"}, + {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:37a6a8382864a1defb5b370b66a635e04358c7334054457bbbb8645610cd95b2"}, + {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:01e3ba46c2dee6d47a4ab22561a01d8ee6772f681defc9fcb357097a055e48cf"}, + {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:477b9456eb7d70f385dc8f097a1d66ee40771b62e47b3b3e33406dcfbc1c6a3b"}, + {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2965fd8ba31b04c42e4b696fad509dc5ab50663efca6eb06bb3b6d08587f3a09"}, + {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc76ad7453816318d794248fba4032967eaffd992d76e5d1af10ef9d46589770"}, + {file = "bitarray-3.7.1-cp310-cp310-win32.whl", hash = "sha256:d3f38373d9b2629dedc559e647010541cc4ec4ad9bea560e2eb1017e6a00d9ef"}, + {file = "bitarray-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:e39f5e85e1e3d7d84ac2217cd095b3678306c979e991532df47012880e02215d"}, + {file = "bitarray-3.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac39319e6322c2c093a660c02cea6bb3b1ae53d049b573d4781df8896e443e04"}, + {file = "bitarray-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a43f4631ecb87bedc510568fef67db53f2a20c4a5953a9d1e07457e7b1d14911"}, + {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd112646486a31ea5a45aa1eca0e2cd90b6a12f67e848e50349e324c24cc2e7"}, + {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db0441e80773d747a1ed9edfb9f75e7acb68ce8627583bbb6f770b7ec49f0064"}, + {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef5a99a8d1a5c47b4cf85925d1420fc4ee584c98be8efc548651447b3047242f"}, + {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb7af369df317527d697c5bb37ab944bb9a17ea1a5e82e47d5c7c638f3ccdd6"}, + {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eda67136343db96752e58ef36ac37116f36cba40961e79fd0e9bd858f5a09b38"}, + {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:79038bf1a7b13d243e51f4b6909c6997c2ba2bffc45bcae264704308a2d17198"}, + {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d12c45da97b2f31d0233e15f8d68731cfa86264c9f04b2669b9fdf46aaf68e1f"}, + {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:64d1143e90299ba8c967324840912a63a903494b1870a52f6675bda53dc332f7"}, + {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c4e04c12f507942f1ddf215cb3a08c244d24051cdd2ba571060166ce8a92be16"}, + {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ddc646cec4899a137c134b13818469e4178a251d77f9f4b23229267e3da78cfb"}, + {file = "bitarray-3.7.1-cp311-cp311-win32.whl", hash = "sha256:a23b5f13f9b292004e94b0b13fead4dae79c7512db04dc817ff2c2478298e04a"}, + {file = "bitarray-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:acc56700963f63307ac096689d4547e8061028a66bb78b90e42c5da2898898fb"}, + {file = "bitarray-3.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b99a0347bc6131046c19e056a113daa34d7df99f1f45510161bc78bc8461a470"}, + {file = "bitarray-3.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d7e274ac1975e55ebfb8166cce27e13dc99120c1d6ce9e490d7a716b9be9abb5"}, + {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b9a2eb7d2e0e9c2f25256d2663c0a2a4798fe3110e3ddbbb1a7b71740b4de08"}, + {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e15e70a3cf5bb519e2448524d689c02ff6bcd4750587a517e2bffee06065bf27"}, + {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c65257899bb8faf6a111297b4ff0066324a6b901318582c0453a01422c3bcd5a"}, + {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38b0261483c59bb39ae9300ad46bf0bbf431ab604266382d986a349c96171b36"}, + {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2b1ed363a4ef5622dccbf7822f01b51195062c4f382b28c9bd125d046d0324c"}, + {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:dfde50ae55e075dcd5801e2c3ea0e749c849ed2cbbee991af0f97f1bdbadb2a6"}, + {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:45660e2fabcdc1bab9699a468b312f47956300d41d6a2ea91c8f067572aaf38a"}, + {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7b4a41dc183d7d16750634f65566205990f94144755a39f33da44c0350c3e1a8"}, + {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8b8e07374d60040b24d1a158895d9758424db13be63d4b2fe1870e37f9dec009"}, + {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f31d8c2168bf2a52e4539232392352832c2296e07e0e14b6e06a44da574099ba"}, + {file = "bitarray-3.7.1-cp312-cp312-win32.whl", hash = "sha256:fe1f1f4010244cb07f6a079854a12e1627e4fb9ea99d672f2ceccaf6653ca514"}, + {file = "bitarray-3.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:f41a4b57cbc128a699e9d716a56c90c7fc76554e680fe2962f49cc4d8688b051"}, + {file = "bitarray-3.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e62892645f6a214eefb58a42c3ed2501af2e40a797844e0e09ec1e400ce75f3d"}, + {file = "bitarray-3.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3092f6bbf4a75b1e6f14a5b1030e27c435f341afeb23987115e45a25cc68ba91"}, + {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:851398428f5604c53371b72c5e0a28163274264ada4a08cd1eafe65fde1f68d0"}, + {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa05460dc4f57358680b977b4a254d331b24c8beb501319b998625fd6a22654b"}, + {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ad0df7886cb9d6d2ff75e87d323108a0e32bdca5c9918071681864129ce8ea8"}, + {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55c31bc3d2c9e48741c812ee5ce4607c6f33e33f339831c214d923ffc7777d21"}, + {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44f468fb4857fff86c65bec5e2fb67067789e40dad69258e9bb78fc6a6df49e7"}, + {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:340c524c7c934b61d1985d805bffe7609180fb5d16ece6ce89b51aa535b936f2"}, + {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0751596f60f33df66245b2dafa3f7fbe13cb7ac91dd14ead87d8c2eec57cb3ed"}, + {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e501bd27c795105aaba02b5212ecd1bb552ca2ee2ede53e5a8cb74deee0e2052"}, + {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe2493d3f49e314e573022ead4d8c845c9748979b7eb95e815429fe947c4bde2"}, + {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f1575cc0f66aa70a0bb5cb57c8d9d1b7d541d920455169c6266919bf804dc20"}, + {file = "bitarray-3.7.1-cp313-cp313-win32.whl", hash = "sha256:da3dfd2776226e15d3288a3a24c7975f9ee160ba198f2efa66bc28c5ba76d792"}, + {file = "bitarray-3.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:33f604bffd06b170637f8a48ddcf42074ed1e1980366ac46058e065ce04bfe2a"}, + {file = "bitarray-3.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f0795e2be2aa8afd013635f30ffe599cc00f1bbaca2d1d19b6187b4d1c58fb44"}, + {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f9f9bb2c5cc1f679605ebbeb72f46fc395d850b93fa7de7addd502a1dc66e99"}, + {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9faa4c6fcb19a31240ad389426699a99df481b6576f7286471e24efbf1b44dfc"}, + {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7998dfb1e9e0255fb8553abb019c3e7f558925de4edc8604243775ff9dd3898d"}, + {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bfdfe2e2af434d3f4e47250f693657334e34a7ec557cd703b129a814422b4b8"}, + {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97c448a20aded59727261468873d9b11dfdcce5a6338a359135667d5e3f1d070"}, + {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:f7c531722e8c3901f6bb303db464cac98ab44ed422c0fd0c762baa4a8d49ffa1"}, + {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:639389b023315596e0293f85999645f47ec3dc28c892e51242dde6176c91486b"}, + {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:4a83d247420b147d4b3cba0335e484365e117dc1cfe5ab35acd6a0817ad9244f"}, + {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_s390x.whl", hash = "sha256:befac6644c6f304a1b6a7948a04095682849c426cebcc44cb2459aa92d3e1735"}, + {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:87a29b8a4cc72af6118954592dcd4e49223420470ccc3f8091c255f6c7330bb1"}, + {file = "bitarray-3.7.1-cp36-cp36m-win32.whl", hash = "sha256:7afc740ad45ee0e0cef055765faf64789c2c183eb4aa3ecb8cecdb4b607396b3"}, + {file = "bitarray-3.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:ea60cf85b4e5a78b5a41eed3a65abc3839a50d915c6e0f6966cbcf81b85991bd"}, + {file = "bitarray-3.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a5b89349f05431270d1ccc7321aaab91c42ff33f463868779e502438b7f0e668"}, + {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b6bd81c77d9925809b714980cd30b1831a86bd090316d37cab124d92af1daf"}, + {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98373c273e01a5a7c17103ecb617de7c9980b7608351d58c72198e3525f0002e"}, + {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e4648c09103bc18f488957c1e0863d2397bab6625c0e6771891f151ee0bd96"}, + {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03dc877ec286b7f2813185ea6bc5f1f5527fd859e61038d38768883b134e06b3"}, + {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:101230b8074919970433ef79866570989157ade3421246d4c3afb7a994fdc614"}, + {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:fbe1ef622748d2edb3dd4fef933b934e90e479f9831dfe31bda3fdc16bf5287f"}, + {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:d160173efdad8a57c22e422a034196df3d84753672c497aee2f94bd5b128f8dd"}, + {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:e84cff8e8fe71903a6cf873fb3c8731df8bd7c1dac878e7a0fe19d8e2ef39aa9"}, + {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:03eeab48f376c3cd988add2b75c20d2d084b6fcc9a164adb0dc390ef152255b4"}, + {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:2db04b165a57499fbcfe0eaa2f7752f118552bbcfab2163a43fef8d95f4ae745"}, + {file = "bitarray-3.7.1-cp37-cp37m-win32.whl", hash = "sha256:f8ab90410b2ba5b8276657c66941bcaae556a38be8dd81630a7647e8735f0a20"}, + {file = "bitarray-3.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:bc0880011b86f81c5353ce4abaeb2472d942ba2320985166a2a3dd4f783563a9"}, + {file = "bitarray-3.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c1f4880bcb6fb7a8e2ab89128032b3dcf59e1e877ff4493b11c8bf7c3a5b3df2"}, + {file = "bitarray-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:78103afbd0a94ac4c1f0b4014545fd149b968d5ea423aaa3b1f6e2c3fc19423e"}, + {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec3fd30622180cbe2326d48c14a4ab7f98a504b104bdca7dda88b134adad6e31"}, + {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98e4a17f55f3cbf6fe06cc79234269572f234467c8355b6758eb252073f78e6b"}, + {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c48cf5a92244ef3df4161c8625ee1890bb3d931db9a9f3b699e61a037cd58a"}, + {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8489bff00a1f81ac0754355772e76775878c32a42f16f01d427c3645546761c4"}, + {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e75eb1734046291c554d9addecca9a8785bdf5d53a64f525569f8549da863dde"}, + {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4079857566077f290d35e23ff0e8ba593069c139ae85b0d152b9fa476494f50a"}, + {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7378055c9f456c5bb034ac313d9a9028fc6597619a0b16584099adba5a589fdb"}, + {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:c44cf0059633470c6bb415091def546adbeb5dcfa91cc3fcb1ac16593f14e52a"}, + {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:1fb0a46ae4b8d244a3fb80c3055717baa3dec6be17938e6871042a8d5b4ce670"}, + {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bebb17125373c499beea009cc5bced757bde52bcb3fa1d6335650e6c2d8111d7"}, + {file = "bitarray-3.7.1-cp38-cp38-win32.whl", hash = "sha256:df7cc9584614f495f474a5ded365cf72decbcee4efcdc888d2943f8a794c789e"}, + {file = "bitarray-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:3110b98c5dfb31dc1cf82d8b0c32e3fa6d6d0b268ff9f2a1599165770c1af80f"}, + {file = "bitarray-3.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3bb3cf22c3c03ae698647e6766314149c9cf04aa2018d9f48d5efddc3ced2764"}, + {file = "bitarray-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:30a2fc37698820cbf9b51d5f801219ef4bed828a04f3307072b8f983dc422a0e"}, + {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11fcfdf272549a3d876f10d8422bcd5f675750aa746ce04ff04937ec3bb2329e"}, + {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d4aa56782368269eb9402caf7378b2a5ada6f05eb9c7edc2362be258973fd7e"}, + {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3572889fcb87e5ca94add412d8b365dbb7b59773a4362e52caa556e5fd98643"}, + {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a393b0f881eff94440f72846a6f0f95b983594a0a50af81c41ed18107420d6a7"}, + {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fdf059d4e3acec44f512ebe247718ae511fde632e2b06992022df8e637385a6"}, + {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a569c993942ac26c6c590639ed6712c6c9c3f0c8d287a067bf2a60eb615f3c6b"}, + {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:dbbaa147cf28b3e87738c624d390a3a9e2a5dfef4316f4c38b4ecaf3155a3eab"}, + {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d877759842ff9eb16d9c2b8b497953a7d994d4b231c171515f0bf3a2ae185c0c"}, + {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c3e014f7295b9327fa6f0b3e55a3fd485abac98be145b9597e0cdbb05c44ad07"}, + {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57b9df5d38ab49c13eaa9e0152fdfa8501fc23987f6dcf421b73484bfe573918"}, + {file = "bitarray-3.7.1-cp39-cp39-win32.whl", hash = "sha256:08c114cf02a63e13ce6d70bc5b9e7bdcfa8d5db17cece207cfa085c4bc4a7a0c"}, + {file = "bitarray-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:c427dfcce13a8c814556dfe7c110b8ef61b8fab5fca0d856d4890856807321dc"}, + {file = "bitarray-3.7.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c9bf2bf29854f165a47917b8782b6cf3a7d602971bf454806208d0cbb96f797a"}, + {file = "bitarray-3.7.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:002b73bf4a9f7b3ecb02260bd4dd332a6ee4d7f74ee9779a1ef342a36244d0cf"}, + {file = "bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:481239cd0966f965c2b8fa78b88614be5f12a64e7773bb5feecc567d39bb2dd5"}, + {file = "bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f583a1fb180a123c00064fab1a3bfb9d43e574b6474be1be3f6469e0331e3e2e"}, + {file = "bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3db0648536f3e08afa7ceb928153c39913f98fd50a5c3adf92a4d0d4268f213e"}, + {file = "bitarray-3.7.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3875578748b484638f6ea776f534e9088cfb15eee131aac051036cba40fd5d05"}, + {file = "bitarray-3.7.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ed4a87eda16e2f95d536152c5acccae07841fbdda3b9a752f3dbf43e39f4d6b"}, + {file = "bitarray-3.7.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f7a8fc5085450635a539c47c9fce6d441b4a973686f88fc220aa20e3921fe55"}, + {file = "bitarray-3.7.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be2f40045432e8aa33d9fd5cb43c91b0c61d77d3d8810f88e84e2e46411c27a7"}, + {file = "bitarray-3.7.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f825ebedcad87a2825ddb6cf62f6d7d5b7a56ddaf7c93eef4b974e7ddc16408"}, + {file = "bitarray-3.7.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:59ddb8a9f47ec807009c69e582d0de1c86c005f9f614557f4cebc7b8ac9b7d28"}, + {file = "bitarray-3.7.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a048e41e1cb0c1a37021269d02698e30d2a7cc9a0205dd3390e0807745b76dae"}, + {file = "bitarray-3.7.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:61b9f3cf3a55322baed8f0532b73bce77d688a01446c179392c4056ab74eb551"}, + {file = "bitarray-3.7.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53d2abeabb91a822e9d76420c9b44980edd2d6b21767c7bb9cb2b1b4cf091049"}, + {file = "bitarray-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b524306104c1296f1e91d74ee4ccbeeea621f6a13e44addf0bb630a1839fd72"}, + {file = "bitarray-3.7.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69687ef16d501c9217675af36fa3c68c009c03e184b07d22ba245e5c01d47e6b"}, + {file = "bitarray-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3dc654da62b3a3027b7c922f7e9f4b27feaabd5d38b2a98ea98de5e8107c72f2"}, + {file = "bitarray-3.7.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:eccc6829035c8b7b391a0aa124fade54932bb937dd1079f2740b9f1bde829226"}, + {file = "bitarray-3.7.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:05ee46a734b5110c5ac483815da4379f7622f4316362872ec7c0ed16db4b0148"}, + {file = "bitarray-3.7.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd7f6bfa2a36fb91b7dec9ddf905716f2ed0c3675d2b63c69b7530c9d211e715"}, + {file = "bitarray-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99124e39658b2f72d296819ec03418609dd4f1b275b00289c2f278a19da6f9c0"}, + {file = "bitarray-3.7.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16426a843b1bc9c552a7c97d6d7555e69730c2de1e2f560503d3fc0e7f6d8005"}, + {file = "bitarray-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6f7e1cdf0abb11718e655bb258920453b1e89c2315e9019f60f0775704b12a8c"}, + {file = "bitarray-3.7.1.tar.gz", hash = "sha256:795b1760418ab750826420ae24f06f392c08e21dc234f0a369a69cc00444f8ec"}, ] [[package]] name = "bitstring" -version = "4.2.3" +version = "4.3.1" description = "Simple construction, analysis and modification of binary data." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "bitstring-4.2.3-py3-none-any.whl", hash = "sha256:20ed0036e2fcf0323acb0f92f0b7b178516a080f3e91061470aa019ac4ede404"}, - {file = "bitstring-4.2.3.tar.gz", hash = "sha256:e0c447af3fda0d114f77b88c2d199f02f97ee7e957e6d719f40f41cf15fbb897"}, + {file = "bitstring-4.3.1-py3-none-any.whl", hash = "sha256:69d1587f0ac18dc7d93fc7e80d5f447161a33e57027e726dc18a0a8bacf1711a"}, + {file = "bitstring-4.3.1.tar.gz", hash = "sha256:a08bc09d3857216d4c0f412a1611056f1cc2b64fd254fb1e8a0afba7cfa1a95a"}, ] [package.dependencies] -bitarray = ">=2.9.0,<3.0.0" - -[[package]] -name = "black" -version = "24.10.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.9" -files = [ - {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, - {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, - {file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"}, - {file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"}, - {file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"}, - {file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"}, - {file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"}, - {file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"}, - {file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"}, - {file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"}, - {file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"}, - {file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"}, - {file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"}, - {file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"}, - {file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"}, - {file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"}, - {file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"}, - {file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"}, - {file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"}, - {file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"}, - {file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"}, - {file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.10)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] +bitarray = ">=3.0.0,<4.0" [[package]] name = "bolt11" -version = "2.1.0" +version = "2.1.1" description = "A library for encoding and decoding BOLT11 payment requests." optional = false -python-versions = ">=3.8.1" +python-versions = ">=3.10" +groups = ["main"] files = [ - {file = "bolt11-2.1.0-py3-none-any.whl", hash = "sha256:1535e441233414a9d8031a99fd3be07de4674bffda948033579404d44a42f614"}, - {file = "bolt11-2.1.0.tar.gz", hash = "sha256:177c63cd88d1eaba669eddb5937364676226253f2e9e5b77e8fe317ef32e62dd"}, + {file = "bolt11-2.1.1-py3-none-any.whl", hash = "sha256:fd4edb9e73e27bf5e017f47c97f7c6827b523fcf9cab152b123961ca78323e2d"}, + {file = "bolt11-2.1.1.tar.gz", hash = "sha256:4e903d77208bfc4de8fc7e183a0689ea54afe874c91d62524d3b8c09492fa7ea"}, ] [package.dependencies] @@ -410,228 +554,212 @@ coincurve = "*" [[package]] name = "certifi" -version = "2024.8.30" +version = "2025.8.3" description = "Python package for providing Mozilla's CA Bundle." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}, + {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}, ] [[package]] name = "cffi" -version = "1.17.1" +version = "2.0.0" description = "Foreign Function Interface for Python calling C code." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, + {file = "cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44"}, + {file = "cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb"}, + {file = "cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a"}, + {file = "cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739"}, + {file = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"}, + {file = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"}, + {file = "cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"}, + {file = "cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"}, + {file = "cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"}, + {file = "cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"}, + {file = "cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"}, + {file = "cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"}, + {file = "cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb"}, + {file = "cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26"}, + {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c"}, + {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b"}, + {file = "cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27"}, + {file = "cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75"}, + {file = "cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91"}, + {file = "cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5"}, + {file = "cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775"}, + {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205"}, + {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1"}, + {file = "cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f"}, + {file = "cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25"}, + {file = "cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad"}, + {file = "cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9"}, + {file = "cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592"}, + {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512"}, + {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4"}, + {file = "cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e"}, + {file = "cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6"}, + {file = "cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9"}, + {file = "cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf"}, + {file = "cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322"}, + {file = "cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a"}, + {file = "cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9"}, + {file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"}, ] [package.dependencies] -pycparser = "*" - -[[package]] -name = "cfgv" -version = "3.4.0" -description = "Validate configuration and produce human readable error messages." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, - {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, -] +pycparser = {version = "*", markers = "implementation_name != \"PyPy\""} [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.3" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-win32.whl", hash = "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca"}, + {file = "charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a"}, + {file = "charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.2.1" description = "Composable command line interface toolkit" optional = false -python-versions = ">=3.7" +python-versions = ">=3.10" +groups = ["main"] files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"}, + {file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"}, ] [package.dependencies] @@ -643,6 +771,7 @@ version = "20.0.0" description = "Cross-platform Python CFFI bindings for libsecp256k1" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "coincurve-20.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d559b22828638390118cae9372a1bb6f6594f5584c311deb1de6a83163a0919b"}, {file = "coincurve-20.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33d7f6ebd90fcc550f819f7f2cce2af525c342aac07f0ccda46ad8956ad9d99b"}, @@ -709,6 +838,8 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] +markers = "platform_system == \"Windows\" or sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -716,115 +847,113 @@ files = [ [[package]] name = "cryptography" -version = "42.0.8" +version = "45.0.7" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false -python-versions = ">=3.7" +python-versions = "!=3.9.0,!=3.9.1,>=3.7" +groups = ["main"] files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-45.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:3be4f21c6245930688bd9e162829480de027f8bf962ede33d4f8ba7d67a00cee"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:67285f8a611b0ebc0857ced2081e30302909f571a46bfa7a3cc0ad303fe015c6"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:577470e39e60a6cd7780793202e63536026d9b8641de011ed9d8174da9ca5339"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4bd3e5c4b9682bc112d634f2c6ccc6736ed3635fc3319ac2bb11d768cc5a00d8"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:465ccac9d70115cd4de7186e60cfe989de73f7bb23e8a7aa45af18f7412e75bf"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:16ede8a4f7929b4b7ff3642eba2bf79aa1d71f24ab6ee443935c0d269b6bc513"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8978132287a9d3ad6b54fcd1e08548033cc09dc6aacacb6c004c73c3eb5d3ac3"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b6a0e535baec27b528cb07a119f321ac024592388c5681a5ced167ae98e9fff3"}, + {file = "cryptography-45.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a24ee598d10befaec178efdff6054bc4d7e883f615bfbcd08126a0f4931c83a6"}, + {file = "cryptography-45.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:fa26fa54c0a9384c27fcdc905a2fb7d60ac6e47d14bc2692145f2b3b1e2cfdbd"}, + {file = "cryptography-45.0.7-cp311-abi3-win32.whl", hash = "sha256:bef32a5e327bd8e5af915d3416ffefdbe65ed975b646b3805be81b23580b57b8"}, + {file = "cryptography-45.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:3808e6b2e5f0b46d981c24d79648e5c25c35e59902ea4391a0dcb3e667bf7443"}, + {file = "cryptography-45.0.7-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bfb4c801f65dd61cedfc61a83732327fafbac55a47282e6f26f073ca7a41c3b2"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:81823935e2f8d476707e85a78a405953a03ef7b7b4f55f93f7c2d9680e5e0691"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3994c809c17fc570c2af12c9b840d7cea85a9fd3e5c0e0491f4fa3c029216d59"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dad43797959a74103cb59c5dac71409f9c27d34c8a05921341fb64ea8ccb1dd4"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ce7a453385e4c4693985b4a4a3533e041558851eae061a58a5405363b098fcd3"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b04f85ac3a90c227b6e5890acb0edbaf3140938dbecf07bff618bf3638578cf1"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:48c41a44ef8b8c2e80ca4527ee81daa4c527df3ecbc9423c41a420a9559d0e27"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f3df7b3d0f91b88b2106031fd995802a2e9ae13e02c36c1fc075b43f420f3a17"}, + {file = "cryptography-45.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd342f085542f6eb894ca00ef70236ea46070c8a13824c6bde0dfdcd36065b9b"}, + {file = "cryptography-45.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1993a1bb7e4eccfb922b6cd414f072e08ff5816702a0bdb8941c247a6b1b287c"}, + {file = "cryptography-45.0.7-cp37-abi3-win32.whl", hash = "sha256:18fcf70f243fe07252dcb1b268a687f2358025ce32f9f88028ca5c364b123ef5"}, + {file = "cryptography-45.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:7285a89df4900ed3bfaad5679b1e668cb4b38a8de1ccbfc84b05f34512da0a90"}, + {file = "cryptography-45.0.7-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:de58755d723e86175756f463f2f0bddd45cc36fbd62601228a3f8761c9f58252"}, + {file = "cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a20e442e917889d1a6b3c570c9e3fa2fdc398c20868abcea268ea33c024c4083"}, + {file = "cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:258e0dff86d1d891169b5af222d362468a9570e2532923088658aa866eb11130"}, + {file = "cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d97cf502abe2ab9eff8bd5e4aca274da8d06dd3ef08b759a8d6143f4ad65d4b4"}, + {file = "cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:c987dad82e8c65ebc985f5dae5e74a3beda9d0a2a4daf8a1115f3772b59e5141"}, + {file = "cryptography-45.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c13b1e3afd29a5b3b2656257f14669ca8fa8d7956d509926f0b130b600b50ab7"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a862753b36620af6fc54209264f92c716367f2f0ff4624952276a6bbd18cbde"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:06ce84dc14df0bf6ea84666f958e6080cdb6fe1231be2a51f3fc1267d9f3fb34"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d0c5c6bac22b177bf8da7435d9d27a6834ee130309749d162b26c3105c0795a9"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:2f641b64acc00811da98df63df7d59fd4706c0df449da71cb7ac39a0732b40ae"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:f5414a788ecc6ee6bc58560e85ca624258a55ca434884445440a810796ea0e0b"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:1f3d56f73595376f4244646dd5c5870c14c196949807be39e79e7bd9bac3da63"}, + {file = "cryptography-45.0.7.tar.gz", hash = "sha256:4b1654dfc64ea479c242508eb8c724044f1e964a47d1d1cacc5132292d851971"}, ] [package.dependencies] -cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} +cffi = {version = ">=1.14", markers = "platform_python_implementation != \"PyPy\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs ; python_full_version >= \"3.8.0\"", "sphinx-rtd-theme (>=3.0.0) ; python_full_version >= \"3.8.0\""] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_full_version >= \"3.8.0\""] +pep8test = ["check-sdist ; python_full_version >= \"3.8.0\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi (>=2024)", "cryptography-vectors (==45.0.7)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.15" +version = "1.2.18" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +groups = ["main"] files = [ - {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, - {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, + {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, + {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] - -[[package]] -name = "distlib" -version = "0.3.9" -description = "Distribution utilities" -optional = false -python-versions = "*" -files = [ - {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, - {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, -] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"] [[package]] name = "dnspython" -version = "2.7.0" +version = "2.8.0" description = "DNS toolkit" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" +groups = ["main"] files = [ - {file = "dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86"}, - {file = "dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1"}, + {file = "dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af"}, + {file = "dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f"}, ] [package.extras] -dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "hypercorn (>=0.16.0)", "mypy (>=1.8)", "pylint (>=3)", "pytest (>=7.4)", "pytest-cov (>=4.1.0)", "quart-trio (>=0.11.0)", "sphinx (>=7.2.0)", "sphinx-rtd-theme (>=2.0.0)", "twine (>=4.0.0)", "wheel (>=0.42.0)"] -dnssec = ["cryptography (>=43)"] -doh = ["h2 (>=4.1.0)", "httpcore (>=1.0.0)", "httpx (>=0.26.0)"] -doq = ["aioquic (>=1.0.0)"] -idna = ["idna (>=3.7)"] -trio = ["trio (>=0.23)"] -wmi = ["wmi (>=1.5.1)"] +dev = ["black (>=25.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "hypercorn (>=0.17.0)", "mypy (>=1.17)", "pylint (>=3)", "pytest (>=8.4)", "pytest-cov (>=6.2.0)", "quart-trio (>=0.12.0)", "sphinx (>=8.2.0)", "sphinx-rtd-theme (>=3.0.0)", "twine (>=6.1.0)", "wheel (>=0.45.0)"] +dnssec = ["cryptography (>=45)"] +doh = ["h2 (>=4.2.0)", "httpcore (>=1.0.0)", "httpx (>=0.28.0)"] +doq = ["aioquic (>=1.2.0)"] +idna = ["idna (>=3.10)"] +trio = ["trio (>=0.30)"] +wmi = ["wmi (>=1.5.1) ; platform_system == \"Windows\""] [[package]] name = "ecdsa" -version = "0.19.0" +version = "0.19.1" description = "ECDSA cryptographic signature library (pure python)" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.6" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.6" +groups = ["main"] files = [ - {file = "ecdsa-0.19.0-py2.py3-none-any.whl", hash = "sha256:2cea9b88407fdac7bbeca0833b189e4c9c53f2ef1e1eaa29f6224dbc809b707a"}, - {file = "ecdsa-0.19.0.tar.gz", hash = "sha256:60eaad1199659900dd0af521ed462b793bbdf867432b3948e87416ae4caf6bf8"}, + {file = "ecdsa-0.19.1-py2.py3-none-any.whl", hash = "sha256:30638e27cf77b7e15c4c4cc1973720149e1033827cfd00661ca5c8cc0cdb24c3"}, + {file = "ecdsa-0.19.1.tar.gz", hash = "sha256:478cba7b62555866fcb3bb3fe985e06decbdb68ef55713c4e5ab98c57d508e61"}, ] [package.dependencies] @@ -836,13 +965,14 @@ gmpy2 = ["gmpy2"] [[package]] name = "email-validator" -version = "2.2.0" +version = "2.3.0" description = "A robust email address syntax and deliverability validation library." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"}, - {file = "email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"}, + {file = "email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4"}, + {file = "email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426"}, ] [package.dependencies] @@ -855,6 +985,7 @@ version = "0.8.0" description = "A minimal bitcoin library for MicroPython and Python3 with a focus on embedded systems." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "embit-0.8.0.tar.gz", hash = "sha256:8bf4b10073c67400370ce523fb16f035fe759f6fdd987c579bdcc268d75ed770"}, ] @@ -864,68 +995,76 @@ dev = ["black", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mypy", "pr [[package]] name = "environs" -version = "9.5.0" +version = "14.2.0" description = "simplified environment variable parsing" optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "environs-9.5.0-py2.py3-none-any.whl", hash = "sha256:1e549569a3de49c05f856f40bce86979e7d5ffbbc4398e7f338574c220189124"}, - {file = "environs-9.5.0.tar.gz", hash = "sha256:a76307b36fbe856bdca7ee9161e6c466fd7fcffc297109a118c59b54e27e30c9"}, + {file = "environs-14.2.0-py3-none-any.whl", hash = "sha256:22669a58d53c5b86a25d0231c4a41a6ebeb82d3942b8fbd9cf645890c92a1843"}, + {file = "environs-14.2.0.tar.gz", hash = "sha256:2b6c78a77dfefb57ca30d43a232270ecc82adabf67ab318e018084b9a3529e9b"}, ] [package.dependencies] -marshmallow = ">=3.0.0" +marshmallow = ">=3.18.0" python-dotenv = "*" +typing-extensions = {version = "*", markers = "python_version < \"3.11\""} [package.extras] -dev = ["dj-database-url", "dj-email-url", "django-cache-url", "flake8 (==4.0.1)", "flake8-bugbear (==21.9.2)", "mypy (==0.910)", "pre-commit (>=2.4,<3.0)", "pytest", "tox"] +dev = ["environs[tests]", "pre-commit (>=4.0,<5.0)", "tox"] django = ["dj-database-url", "dj-email-url", "django-cache-url"] -lint = ["flake8 (==4.0.1)", "flake8-bugbear (==21.9.2)", "mypy (==0.910)", "pre-commit (>=2.4,<3.0)"] -tests = ["dj-database-url", "dj-email-url", "django-cache-url", "pytest"] +tests = ["backports.strenum ; python_version < \"3.11\"", "environs[django]", "packaging", "pytest"] [[package]] name = "exceptiongroup" -version = "1.2.2" +version = "1.3.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" +groups = ["main"] +markers = "python_version == \"3.10\"" files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, + {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, + {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + [package.extras] test = ["pytest (>=6)"] [[package]] name = "fastapi" -version = "0.115.2" +version = "0.115.13" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "fastapi-0.115.2-py3-none-any.whl", hash = "sha256:61704c71286579cc5a598763905928f24ee98bfcc07aabe84cfefb98812bbc86"}, - {file = "fastapi-0.115.2.tar.gz", hash = "sha256:3995739e0b09fa12f984bce8fa9ae197b35d433750d3d312422d846e283697ee"}, + {file = "fastapi-0.115.13-py3-none-any.whl", hash = "sha256:0a0cab59afa7bab22f5eb347f8c9864b681558c278395e94035a741fc10cd865"}, + {file = "fastapi-0.115.13.tar.gz", hash = "sha256:55d1d25c2e1e0a0a50aceb1c8705cd932def273c102bff0b1c1da88b3c6eb307"}, ] [package.dependencies] pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.37.2,<0.41.0" +starlette = ">=0.40.0,<0.47.0" typing-extensions = ">=4.8.0" [package.extras] -all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] -standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"] +all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"] [[package]] name = "fastapi-sso" -version = "0.15.0" +version = "0.18.0" description = "FastAPI plugin to enable SSO to most common providers (such as Facebook login, Google login and login via Microsoft Office 365 Account)" optional = false -python-versions = "<4.0,>=3.8" +python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ - {file = "fastapi_sso-0.15.0-py3-none-any.whl", hash = "sha256:071e0c204181bdb6a8afad2714f9f6abad32bd8984b9e57500ff0d2b680fdb37"}, - {file = "fastapi_sso-0.15.0.tar.gz", hash = "sha256:9717c3e0f88ae7cccb43fa1827e6b85fa2621a4c41b21347ddebf719b40abc15"}, + {file = "fastapi_sso-0.18.0-py3-none-any.whl", hash = "sha256:727754ad770b70690f1471f7b0a9e17c6dfd8ebd6e477616d3bde1eaf62e53dc"}, + {file = "fastapi_sso-0.18.0.tar.gz", hash = "sha256:d8df5a686af7a6a7be248817544b405cf77f7e9ffcd5d0d7d2a196fd071964bc"}, ] [package.dependencies] @@ -933,176 +1072,281 @@ fastapi = ">=0.80" httpx = ">=0.23.0" oauthlib = ">=3.1.0" pydantic = {version = ">=1.8.0", extras = ["email"]} +pyjwt = ">=2.10.1,<3.0.0" [[package]] -name = "filelock" -version = "3.16.1" -description = "A platform independent file lock." +name = "filetype" +version = "1.2.0" +description = "Infer file type and MIME type of any file/buffer. No external dependencies." optional = false -python-versions = ">=3.8" +python-versions = "*" +groups = ["main"] files = [ - {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, - {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, + {file = "filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25"}, + {file = "filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb"}, ] -[package.extras] -docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] -typing = ["typing-extensions (>=4.12.2)"] +[[package]] +name = "frozenlist" +version = "1.7.0" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "frozenlist-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc4df77d638aa2ed703b878dd093725b72a824c3c546c076e8fdf276f78ee84a"}, + {file = "frozenlist-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:716a9973a2cc963160394f701964fe25012600f3d311f60c790400b00e568b61"}, + {file = "frozenlist-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0fd1bad056a3600047fb9462cff4c5322cebc59ebf5d0a3725e0ee78955001d"}, + {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3789ebc19cb811163e70fe2bd354cea097254ce6e707ae42e56f45e31e96cb8e"}, + {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af369aa35ee34f132fcfad5be45fbfcde0e3a5f6a1ec0712857f286b7d20cca9"}, + {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac64b6478722eeb7a3313d494f8342ef3478dff539d17002f849101b212ef97c"}, + {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f89f65d85774f1797239693cef07ad4c97fdd0639544bad9ac4b869782eb1981"}, + {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1073557c941395fdfcfac13eb2456cb8aad89f9de27bae29fabca8e563b12615"}, + {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed8d2fa095aae4bdc7fdd80351009a48d286635edffee66bf865e37a9125c50"}, + {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:24c34bea555fe42d9f928ba0a740c553088500377448febecaa82cc3e88aa1fa"}, + {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:69cac419ac6a6baad202c85aaf467b65ac860ac2e7f2ac1686dc40dbb52f6577"}, + {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:960d67d0611f4c87da7e2ae2eacf7ea81a5be967861e0c63cf205215afbfac59"}, + {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:41be2964bd4b15bf575e5daee5a5ce7ed3115320fb3c2b71fca05582ffa4dc9e"}, + {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46d84d49e00c9429238a7ce02dc0be8f6d7cd0cd405abd1bebdc991bf27c15bd"}, + {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15900082e886edb37480335d9d518cec978afc69ccbc30bd18610b7c1b22a718"}, + {file = "frozenlist-1.7.0-cp310-cp310-win32.whl", hash = "sha256:400ddd24ab4e55014bba442d917203c73b2846391dd42ca5e38ff52bb18c3c5e"}, + {file = "frozenlist-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:6eb93efb8101ef39d32d50bce242c84bcbddb4f7e9febfa7b524532a239b4464"}, + {file = "frozenlist-1.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa51e147a66b2d74de1e6e2cf5921890de6b0f4820b257465101d7f37b49fb5a"}, + {file = "frozenlist-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b35db7ce1cd71d36ba24f80f0c9e7cff73a28d7a74e91fe83e23d27c7828750"}, + {file = "frozenlist-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34a69a85e34ff37791e94542065c8416c1afbf820b68f720452f636d5fb990cd"}, + {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a646531fa8d82c87fe4bb2e596f23173caec9185bfbca5d583b4ccfb95183e2"}, + {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:79b2ffbba483f4ed36a0f236ccb85fbb16e670c9238313709638167670ba235f"}, + {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26f205c9ca5829cbf82bb2a84b5c36f7184c4316617d7ef1b271a56720d6b30"}, + {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcacfad3185a623fa11ea0e0634aac7b691aa925d50a440f39b458e41c561d98"}, + {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72c1b0fe8fe451b34f12dce46445ddf14bd2a5bcad7e324987194dc8e3a74c86"}, + {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d1a5baeaac6c0798ff6edfaeaa00e0e412d49946c53fae8d4b8e8b3566c4ae"}, + {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7edf5c043c062462f09b6820de9854bf28cc6cc5b6714b383149745e287181a8"}, + {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d50ac7627b3a1bd2dcef6f9da89a772694ec04d9a61b66cf87f7d9446b4a0c31"}, + {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce48b2fece5aeb45265bb7a58259f45027db0abff478e3077e12b05b17fb9da7"}, + {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:fe2365ae915a1fafd982c146754e1de6ab3478def8a59c86e1f7242d794f97d5"}, + {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:45a6f2fdbd10e074e8814eb98b05292f27bad7d1883afbe009d96abdcf3bc898"}, + {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:21884e23cffabb157a9dd7e353779077bf5b8f9a58e9b262c6caad2ef5f80a56"}, + {file = "frozenlist-1.7.0-cp311-cp311-win32.whl", hash = "sha256:284d233a8953d7b24f9159b8a3496fc1ddc00f4db99c324bd5fb5f22d8698ea7"}, + {file = "frozenlist-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:387cbfdcde2f2353f19c2f66bbb52406d06ed77519ac7ee21be0232147c2592d"}, + {file = "frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2"}, + {file = "frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb"}, + {file = "frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478"}, + {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8"}, + {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08"}, + {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4"}, + {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b"}, + {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e"}, + {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca"}, + {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df"}, + {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5"}, + {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025"}, + {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01"}, + {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08"}, + {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43"}, + {file = "frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3"}, + {file = "frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a"}, + {file = "frozenlist-1.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee80eeda5e2a4e660651370ebffd1286542b67e268aa1ac8d6dbe973120ef7ee"}, + {file = "frozenlist-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1a81c85417b914139e3a9b995d4a1c84559afc839a93cf2cb7f15e6e5f6ed2d"}, + {file = "frozenlist-1.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbb65198a9132ebc334f237d7b0df163e4de83fb4f2bdfe46c1e654bdb0c5d43"}, + {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dab46c723eeb2c255a64f9dc05b8dd601fde66d6b19cdb82b2e09cc6ff8d8b5d"}, + {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6aeac207a759d0dedd2e40745575ae32ab30926ff4fa49b1635def65806fddee"}, + {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd8c4e58ad14b4fa7802b8be49d47993182fdd4023393899632c88fd8cd994eb"}, + {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fb24d104f425da3540ed83cbfc31388a586a7696142004c577fa61c6298c3f"}, + {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a5c505156368e4ea6b53b5ac23c92d7edc864537ff911d2fb24c140bb175e60"}, + {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bd7eb96a675f18aa5c553eb7ddc24a43c8c18f22e1f9925528128c052cdbe00"}, + {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:05579bf020096fe05a764f1f84cd104a12f78eaab68842d036772dc6d4870b4b"}, + {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:376b6222d114e97eeec13d46c486facd41d4f43bab626b7c3f6a8b4e81a5192c"}, + {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa7e176ebe115379b5b1c95b4096fb1c17cce0847402e227e712c27bdb5a949"}, + {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3fbba20e662b9c2130dc771e332a99eff5da078b2b2648153a40669a6d0e36ca"}, + {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f4410a0a601d349dd406b5713fec59b4cee7e71678d5b17edda7f4655a940b"}, + {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cdfaaec6a2f9327bf43c933c0319a7c429058e8537c508964a133dffee412e"}, + {file = "frozenlist-1.7.0-cp313-cp313-win32.whl", hash = "sha256:5fc4df05a6591c7768459caba1b342d9ec23fa16195e744939ba5914596ae3e1"}, + {file = "frozenlist-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:52109052b9791a3e6b5d1b65f4b909703984b770694d3eb64fad124c835d7cba"}, + {file = "frozenlist-1.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a6f86e4193bb0e235ef6ce3dde5cbabed887e0b11f516ce8a0f4d3b33078ec2d"}, + {file = "frozenlist-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:82d664628865abeb32d90ae497fb93df398a69bb3434463d172b80fc25b0dd7d"}, + {file = "frozenlist-1.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:912a7e8375a1c9a68325a902f3953191b7b292aa3c3fb0d71a216221deca460b"}, + {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9537c2777167488d539bc5de2ad262efc44388230e5118868e172dd4a552b146"}, + {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f34560fb1b4c3e30ba35fa9a13894ba39e5acfc5f60f57d8accde65f46cc5e74"}, + {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acd03d224b0175f5a850edc104ac19040d35419eddad04e7cf2d5986d98427f1"}, + {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2038310bc582f3d6a09b3816ab01737d60bf7b1ec70f5356b09e84fb7408ab1"}, + {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c05e4c8e5f36e5e088caa1bf78a687528f83c043706640a92cb76cd6999384"}, + {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:765bb588c86e47d0b68f23c1bee323d4b703218037765dcf3f25c838c6fecceb"}, + {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:32dc2e08c67d86d0969714dd484fd60ff08ff81d1a1e40a77dd34a387e6ebc0c"}, + {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:c0303e597eb5a5321b4de9c68e9845ac8f290d2ab3f3e2c864437d3c5a30cd65"}, + {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a47f2abb4e29b3a8d0b530f7c3598badc6b134562b1a5caee867f7c62fee51e3"}, + {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:3d688126c242a6fabbd92e02633414d40f50bb6002fa4cf995a1d18051525657"}, + {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4e7e9652b3d367c7bd449a727dc79d5043f48b88d0cbfd4f9f1060cf2b414104"}, + {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1a85e345b4c43db8b842cab1feb41be5cc0b10a1830e6295b69d7310f99becaf"}, + {file = "frozenlist-1.7.0-cp313-cp313t-win32.whl", hash = "sha256:3a14027124ddb70dfcee5148979998066897e79f89f64b13328595c4bdf77c81"}, + {file = "frozenlist-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3bf8010d71d4507775f658e9823210b7427be36625b387221642725b515dcf3e"}, + {file = "frozenlist-1.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cea3dbd15aea1341ea2de490574a4a37ca080b2ae24e4b4f4b51b9057b4c3630"}, + {file = "frozenlist-1.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7d536ee086b23fecc36c2073c371572374ff50ef4db515e4e503925361c24f71"}, + {file = "frozenlist-1.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dfcebf56f703cb2e346315431699f00db126d158455e513bd14089d992101e44"}, + {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974c5336e61d6e7eb1ea5b929cb645e882aadab0095c5a6974a111e6479f8878"}, + {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c70db4a0ab5ab20878432c40563573229a7ed9241506181bba12f6b7d0dc41cb"}, + {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1137b78384eebaf70560a36b7b229f752fb64d463d38d1304939984d5cb887b6"}, + {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e793a9f01b3e8b5c0bc646fb59140ce0efcc580d22a3468d70766091beb81b35"}, + {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74739ba8e4e38221d2c5c03d90a7e542cb8ad681915f4ca8f68d04f810ee0a87"}, + {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e63344c4e929b1a01e29bc184bbb5fd82954869033765bfe8d65d09e336a677"}, + {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ea2a7369eb76de2217a842f22087913cdf75f63cf1307b9024ab82dfb525938"}, + {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:836b42f472a0e006e02499cef9352ce8097f33df43baaba3e0a28a964c26c7d2"}, + {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e22b9a99741294b2571667c07d9f8cceec07cb92aae5ccda39ea1b6052ed4319"}, + {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:9a19e85cc503d958abe5218953df722748d87172f71b73cf3c9257a91b999890"}, + {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f22dac33bb3ee8fe3e013aa7b91dc12f60d61d05b7fe32191ffa84c3aafe77bd"}, + {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9ccec739a99e4ccf664ea0775149f2749b8a6418eb5b8384b4dc0a7d15d304cb"}, + {file = "frozenlist-1.7.0-cp39-cp39-win32.whl", hash = "sha256:b3950f11058310008a87757f3eee16a8e1ca97979833239439586857bc25482e"}, + {file = "frozenlist-1.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:43a82fce6769c70f2f5a06248b614a7d268080a9d20f7457ef10ecee5af82b63"}, + {file = "frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e"}, + {file = "frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f"}, +] [[package]] name = "greenlet" -version = "3.1.1" +version = "3.2.4" description = "Lightweight in-process concurrent programming" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" +groups = ["main"] +markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\"" files = [ - {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617"}, - {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7"}, - {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6"}, - {file = "greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80"}, - {file = "greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a"}, - {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511"}, - {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395"}, - {file = "greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39"}, - {file = "greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9"}, - {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0"}, - {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942"}, - {file = "greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01"}, - {file = "greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e"}, - {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1"}, - {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c"}, - {file = "greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822"}, - {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01"}, - {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47da355d8687fd65240c364c90a31569a133b7b60de111c255ef5b606f2ae291"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98884ecf2ffb7d7fe6bd517e8eb99d31ff7855a840fa6d0d63cd07c037f6a981"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1d4aeb8891338e60d1ab6127af1fe45def5259def8094b9c7e34690c8858803"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db32b5348615a04b82240cc67983cb315309e88d444a288934ee6ceaebcad6cc"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dcc62f31eae24de7f8dce72134c8651c58000d3b1868e01392baea7c32c247de"}, - {file = "greenlet-3.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1d3755bcb2e02de341c55b4fca7a745a24a9e7212ac953f6b3a48d117d7257aa"}, - {file = "greenlet-3.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b8da394b34370874b4572676f36acabac172602abf054cbc4ac910219f3340af"}, - {file = "greenlet-3.1.1-cp37-cp37m-win32.whl", hash = "sha256:a0dfc6c143b519113354e780a50381508139b07d2177cb6ad6a08278ec655798"}, - {file = "greenlet-3.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:54558ea205654b50c438029505def3834e80f0869a70fb15b871c29b4575ddef"}, - {file = "greenlet-3.1.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:346bed03fe47414091be4ad44786d1bd8bef0c3fcad6ed3dee074a032ab408a9"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfc59d69fc48664bc693842bd57acfdd490acafda1ab52c7836e3fc75c90a111"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21e10da6ec19b457b82636209cbe2331ff4306b54d06fa04b7c138ba18c8a81"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37b9de5a96111fc15418819ab4c4432e4f3c2ede61e660b1e33971eba26ef9ba"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ef9ea3f137e5711f0dbe5f9263e8c009b7069d8a1acea822bd5e9dae0ae49c8"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85f3ff71e2e60bd4b4932a043fbbe0f499e263c628390b285cb599154a3b03b1"}, - {file = "greenlet-3.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:95ffcf719966dd7c453f908e208e14cde192e09fde6c7186c8f1896ef778d8cd"}, - {file = "greenlet-3.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:03a088b9de532cbfe2ba2034b2b85e82df37874681e8c470d6fb2f8c04d7e4b7"}, - {file = "greenlet-3.1.1-cp38-cp38-win32.whl", hash = "sha256:8b8b36671f10ba80e159378df9c4f15c14098c4fd73a36b9ad715f057272fbef"}, - {file = "greenlet-3.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:7017b2be767b9d43cc31416aba48aab0d2309ee31b4dbf10a1d38fb7972bdf9d"}, - {file = "greenlet-3.1.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:396979749bd95f018296af156201d6211240e7a23090f50a8d5d18c370084dc3"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca9d0ff5ad43e785350894d97e13633a66e2b50000e8a183a50a88d834752d42"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f6ff3b14f2df4c41660a7dec01045a045653998784bf8cfcb5a525bdffffbc8f"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94ebba31df2aa506d7b14866fed00ac141a867e63143fe5bca82a8e503b36437"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73aaad12ac0ff500f62cebed98d8789198ea0e6f233421059fa68a5aa7220145"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63e4844797b975b9af3a3fb8f7866ff08775f5426925e1e0bbcfe7932059a12c"}, - {file = "greenlet-3.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7939aa3ca7d2a1593596e7ac6d59391ff30281ef280d8632fa03d81f7c5f955e"}, - {file = "greenlet-3.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d0028e725ee18175c6e422797c407874da24381ce0690d6b9396c204c7f7276e"}, - {file = "greenlet-3.1.1-cp39-cp39-win32.whl", hash = "sha256:5e06afd14cbaf9e00899fae69b24a32f2196c19de08fcb9f4779dd4f004e5e7c"}, - {file = "greenlet-3.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:3319aa75e0e0639bc15ff54ca327e8dc7a6fe404003496e3c6925cd3142e0e22"}, - {file = "greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467"}, + {file = "greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d"}, + {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5"}, + {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f"}, + {file = "greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c"}, + {file = "greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8"}, + {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52"}, + {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa"}, + {file = "greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9"}, + {file = "greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0"}, + {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0"}, + {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f"}, + {file = "greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02"}, + {file = "greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671"}, + {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b"}, + {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae"}, + {file = "greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b"}, + {file = "greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337"}, + {file = "greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01"}, + {file = "greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:18d9260df2b5fbf41ae5139e1be4e796d99655f023a636cd0e11e6406cca7d58"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:671df96c1f23c4a0d4077a325483c1503c96a1b7d9db26592ae770daa41233d4"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:16458c245a38991aa19676900d48bd1a6f2ce3e16595051a4db9d012154e8433"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df"}, + {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594"}, + {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98"}, + {file = "greenlet-3.2.4-cp39-cp39-win32.whl", hash = "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b"}, + {file = "greenlet-3.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb"}, + {file = "greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d"}, ] [package.extras] docs = ["Sphinx", "furo"] -test = ["objgraph", "psutil"] +test = ["objgraph", "psutil", "setuptools"] [[package]] name = "grpcio" -version = "1.66.1" +version = "1.69.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "grpcio-1.66.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:4877ba180591acdf127afe21ec1c7ff8a5ecf0fe2600f0d3c50e8c4a1cbc6492"}, - {file = "grpcio-1.66.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:3750c5a00bd644c75f4507f77a804d0189d97a107eb1481945a0cf3af3e7a5ac"}, - {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:a013c5fbb12bfb5f927444b477a26f1080755a931d5d362e6a9a720ca7dbae60"}, - {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1b24c23d51a1e8790b25514157d43f0a4dce1ac12b3f0b8e9f66a5e2c4c132f"}, - {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7ffb8ea674d68de4cac6f57d2498fef477cef582f1fa849e9f844863af50083"}, - {file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:307b1d538140f19ccbd3aed7a93d8f71103c5d525f3c96f8616111614b14bf2a"}, - {file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c17ebcec157cfb8dd445890a03e20caf6209a5bd4ac5b040ae9dbc59eef091d"}, - {file = "grpcio-1.66.1-cp310-cp310-win32.whl", hash = "sha256:ef82d361ed5849d34cf09105d00b94b6728d289d6b9235513cb2fcc79f7c432c"}, - {file = "grpcio-1.66.1-cp310-cp310-win_amd64.whl", hash = "sha256:292a846b92cdcd40ecca46e694997dd6b9be6c4c01a94a0dfb3fcb75d20da858"}, - {file = "grpcio-1.66.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:c30aeceeaff11cd5ddbc348f37c58bcb96da8d5aa93fed78ab329de5f37a0d7a"}, - {file = "grpcio-1.66.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8a1e224ce6f740dbb6b24c58f885422deebd7eb724aff0671a847f8951857c26"}, - {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a66fe4dc35d2330c185cfbb42959f57ad36f257e0cc4557d11d9f0a3f14311df"}, - {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ba04659e4fce609de2658fe4dbf7d6ed21987a94460f5f92df7579fd5d0e22"}, - {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4573608e23f7e091acfbe3e84ac2045680b69751d8d67685ffa193a4429fedb1"}, - {file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7e06aa1f764ec8265b19d8f00140b8c4b6ca179a6dc67aa9413867c47e1fb04e"}, - {file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3885f037eb11f1cacc41f207b705f38a44b69478086f40608959bf5ad85826dd"}, - {file = "grpcio-1.66.1-cp311-cp311-win32.whl", hash = "sha256:97ae7edd3f3f91480e48ede5d3e7d431ad6005bfdbd65c1b56913799ec79e791"}, - {file = "grpcio-1.66.1-cp311-cp311-win_amd64.whl", hash = "sha256:cfd349de4158d797db2bd82d2020554a121674e98fbe6b15328456b3bf2495bb"}, - {file = "grpcio-1.66.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:a92c4f58c01c77205df6ff999faa008540475c39b835277fb8883b11cada127a"}, - {file = "grpcio-1.66.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fdb14bad0835914f325349ed34a51940bc2ad965142eb3090081593c6e347be9"}, - {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f03a5884c56256e08fd9e262e11b5cfacf1af96e2ce78dc095d2c41ccae2c80d"}, - {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ca2559692d8e7e245d456877a85ee41525f3ed425aa97eb7a70fc9a79df91a0"}, - {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ca1be089fb4446490dd1135828bd42a7c7f8421e74fa581611f7afdf7ab761"}, - {file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d639c939ad7c440c7b2819a28d559179a4508783f7e5b991166f8d7a34b52815"}, - {file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b9feb4e5ec8dc2d15709f4d5fc367794d69277f5d680baf1910fc9915c633524"}, - {file = "grpcio-1.66.1-cp312-cp312-win32.whl", hash = "sha256:7101db1bd4cd9b880294dec41a93fcdce465bdbb602cd8dc5bd2d6362b618759"}, - {file = "grpcio-1.66.1-cp312-cp312-win_amd64.whl", hash = "sha256:b0aa03d240b5539648d996cc60438f128c7f46050989e35b25f5c18286c86734"}, - {file = "grpcio-1.66.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:ecfe735e7a59e5a98208447293ff8580e9db1e890e232b8b292dc8bd15afc0d2"}, - {file = "grpcio-1.66.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4825a3aa5648010842e1c9d35a082187746aa0cdbf1b7a2a930595a94fb10fce"}, - {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:f517fd7259fe823ef3bd21e508b653d5492e706e9f0ef82c16ce3347a8a5620c"}, - {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1fe60d0772831d96d263b53d83fb9a3d050a94b0e94b6d004a5ad111faa5b5b"}, - {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31a049daa428f928f21090403e5d18ea02670e3d5d172581670be006100db9ef"}, - {file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f914386e52cbdeb5d2a7ce3bf1fdfacbe9d818dd81b6099a05b741aaf3848bb"}, - {file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bff2096bdba686019fb32d2dde45b95981f0d1490e054400f70fc9a8af34b49d"}, - {file = "grpcio-1.66.1-cp38-cp38-win32.whl", hash = "sha256:aa8ba945c96e73de29d25331b26f3e416e0c0f621e984a3ebdb2d0d0b596a3b3"}, - {file = "grpcio-1.66.1-cp38-cp38-win_amd64.whl", hash = "sha256:161d5c535c2bdf61b95080e7f0f017a1dfcb812bf54093e71e5562b16225b4ce"}, - {file = "grpcio-1.66.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:d0cd7050397b3609ea51727b1811e663ffda8bda39c6a5bb69525ef12414b503"}, - {file = "grpcio-1.66.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0e6c9b42ded5d02b6b1fea3a25f036a2236eeb75d0579bfd43c0018c88bf0a3e"}, - {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:c9f80f9fad93a8cf71c7f161778ba47fd730d13a343a46258065c4deb4b550c0"}, - {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dd67ed9da78e5121efc5c510f0122a972216808d6de70953a740560c572eb44"}, - {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48b0d92d45ce3be2084b92fb5bae2f64c208fea8ceed7fccf6a7b524d3c4942e"}, - {file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d813316d1a752be6f5c4360c49f55b06d4fe212d7df03253dfdae90c8a402bb"}, - {file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9c9bebc6627873ec27a70fc800f6083a13c70b23a5564788754b9ee52c5aef6c"}, - {file = "grpcio-1.66.1-cp39-cp39-win32.whl", hash = "sha256:30a1c2cf9390c894c90bbc70147f2372130ad189cffef161f0432d0157973f45"}, - {file = "grpcio-1.66.1-cp39-cp39-win_amd64.whl", hash = "sha256:17663598aadbedc3cacd7bbde432f541c8e07d2496564e22b214b22c7523dac8"}, - {file = "grpcio-1.66.1.tar.gz", hash = "sha256:35334f9c9745add3e357e3372756fd32d925bd52c41da97f4dfdafbde0bf0ee2"}, + {file = "grpcio-1.69.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:2060ca95a8db295ae828d0fc1c7f38fb26ccd5edf9aa51a0f44251f5da332e97"}, + {file = "grpcio-1.69.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2e52e107261fd8fa8fa457fe44bfadb904ae869d87c1280bf60f93ecd3e79278"}, + {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:316463c0832d5fcdb5e35ff2826d9aa3f26758d29cdfb59a368c1d6c39615a11"}, + {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26c9a9c4ac917efab4704b18eed9082ed3b6ad19595f047e8173b5182fec0d5e"}, + {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90b3646ced2eae3a0599658eeccc5ba7f303bf51b82514c50715bdd2b109e5ec"}, + {file = "grpcio-1.69.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3b75aea7c6cb91b341c85e7c1d9db1e09e1dd630b0717f836be94971e015031e"}, + {file = "grpcio-1.69.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5cfd14175f9db33d4b74d63de87c64bb0ee29ce475ce3c00c01ad2a3dc2a9e51"}, + {file = "grpcio-1.69.0-cp310-cp310-win32.whl", hash = "sha256:9031069d36cb949205293cf0e243abd5e64d6c93e01b078c37921493a41b72dc"}, + {file = "grpcio-1.69.0-cp310-cp310-win_amd64.whl", hash = "sha256:cc89b6c29f3dccbe12d7a3b3f1b3999db4882ae076c1c1f6df231d55dbd767a5"}, + {file = "grpcio-1.69.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:8de1b192c29b8ce45ee26a700044717bcbbd21c697fa1124d440548964328561"}, + {file = "grpcio-1.69.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:7e76accf38808f5c5c752b0ab3fd919eb14ff8fafb8db520ad1cc12afff74de6"}, + {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:d5658c3c2660417d82db51e168b277e0ff036d0b0f859fa7576c0ffd2aec1442"}, + {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5494d0e52bf77a2f7eb17c6da662886ca0a731e56c1c85b93505bece8dc6cf4c"}, + {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ed866f9edb574fd9be71bf64c954ce1b88fc93b2a4cbf94af221e9426eb14d6"}, + {file = "grpcio-1.69.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c5ba38aeac7a2fe353615c6b4213d1fbb3a3c34f86b4aaa8be08baaaee8cc56d"}, + {file = "grpcio-1.69.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f79e05f5bbf551c4057c227d1b041ace0e78462ac8128e2ad39ec58a382536d2"}, + {file = "grpcio-1.69.0-cp311-cp311-win32.whl", hash = "sha256:bf1f8be0da3fcdb2c1e9f374f3c2d043d606d69f425cd685110dd6d0d2d61258"}, + {file = "grpcio-1.69.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb9302afc3a0e4ba0b225cd651ef8e478bf0070cf11a529175caecd5ea2474e7"}, + {file = "grpcio-1.69.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:fc18a4de8c33491ad6f70022af5c460b39611e39578a4d84de0fe92f12d5d47b"}, + {file = "grpcio-1.69.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:0f0270bd9ffbff6961fe1da487bdcd594407ad390cc7960e738725d4807b18c4"}, + {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:dc48f99cc05e0698e689b51a05933253c69a8c8559a47f605cff83801b03af0e"}, + {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e925954b18d41aeb5ae250262116d0970893b38232689c4240024e4333ac084"}, + {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d222569273720366f68a99cb62e6194681eb763ee1d3b1005840678d4884f9"}, + {file = "grpcio-1.69.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b62b0f41e6e01a3e5082000b612064c87c93a49b05f7602fe1b7aa9fd5171a1d"}, + {file = "grpcio-1.69.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:db6f9fd2578dbe37db4b2994c94a1d9c93552ed77dca80e1657bb8a05b898b55"}, + {file = "grpcio-1.69.0-cp312-cp312-win32.whl", hash = "sha256:b192b81076073ed46f4b4dd612b8897d9a1e39d4eabd822e5da7b38497ed77e1"}, + {file = "grpcio-1.69.0-cp312-cp312-win_amd64.whl", hash = "sha256:1227ff7836f7b3a4ab04e5754f1d001fa52a730685d3dc894ed8bc262cc96c01"}, + {file = "grpcio-1.69.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:a78a06911d4081a24a1761d16215a08e9b6d4d29cdbb7e427e6c7e17b06bcc5d"}, + {file = "grpcio-1.69.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:dc5a351927d605b2721cbb46158e431dd49ce66ffbacb03e709dc07a491dde35"}, + {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:3629d8a8185f5139869a6a17865d03113a260e311e78fbe313f1a71603617589"}, + {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9a281878feeb9ae26db0622a19add03922a028d4db684658f16d546601a4870"}, + {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc614e895177ab7e4b70f154d1a7c97e152577ea101d76026d132b7aaba003b"}, + {file = "grpcio-1.69.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:1ee76cd7e2e49cf9264f6812d8c9ac1b85dda0eaea063af07292400f9191750e"}, + {file = "grpcio-1.69.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:0470fa911c503af59ec8bc4c82b371ee4303ececbbdc055f55ce48e38b20fd67"}, + {file = "grpcio-1.69.0-cp313-cp313-win32.whl", hash = "sha256:b650f34aceac8b2d08a4c8d7dc3e8a593f4d9e26d86751ebf74ebf5107d927de"}, + {file = "grpcio-1.69.0-cp313-cp313-win_amd64.whl", hash = "sha256:028337786f11fecb5d7b7fa660475a06aabf7e5e52b5ac2df47414878c0ce7ea"}, + {file = "grpcio-1.69.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:b7f693db593d6bf285e015d5538bf1c86cf9c60ed30b6f7da04a00ed052fe2f3"}, + {file = "grpcio-1.69.0-cp38-cp38-macosx_10_14_universal2.whl", hash = "sha256:8b94e83f66dbf6fd642415faca0608590bc5e8d30e2c012b31d7d1b91b1de2fd"}, + {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:b634851b92c090763dde61df0868c730376cdb73a91bcc821af56ae043b09596"}, + {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf5f680d3ed08c15330d7830d06bc65f58ca40c9999309517fd62880d70cb06e"}, + {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:200e48a6e7b00f804cf00a1c26292a5baa96507c7749e70a3ec10ca1a288936e"}, + {file = "grpcio-1.69.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:45a4704339b6e5b24b0e136dea9ad3815a94f30eb4f1e1d44c4ac484ef11d8dd"}, + {file = "grpcio-1.69.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85d347cb8237751b23539981dbd2d9d8f6e9ff90082b427b13022b948eb6347a"}, + {file = "grpcio-1.69.0-cp38-cp38-win32.whl", hash = "sha256:60e5de105dc02832dc8f120056306d0ef80932bcf1c0e2b4ca3b676de6dc6505"}, + {file = "grpcio-1.69.0-cp38-cp38-win_amd64.whl", hash = "sha256:282f47d0928e40f25d007f24eb8fa051cb22551e3c74b8248bc9f9bea9c35fe0"}, + {file = "grpcio-1.69.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:dd034d68a2905464c49479b0c209c773737a4245d616234c79c975c7c90eca03"}, + {file = "grpcio-1.69.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:01f834732c22a130bdf3dc154d1053bdbc887eb3ccb7f3e6285cfbfc33d9d5cc"}, + {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:a7f4ed0dcf202a70fe661329f8874bc3775c14bb3911d020d07c82c766ce0eb1"}, + {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd7ea241b10bc5f0bb0f82c0d7896822b7ed122b3ab35c9851b440c1ccf81588"}, + {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f03dc9b4da4c0dc8a1db7a5420f575251d7319b7a839004d8916257ddbe4816"}, + {file = "grpcio-1.69.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ca71d73a270dff052fe4edf74fef142d6ddd1f84175d9ac4a14b7280572ac519"}, + {file = "grpcio-1.69.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ccbed100dc43704e94ccff9e07680b540d64e4cc89213ab2832b51b4f68a520"}, + {file = "grpcio-1.69.0-cp39-cp39-win32.whl", hash = "sha256:1514341def9c6ec4b7f0b9628be95f620f9d4b99331b7ef0a1845fd33d9b579c"}, + {file = "grpcio-1.69.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1fea55d26d647346acb0069b08dca70984101f2dc95066e003019207212e303"}, + {file = "grpcio-1.69.0.tar.gz", hash = "sha256:936fa44241b5379c5afc344e1260d467bee495747eaf478de825bab2791da6f5"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.66.1)"] +protobuf = ["grpcio-tools (>=1.69.0)"] [[package]] name = "h11" -version = "0.14.0" +version = "0.16.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, + {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, + {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, ] [[package]] @@ -1111,6 +1355,7 @@ version = "1.2.1" description = "Encrypted Content Encoding for HTTP" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "http_ece-1.2.1.tar.gz", hash = "sha256:8c6ab23116bbf6affda894acfd5f2ca0fb8facbcbb72121c11c75c33e7ce8cff"}, ] @@ -1120,18 +1365,19 @@ cryptography = ">=2.5" [[package]] name = "httpcore" -version = "1.0.7" +version = "1.0.9" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, - {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, + {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}, + {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}, ] [package.dependencies] certifi = "*" -h11 = ">=0.13,<0.15" +h11 = ">=0.16" [package.extras] asyncio = ["anyio (>=4.0,<5.0)"] @@ -1145,6 +1391,7 @@ version = "0.27.0" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, @@ -1158,31 +1405,18 @@ idna = "*" sniffio = "*" [package.extras] -brotli = ["brotli", "brotlicffi"] +brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""] cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] -[[package]] -name = "identify" -version = "2.6.2" -description = "File identification library for Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3"}, - {file = "identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd"}, -] - -[package.extras] -license = ["ukkonen"] - [[package]] name = "idna" version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -1191,45 +1425,13 @@ files = [ [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] -[[package]] -name = "importlib-resources" -version = "6.4.5" -description = "Read resources from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717"}, - {file = "importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065"}, -] - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] -type = ["pytest-mypy"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - [[package]] name = "itsdangerous" version = "2.2.0" description = "Safely pass data to untrusted environments and back." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"}, {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"}, @@ -1237,13 +1439,14 @@ files = [ [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, ] [package.dependencies] @@ -1252,88 +1455,109 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jsonpath-ng" +version = "1.7.0" +description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c"}, + {file = "jsonpath_ng-1.7.0-py2-none-any.whl", hash = "sha256:898c93fc173f0c336784a3fa63d7434297544b7198124a68f9a3ef9597b0ae6e"}, + {file = "jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6"}, +] + +[package.dependencies] +ply = "*" + [[package]] name = "limits" -version = "3.13.0" +version = "5.5.0" description = "Rate limiting utilities" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" +groups = ["main"] files = [ - {file = "limits-3.13.0-py3-none-any.whl", hash = "sha256:9767f7233da4255e9904b79908a728e8ec0984c0b086058b4cbbd309aea553f6"}, - {file = "limits-3.13.0.tar.gz", hash = "sha256:6571b0c567bfa175a35fed9f8a954c0c92f1c3200804282f1b8f1de4ad98a953"}, + {file = "limits-5.5.0-py3-none-any.whl", hash = "sha256:57217d01ffa5114f7e233d1f5e5bdc6fe60c9b24ade387bf4d5e83c5cf929bae"}, + {file = "limits-5.5.0.tar.gz", hash = "sha256:ee269fedb078a904608b264424d9ef4ab10555acc8d090b6fc1db70e913327ea"}, ] [package.dependencies] deprecated = ">=1.2" -importlib-resources = ">=1.3" -packaging = ">=21,<25" -typing-extensions = "*" +packaging = ">=21" +typing_extensions = "*" [package.extras] -all = ["aetcd", "coredis (>=3.4.0,<5)", "emcache (>=0.6.1)", "emcache (>=1)", "etcd3", "motor (>=3,<4)", "pymemcache (>3,<5.0.0)", "pymongo (>4.1,<5)", "redis (>3,!=4.5.2,!=4.5.3,<6.0.0)", "redis (>=4.2.0,!=4.5.2,!=4.5.3)"] -async-etcd = ["aetcd"] -async-memcached = ["emcache (>=0.6.1)", "emcache (>=1)"] +all = ["coredis (>=3.4.0,<6)", "memcachio (>=0.3)", "motor (>=3,<4)", "pymemcache (>3,<5.0.0)", "pymongo (>4.1,<5)", "redis (>3,!=4.5.2,!=4.5.3,<7.0.0)", "redis (>=4.2.0,!=4.5.2,!=4.5.3)", "valkey (>=6)", "valkey (>=6)"] +async-memcached = ["memcachio (>=0.3)"] async-mongodb = ["motor (>=3,<4)"] -async-redis = ["coredis (>=3.4.0,<5)"] -etcd = ["etcd3"] +async-redis = ["coredis (>=3.4.0,<6)"] +async-valkey = ["valkey (>=6)"] memcached = ["pymemcache (>3,<5.0.0)"] mongodb = ["pymongo (>4.1,<5)"] -redis = ["redis (>3,!=4.5.2,!=4.5.3,<6.0.0)"] +redis = ["redis (>3,!=4.5.2,!=4.5.3,<7.0.0)"] rediscluster = ["redis (>=4.2.0,!=4.5.2,!=4.5.3)"] +valkey = ["valkey (>=6)"] [[package]] name = "lnbits" -version = "1.0.0rc5" +version = "1.2.1" description = "LNbits, free and open-source Lightning wallet and accounts system." optional = false -python-versions = "<4.0,>=3.9" +python-versions = "<3.13,>=3.10" +groups = ["main"] files = [ - {file = "lnbits-1.0.0rc5-py3-none-any.whl", hash = "sha256:3107a9c6711720299add7880b62c020cbf34cee2486d47f2c3ddd3f6b4a76b9d"}, - {file = "lnbits-1.0.0rc5.tar.gz", hash = "sha256:f5559efa5d9b81f89acc1510db052d6300b3e93e1d0acdc70204689501865a51"}, + {file = "lnbits-1.2.1-py3-none-any.whl", hash = "sha256:64d5b8dc0fe5b72f811e13ada1677b09f55f1070d3da901dc26102f47a07563b"}, + {file = "lnbits-1.2.1.tar.gz", hash = "sha256:7770e90c7072657fb759f4615962a2dd05d064851f58343695a7dd922a6bc20b"}, ] [package.dependencies] -aiosqlite = "0.20.0" -asyncpg = "0.29.0" -bcrypt = "4.2.0" +aiosqlite = "0.21.0" +asyncpg = "0.30.0" bech32 = "1.2.0" -bolt11 = "2.1.0" -click = "8.1.7" -ecdsa = "0.19.0" +bolt11 = "2.1.1" +click = "8.2.1" +ecdsa = "0.19.1" embit = "0.8.0" -environs = "9.5.0" -fastapi = "0.115.2" -fastapi-sso = "0.15.0" -grpcio = "1.66.1" +environs = "14.2.0" +fastapi = "0.115.13" +fastapi-sso = "0.18.0" +filetype = ">=1.2.0,<2.0.0" +grpcio = "1.69.0" httpx = "0.27.0" itsdangerous = "2.2.0" -jinja2 = "3.1.4" +jinja2 = "3.1.6" +jsonpath-ng = ">=1.7.0,<2.0.0" lnurl = "0.5.3" -loguru = "0.7.2" -packaging = "24.0" +loguru = "0.7.3" +nostr-sdk = ">=0.42.1,<0.43.0" +packaging = "25.0" passlib = "1.7.4" -protobuf = "5.28.0" -pycryptodomex = "3.20.0" +protobuf = "5.29.1" +pycryptodomex = "3.23.0" pydantic = "1.10.18" -pyjwt = "2.9.0" -pyln-client = "24.8.1" +pyjwt = "2.10.1" +pyln-client = "25.5" +pynostr = ">=0.6.2,<0.7.0" pyqrcode = "1.2.1" python-crontab = "3.2.0" -pywebpush = "1.14.1" +python-multipart = ">=0.0.20,<0.0.21" +pywebpush = "2.0.3" secp256k1 = "0.14.0" shortuuid = "1.0.13" slowapi = "0.1.9" sqlalchemy = "1.4.54" -sse-starlette = "1.8.2" -typing-extensions = "4.12.2" -uvicorn = "0.30.6" -uvloop = "0.19.0" +sse-starlette = "2.3.6" +typing-extensions = "4.14.0" +uvicorn = "0.34.3" +uvloop = "0.21.0" websocket-client = "1.8.0" -websockets = "11.0.3" +websockets = "15.0.1" [package.extras] -breez = ["breez-sdk (==0.5.2)"] -liquid = ["wallycore (==1.3.0)"] +breez = ["breez-sdk (==0.8.0)"] +liquid = ["wallycore (==1.4.0)"] [[package]] name = "lnurl" @@ -1341,6 +1565,7 @@ version = "0.5.3" description = "LNURL implementation for Python." optional = false python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ {file = "lnurl-0.5.3-py3-none-any.whl", hash = "sha256:feaf6c60b0b7f104894ef3accbd30d23d52e038c2797c58432baea7f4a8aa952"}, {file = "lnurl-0.5.3.tar.gz", hash = "sha256:60154bcfdbb98fb143eeca970a16d73a582f28e057a826b5f222259411c497fe"}, @@ -1355,13 +1580,14 @@ pydantic = ">=1,<2" [[package]] name = "loguru" -version = "0.7.2" +version = "0.7.3" description = "Python logging made (stupidly) simple" optional = false -python-versions = ">=3.5" +python-versions = "<4.0,>=3.5" +groups = ["main"] files = [ - {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, - {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, + {file = "loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c"}, + {file = "loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6"}, ] [package.dependencies] @@ -1369,7 +1595,31 @@ colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} [package.extras] -dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] +dev = ["Sphinx (==8.1.3) ; python_version >= \"3.11\"", "build (==1.2.2) ; python_version >= \"3.11\"", "colorama (==0.4.5) ; python_version < \"3.8\"", "colorama (==0.4.6) ; python_version >= \"3.8\"", "exceptiongroup (==1.1.3) ; python_version >= \"3.7\" and python_version < \"3.11\"", "freezegun (==1.1.0) ; python_version < \"3.8\"", "freezegun (==1.5.0) ; python_version >= \"3.8\"", "mypy (==v0.910) ; python_version < \"3.6\"", "mypy (==v0.971) ; python_version == \"3.6\"", "mypy (==v1.13.0) ; python_version >= \"3.8\"", "mypy (==v1.4.1) ; python_version == \"3.7\"", "myst-parser (==4.0.0) ; python_version >= \"3.11\"", "pre-commit (==4.0.1) ; python_version >= \"3.9\"", "pytest (==6.1.2) ; python_version < \"3.8\"", "pytest (==8.3.2) ; python_version >= \"3.8\"", "pytest-cov (==2.12.1) ; python_version < \"3.8\"", "pytest-cov (==5.0.0) ; python_version == \"3.8\"", "pytest-cov (==6.0.0) ; python_version >= \"3.9\"", "pytest-mypy-plugins (==1.9.3) ; python_version >= \"3.6\" and python_version < \"3.8\"", "pytest-mypy-plugins (==3.1.0) ; python_version >= \"3.8\"", "sphinx-rtd-theme (==3.0.2) ; python_version >= \"3.11\"", "tox (==3.27.1) ; python_version < \"3.8\"", "tox (==4.23.2) ; python_version >= \"3.8\"", "twine (==6.0.1) ; python_version >= \"3.11\""] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147"}, + {file = "markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "markdown-it-pyrs", "mistletoe (>=1.0,<2.0)", "mistune (>=3.0,<4.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins (>=0.5.0)"] +profiling = ["gprof2dot"] +rtd = ["ipykernel", "jupyter_sphinx", "mdit-py-plugins (>=0.5.0)", "myst-parser", "pyyaml", "sphinx", "sphinx-book-theme (>=1.0,<2.0)", "sphinx-copybutton", "sphinx-design"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "requests"] [[package]] name = "markupsafe" @@ -1377,6 +1627,7 @@ version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, @@ -1443,107 +1694,193 @@ files = [ [[package]] name = "marshmallow" -version = "3.23.1" +version = "4.0.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "marshmallow-3.23.1-py3-none-any.whl", hash = "sha256:fece2eb2c941180ea1b7fcbd4a83c51bfdd50093fdd3ad2585ee5e1df2508491"}, - {file = "marshmallow-3.23.1.tar.gz", hash = "sha256:3a8dfda6edd8dcdbf216c0ede1d1e78d230a6dc9c5a088f58c4083b974a0d468"}, + {file = "marshmallow-4.0.1-py3-none-any.whl", hash = "sha256:72f14ef346f81269dbddee891bac547dda1501e9e08b6a809756ea3dbb7936a1"}, + {file = "marshmallow-4.0.1.tar.gz", hash = "sha256:e1d860bd262737cb2d34e1541b84cb52c32c72c9474e3fe6f30f137ef8b0d97f"}, ] [package.dependencies] -packaging = ">=17.0" +backports-datetime-fromisoformat = {version = "*", markers = "python_version < \"3.11\""} +typing-extensions = {version = "*", markers = "python_version < \"3.11\""} [package.extras] dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] -docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.14)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"] +docs = ["autodocsumm (==0.2.14)", "furo (==2025.7.19)", "sphinx (==8.2.3)", "sphinx-copybutton (==0.5.2)", "sphinx-issues (==5.0.1)", "sphinxext-opengraph (==0.12.0)"] tests = ["pytest", "simplejson"] [[package]] -name = "mypy" -version = "1.13.0" -description = "Optional static typing for Python" +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, - {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, - {file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"}, - {file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"}, - {file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"}, - {file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"}, - {file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"}, - {file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"}, - {file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"}, - {file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"}, - {file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"}, - {file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"}, - {file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"}, - {file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"}, - {file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"}, - {file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"}, - {file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"}, - {file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"}, - {file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"}, - {file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"}, - {file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"}, - {file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"}, + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "multidict" +version = "6.6.4" +description = "multidict implementation" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "multidict-6.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b8aa6f0bd8125ddd04a6593437bad6a7e70f300ff4180a531654aa2ab3f6d58f"}, + {file = "multidict-6.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b9e5853bbd7264baca42ffc53391b490d65fe62849bf2c690fa3f6273dbcd0cb"}, + {file = "multidict-6.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0af5f9dee472371e36d6ae38bde009bd8ce65ac7335f55dcc240379d7bed1495"}, + {file = "multidict-6.6.4-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:d24f351e4d759f5054b641c81e8291e5d122af0fca5c72454ff77f7cbe492de8"}, + {file = "multidict-6.6.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db6a3810eec08280a172a6cd541ff4a5f6a97b161d93ec94e6c4018917deb6b7"}, + {file = "multidict-6.6.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a1b20a9d56b2d81e2ff52ecc0670d583eaabaa55f402e8d16dd062373dbbe796"}, + {file = "multidict-6.6.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8c9854df0eaa610a23494c32a6f44a3a550fb398b6b51a56e8c6b9b3689578db"}, + {file = "multidict-6.6.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4bb7627fd7a968f41905a4d6343b0d63244a0623f006e9ed989fa2b78f4438a0"}, + {file = "multidict-6.6.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caebafea30ed049c57c673d0b36238b1748683be2593965614d7b0e99125c877"}, + {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ad887a8250eb47d3ab083d2f98db7f48098d13d42eb7a3b67d8a5c795f224ace"}, + {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:ed8358ae7d94ffb7c397cecb62cbac9578a83ecefc1eba27b9090ee910e2efb6"}, + {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ecab51ad2462197a4c000b6d5701fc8585b80eecb90583635d7e327b7b6923eb"}, + {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c5c97aa666cf70e667dfa5af945424ba1329af5dd988a437efeb3a09430389fb"}, + {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9a950b7cf54099c1209f455ac5970b1ea81410f2af60ed9eb3c3f14f0bfcf987"}, + {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:163c7ea522ea9365a8a57832dea7618e6cbdc3cd75f8c627663587459a4e328f"}, + {file = "multidict-6.6.4-cp310-cp310-win32.whl", hash = "sha256:17d2cbbfa6ff20821396b25890f155f40c986f9cfbce5667759696d83504954f"}, + {file = "multidict-6.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:ce9a40fbe52e57e7edf20113a4eaddfacac0561a0879734e636aa6d4bb5e3fb0"}, + {file = "multidict-6.6.4-cp310-cp310-win_arm64.whl", hash = "sha256:01d0959807a451fe9fdd4da3e139cb5b77f7328baf2140feeaf233e1d777b729"}, + {file = "multidict-6.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c7a0e9b561e6460484318a7612e725df1145d46b0ef57c6b9866441bf6e27e0c"}, + {file = "multidict-6.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6bf2f10f70acc7a2446965ffbc726e5fc0b272c97a90b485857e5c70022213eb"}, + {file = "multidict-6.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66247d72ed62d5dd29752ffc1d3b88f135c6a8de8b5f63b7c14e973ef5bda19e"}, + {file = "multidict-6.6.4-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:105245cc6b76f51e408451a844a54e6823bbd5a490ebfe5bdfc79798511ceded"}, + {file = "multidict-6.6.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cbbc54e58b34c3bae389ef00046be0961f30fef7cb0dd9c7756aee376a4f7683"}, + {file = "multidict-6.6.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:56c6b3652f945c9bc3ac6c8178cd93132b8d82dd581fcbc3a00676c51302bc1a"}, + {file = "multidict-6.6.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b95494daf857602eccf4c18ca33337dd2be705bccdb6dddbfc9d513e6addb9d9"}, + {file = "multidict-6.6.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e5b1413361cef15340ab9dc61523e653d25723e82d488ef7d60a12878227ed50"}, + {file = "multidict-6.6.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e167bf899c3d724f9662ef00b4f7fef87a19c22b2fead198a6f68b263618df52"}, + {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aaea28ba20a9026dfa77f4b80369e51cb767c61e33a2d4043399c67bd95fb7c6"}, + {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8c91cdb30809a96d9ecf442ec9bc45e8cfaa0f7f8bdf534e082c2443a196727e"}, + {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1a0ccbfe93ca114c5d65a2471d52d8829e56d467c97b0e341cf5ee45410033b3"}, + {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:55624b3f321d84c403cb7d8e6e982f41ae233d85f85db54ba6286f7295dc8a9c"}, + {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4a1fb393a2c9d202cb766c76208bd7945bc194eba8ac920ce98c6e458f0b524b"}, + {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:43868297a5759a845fa3a483fb4392973a95fb1de891605a3728130c52b8f40f"}, + {file = "multidict-6.6.4-cp311-cp311-win32.whl", hash = "sha256:ed3b94c5e362a8a84d69642dbeac615452e8af9b8eb825b7bc9f31a53a1051e2"}, + {file = "multidict-6.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:d8c112f7a90d8ca5d20213aa41eac690bb50a76da153e3afb3886418e61cb22e"}, + {file = "multidict-6.6.4-cp311-cp311-win_arm64.whl", hash = "sha256:3bb0eae408fa1996d87247ca0d6a57b7fc1dcf83e8a5c47ab82c558c250d4adf"}, + {file = "multidict-6.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0ffb87be160942d56d7b87b0fdf098e81ed565add09eaa1294268c7f3caac4c8"}, + {file = "multidict-6.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d191de6cbab2aff5de6c5723101705fd044b3e4c7cfd587a1929b5028b9714b3"}, + {file = "multidict-6.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38a0956dd92d918ad5feff3db8fcb4a5eb7dba114da917e1a88475619781b57b"}, + {file = "multidict-6.6.4-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6865f6d3b7900ae020b495d599fcf3765653bc927951c1abb959017f81ae8287"}, + {file = "multidict-6.6.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a2088c126b6f72db6c9212ad827d0ba088c01d951cee25e758c450da732c138"}, + {file = "multidict-6.6.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0f37bed7319b848097085d7d48116f545985db988e2256b2e6f00563a3416ee6"}, + {file = "multidict-6.6.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:01368e3c94032ba6ca0b78e7ccb099643466cf24f8dc8eefcfdc0571d56e58f9"}, + {file = "multidict-6.6.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fe323540c255db0bffee79ad7f048c909f2ab0edb87a597e1c17da6a54e493c"}, + {file = "multidict-6.6.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8eb3025f17b0a4c3cd08cda49acf312a19ad6e8a4edd9dbd591e6506d999402"}, + {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bbc14f0365534d35a06970d6a83478b249752e922d662dc24d489af1aa0d1be7"}, + {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:75aa52fba2d96bf972e85451b99d8e19cc37ce26fd016f6d4aa60da9ab2b005f"}, + {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4fefd4a815e362d4f011919d97d7b4a1e566f1dde83dc4ad8cfb5b41de1df68d"}, + {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:db9801fe021f59a5b375ab778973127ca0ac52429a26e2fd86aa9508f4d26eb7"}, + {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a650629970fa21ac1fb06ba25dabfc5b8a2054fcbf6ae97c758aa956b8dba802"}, + {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:452ff5da78d4720d7516a3a2abd804957532dd69296cb77319c193e3ffb87e24"}, + {file = "multidict-6.6.4-cp312-cp312-win32.whl", hash = "sha256:8c2fcb12136530ed19572bbba61b407f655e3953ba669b96a35036a11a485793"}, + {file = "multidict-6.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:047d9425860a8c9544fed1b9584f0c8bcd31bcde9568b047c5e567a1025ecd6e"}, + {file = "multidict-6.6.4-cp312-cp312-win_arm64.whl", hash = "sha256:14754eb72feaa1e8ae528468f24250dd997b8e2188c3d2f593f9eba259e4b364"}, + {file = "multidict-6.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f46a6e8597f9bd71b31cc708195d42b634c8527fecbcf93febf1052cacc1f16e"}, + {file = "multidict-6.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:22e38b2bc176c5eb9c0a0e379f9d188ae4cd8b28c0f53b52bce7ab0a9e534657"}, + {file = "multidict-6.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5df8afd26f162da59e218ac0eefaa01b01b2e6cd606cffa46608f699539246da"}, + {file = "multidict-6.6.4-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:49517449b58d043023720aa58e62b2f74ce9b28f740a0b5d33971149553d72aa"}, + {file = "multidict-6.6.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae9408439537c5afdca05edd128a63f56a62680f4b3c234301055d7a2000220f"}, + {file = "multidict-6.6.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87a32d20759dc52a9e850fe1061b6e41ab28e2998d44168a8a341b99ded1dba0"}, + {file = "multidict-6.6.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:52e3c8d43cdfff587ceedce9deb25e6ae77daba560b626e97a56ddcad3756879"}, + {file = "multidict-6.6.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ad8850921d3a8d8ff6fbef790e773cecfc260bbfa0566998980d3fa8f520bc4a"}, + {file = "multidict-6.6.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:497a2954adc25c08daff36f795077f63ad33e13f19bfff7736e72c785391534f"}, + {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:024ce601f92d780ca1617ad4be5ac15b501cc2414970ffa2bb2bbc2bd5a68fa5"}, + {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a693fc5ed9bdd1c9e898013e0da4dcc640de7963a371c0bd458e50e046bf6438"}, + {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:190766dac95aab54cae5b152a56520fd99298f32a1266d66d27fdd1b5ac00f4e"}, + {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:34d8f2a5ffdceab9dcd97c7a016deb2308531d5f0fced2bb0c9e1df45b3363d7"}, + {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:59e8d40ab1f5a8597abcef00d04845155a5693b5da00d2c93dbe88f2050f2812"}, + {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:467fe64138cfac771f0e949b938c2e1ada2b5af22f39692aa9258715e9ea613a"}, + {file = "multidict-6.6.4-cp313-cp313-win32.whl", hash = "sha256:14616a30fe6d0a48d0a48d1a633ab3b8bec4cf293aac65f32ed116f620adfd69"}, + {file = "multidict-6.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:40cd05eaeb39e2bc8939451f033e57feaa2ac99e07dbca8afe2be450a4a3b6cf"}, + {file = "multidict-6.6.4-cp313-cp313-win_arm64.whl", hash = "sha256:f6eb37d511bfae9e13e82cb4d1af36b91150466f24d9b2b8a9785816deb16605"}, + {file = "multidict-6.6.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6c84378acd4f37d1b507dfa0d459b449e2321b3ba5f2338f9b085cf7a7ba95eb"}, + {file = "multidict-6.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0e0558693063c75f3d952abf645c78f3c5dfdd825a41d8c4d8156fc0b0da6e7e"}, + {file = "multidict-6.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3f8e2384cb83ebd23fd07e9eada8ba64afc4c759cd94817433ab8c81ee4b403f"}, + {file = "multidict-6.6.4-cp313-cp313t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:f996b87b420995a9174b2a7c1a8daf7db4750be6848b03eb5e639674f7963773"}, + {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc356250cffd6e78416cf5b40dc6a74f1edf3be8e834cf8862d9ed5265cf9b0e"}, + {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:dadf95aa862714ea468a49ad1e09fe00fcc9ec67d122f6596a8d40caf6cec7d0"}, + {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7dd57515bebffd8ebd714d101d4c434063322e4fe24042e90ced41f18b6d3395"}, + {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:967af5f238ebc2eb1da4e77af5492219fbd9b4b812347da39a7b5f5c72c0fa45"}, + {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a4c6875c37aae9794308ec43e3530e4aa0d36579ce38d89979bbf89582002bb"}, + {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:7f683a551e92bdb7fac545b9c6f9fa2aebdeefa61d607510b3533286fcab67f5"}, + {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:3ba5aaf600edaf2a868a391779f7a85d93bed147854925f34edd24cc70a3e141"}, + {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:580b643b7fd2c295d83cad90d78419081f53fd532d1f1eb67ceb7060f61cff0d"}, + {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:37b7187197da6af3ee0b044dbc9625afd0c885f2800815b228a0e70f9a7f473d"}, + {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e1b93790ed0bc26feb72e2f08299691ceb6da5e9e14a0d13cc74f1869af327a0"}, + {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a506a77ddee1efcca81ecbeae27ade3e09cdf21a8ae854d766c2bb4f14053f92"}, + {file = "multidict-6.6.4-cp313-cp313t-win32.whl", hash = "sha256:f93b2b2279883d1d0a9e1bd01f312d6fc315c5e4c1f09e112e4736e2f650bc4e"}, + {file = "multidict-6.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:6d46a180acdf6e87cc41dc15d8f5c2986e1e8739dc25dbb7dac826731ef381a4"}, + {file = "multidict-6.6.4-cp313-cp313t-win_arm64.whl", hash = "sha256:756989334015e3335d087a27331659820d53ba432befdef6a718398b0a8493ad"}, + {file = "multidict-6.6.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:af7618b591bae552b40dbb6f93f5518328a949dac626ee75927bba1ecdeea9f4"}, + {file = "multidict-6.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b6819f83aef06f560cb15482d619d0e623ce9bf155115150a85ab11b8342a665"}, + {file = "multidict-6.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4d09384e75788861e046330308e7af54dd306aaf20eb760eb1d0de26b2bea2cb"}, + {file = "multidict-6.6.4-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:a59c63061f1a07b861c004e53869eb1211ffd1a4acbca330e3322efa6dd02978"}, + {file = "multidict-6.6.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:350f6b0fe1ced61e778037fdc7613f4051c8baf64b1ee19371b42a3acdb016a0"}, + {file = "multidict-6.6.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0c5cbac6b55ad69cb6aa17ee9343dfbba903118fd530348c330211dc7aa756d1"}, + {file = "multidict-6.6.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:630f70c32b8066ddfd920350bc236225814ad94dfa493fe1910ee17fe4365cbb"}, + {file = "multidict-6.6.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8d4916a81697faec6cb724a273bd5457e4c6c43d82b29f9dc02c5542fd21fc9"}, + {file = "multidict-6.6.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e42332cf8276bb7645d310cdecca93a16920256a5b01bebf747365f86a1675b"}, + {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f3be27440f7644ab9a13a6fc86f09cdd90b347c3c5e30c6d6d860de822d7cb53"}, + {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:21f216669109e02ef3e2415ede07f4f8987f00de8cdfa0cc0b3440d42534f9f0"}, + {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d9890d68c45d1aeac5178ded1d1cccf3bc8d7accf1f976f79bf63099fb16e4bd"}, + {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:edfdcae97cdc5d1a89477c436b61f472c4d40971774ac4729c613b4b133163cb"}, + {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0b2e886624be5773e69cf32bcb8534aecdeb38943520b240fed3d5596a430f2f"}, + {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:be5bf4b3224948032a845d12ab0f69f208293742df96dc14c4ff9b09e508fc17"}, + {file = "multidict-6.6.4-cp39-cp39-win32.whl", hash = "sha256:10a68a9191f284fe9d501fef4efe93226e74df92ce7a24e301371293bd4918ae"}, + {file = "multidict-6.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:ee25f82f53262f9ac93bd7e58e47ea1bdcc3393cef815847e397cba17e284210"}, + {file = "multidict-6.6.4-cp39-cp39-win_arm64.whl", hash = "sha256:f9867e55590e0855bcec60d4f9a092b69476db64573c9fe17e92b0c50614c16a"}, + {file = "multidict-6.6.4-py3-none-any.whl", hash = "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c"}, + {file = "multidict-6.6.4.tar.gz", hash = "sha256:d2d4e4787672911b48350df02ed3fa3fffdc2f2e8ca06dd6afdf34189b76a9dd"}, ] [package.dependencies] -mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -faster-cache = ["orjson"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] +typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} [[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." +name = "nostr-sdk" +version = "0.42.1" +description = "Nostr protocol implementation, Relay, RelayPool, high-level client library, NWC client and more." optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "nodeenv" -version = "1.9.1" -description = "Node.js virtual environment builder" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, - {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:57ac8b7a6f56bb619a3ef58fbfe1bd93e180d5cd73681b45eeaf5ae2dd45d345"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-macosx_11_0_x86_64.whl", hash = "sha256:8897a4c3c34aa3cf4d500e570a1697ba253f89223e8548d2b75da2006fc730eb"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-manylinux_2_17_aarch64.whl", hash = "sha256:166f1c7b1901813ad9a6296641384cbcc7e35c18ccdf3229d88fcd1e0b51d6ee"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-manylinux_2_17_armv7l.whl", hash = "sha256:f2b86bc50805be59113c974665bdf4dcaaf76a1f591a9dba41f1d50acb674b3c"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-manylinux_2_17_i686.whl", hash = "sha256:73b0c16494221a0faf8ec369a2609faba3f17ffd0f03620baa0ec83c58c49b71"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:f68663073630c8edee55d9bec689f019ea616ef6482857e7f72ba1dc1b4fa9cc"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b6659308d7629e23be252455c46d81549fe6bf945915ec4a0cba2c4b61815c07"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:1fa8a8688cf17e838c31caf5c8a357b7c7c2ba3b6ee85e39c05c93e80d999b99"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:0a89ae1c7b2c36025024511240aa10540aade2551e8b97d40b4a0b88feaabe8c"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e3dda5d65591158a0c9794aa79a2f2ea7bbe3cfcba236645fbff8291d94946f1"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-win32.whl", hash = "sha256:d20988c0d6dd16c183607dfdbd243e4f5cc9d8a4faa0c498df546fa8383da902"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-win_amd64.whl", hash = "sha256:35978a8e526e66d05a346546391c28d643dfca31117a95c51c940c994c422d7d"}, + {file = "nostr_sdk-0.42.1-cp39-abi3-win_arm64.whl", hash = "sha256:802c74f903b120b74bf501bf68c81d5ee1dc9f7f57801a53a507044a14b9a840"}, ] [[package]] name = "oauthlib" -version = "3.2.2" +version = "3.3.1" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, - {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, + {file = "oauthlib-3.3.1-py3-none-any.whl", hash = "sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1"}, + {file = "oauthlib-3.3.1.tar.gz", hash = "sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9"}, ] [package.extras] @@ -1553,13 +1890,14 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "packaging" -version = "24.0" +version = "25.0" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, ] [[package]] @@ -1568,6 +1906,7 @@ version = "1.7.4" description = "comprehensive password hashing framework supporting over 30 schemes" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"}, {file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"}, @@ -1580,83 +1919,144 @@ build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fullt totp = ["cryptography"] [[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." +name = "ply" +version = "3.11" +description = "Python Lex & Yacc" optional = false -python-versions = ">=3.8" +python-versions = "*" +groups = ["main"] files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, + {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, + {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, ] [[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "3.8.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." +name = "propcache" +version = "0.3.2" +description = "Accelerated property cache" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, - {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, + {file = "propcache-0.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:22d9962a358aedbb7a2e36187ff273adeaab9743373a272976d2e348d08c7770"}, + {file = "propcache-0.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d0fda578d1dc3f77b6b5a5dce3b9ad69a8250a891760a548df850a5e8da87f3"}, + {file = "propcache-0.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3def3da3ac3ce41562d85db655d18ebac740cb3fa4367f11a52b3da9d03a5cc3"}, + {file = "propcache-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bec58347a5a6cebf239daba9bda37dffec5b8d2ce004d9fe4edef3d2815137e"}, + {file = "propcache-0.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ffda449a507e9fbd4aca1a7d9aa6753b07d6166140e5a18d2ac9bc49eac220"}, + {file = "propcache-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a67fb39229a8a8491dd42f864e5e263155e729c2e7ff723d6e25f596b1e8cb"}, + {file = "propcache-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da1cf97b92b51253d5b68cf5a2b9e0dafca095e36b7f2da335e27dc6172a614"}, + {file = "propcache-0.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f559e127134b07425134b4065be45b166183fdcb433cb6c24c8e4149056ad50"}, + {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aff2e4e06435d61f11a428360a932138d0ec288b0a31dd9bd78d200bd4a2b339"}, + {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4927842833830942a5d0a56e6f4839bc484785b8e1ce8d287359794818633ba0"}, + {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6107ddd08b02654a30fb8ad7a132021759d750a82578b94cd55ee2772b6ebea2"}, + {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:70bd8b9cd6b519e12859c99f3fc9a93f375ebd22a50296c3a295028bea73b9e7"}, + {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2183111651d710d3097338dd1893fcf09c9f54e27ff1a8795495a16a469cc90b"}, + {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fb075ad271405dcad8e2a7ffc9a750a3bf70e533bd86e89f0603e607b93aa64c"}, + {file = "propcache-0.3.2-cp310-cp310-win32.whl", hash = "sha256:404d70768080d3d3bdb41d0771037da19d8340d50b08e104ca0e7f9ce55fce70"}, + {file = "propcache-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:7435d766f978b4ede777002e6b3b6641dd229cd1da8d3d3106a45770365f9ad9"}, + {file = "propcache-0.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b8d2f607bd8f80ddc04088bc2a037fdd17884a6fcadc47a96e334d72f3717be"}, + {file = "propcache-0.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06766d8f34733416e2e34f46fea488ad5d60726bb9481d3cddf89a6fa2d9603f"}, + {file = "propcache-0.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2dc1f4a1df4fecf4e6f68013575ff4af84ef6f478fe5344317a65d38a8e6dc9"}, + {file = "propcache-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be29c4f4810c5789cf10ddf6af80b041c724e629fa51e308a7a0fb19ed1ef7bf"}, + {file = "propcache-0.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d61f6970ecbd8ff2e9360304d5c8876a6abd4530cb752c06586849ac8a9dc9"}, + {file = "propcache-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62180e0b8dbb6b004baec00a7983e4cc52f5ada9cd11f48c3528d8cfa7b96a66"}, + {file = "propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c144ca294a204c470f18cf4c9d78887810d04a3e2fbb30eea903575a779159df"}, + {file = "propcache-0.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5c2a784234c28854878d68978265617aa6dc0780e53d44b4d67f3651a17a9a2"}, + {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5745bc7acdafa978ca1642891b82c19238eadc78ba2aaa293c6863b304e552d7"}, + {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c0075bf773d66fa8c9d41f66cc132ecc75e5bb9dd7cce3cfd14adc5ca184cb95"}, + {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5f57aa0847730daceff0497f417c9de353c575d8da3579162cc74ac294c5369e"}, + {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:eef914c014bf72d18efb55619447e0aecd5fb7c2e3fa7441e2e5d6099bddff7e"}, + {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a4092e8549031e82facf3decdbc0883755d5bbcc62d3aea9d9e185549936dcf"}, + {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85871b050f174bc0bfb437efbdb68aaf860611953ed12418e4361bc9c392749e"}, + {file = "propcache-0.3.2-cp311-cp311-win32.whl", hash = "sha256:36c8d9b673ec57900c3554264e630d45980fd302458e4ac801802a7fd2ef7897"}, + {file = "propcache-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53af8cb6a781b02d2ea079b5b853ba9430fcbe18a8e3ce647d5982a3ff69f39"}, + {file = "propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10"}, + {file = "propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154"}, + {file = "propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615"}, + {file = "propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db"}, + {file = "propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1"}, + {file = "propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c"}, + {file = "propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67"}, + {file = "propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b"}, + {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8"}, + {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251"}, + {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474"}, + {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535"}, + {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06"}, + {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1"}, + {file = "propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1"}, + {file = "propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c"}, + {file = "propcache-0.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ca592ed634a73ca002967458187109265e980422116c0a107cf93d81f95af945"}, + {file = "propcache-0.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ecb0aad4020e275652ba3975740f241bd12a61f1a784df044cf7477a02bc252"}, + {file = "propcache-0.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f08f1cc28bd2eade7a8a3d2954ccc673bb02062e3e7da09bc75d843386b342f"}, + {file = "propcache-0.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1a342c834734edb4be5ecb1e9fb48cb64b1e2320fccbd8c54bf8da8f2a84c33"}, + {file = "propcache-0.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a544caaae1ac73f1fecfae70ded3e93728831affebd017d53449e3ac052ac1e"}, + {file = "propcache-0.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310d11aa44635298397db47a3ebce7db99a4cc4b9bbdfcf6c98a60c8d5261cf1"}, + {file = "propcache-0.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1396592321ac83157ac03a2023aa6cc4a3cc3cfdecb71090054c09e5a7cce3"}, + {file = "propcache-0.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cabf5b5902272565e78197edb682017d21cf3b550ba0460ee473753f28d23c1"}, + {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0a2f2235ac46a7aa25bdeb03a9e7060f6ecbd213b1f9101c43b3090ffb971ef6"}, + {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:92b69e12e34869a6970fd2f3da91669899994b47c98f5d430b781c26f1d9f387"}, + {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:54e02207c79968ebbdffc169591009f4474dde3b4679e16634d34c9363ff56b4"}, + {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4adfb44cb588001f68c5466579d3f1157ca07f7504fc91ec87862e2b8e556b88"}, + {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fd3e6019dc1261cd0291ee8919dd91fbab7b169bb76aeef6c716833a3f65d206"}, + {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4c181cad81158d71c41a2bce88edce078458e2dd5ffee7eddd6b05da85079f43"}, + {file = "propcache-0.3.2-cp313-cp313-win32.whl", hash = "sha256:8a08154613f2249519e549de2330cf8e2071c2887309a7b07fb56098f5170a02"}, + {file = "propcache-0.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e41671f1594fc4ab0a6dec1351864713cb3a279910ae8b58f884a88a0a632c05"}, + {file = "propcache-0.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:9a3cf035bbaf035f109987d9d55dc90e4b0e36e04bbbb95af3055ef17194057b"}, + {file = "propcache-0.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:156c03d07dc1323d8dacaa221fbe028c5c70d16709cdd63502778e6c3ccca1b0"}, + {file = "propcache-0.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74413c0ba02ba86f55cf60d18daab219f7e531620c15f1e23d95563f505efe7e"}, + {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f066b437bb3fa39c58ff97ab2ca351db465157d68ed0440abecb21715eb24b28"}, + {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1304b085c83067914721e7e9d9917d41ad87696bf70f0bc7dee450e9c71ad0a"}, + {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab50cef01b372763a13333b4e54021bdcb291fc9a8e2ccb9c2df98be51bcde6c"}, + {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad3b2a085ec259ad2c2842666b2a0a49dea8463579c606426128925af1ed725"}, + {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:261fa020c1c14deafd54c76b014956e2f86991af198c51139faf41c4d5e83892"}, + {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:46d7f8aa79c927e5f987ee3a80205c987717d3659f035c85cf0c3680526bdb44"}, + {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:6d8f3f0eebf73e3c0ff0e7853f68be638b4043c65a70517bb575eff54edd8dbe"}, + {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:03c89c1b14a5452cf15403e291c0ccd7751d5b9736ecb2c5bab977ad6c5bcd81"}, + {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0cc17efde71e12bbaad086d679ce575268d70bc123a5a71ea7ad76f70ba30bba"}, + {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:acdf05d00696bc0447e278bb53cb04ca72354e562cf88ea6f9107df8e7fd9770"}, + {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4445542398bd0b5d32df908031cb1b30d43ac848e20470a878b770ec2dcc6330"}, + {file = "propcache-0.3.2-cp313-cp313t-win32.whl", hash = "sha256:f86e5d7cd03afb3a1db8e9f9f6eff15794e79e791350ac48a8c924e6f439f394"}, + {file = "propcache-0.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9704bedf6e7cbe3c65eca4379a9b53ee6a83749f047808cbb5044d40d7d72198"}, + {file = "propcache-0.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a7fad897f14d92086d6b03fdd2eb844777b0c4d7ec5e3bac0fbae2ab0602bbe5"}, + {file = "propcache-0.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1f43837d4ca000243fd7fd6301947d7cb93360d03cd08369969450cc6b2ce3b4"}, + {file = "propcache-0.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:261df2e9474a5949c46e962065d88eb9b96ce0f2bd30e9d3136bcde84befd8f2"}, + {file = "propcache-0.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e514326b79e51f0a177daab1052bc164d9d9e54133797a3a58d24c9c87a3fe6d"}, + {file = "propcache-0.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4a996adb6904f85894570301939afeee65f072b4fd265ed7e569e8d9058e4ec"}, + {file = "propcache-0.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76cace5d6b2a54e55b137669b30f31aa15977eeed390c7cbfb1dafa8dfe9a701"}, + {file = "propcache-0.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31248e44b81d59d6addbb182c4720f90b44e1efdc19f58112a3c3a1615fb47ef"}, + {file = "propcache-0.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abb7fa19dbf88d3857363e0493b999b8011eea856b846305d8c0512dfdf8fbb1"}, + {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d81ac3ae39d38588ad0549e321e6f773a4e7cc68e7751524a22885d5bbadf886"}, + {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:cc2782eb0f7a16462285b6f8394bbbd0e1ee5f928034e941ffc444012224171b"}, + {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:db429c19a6c7e8a1c320e6a13c99799450f411b02251fb1b75e6217cf4a14fcb"}, + {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:21d8759141a9e00a681d35a1f160892a36fb6caa715ba0b832f7747da48fb6ea"}, + {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2ca6d378f09adb13837614ad2754fa8afaee330254f404299611bce41a8438cb"}, + {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:34a624af06c048946709f4278b4176470073deda88d91342665d95f7c6270fbe"}, + {file = "propcache-0.3.2-cp39-cp39-win32.whl", hash = "sha256:4ba3fef1c30f306b1c274ce0b8baaa2c3cdd91f645c48f06394068f37d3837a1"}, + {file = "propcache-0.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:7a2368eed65fc69a7a7a40b27f22e85e7627b74216f0846b04ba5c116e191ec9"}, + {file = "propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f"}, + {file = "propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168"}, ] -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - [[package]] name = "protobuf" -version = "5.28.0" +version = "5.29.1" description = "" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "protobuf-5.28.0-cp310-abi3-win32.whl", hash = "sha256:66c3edeedb774a3508ae70d87b3a19786445fe9a068dd3585e0cefa8a77b83d0"}, - {file = "protobuf-5.28.0-cp310-abi3-win_amd64.whl", hash = "sha256:6d7cc9e60f976cf3e873acb9a40fed04afb5d224608ed5c1a105db4a3f09c5b6"}, - {file = "protobuf-5.28.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:532627e8fdd825cf8767a2d2b94d77e874d5ddb0adefb04b237f7cc296748681"}, - {file = "protobuf-5.28.0-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:018db9056b9d75eb93d12a9d35120f97a84d9a919bcab11ed56ad2d399d6e8dd"}, - {file = "protobuf-5.28.0-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:6206afcb2d90181ae8722798dcb56dc76675ab67458ac24c0dd7d75d632ac9bd"}, - {file = "protobuf-5.28.0-cp38-cp38-win32.whl", hash = "sha256:eef7a8a2f4318e2cb2dee8666d26e58eaf437c14788f3a2911d0c3da40405ae8"}, - {file = "protobuf-5.28.0-cp38-cp38-win_amd64.whl", hash = "sha256:d001a73c8bc2bf5b5c1360d59dd7573744e163b3607fa92788b7f3d5fefbd9a5"}, - {file = "protobuf-5.28.0-cp39-cp39-win32.whl", hash = "sha256:dde9fcaa24e7a9654f4baf2a55250b13a5ea701493d904c54069776b99a8216b"}, - {file = "protobuf-5.28.0-cp39-cp39-win_amd64.whl", hash = "sha256:853db610214e77ee817ecf0514e0d1d052dff7f63a0c157aa6eabae98db8a8de"}, - {file = "protobuf-5.28.0-py3-none-any.whl", hash = "sha256:510ed78cd0980f6d3218099e874714cdf0d8a95582e7b059b06cabad855ed0a0"}, - {file = "protobuf-5.28.0.tar.gz", hash = "sha256:dde74af0fa774fa98892209992295adbfb91da3fa98c8f67a88afe8f5a349add"}, + {file = "protobuf-5.29.1-cp310-abi3-win32.whl", hash = "sha256:22c1f539024241ee545cbcb00ee160ad1877975690b16656ff87dde107b5f110"}, + {file = "protobuf-5.29.1-cp310-abi3-win_amd64.whl", hash = "sha256:1fc55267f086dd4050d18ef839d7bd69300d0d08c2a53ca7df3920cc271a3c34"}, + {file = "protobuf-5.29.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:d473655e29c0c4bbf8b69e9a8fb54645bc289dead6d753b952e7aa660254ae18"}, + {file = "protobuf-5.29.1-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5ba1d0e4c8a40ae0496d0e2ecfdbb82e1776928a205106d14ad6985a09ec155"}, + {file = "protobuf-5.29.1-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:8ee1461b3af56145aca2800e6a3e2f928108c749ba8feccc6f5dd0062c410c0d"}, + {file = "protobuf-5.29.1-cp38-cp38-win32.whl", hash = "sha256:50879eb0eb1246e3a5eabbbe566b44b10348939b7cc1b267567e8c3d07213853"}, + {file = "protobuf-5.29.1-cp38-cp38-win_amd64.whl", hash = "sha256:027fbcc48cea65a6b17028510fdd054147057fa78f4772eb547b9274e5219331"}, + {file = "protobuf-5.29.1-cp39-cp39-win32.whl", hash = "sha256:5a41deccfa5e745cef5c65a560c76ec0ed8e70908a67cc8f4da5fce588b50d57"}, + {file = "protobuf-5.29.1-cp39-cp39-win_amd64.whl", hash = "sha256:012ce28d862ff417fd629285aca5d9772807f15ceb1a0dbd15b88f58c776c98c"}, + {file = "protobuf-5.29.1-py3-none-any.whl", hash = "sha256:32600ddb9c2a53dedc25b8581ea0f1fd8ea04956373c0c07577ce58d312522e0"}, + {file = "protobuf-5.29.1.tar.gz", hash = "sha256:683be02ca21a6ffe80db6dd02c0b5b2892322c59ca57fd6c872d652cb80549cb"}, ] [[package]] @@ -1665,6 +2065,7 @@ version = "1.9.2" description = "Simple VAPID header generation library" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "py_vapid-1.9.2-py3-none-any.whl", hash = "sha256:4ccf8a00fc54f1f99f66fb543c96f2c82622508ad814b6e9225f2c26948934d7"}, {file = "py_vapid-1.9.2.tar.gz", hash = "sha256:3c8973b6cf8384ad0c9ae64d6270ccc480e0b92c702d8f5ea2cc03e6b51247f9"}, @@ -1675,54 +2076,66 @@ cryptography = ">=2.5" [[package]] name = "pycparser" -version = "2.22" +version = "2.23" description = "C parser in Python" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "implementation_name != \"PyPy\"" files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, + {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, + {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, ] [[package]] name = "pycryptodomex" -version = "3.20.0" +version = "3.23.0" description = "Cryptographic library for Python" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] files = [ - {file = "pycryptodomex-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:645bd4ca6f543685d643dadf6a856cc382b654cc923460e3a10a49c1b3832aeb"}, - {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ff5c9a67f8a4fba4aed887216e32cbc48f2a6fb2673bb10a99e43be463e15913"}, - {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8ee606964553c1a0bc74057dd8782a37d1c2bc0f01b83193b6f8bb14523b877b"}, - {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7805830e0c56d88f4d491fa5ac640dfc894c5ec570d1ece6ed1546e9df2e98d6"}, - {file = "pycryptodomex-3.20.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:bc3ee1b4d97081260d92ae813a83de4d2653206967c4a0a017580f8b9548ddbc"}, - {file = "pycryptodomex-3.20.0-cp27-cp27m-win32.whl", hash = "sha256:8af1a451ff9e123d0d8bd5d5e60f8e3315c3a64f3cdd6bc853e26090e195cdc8"}, - {file = "pycryptodomex-3.20.0-cp27-cp27m-win_amd64.whl", hash = "sha256:cbe71b6712429650e3883dc81286edb94c328ffcd24849accac0a4dbcc76958a"}, - {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:76bd15bb65c14900d98835fcd10f59e5e0435077431d3a394b60b15864fddd64"}, - {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:653b29b0819605fe0898829c8ad6400a6ccde096146730c2da54eede9b7b8baa"}, - {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a5ec91388984909bb5398ea49ee61b68ecb579123694bffa172c3b0a107079"}, - {file = "pycryptodomex-3.20.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:108e5f1c1cd70ffce0b68739c75734437c919d2eaec8e85bffc2c8b4d2794305"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:59af01efb011b0e8b686ba7758d59cf4a8263f9ad35911bfe3f416cee4f5c08c"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:82ee7696ed8eb9a82c7037f32ba9b7c59e51dda6f105b39f043b6ef293989cb3"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91852d4480a4537d169c29a9d104dda44094c78f1f5b67bca76c29a91042b623"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca649483d5ed251d06daf25957f802e44e6bb6df2e8f218ae71968ff8f8edc4"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e186342cfcc3aafaad565cbd496060e5a614b441cacc3995ef0091115c1f6c5"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:25cd61e846aaab76d5791d006497134602a9e451e954833018161befc3b5b9ed"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:9c682436c359b5ada67e882fec34689726a09c461efd75b6ea77b2403d5665b7"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7a7a8f33a1f1fb762ede6cc9cbab8f2a9ba13b196bfaf7bc6f0b39d2ba315a43"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-win32.whl", hash = "sha256:c39778fd0548d78917b61f03c1fa8bfda6cfcf98c767decf360945fe6f97461e"}, - {file = "pycryptodomex-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:2a47bcc478741b71273b917232f521fd5704ab4b25d301669879e7273d3586cc"}, - {file = "pycryptodomex-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:1be97461c439a6af4fe1cf8bf6ca5936d3db252737d2f379cc6b2e394e12a458"}, - {file = "pycryptodomex-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:19764605feea0df966445d46533729b645033f134baeb3ea26ad518c9fdf212c"}, - {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e497413560e03421484189a6b65e33fe800d3bd75590e6d78d4dfdb7accf3b"}, - {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48217c7901edd95f9f097feaa0388da215ed14ce2ece803d3f300b4e694abea"}, - {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d00fe8596e1cc46b44bf3907354e9377aa030ec4cd04afbbf6e899fc1e2a7781"}, - {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88afd7a3af7ddddd42c2deda43d53d3dfc016c11327d0915f90ca34ebda91499"}, - {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d3584623e68a5064a04748fb6d76117a21a7cb5eaba20608a41c7d0c61721794"}, - {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0daad007b685db36d977f9de73f61f8da2a7104e20aca3effd30752fd56f73e1"}, - {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dcac11031a71348faaed1f403a0debd56bf5404232284cf8c761ff918886ebc"}, - {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:69138068268127cd605e03438312d8f271135a33140e2742b417d027a0539427"}, - {file = "pycryptodomex-3.20.0.tar.gz", hash = "sha256:7a710b79baddd65b806402e14766c721aee8fb83381769c27920f26476276c1e"}, + {file = "pycryptodomex-3.23.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:add243d204e125f189819db65eed55e6b4713f70a7e9576c043178656529cec7"}, + {file = "pycryptodomex-3.23.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1c6d919fc8429e5cb228ba8c0d4d03d202a560b421c14867a65f6042990adc8e"}, + {file = "pycryptodomex-3.23.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:1c3a65ad441746b250d781910d26b7ed0a396733c6f2dbc3327bd7051ec8a541"}, + {file = "pycryptodomex-3.23.0-cp27-cp27m-win32.whl", hash = "sha256:47f6d318fe864d02d5e59a20a18834819596c4ed1d3c917801b22b92b3ffa648"}, + {file = "pycryptodomex-3.23.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:d9825410197a97685d6a1fa2a86196430b01877d64458a20e95d4fd00d739a08"}, + {file = "pycryptodomex-3.23.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:267a3038f87a8565bd834317dbf053a02055915acf353bf42ededb9edaf72010"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:7b37e08e3871efe2187bc1fd9320cc81d87caf19816c648f24443483005ff886"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:91979028227543010d7b2ba2471cf1d1e398b3f183cb105ac584df0c36dac28d"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8962204c47464d5c1c4038abeadd4514a133b28748bcd9fa5b6d62e3cec6fa"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a33986a0066860f7fcf7c7bd2bc804fa90e434183645595ae7b33d01f3c91ed8"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7947ab8d589e3178da3d7cdeabe14f841b391e17046954f2fbcd941705762b5"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c25e30a20e1b426e1f0fa00131c516f16e474204eee1139d1603e132acffc314"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:da4fa650cef02db88c2b98acc5434461e027dce0ae8c22dd5a69013eaf510006"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:58b851b9effd0d072d4ca2e4542bf2a4abcf13c82a29fd2c93ce27ee2a2e9462"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-win32.whl", hash = "sha256:a9d446e844f08299236780f2efa9898c818fe7e02f17263866b8550c7d5fb328"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:bc65bdd9fc8de7a35a74cab1c898cab391a4add33a8fe740bda00f5976ca4708"}, + {file = "pycryptodomex-3.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:c885da45e70139464f082018ac527fdaad26f1657a99ee13eecdce0f0ca24ab4"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:06698f957fe1ab229a99ba2defeeae1c09af185baa909a31a5d1f9d42b1aaed6"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b2c2537863eccef2d41061e82a881dcabb04944c5c06c5aa7110b577cc487545"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43c446e2ba8df8889e0e16f02211c25b4934898384c1ec1ec04d7889c0333587"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f489c4765093fb60e2edafdf223397bc716491b2b69fe74367b70d6999257a5c"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdc69d0d3d989a1029df0eed67cc5e8e5d968f3724f4519bd03e0ec68df7543c"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6bbcb1dd0f646484939e142462d9e532482bc74475cecf9c4903d4e1cd21f003"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:8a4fcd42ccb04c31268d1efeecfccfd1249612b4de6374205376b8f280321744"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:55ccbe27f049743a4caf4f4221b166560d3438d0b1e5ab929e07ae1702a4d6fd"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-win32.whl", hash = "sha256:189afbc87f0b9f158386bf051f720e20fa6145975f1e76369303d0f31d1a8d7c"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-win_amd64.whl", hash = "sha256:52e5ca58c3a0b0bd5e100a9fbc8015059b05cffc6c66ce9d98b4b45e023443b9"}, + {file = "pycryptodomex-3.23.0-cp37-abi3-win_arm64.whl", hash = "sha256:02d87b80778c171445d67e23d1caef279bf4b25c3597050ccd2e13970b57fd51"}, + {file = "pycryptodomex-3.23.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:febec69c0291efd056c65691b6d9a339f8b4bc43c6635b8699471248fe897fea"}, + {file = "pycryptodomex-3.23.0-pp27-pypy_73-win32.whl", hash = "sha256:c84b239a1f4ec62e9c789aafe0543f0594f0acd90c8d9e15bcece3efe55eca66"}, + {file = "pycryptodomex-3.23.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ebfff755c360d674306e5891c564a274a47953562b42fb74a5c25b8fc1fb1cb5"}, + {file = "pycryptodomex-3.23.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eca54f4bb349d45afc17e3011ed4264ef1cc9e266699874cdd1349c504e64798"}, + {file = "pycryptodomex-3.23.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2596e643d4365e14d0879dc5aafe6355616c61c2176009270f3048f6d9a61f"}, + {file = "pycryptodomex-3.23.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdfac7cda115bca3a5abb2f9e43bc2fb66c2b65ab074913643803ca7083a79ea"}, + {file = "pycryptodomex-3.23.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:14c37aaece158d0ace436f76a7bb19093db3b4deade9797abfc39ec6cd6cc2fe"}, + {file = "pycryptodomex-3.23.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7de1e40a41a5d7f1ac42b6569b10bcdded34339950945948529067d8426d2785"}, + {file = "pycryptodomex-3.23.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bffc92138d75664b6d543984db7893a628559b9e78658563b0395e2a5fb47ed9"}, + {file = "pycryptodomex-3.23.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df027262368334552db2c0ce39706b3fb32022d1dce34673d0f9422df004b96a"}, + {file = "pycryptodomex-3.23.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e79f1aaff5a3a374e92eb462fa9e598585452135012e2945f96874ca6eeb1ff"}, + {file = "pycryptodomex-3.23.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:27e13c80ac9a0a1d050ef0a7e0a18cc04c8850101ec891815b6c5a0375e8a245"}, + {file = "pycryptodomex-3.23.0.tar.gz", hash = "sha256:71909758f010c82bc99b0abf4ea12012c98962fbf0583c2164f8b84533c2e4da"}, ] [[package]] @@ -1731,6 +2144,7 @@ version = "1.10.18" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, @@ -1786,14 +2200,30 @@ dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] [[package]] -name = "pyjwt" -version = "2.9.0" -description = "JSON Web Token implementation in Python" +name = "pygments" +version = "2.19.2" +description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, + {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pyjwt" +version = "2.10.1" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1808,6 +2238,7 @@ version = "1.0.246" description = "BOLT7" optional = false python-versions = ">=3.7,<4.0" +groups = ["main"] files = [ {file = "pyln-bolt7-1.0.246.tar.gz", hash = "sha256:2b53744fa21c1b12d2c9c9df153651b122e38fa65d4a5c3f2957317ee148e089"}, {file = "pyln_bolt7-1.0.246-py3-none-any.whl", hash = "sha256:54d48ec27fdc8751762cb068b0a9f2757a58fb57933c6d8f8255d02c27eb63c5"}, @@ -1815,13 +2246,14 @@ files = [ [[package]] name = "pyln-client" -version = "24.8.1" +version = "25.5" description = "Client library and plugin library for Core Lightning" optional = false -python-versions = "<4.0,>=3.8" +python-versions = "<4.0,>=3.9" +groups = ["main"] files = [ - {file = "pyln_client-24.8.1-py3-none-any.whl", hash = "sha256:4a389de96813a23b587007f181a5d4ba37bb8a4ac6bed7074a591b6b710e4615"}, - {file = "pyln_client-24.8.1.tar.gz", hash = "sha256:47e1bcadc91df511b7dbd66059d25a6c67fb0d49953291762272abf151fe8846"}, + {file = "pyln_client-25.5-py3-none-any.whl", hash = "sha256:269f9ab346ff679b532af2d24c2a524201884efc5b4781dd40685c8ccaec9507"}, + {file = "pyln_client-25.5.tar.gz", hash = "sha256:18656e667c7218f8b40c70f893b936aef4518e87e3ce99081bd52f89e6e5af85"}, ] [package.dependencies] @@ -1830,21 +2262,46 @@ pyln-proto = ">=23" [[package]] name = "pyln-proto" -version = "24.8.2" +version = "25.9" description = "This package implements some of the Lightning Network protocol in pure python. It is intended for protocol testing and some minor tooling only. It is not deemed secure enough to handle any amount of real funds (you have been warned!)." optional = false python-versions = "<4.0,>=3.8" +groups = ["main"] files = [ - {file = "pyln_proto-24.8.2-py3-none-any.whl", hash = "sha256:9c6c080c41fff40b119ea518fae37b1c8d4e917fa55389002afceffd4850ec98"}, - {file = "pyln_proto-24.8.2.tar.gz", hash = "sha256:efa222284e2990f7227f0243acc0e9ec5acd3bb89bb66ecad9f7dfb22b09fc90"}, + {file = "pyln_proto-25.9-py3-none-any.whl", hash = "sha256:41965d96b7fe62323cb6b2fe8953d82f004a2a06ba1c009f91cd5e899ed5575e"}, + {file = "pyln_proto-25.9.tar.gz", hash = "sha256:df309cf715e92049bb82cc0db994060c7313f545cf62f4ae252a04a810067c57"}, ] [package.dependencies] -base58 = ">=2.1.1,<3.0.0" -bitstring = ">=4.1.0,<5.0.0" -coincurve = ">=20,<21" -cryptography = ">=42,<43" -PySocks = ">=1,<2" +base58 = ">=2.1.1" +bitstring = ">=4.1.0" +coincurve = "20.0.0" +cryptography = ">=42" +pysocks = ">=1" + +[[package]] +name = "pynostr" +version = "0.6.2" +description = "Python Library for nostr." +optional = false +python-versions = ">3.7.0" +groups = ["main"] +files = [ + {file = "pynostr-0.6.2-py3-none-any.whl", hash = "sha256:d43fb236c73174093275ee0080b2f8ed17e974b2b516f0d73da4c9a3e908ddc5"}, + {file = "pynostr-0.6.2.tar.gz", hash = "sha256:2974ea05b3ff41a1a4060e3b1813eb0ce0e60c0b81fbe668afaa65164c7f82f4"}, +] + +[package.dependencies] +coincurve = ">=1.8.0" +cryptography = ">=37.0.4" +requests = "*" +rich = "*" +tlv8 = "*" +tornado = "*" +typer = "*" + +[package.extras] +websocket-client = ["websocket-client (>=1.3.3)"] [[package]] name = "pyqrcode" @@ -1852,6 +2309,7 @@ version = "1.2.1" description = "A QR code generator written purely in Python with SVG, EPS, PNG and terminal output." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "PyQRCode-1.2.1.tar.gz", hash = "sha256:fdbf7634733e56b72e27f9bce46e4550b75a3a2c420414035cae9d9d26b234d5"}, {file = "PyQRCode-1.2.1.zip", hash = "sha256:1b2812775fa6ff5c527977c4cd2ccb07051ca7d0bc0aecf937a43864abe5eff6"}, @@ -1866,72 +2324,20 @@ version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] files = [ {file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"}, {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"}, {file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"}, ] -[[package]] -name = "pytest" -version = "7.4.4" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-asyncio" -version = "0.21.2" -description = "Pytest support for asyncio" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest_asyncio-0.21.2-py3-none-any.whl", hash = "sha256:ab664c88bb7998f711d8039cacd4884da6430886ae8bbd4eded552ed2004f16b"}, - {file = "pytest_asyncio-0.21.2.tar.gz", hash = "sha256:d67738fc232b94b326b9d060750beb16e0074210b98dd8b58a5239fa2a154f45"}, -] - -[package.dependencies] -pytest = ">=7.0.0" - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] - -[[package]] -name = "pytest-md" -version = "0.2.0" -description = "Plugin for generating Markdown reports for pytest results" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-md-0.2.0.tar.gz", hash = "sha256:3b248d5b360ea5198e05b4f49c7442234812809a63137ec6cdd3643a40cf0112"}, - {file = "pytest_md-0.2.0-py3-none-any.whl", hash = "sha256:4c4cd16fea6d1485e87ee254558712c804a96d2aa9674b780e7eb8fb6526e1d1"}, -] - -[package.dependencies] -pytest = ">=4.2.1" - [[package]] name = "python-crontab" version = "3.2.0" description = "Python Crontab API" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "python_crontab-3.2.0-py3-none-any.whl", hash = "sha256:82cb9b6a312d41ff66fd3caf3eed7115c28c195bfb50711bc2b4b9592feb9fe5"}, {file = "python_crontab-3.2.0.tar.gz", hash = "sha256:40067d1dd39ade3460b2ad8557c7651514cd3851deffff61c5c60e1227c5c36b"}, @@ -1950,6 +2356,7 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -1960,112 +2367,69 @@ six = ">=1.5" [[package]] name = "python-dotenv" -version = "1.0.1" +version = "1.1.1" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, - {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, + {file = "python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc"}, + {file = "python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab"}, ] [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "python-multipart" +version = "0.0.20" +description = "A streaming multipart parser for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104"}, + {file = "python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13"}, +] + [[package]] name = "pywebpush" -version = "1.14.1" +version = "2.0.3" description = "WebPush publication library" optional = false python-versions = "*" +groups = ["main"] files = [ - {file = "pywebpush-1.14.1-py3-none-any.whl", hash = "sha256:2865ee65cf44375f7cbdcfd5ba915a9d84c239900c6fba2245efd8d8314a3e84"}, - {file = "pywebpush-1.14.1.tar.gz", hash = "sha256:f88d7e2bf5e87c616dfb04b8c95c119238c511659b02f735ee77cc16842855ee"}, + {file = "pywebpush-2.0.3-py3-none-any.whl", hash = "sha256:04666441715bc547918d7668b2ac7ad5c4b5de7d0a6cf528daf61e0c4bc5431c"}, + {file = "pywebpush-2.0.3.tar.gz", hash = "sha256:584878e3c243e873a22db8895505d95715bc796ef74cc1b8fe99f596174161e3"}, ] [package.dependencies] +aiohttp = "*" cryptography = ">=2.6.1" http-ece = ">=1.1.0" py-vapid = ">=1.7.0" requests = ">=2.21.0" six = ">=1.15.0" -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] +[package.extras] +dev = ["black", "mock", "pytest"] [[package]] name = "requests" -version = "2.32.3" +version = "2.32.5" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, + {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, + {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, ] [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" +charset_normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<3" @@ -2074,37 +2438,31 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] -name = "ruff" -version = "0.3.7" -description = "An extremely fast Python linter and code formatter, written in Rust." +name = "rich" +version = "14.1.0" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8.0" +groups = ["main"] files = [ - {file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0e8377cccb2f07abd25e84fc5b2cbe48eeb0fea9f1719cad7caedb061d70e5ce"}, - {file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:15a4d1cc1e64e556fa0d67bfd388fed416b7f3b26d5d1c3e7d192c897e39ba4b"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d28bdf3d7dc71dd46929fafeec98ba89b7c3550c3f0978e36389b5631b793663"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:379b67d4f49774ba679593b232dcd90d9e10f04d96e3c8ce4a28037ae473f7bb"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c060aea8ad5ef21cdfbbe05475ab5104ce7827b639a78dd55383a6e9895b7c51"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ebf8f615dde968272d70502c083ebf963b6781aacd3079081e03b32adfe4d58a"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d48098bd8f5c38897b03604f5428901b65e3c97d40b3952e38637b5404b739a2"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da8a4fda219bf9024692b1bc68c9cff4b80507879ada8769dc7e985755d662ea"}, - {file = "ruff-0.3.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c44e0149f1d8b48c4d5c33d88c677a4aa22fd09b1683d6a7ff55b816b5d074f"}, - {file = "ruff-0.3.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3050ec0af72b709a62ecc2aca941b9cd479a7bf2b36cc4562f0033d688e44fa1"}, - {file = "ruff-0.3.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a29cc38e4c1ab00da18a3f6777f8b50099d73326981bb7d182e54a9a21bb4ff7"}, - {file = "ruff-0.3.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b15cc59c19edca917f51b1956637db47e200b0fc5e6e1878233d3a938384b0b"}, - {file = "ruff-0.3.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e491045781b1e38b72c91247cf4634f040f8d0cb3e6d3d64d38dcf43616650b4"}, - {file = "ruff-0.3.7-py3-none-win32.whl", hash = "sha256:bc931de87593d64fad3a22e201e55ad76271f1d5bfc44e1a1887edd0903c7d9f"}, - {file = "ruff-0.3.7-py3-none-win_amd64.whl", hash = "sha256:5ef0e501e1e39f35e03c2acb1d1238c595b8bb36cf7a170e7c1df1b73da00e74"}, - {file = "ruff-0.3.7-py3-none-win_arm64.whl", hash = "sha256:789e144f6dc7019d1f92a812891c645274ed08af6037d11fc65fcbc183b7d59f"}, - {file = "ruff-0.3.7.tar.gz", hash = "sha256:d5c1aebee5162c2226784800ae031f660c350e7a3402c4d1f8ea4e97e232e3ba"}, + {file = "rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f"}, + {file = "rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8"}, ] +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + [[package]] name = "secp256k1" version = "0.14.0" description = "FFI bindings to libsecp256k1" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "secp256k1-0.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f666c67dcf1dc69e1448b2ede5e12aaf382b600204a61dbc65e4f82cea444405"}, {file = "secp256k1-0.14.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fcabb3c3497a902fb61eec72d1b69bf72747d7bcc2a732d56d9319a1e8322262"}, @@ -2134,12 +2492,25 @@ files = [ [package.dependencies] cffi = ">=1.3.0" +[[package]] +name = "shellingham" +version = "1.5.4" +description = "Tool to Detect Surrounding Shell" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + [[package]] name = "shortuuid" version = "1.0.13" description = "A generator library for concise, unambiguous and URL-safe UUIDs." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "shortuuid-1.0.13-py3-none-any.whl", hash = "sha256:a482a497300b49b4953e15108a7913244e1bb0d41f9d332f5e9925dba33a3c5a"}, {file = "shortuuid-1.0.13.tar.gz", hash = "sha256:3bb9cf07f606260584b1df46399c0b87dd84773e7b25912b7e391e30797c5e72"}, @@ -2147,13 +2518,14 @@ files = [ [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -2162,6 +2534,7 @@ version = "0.1.9" description = "A rate limiting extension for Starlette and Fastapi" optional = false python-versions = ">=3.7,<4.0" +groups = ["main"] files = [ {file = "slowapi-0.1.9-py3-none-any.whl", hash = "sha256:cfad116cfb84ad9d763ee155c1e5c5cbf00b0d47399a769b227865f5df576e36"}, {file = "slowapi-0.1.9.tar.gz", hash = "sha256:639192d0f1ca01b1c6d95bf6c71d794c3a9ee189855337b4821f7f457dddad77"}, @@ -2179,6 +2552,7 @@ version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, @@ -2190,6 +2564,7 @@ version = "1.4.54" description = "Database Abstraction Library" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +groups = ["main"] files = [ {file = "SQLAlchemy-1.4.54-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:af00236fe21c4d4f4c227b6ccc19b44c594160cc3ff28d104cdce85855369277"}, {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1183599e25fa38a1a322294b949da02b4f0da13dbc2688ef9dbe746df573f8a6"}, @@ -2241,109 +2616,156 @@ files = [ greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} [package.extras] -aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] -aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (!=0.4.17)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "greenlet (!=0.4.17)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)", "mariadb (>=1.0.1,!=1.1.2)"] +aiomysql = ["aiomysql (>=0.2.0) ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\""] +aiosqlite = ["aiosqlite ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\"", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (!=0.4.17) ; python_version >= \"3\""] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4) ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\""] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2) ; python_version >= \"3\"", "mariadb (>=1.0.1,!=1.1.2) ; python_version >= \"3\""] mssql = ["pyodbc"] mssql-pymssql = ["pymssql", "pymssql"] mssql-pyodbc = ["pyodbc", "pyodbc"] -mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"] -mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"] +mypy = ["mypy (>=0.910) ; python_version >= \"3\"", "sqlalchemy2-stubs"] +mysql = ["mysqlclient (>=1.4.0) ; python_version >= \"3\"", "mysqlclient (>=1.4.0,<2) ; python_version < \"3\""] mysql-connector = ["mysql-connector-python", "mysql-connector-python"] -oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"] +oracle = ["cx_oracle (>=7) ; python_version >= \"3\"", "cx_oracle (>=7,<8) ; python_version < \"3\""] postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "asyncpg", "greenlet (!=0.4.17)", "greenlet (!=0.4.17)"] -postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)", "pg8000 (>=1.16.6,!=1.29.0)"] +postgresql-asyncpg = ["asyncpg ; python_version >= \"3\"", "asyncpg ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\""] +postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0) ; python_version >= \"3\"", "pg8000 (>=1.16.6,!=1.29.0) ; python_version >= \"3\""] postgresql-psycopg2binary = ["psycopg2-binary"] postgresql-psycopg2cffi = ["psycopg2cffi"] -pymysql = ["pymysql", "pymysql (<1)"] -sqlcipher = ["sqlcipher3_binary"] +pymysql = ["pymysql (<1) ; python_version < \"3\"", "pymysql ; python_version >= \"3\""] +sqlcipher = ["sqlcipher3_binary ; python_version >= \"3\""] [[package]] name = "sse-starlette" -version = "1.8.2" +version = "2.3.6" description = "SSE plugin for Starlette" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "sse_starlette-1.8.2-py3-none-any.whl", hash = "sha256:70cc7ef5aca4abe8a25dec1284cce4fe644dd7bf0c406d3e852e516092b7f849"}, - {file = "sse_starlette-1.8.2.tar.gz", hash = "sha256:e0f9b8dec41adc092a0a6e0694334bd3cfd3084c44c497a6ebc1fb4bdd919acd"}, + {file = "sse_starlette-2.3.6-py3-none-any.whl", hash = "sha256:d49a8285b182f6e2228e2609c350398b2ca2c36216c2675d875f81e93548f760"}, + {file = "sse_starlette-2.3.6.tar.gz", hash = "sha256:0382336f7d4ec30160cf9ca0518962905e1b69b72d6c1c995131e0a703b436e3"}, ] [package.dependencies] -anyio = "*" -fastapi = "*" -starlette = "*" -uvicorn = "*" +anyio = ">=4.7.0" + +[package.extras] +daphne = ["daphne (>=4.2.0)"] +examples = ["aiosqlite (>=0.21.0)", "fastapi (>=0.115.12)", "sqlalchemy[asyncio,examples] (>=2.0.41)", "starlette (>=0.41.3)", "uvicorn (>=0.34.0)"] +granian = ["granian (>=2.3.1)"] +uvicorn = ["uvicorn (>=0.34.0)"] [[package]] name = "starlette" -version = "0.40.0" +version = "0.46.2" description = "The little ASGI library that shines." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "starlette-0.40.0-py3-none-any.whl", hash = "sha256:c494a22fae73805376ea6bf88439783ecfba9aac88a43911b48c653437e784c4"}, - {file = "starlette-0.40.0.tar.gz", hash = "sha256:1a3139688fb298ce5e2d661d37046a66ad996ce94be4d4983be019a23a04ea35"}, + {file = "starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35"}, + {file = "starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5"}, ] [package.dependencies] -anyio = ">=3.4.0,<5" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} +anyio = ">=3.6.2,<5" [package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] +full = ["httpx (>=0.27.0,<0.29.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.18)", "pyyaml"] [[package]] -name = "tomli" -version = "2.1.0" -description = "A lil' TOML parser" +name = "tlv8" +version = "0.10.0" +description = "Python module to handle type-length-value (TLV) encoded data 8-bit type, 8-bit length, and N-byte value as described within the Apple HomeKit Accessory Protocol Specification Non-Commercial Version Release R2." optional = false -python-versions = ">=3.8" +python-versions = "*" +groups = ["main"] files = [ - {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"}, - {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"}, + {file = "tlv8-0.10.0.tar.gz", hash = "sha256:7930a590267b809952272ac2a27ee81b99ec5191fa2eba08050e0daee4262684"}, ] [[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" +name = "tornado" +version = "6.5.2" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, + {file = "tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6"}, + {file = "tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef"}, + {file = "tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e"}, + {file = "tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882"}, + {file = "tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108"}, + {file = "tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c"}, + {file = "tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4"}, + {file = "tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04"}, + {file = "tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0"}, + {file = "tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f"}, + {file = "tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af"}, + {file = "tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0"}, +] + +[[package]] +name = "typer" +version = "0.17.4" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "typer-0.17.4-py3-none-any.whl", hash = "sha256:015534a6edaa450e7007eba705d5c18c3349dcea50a6ad79a5ed530967575824"}, + {file = "typer-0.17.4.tar.gz", hash = "sha256:b77dc07d849312fd2bb5e7f20a7af8985c7ec360c45b051ed5412f64d8dc1580"}, +] + +[package.dependencies] +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" + +[[package]] +name = "typing-extensions" +version = "4.14.0" +description = "Backported and Experimental Type Hints for Python 3.9+" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af"}, + {file = "typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4"}, ] [[package]] name = "urllib3" -version = "2.2.3" +version = "2.5.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, + {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "uvicorn" -version = "0.30.6" +version = "0.34.3" description = "The lightning-fast ASGI server." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "uvicorn-0.30.6-py3-none-any.whl", hash = "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5"}, - {file = "uvicorn-0.30.6.tar.gz", hash = "sha256:4b15decdda1e72be08209e860a1e10e92439ad5b97cf44cc945fcbee66fc5788"}, + {file = "uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885"}, + {file = "uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a"}, ] [package.dependencies] @@ -2352,71 +2774,59 @@ h11 = ">=0.8" typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} [package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] +standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.15.1) ; sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"", "watchfiles (>=0.13)", "websockets (>=10.4)"] [[package]] name = "uvloop" -version = "0.19.0" +version = "0.21.0" description = "Fast implementation of asyncio event loop on top of libuv" optional = false python-versions = ">=3.8.0" +groups = ["main"] files = [ - {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"}, - {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"}, - {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"}, - {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"}, - {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"}, - {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"}, - {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"}, - {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"}, - {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"}, - {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"}, - {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"}, - {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"}, - {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"}, - {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"}, - {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"}, - {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"}, - {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"}, - {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"}, - {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"}, - {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"}, - {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"}, - {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"}, - {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"}, - {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"}, - {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"}, - {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"}, - {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"}, - {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"}, - {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"}, - {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"}, - {file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"}, + {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f"}, + {file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d"}, + {file = "uvloop-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26"}, + {file = "uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb"}, + {file = "uvloop-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f"}, + {file = "uvloop-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c"}, + {file = "uvloop-0.21.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8"}, + {file = "uvloop-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0"}, + {file = "uvloop-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e"}, + {file = "uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb"}, + {file = "uvloop-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6"}, + {file = "uvloop-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d"}, + {file = "uvloop-0.21.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c"}, + {file = "uvloop-0.21.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2"}, + {file = "uvloop-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d"}, + {file = "uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc"}, + {file = "uvloop-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb"}, + {file = "uvloop-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f"}, + {file = "uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281"}, + {file = "uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af"}, + {file = "uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6"}, + {file = "uvloop-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816"}, + {file = "uvloop-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc"}, + {file = "uvloop-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553"}, + {file = "uvloop-0.21.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:17df489689befc72c39a08359efac29bbee8eee5209650d4b9f34df73d22e414"}, + {file = "uvloop-0.21.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc09f0ff191e61c2d592a752423c767b4ebb2986daa9ed62908e2b1b9a9ae206"}, + {file = "uvloop-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0ce1b49560b1d2d8a2977e3ba4afb2414fb46b86a1b64056bc4ab929efdafbe"}, + {file = "uvloop-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e678ad6fe52af2c58d2ae3c73dc85524ba8abe637f134bf3564ed07f555c5e79"}, + {file = "uvloop-0.21.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:460def4412e473896ef179a1671b40c039c7012184b627898eea5072ef6f017a"}, + {file = "uvloop-0.21.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:10da8046cc4a8f12c91a1c39d1dd1585c41162a15caaef165c2174db9ef18bdc"}, + {file = "uvloop-0.21.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c097078b8031190c934ed0ebfee8cc5f9ba9642e6eb88322b9958b649750f72b"}, + {file = "uvloop-0.21.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:46923b0b5ee7fc0020bef24afe7836cb068f5050ca04caf6b487c513dc1a20b2"}, + {file = "uvloop-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53e420a3afe22cdcf2a0f4846e377d16e718bc70103d7088a4f7623567ba5fb0"}, + {file = "uvloop-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88cb67cdbc0e483da00af0b2c3cdad4b7c61ceb1ee0f33fe00e09c81e3a6cb75"}, + {file = "uvloop-0.21.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:221f4f2a1f46032b403bf3be628011caf75428ee3cc204a22addf96f586b19fd"}, + {file = "uvloop-0.21.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2d1f581393673ce119355d56da84fe1dd9d2bb8b3d13ce792524e1607139feff"}, + {file = "uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3"}, ] [package.extras] +dev = ["Cython (>=3.0,<4.0)", "setuptools (>=60)"] docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] - -[[package]] -name = "virtualenv" -version = "20.27.1" -description = "Virtual Python Environment builder" -optional = false -python-versions = ">=3.8" -files = [ - {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, - {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, -] - -[package.dependencies] -distlib = ">=0.3.7,<1" -filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<5" - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] +test = ["aiohttp (>=3.10.5)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] [[package]] name = "websocket-client" @@ -2424,6 +2834,7 @@ version = "1.8.0" description = "WebSocket client for Python with low level API options" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, @@ -2436,196 +2847,310 @@ test = ["websockets"] [[package]] name = "websockets" -version = "11.0.3" +version = "15.0.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac"}, - {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d"}, - {file = "websockets-11.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f"}, - {file = "websockets-11.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564"}, - {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11"}, - {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca"}, - {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54"}, - {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4"}, - {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526"}, - {file = "websockets-11.0.3-cp310-cp310-win32.whl", hash = "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69"}, - {file = "websockets-11.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f"}, - {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb"}, - {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288"}, - {file = "websockets-11.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d"}, - {file = "websockets-11.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3"}, - {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b"}, - {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6"}, - {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97"}, - {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf"}, - {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd"}, - {file = "websockets-11.0.3-cp311-cp311-win32.whl", hash = "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c"}, - {file = "websockets-11.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8"}, - {file = "websockets-11.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f59a3c656fef341a99e3d63189852be7084c0e54b75734cde571182c087b152"}, - {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2529338a6ff0eb0b50c7be33dc3d0e456381157a31eefc561771ee431134a97f"}, - {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34fd59a4ac42dff6d4681d8843217137f6bc85ed29722f2f7222bd619d15e95b"}, - {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:332d126167ddddec94597c2365537baf9ff62dfcc9db4266f263d455f2f031cb"}, - {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6505c1b31274723ccaf5f515c1824a4ad2f0d191cec942666b3d0f3aa4cb4007"}, - {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f467ba0050b7de85016b43f5a22b46383ef004c4f672148a8abf32bc999a87f0"}, - {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9d9acd80072abcc98bd2c86c3c9cd4ac2347b5a5a0cae7ed5c0ee5675f86d9af"}, - {file = "websockets-11.0.3-cp37-cp37m-win32.whl", hash = "sha256:e590228200fcfc7e9109509e4d9125eace2042fd52b595dd22bbc34bb282307f"}, - {file = "websockets-11.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:b16fff62b45eccb9c7abb18e60e7e446998093cdcb50fed33134b9b6878836de"}, - {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fb06eea71a00a7af0ae6aefbb932fb8a7df3cb390cc217d51a9ad7343de1b8d0"}, - {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8a34e13a62a59c871064dfd8ffb150867e54291e46d4a7cf11d02c94a5275bae"}, - {file = "websockets-11.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4841ed00f1026dfbced6fca7d963c4e7043aa832648671b5138008dc5a8f6d99"}, - {file = "websockets-11.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a073fc9ab1c8aff37c99f11f1641e16da517770e31a37265d2755282a5d28aa"}, - {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68b977f21ce443d6d378dbd5ca38621755f2063d6fdb3335bda981d552cfff86"}, - {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a99a7a71631f0efe727c10edfba09ea6bee4166a6f9c19aafb6c0b5917d09c"}, - {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bee9fcb41db2a23bed96c6b6ead6489702c12334ea20a297aa095ce6d31370d0"}, - {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4b253869ea05a5a073ebfdcb5cb3b0266a57c3764cf6fe114e4cd90f4bfa5f5e"}, - {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1553cb82942b2a74dd9b15a018dce645d4e68674de2ca31ff13ebc2d9f283788"}, - {file = "websockets-11.0.3-cp38-cp38-win32.whl", hash = "sha256:f61bdb1df43dc9c131791fbc2355535f9024b9a04398d3bd0684fc16ab07df74"}, - {file = "websockets-11.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f"}, - {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8"}, - {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd"}, - {file = "websockets-11.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016"}, - {file = "websockets-11.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61"}, - {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b"}, - {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd"}, - {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7"}, - {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1"}, - {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311"}, - {file = "websockets-11.0.3-cp39-cp39-win32.whl", hash = "sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128"}, - {file = "websockets-11.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602"}, - {file = "websockets-11.0.3-py3-none-any.whl", hash = "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6"}, - {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"}, + {file = "websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b"}, + {file = "websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205"}, + {file = "websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a"}, + {file = "websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e"}, + {file = "websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf"}, + {file = "websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb"}, + {file = "websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d"}, + {file = "websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9"}, + {file = "websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c"}, + {file = "websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256"}, + {file = "websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41"}, + {file = "websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431"}, + {file = "websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57"}, + {file = "websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905"}, + {file = "websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562"}, + {file = "websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792"}, + {file = "websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413"}, + {file = "websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8"}, + {file = "websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3"}, + {file = "websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf"}, + {file = "websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85"}, + {file = "websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065"}, + {file = "websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3"}, + {file = "websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665"}, + {file = "websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2"}, + {file = "websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215"}, + {file = "websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5"}, + {file = "websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65"}, + {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe"}, + {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4"}, + {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597"}, + {file = "websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9"}, + {file = "websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7"}, + {file = "websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931"}, + {file = "websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675"}, + {file = "websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151"}, + {file = "websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22"}, + {file = "websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f"}, + {file = "websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8"}, + {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375"}, + {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d"}, + {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4"}, + {file = "websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa"}, + {file = "websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561"}, + {file = "websockets-15.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f4c04ead5aed67c8a1a20491d54cdfba5884507a48dd798ecaf13c74c4489f5"}, + {file = "websockets-15.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abdc0c6c8c648b4805c5eacd131910d2a7f6455dfd3becab248ef108e89ab16a"}, + {file = "websockets-15.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a625e06551975f4b7ea7102bc43895b90742746797e2e14b70ed61c43a90f09b"}, + {file = "websockets-15.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d591f8de75824cbb7acad4e05d2d710484f15f29d4a915092675ad3456f11770"}, + {file = "websockets-15.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47819cea040f31d670cc8d324bb6435c6f133b8c7a19ec3d61634e62f8d8f9eb"}, + {file = "websockets-15.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac017dd64572e5c3bd01939121e4d16cf30e5d7e110a119399cf3133b63ad054"}, + {file = "websockets-15.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4a9fac8e469d04ce6c25bb2610dc535235bd4aa14996b4e6dbebf5e007eba5ee"}, + {file = "websockets-15.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363c6f671b761efcb30608d24925a382497c12c506b51661883c3e22337265ed"}, + {file = "websockets-15.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2034693ad3097d5355bfdacfffcbd3ef5694f9718ab7f29c29689a9eae841880"}, + {file = "websockets-15.0.1-cp39-cp39-win32.whl", hash = "sha256:3b1ac0d3e594bf121308112697cf4b32be538fb1444468fb0a6ae4feebc83411"}, + {file = "websockets-15.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7643a03db5c95c799b89b31c036d5f27eeb4d259c798e878d6937d71832b1e4"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04"}, + {file = "websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7f493881579c90fc262d9cdbaa05a6b54b3811c2f300766748db79f098db9940"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:47b099e1f4fbc95b701b6e85768e1fcdaf1630f3cbe4765fa216596f12310e2e"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67f2b6de947f8c757db2db9c71527933ad0019737ec374a8a6be9a956786aaf9"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d08eb4c2b7d6c41da6ca0600c077e93f5adcfd979cd777d747e9ee624556da4b"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b826973a4a2ae47ba357e4e82fa44a463b8f168e1ca775ac64521442b19e87f"}, + {file = "websockets-15.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:21c1fa28a6a7e3cbdc171c694398b6df4744613ce9b36b1a498e816787e28123"}, + {file = "websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f"}, + {file = "websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee"}, ] [[package]] name = "win32-setctime" -version = "1.1.0" +version = "1.2.0" description = "A small Python utility to set file creation time on Windows" optional = false python-versions = ">=3.5" +groups = ["main"] +markers = "sys_platform == \"win32\"" files = [ - {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, - {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, + {file = "win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390"}, + {file = "win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0"}, ] [package.extras] -dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] +dev = ["black (>=19.3b0) ; python_version >= \"3.6\"", "pytest (>=4.6.2)"] [[package]] name = "wrapt" -version = "1.16.0" +version = "1.17.3" description = "Module for decorators, wrappers and monkey patching." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04"}, + {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2"}, + {file = "wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c"}, + {file = "wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775"}, + {file = "wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd"}, + {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05"}, + {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418"}, + {file = "wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390"}, + {file = "wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6"}, + {file = "wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18"}, + {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7"}, + {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85"}, + {file = "wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f"}, + {file = "wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311"}, + {file = "wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1"}, + {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5"}, + {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2"}, + {file = "wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89"}, + {file = "wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77"}, + {file = "wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a"}, + {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0"}, + {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba"}, + {file = "wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd"}, + {file = "wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828"}, + {file = "wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9"}, + {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396"}, + {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc"}, + {file = "wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe"}, + {file = "wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c"}, + {file = "wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6"}, + {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0"}, + {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77"}, + {file = "wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7"}, + {file = "wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277"}, + {file = "wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d"}, + {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa"}, + {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050"}, + {file = "wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8"}, + {file = "wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb"}, + {file = "wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16"}, + {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39"}, + {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235"}, + {file = "wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c"}, + {file = "wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b"}, + {file = "wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa"}, + {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7"}, + {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4"}, + {file = "wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10"}, + {file = "wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6"}, + {file = "wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58"}, + {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a"}, + {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067"}, + {file = "wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454"}, + {file = "wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e"}, + {file = "wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f"}, + {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056"}, + {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804"}, + {file = "wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977"}, + {file = "wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116"}, + {file = "wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6"}, + {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225"}, + {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a"}, + {file = "wrapt-1.17.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f"}, + {file = "wrapt-1.17.3-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00"}, + {file = "wrapt-1.17.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56"}, + {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5"}, + {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22"}, + {file = "wrapt-1.17.3-cp38-cp38-win32.whl", hash = "sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c"}, + {file = "wrapt-1.17.3-cp38-cp38-win_amd64.whl", hash = "sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2"}, + {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc"}, + {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9"}, + {file = "wrapt-1.17.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d"}, + {file = "wrapt-1.17.3-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a"}, + {file = "wrapt-1.17.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139"}, + {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df"}, + {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b"}, + {file = "wrapt-1.17.3-cp39-cp39-win32.whl", hash = "sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81"}, + {file = "wrapt-1.17.3-cp39-cp39-win_amd64.whl", hash = "sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f"}, + {file = "wrapt-1.17.3-cp39-cp39-win_arm64.whl", hash = "sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f"}, + {file = "wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22"}, + {file = "wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0"}, ] [[package]] -name = "zipp" -version = "3.21.0" -description = "Backport of pathlib-compatible object wrapper for zip files" +name = "yarl" +version = "1.20.1" +description = "Yet another URL library" optional = false python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, - {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, + {file = "yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4"}, + {file = "yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a"}, + {file = "yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed"}, + {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e"}, + {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73"}, + {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e"}, + {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8"}, + {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23"}, + {file = "yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70"}, + {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb"}, + {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2"}, + {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30"}, + {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309"}, + {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24"}, + {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13"}, + {file = "yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8"}, + {file = "yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16"}, + {file = "yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e"}, + {file = "yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b"}, + {file = "yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b"}, + {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4"}, + {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1"}, + {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833"}, + {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d"}, + {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8"}, + {file = "yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf"}, + {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e"}, + {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389"}, + {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f"}, + {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845"}, + {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1"}, + {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e"}, + {file = "yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773"}, + {file = "yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e"}, + {file = "yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9"}, + {file = "yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a"}, + {file = "yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2"}, + {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee"}, + {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819"}, + {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16"}, + {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6"}, + {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd"}, + {file = "yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a"}, + {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38"}, + {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef"}, + {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f"}, + {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8"}, + {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a"}, + {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004"}, + {file = "yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5"}, + {file = "yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698"}, + {file = "yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a"}, + {file = "yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3"}, + {file = "yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7"}, + {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691"}, + {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31"}, + {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28"}, + {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653"}, + {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5"}, + {file = "yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02"}, + {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53"}, + {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc"}, + {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04"}, + {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4"}, + {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b"}, + {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1"}, + {file = "yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7"}, + {file = "yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c"}, + {file = "yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d"}, + {file = "yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf"}, + {file = "yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3"}, + {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d"}, + {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c"}, + {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1"}, + {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce"}, + {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3"}, + {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be"}, + {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16"}, + {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513"}, + {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f"}, + {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390"}, + {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458"}, + {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e"}, + {file = "yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d"}, + {file = "yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f"}, + {file = "yarl-1.20.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e42ba79e2efb6845ebab49c7bf20306c4edf74a0b20fc6b2ccdd1a219d12fad3"}, + {file = "yarl-1.20.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:41493b9b7c312ac448b7f0a42a089dffe1d6e6e981a2d76205801a023ed26a2b"}, + {file = "yarl-1.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f5a5928ff5eb13408c62a968ac90d43f8322fd56d87008b8f9dabf3c0f6ee983"}, + {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30c41ad5d717b3961b2dd785593b67d386b73feca30522048d37298fee981805"}, + {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:59febc3969b0781682b469d4aca1a5cab7505a4f7b85acf6db01fa500fa3f6ba"}, + {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2b6fb3622b7e5bf7a6e5b679a69326b4279e805ed1699d749739a61d242449e"}, + {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:749d73611db8d26a6281086f859ea7ec08f9c4c56cec864e52028c8b328db723"}, + {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9427925776096e664c39e131447aa20ec738bdd77c049c48ea5200db2237e000"}, + {file = "yarl-1.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff70f32aa316393eaf8222d518ce9118148eddb8a53073c2403863b41033eed5"}, + {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c7ddf7a09f38667aea38801da8b8d6bfe81df767d9dfc8c88eb45827b195cd1c"}, + {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:57edc88517d7fc62b174fcfb2e939fbc486a68315d648d7e74d07fac42cec240"}, + {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:dab096ce479d5894d62c26ff4f699ec9072269d514b4edd630a393223f45a0ee"}, + {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14a85f3bd2d7bb255be7183e5d7d6e70add151a98edf56a770d6140f5d5f4010"}, + {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c89b5c792685dd9cd3fa9761c1b9f46fc240c2a3265483acc1565769996a3f8"}, + {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:69e9b141de5511021942a6866990aea6d111c9042235de90e08f94cf972ca03d"}, + {file = "yarl-1.20.1-cp39-cp39-win32.whl", hash = "sha256:b5f307337819cdfdbb40193cad84978a029f847b0a357fbe49f712063cfc4f06"}, + {file = "yarl-1.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:eae7bfe2069f9c1c5b05fc7fe5d612e5bbc089a39309904ee8b829e322dcad00"}, + {file = "yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77"}, + {file = "yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac"}, ] -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] -type = ["pytest-mypy"] +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" +propcache = ">=0.2.1" [metadata] -lock-version = "2.0" -python-versions = "^3.10 | ^3.9" -content-hash = "e353a743e101c1121a4275284a36b98e2033dbca94f03d7582e8d47c1af864aa" +lock-version = "2.1" +python-versions = ">=3.10,<3.13" +content-hash = "6b38f9108f60eaad5b2bd2ff3b66723c04b5844228e7644c6b6093f9ca45a0c5" diff --git a/pyproject.toml b/pyproject.toml index d033272..76f6851 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,37 +1,41 @@ -[tool.poetry] +[project] name = "nwcprovider" version = "0.0.0" description = "A NWC service provider for LNbits." -authors = ["Riccardo Balbo "] +requires-python = ">=3.10,<3.13" +authors = [{ name = "Riccardo Balbo", email = "oc@rblb.it" }] +urls = { Homepage = "https://lnbits.com", Repository = "https://github.com/lnbits/nwcprovider" } +dependencies = [ "lnbits>1" ] -[tool.poetry.dependencies] -python = "^3.10 | ^3.9" -lnbits = {version = "*", allow-prereleases = true} -mypy = "^1.13.0" +[tool.poetry] +package-mode = false -[tool.poetry.group.dev.dependencies] -black = "^24.3.0" -pytest-asyncio = "^0.21.0" -pytest = "^7.3.2" -mypy = "^1.5.1" -pre-commit = "^3.2.2" -ruff = "^0.3.2" -pytest-md = "^0.2.0" - -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" +[tool.uv] +dev-dependencies = [ + "black", + "pytest-asyncio", + "pytest", + "mypy", + "pre-commit", + "ruff", + "pytest-md", +] [tool.mypy] +plugins = ["pydantic.mypy"] + [[tool.mypy.overrides]] module = [ - "lnbits.*", - "loguru.*", - "fastapi.*", - "pydantic.*", + "secp256k1.*", ] ignore_missing_imports = "True" +[tool.pydantic-mypy] +init_forbid_extra = true +init_typed = true +warn_required_dynamic_aliases = true +warn_untyped_fields = true + [tool.pytest.ini_options] log_cli = false testpaths = [ diff --git a/static/js/admin.js b/static/js/admin.js index afacb7e..2e18b9b 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -1,87 +1,87 @@ window.app = Vue.createApp({ - el: "#vue", + el: '#vue', mixins: [windowMixin], - delimiters: ["${", "}"], + delimiters: ['${', '}'], data: function () { return { entries: [], columns: [ { - name: "key", + name: 'key', required: true, - label: "Key", - align: "left", - field: (row) => row.key, - sortable: true, + label: 'Key', + align: 'left', + field: row => row.key, + sortable: true }, { - name: "value", + name: 'value', required: true, - label: "Value", - align: "left", - field: (row) => row.value, - sortable: true, - }, - ], - }; + label: 'Value', + align: 'left', + field: row => row.value, + sortable: true + } + ] + } }, methods: { fetchConfig() { - this.entries = []; + this.entries = [] LNbits.api .request( - "GET", - "/nwcprovider/api/v1/config", - this.g.user.wallets[0].adminkey, + 'GET', + '/nwcprovider/api/v1/config', + this.g.user.wallets[0].adminkey ) - .then((response) => { - const newEntries = []; + .then(response => { + const newEntries = [] for (const [key, value] of Object.entries(response.data)) { newEntries.push({ key: key, - value: value, - }); + value: value + }) } - this.entries.length = 0; - this.entries.push(...newEntries); + this.entries.length = 0 + this.entries.push(...newEntries) }) .catch(function (error) { - console.error("Error fetching config:", error); - }); + console.error('Error fetching config:', error) + }) }, async saveConfig() { - const data = {}; + const data = {} for (const entry of this.entries) { - data[entry.key] = entry.value; + data[entry.key] = entry.value } try { const response = await LNbits.api.request( - "POST", - "/nwcprovider/api/v1/config", + 'POST', + '/nwcprovider/api/v1/config', this.g.user.wallets[0].adminkey, - data, - ); + data + ) Quasar.Notify.create({ - type: "positive", - message: "Config saved!", - }); + type: 'positive', + message: 'Config saved!' + }) Quasar.Notify.create({ - type: "warning", + type: 'warning', message: - "You need to restart the server for the changes to take effect!", - }); + 'You need to restart the server for the changes to take effect!' + }) } catch (error) { Quasar.Notify.create({ - type: "negative", - message: "Error saving config: " + String(error), - }); - console.error("Error saving config:", error); + type: 'negative', + message: 'Error saving config: ' + String(error) + }) + console.error('Error saving config:', error) } - }, + } }, created: function () { - this.fetchConfig(); - }, -}); + this.fetchConfig() + } +}) diff --git a/static/js/index.js b/static/js/index.js index e8a4ec1..d593469 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -1,7 +1,7 @@ window.app = Vue.createApp({ - el: "#vue", + el: '#vue', mixins: [windowMixin], - delimiters: ["${", "}"], + delimiters: ['${', '}'], data: function () { return { selectedWallet: null, @@ -10,244 +10,244 @@ window.app = Vue.createApp({ nwcsTable: { columns: [ { - name: "description", - align: "left", - label: "Description", - field: "description", + name: 'description', + align: 'left', + label: 'Description', + field: 'description' }, - { name: "status", align: "left", label: "Status", field: "status" }, + {name: 'status', align: 'left', label: 'Status', field: 'status'}, { - name: "last_used", - align: "left", - label: "Last used", - field: "last_used", + name: 'last_used', + align: 'left', + label: 'Last used', + field: 'last_used' }, { - name: "created_at", - align: "left", - label: "Created", - field: "created_at", + name: 'created_at', + align: 'left', + label: 'Created', + field: 'created_at' }, { - name: "expires_at", - align: "left", - label: "Expires", - field: "expires_at", - }, + name: 'expires_at', + align: 'left', + label: 'Expires', + field: 'expires_at' + } ], pagination: { - rowsPerPage: 10, - }, + rowsPerPage: 10 + } }, connectDialog: { show: false, - data: {}, + data: {} }, pairingDialog: { show: false, data: { - pairingUrl: "", - }, + pairingUrl: '' + } }, pairingQrDialog: { show: false, data: { - pairingUrl: "", - }, + pairingUrl: '' + } }, connectionInfoDialog: { show: false, - data: {}, - }, - }; + data: {} + } + } }, methods: { showConnectDialog() { - const wallet = this.getWallet(); + const wallet = this.getWallet() if (!wallet) { Quasar.Notify.create({ - type: "negative", - message: "Please select a wallet first", - }); - return; + type: 'negative', + message: 'Please select a wallet first' + }) + return } else { - this.connectDialog.show = true; + this.connectDialog.show = true } }, openConnectionInfoDialog(data) { - this.connectionInfoDialog.data = data; - this.connectionInfoDialog.show = true; + this.connectionInfoDialog.data = data + this.connectionInfoDialog.show = true }, closeConnectionInfoDialog() { - this.connectionInfoDialog.show = false; + this.connectionInfoDialog.show = false }, openPairingUrl() { - const url = this.pairingDialog.data.pairingUrl; - if (url) window.open(url, "_blank"); + const url = this.pairingDialog.data.pairingUrl + if (url) window.open(url, '_blank') }, go(url) { - window.open(url, "_blank"); + window.open(url, '_blank') }, async copyPairingUrl() { - const url = this.pairingDialog.data.pairingUrl; + const url = this.pairingDialog.data.pairingUrl if (url) { try { - await navigator.clipboard.writeText(url); + await navigator.clipboard.writeText(url) Quasar.Notify.create({ - type: "positive", - message: "URL copied to clipboard", - }); + type: 'positive', + message: 'URL copied to clipboard' + }) } catch (err) { Quasar.Notify.create({ - type: "negative", - message: "Failed to copy URL.", - }); + type: 'negative', + message: 'Failed to copy URL.' + }) } } }, showPairingQR() { - this.pairingQrDialog.data.pairingUrl = this.pairingDialog.data.pairingUrl; - this.pairingQrDialog.show = true; + this.pairingQrDialog.data.pairingUrl = this.pairingDialog.data.pairingUrl + this.pairingQrDialog.show = true }, closePairingQrDialog() { - this.pairingQrDialog.show = false; + this.pairingQrDialog.show = false }, loadConnectDialogData() { this.connectDialog.data = { - description: "", + description: '', expires_at: Date.now() + 1000 * 60 * 60 * 24 * 7, neverExpires: true, permissions: [], - budgets: [], - }; + budgets: [] + } for (const permission of this.nodePermissions) { this.connectDialog.data.permissions.push({ key: permission.key, name: permission.name, - value: permission.value, - }); + value: permission.value + }) } }, deleteBudget(index) { - this.connectDialog.data.budgets.splice(index, 1); + this.connectDialog.data.budgets.splice(index, 1) }, addBudget() { this.connectDialog.data.budgets.push({ budget_sats: 1000, used_budget_sats: 0, created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, - expiration: "never", - }); + expiration: 'never' + }) }, closeConnectDialog() { - this.connectDialog.show = false; - this.loadConnectDialogData(); + this.connectDialog.show = false + this.loadConnectDialogData() }, getWallet: function () { - let wallet = undefined; + let wallet = undefined for (let i = 0; i < this.g.user.wallets.length; i++) { if (this.g.user.wallets[i].id == this.selectedWallet) { - wallet = this.g.user.wallets[i]; - break; + wallet = this.g.user.wallets[i] + break } } - return wallet; + return wallet }, async generateKeyPair() { while (!window.NobleSecp256k1) { - await new Promise((resolve) => setTimeout(resolve, 1)); + await new Promise(resolve => setTimeout(resolve, 1)) } - const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey(); - const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes); + const privKeyBytes = window.NobleSecp256k1.utils.randomPrivateKey() + const pubKeyBytes = window.NobleSecp256k1.getPublicKey(privKeyBytes) const out = { privKeyBytes: privKeyBytes, pubKeyBytes: pubKeyBytes, privKey: window.NobleSecp256k1.etc.bytesToHex(privKeyBytes), - pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)), - }; - return out; + pubKey: window.NobleSecp256k1.etc.bytesToHex(pubKeyBytes.slice(1)) + } + return out }, deleteNWC: async function (pubkey) { Quasar.Dialog.create({ - title: "Confirm Deletion", - message: "Are you sure you want to delete this connection?", + title: 'Confirm Deletion', + message: 'Are you sure you want to delete this connection?', cancel: true, - persistent: true, + persistent: true }) .onOk(async () => { try { - const wallet = this.getWallet(); + const wallet = this.getWallet() const response = await LNbits.api.request( - "DELETE", + 'DELETE', `/nwcprovider/api/v1/nwc/${pubkey}`, - wallet.adminkey, - ); - this.loadNwcs(); + wallet.adminkey + ) + this.loadNwcs() Quasar.Notify.create({ - type: "positive", - message: "Deleted successfully", - }); + type: 'positive', + message: 'Deleted successfully' + }) } catch (error) { - LNbits.utils.notifyApiError(error); + LNbits.utils.notifyApiError(error) } }) .onCancel(() => { // User canceled the operation - }); + }) }, loadNwcs: async function () { - const wallet = this.getWallet(); + const wallet = this.getWallet() if (!wallet) { - this.nwcs = []; - return; + this.nwcs = [] + return } try { const response = await LNbits.api.request( - "GET", - "/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true", - wallet.adminkey, - ); - this.nwcs = response.data; + 'GET', + '/nwcprovider/api/v1/nwc?include_expired=true&calculate_spent_budget=true', + wallet.adminkey + ) + this.nwcs = response.data } catch (error) { - this.nwcs = []; + this.nwcs = [] } try { const response = await LNbits.api.request( - "GET", - "/nwcprovider/api/v1/permissions", - wallet.adminkey, - ); - const permissions = []; + 'GET', + '/nwcprovider/api/v1/permissions', + wallet.adminkey + ) + const permissions = [] for (const [key, value] of Object.entries(response.data)) { permissions.push({ key: key, name: value.name, - value: value.default, - }); + value: value.default + }) } - this.nodePermissions = permissions; + this.nodePermissions = permissions } catch (error) { - Lnbits.utils.notifyApiError(error); + Lnbits.utils.notifyApiError(error) } - this.loadConnectDialogData(); - const newTableEntries = []; + this.loadConnectDialogData() + const newTableEntries = [] for (const nwc of this.nwcs) { const t = Quasar.date.formatDate( new Date(nwc.data.created_at * 1000), - "YYYY-MM-DD HH:mm", - ); + 'YYYY-MM-DD HH:mm' + ) const e = nwc.data.expires_at > 0 ? Quasar.date.formatDate( new Date(nwc.data.expires_at * 1000), - "YYYY-MM-DD HH:mm", + 'YYYY-MM-DD HH:mm' ) - : "Never"; + : 'Never' const l = Quasar.date.formatDate( new Date(nwc.data.last_used * 1000), - "YYYY-MM-DD HH:mm", - ); + 'YYYY-MM-DD HH:mm' + ) const nwcTableEntry = { description: nwc.data.description, created_at: t, @@ -256,131 +256,130 @@ window.app = Vue.createApp({ pubkey: nwc.data.pubkey, permissions: nwc.data.permissions, budgets: [], - status: "Active", - }; + status: 'Active' + } if ( nwc.data.expires_at > 0 && nwc.data.expires_at < new Date().getTime() / 1000 ) { - nwcTableEntry.status = "Expired"; + nwcTableEntry.status = 'Expired' } for (const budget of nwc.budgets) { const createdAt = Quasar.date.formatDate( new Date(budget.created_at * 1000), - "YYYY-MM-DD HH:mm", - ); - let refreshWindow = budget.refresh_window; + 'YYYY-MM-DD HH:mm' + ) + let refreshWindow = budget.refresh_window if (refreshWindow <= 0) { - refreshWindow = "Never"; + refreshWindow = 'Never' } else if (refreshWindow == 60 * 60 * 24) { - refreshWindow = "Daily"; + refreshWindow = 'Daily' } else if (refreshWindow == 60 * 60 * 24 * 7) { - refreshWindow = "Weekly"; + refreshWindow = 'Weekly' } else if (refreshWindow == 60 * 60 * 24 * 30) { - refreshWindow = "Monthly"; + refreshWindow = 'Monthly' } else if (refreshWindow == 60 * 60 * 24 * 365) { - refreshWindow = "Yearly"; + refreshWindow = 'Yearly' } nwcTableEntry.budgets.push({ budget_sats: budget.budget_msats / 1000, used_budget_sats: budget.used_budget_msats / 1000, created_at: createdAt, - refresh_window: refreshWindow, - }); + refresh_window: refreshWindow + }) } - newTableEntries.push(nwcTableEntry); + newTableEntries.push(nwcTableEntry) } - this.nwcEntries = newTableEntries; + this.nwcEntries = newTableEntries }, closePairingDialog() { - this.pairingDialog.show = false; + this.pairingDialog.show = false }, async showPairingDialog(secret) { let response = await LNbits.api.request( - "GET", - "/nwcprovider/api/v1/pairing/{SECRET}", - ); - response = response.data; - response = response.replace("{SECRET}", secret); - this.pairingDialog.data.pairingUrl = response; - this.pairingDialog.show = true; + 'GET', + '/nwcprovider/api/v1/pairing/{SECRET}' + ) + response = response.data + response = response.replace('{SECRET}', secret) + this.pairingDialog.data.pairingUrl = response + this.pairingDialog.show = true }, async confirmConnectDialog() { - const keyPair = await this.generateKeyPair(); + const keyPair = await this.generateKeyPair() // timestamp - let expires_at = 0; + let expires_at = 0 if (!this.connectDialog.data.neverExpires) { expires_at = - new Date(this.connectDialog.data.expires_at).getTime() / 1000; + new Date(this.connectDialog.data.expires_at).getTime() / 1000 } const data = { permissions: [], description: this.connectDialog.data.description, expires_at: expires_at, - budgets: [], - }; + budgets: [] + } for (const permission of this.connectDialog.data.permissions) { - if (permission.value) data.permissions.push(permission.key); + if (permission.value) data.permissions.push(permission.key) } for (const budget of this.connectDialog.data.budgets) { - const budget_msats = budget.budget_sats * 1000; - let refresh_window = 0; + const budget_msats = budget.budget_sats * 1000 + let refresh_window = 0 switch (budget.expiry) { - case "Daily": - refresh_window = 60 * 60 * 24; - break; - case "Weekly": - refresh_window = 60 * 60 * 24 * 7; - break; - case "Monthly": - refresh_window = 60 * 60 * 24 * 30; - break; - case "Yearly": - refresh_window = 60 * 60 * 24 * 365; - break; - case "Never": - refresh_window = 0; - break; + case 'Daily': + refresh_window = 60 * 60 * 24 + break + case 'Weekly': + refresh_window = 60 * 60 * 24 * 7 + break + case 'Monthly': + refresh_window = 60 * 60 * 24 * 30 + break + case 'Yearly': + refresh_window = 60 * 60 * 24 * 365 + break + case 'Never': + refresh_window = 0 + break } data.budgets.push({ budget_msats: budget_msats, refresh_window: refresh_window, - created_at: - new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000, - }); + created_at: new Date(new Date().setHours(0, 0, 0, 0)).getTime() / 1000 + }) } - const wallet = this.getWallet(); + const wallet = this.getWallet() try { const response = await LNbits.api.request( - "PUT", - "/nwcprovider/api/v1/nwc/" + keyPair.pubKey, + 'PUT', + '/nwcprovider/api/v1/nwc/' + keyPair.pubKey, wallet.adminkey, - data, - ); - this.closeConnectDialog(); + data + ) + this.closeConnectDialog() if ( !response.data || !response.data.data || !response.data.data.pubkey ) { - LNbits.utils.notifyApiError("Error creating nwc pairing"); - return; + LNbits.utils.notifyApiError('Error creating nwc pairing') + return } - this.showPairingDialog(keyPair.privKey); + this.showPairingDialog(keyPair.privKey) } catch (error) { - LNbits.utils.notifyApiError(error); + LNbits.utils.notifyApiError(error) } - this.loadNwcs(); - }, + this.loadNwcs() + } }, created: function () { - this.loadNwcs(); + this.loadNwcs() }, watch: { selectedWallet(newValue, oldValue) { - this.loadNwcs(); - }, - }, -}); + this.loadNwcs() + } + } +}) diff --git a/static/js/noble-secp256k1.min.js b/static/js/noble-secp256k1.min.js index af328c8..c996cd2 100644 --- a/static/js/noble-secp256k1.min.js +++ b/static/js/noble-secp256k1.min.js @@ -4,93 +4,93 @@ const B256 = 2n ** 256n, N = B256 - 0x14551231950b75fc4402da1732fc9bebfn, Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n, Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n, - CURVE = { p: P, n: N, a: 0n, b: 7n, Gx, Gy }, + CURVE = {p: P, n: N, a: 0n, b: 7n, Gx, Gy}, fLen = 32, - crv = (t) => mod(mod(t * t) * t + CURVE.b), - err = (t = "") => { - throw new Error(t); + crv = t => mod(mod(t * t) * t + CURVE.b), + err = (t = '') => { + throw new Error(t) }, - big = (t) => "bigint" == typeof t, - str = (t) => "string" == typeof t, - fe = (t) => big(t) && 0n < t && t < P, - ge = (t) => big(t) && 0n < t && t < N, - isu8 = (t) => + big = t => 'bigint' == typeof t, + str = t => 'string' == typeof t, + fe = t => big(t) && 0n < t && t < P, + ge = t => big(t) && 0n < t && t < N, + isu8 = t => t instanceof Uint8Array || - (null != t && "object" == typeof t && "Uint8Array" === t.constructor.name), + (null != t && 'object' == typeof t && 'Uint8Array' === t.constructor.name), au8 = (t, n) => - !isu8(t) || ("number" == typeof n && n > 0 && t.length !== n) - ? err("Uint8Array expected") + !isu8(t) || ('number' == typeof n && n > 0 && t.length !== n) + ? err('Uint8Array expected') : t, - u8n = (t) => new Uint8Array(t), + u8n = t => new Uint8Array(t), toU8 = (t, n) => au8(str(t) ? h2b(t) : u8n(au8(t)), n), mod = (t, n = P) => { - let e = t % n; - return e >= 0n ? e : n + e; + let e = t % n + return e >= 0n ? e : n + e }, - isPoint = (t) => (t instanceof Point ? t : err("Point expected")); + isPoint = t => (t instanceof Point ? t : err('Point expected')) class Point { constructor(t, n, e) { - (this.px = t), (this.py = n), (this.pz = e); + ;((this.px = t), (this.py = n), (this.pz = e)) } static fromAffine(t) { - return 0n === t.x && 0n === t.y ? Point.ZERO : new Point(t.x, t.y, 1n); + return 0n === t.x && 0n === t.y ? Point.ZERO : new Point(t.x, t.y, 1n) } static fromHex(t) { - let n; + let n const e = (t = toU8(t))[0], r = t.subarray(1), o = slcNum(r, 0, 32), - i = t.length; + i = t.length if (33 === i && [2, 3].includes(e)) { - fe(o) || err("Point hex invalid: x not FE"); - let t = sqrt(crv(o)); - !(1 & ~e) !== (1n === (1n & t)) && (t = mod(-t)), - (n = new Point(o, t, 1n)); + fe(o) || err('Point hex invalid: x not FE') + let t = sqrt(crv(o)) + ;(!(1 & ~e) !== (1n === (1n & t)) && (t = mod(-t)), + (n = new Point(o, t, 1n))) } return ( 65 === i && 4 === e && (n = new Point(o, slcNum(r, 32, 64), 1n)), - n ? n.ok() : err("Point is not on curve") - ); + n ? n.ok() : err('Point is not on curve') + ) } static fromPrivateKey(t) { - return G.mul(toPriv(t)); + return G.mul(toPriv(t)) } get x() { - return this.aff().x; + return this.aff().x } get y() { - return this.aff().y; + return this.aff().y } equals(t) { - const { px: n, py: e, pz: r } = this, - { px: o, py: i, pz: s } = isPoint(t), + const {px: n, py: e, pz: r} = this, + {px: o, py: i, pz: s} = isPoint(t), a = mod(n * s), c = mod(o * r), d = mod(e * s), - u = mod(i * r); - return a === c && d === u; + u = mod(i * r) + return a === c && d === u } negate() { - return new Point(this.px, mod(-this.py), this.pz); + return new Point(this.px, mod(-this.py), this.pz) } double() { - return this.add(this); + return this.add(this) } add(t) { - const { px: n, py: e, pz: r } = this, - { px: o, py: i, pz: s } = isPoint(t), - { a, b: c } = CURVE; + const {px: n, py: e, pz: r} = this, + {px: o, py: i, pz: s} = isPoint(t), + {a, b: c} = CURVE let d = 0n, u = 0n, - m = 0n; - const h = mod(3n * c); + m = 0n + const h = mod(3n * c) let l = mod(n * o), y = mod(e * i), f = mod(r * s), p = mod(n + e), - b = mod(o + i); - (p = mod(p * b)), (b = mod(l + y)), (p = mod(p - b)), (b = mod(n + r)); - let g = mod(o + s); + b = mod(o + i) + ;((p = mod(p * b)), (b = mod(l + y)), (p = mod(p - b)), (b = mod(n + r))) + let g = mod(o + s) return ( (b = mod(b * g)), (g = mod(l + f)), @@ -123,300 +123,301 @@ class Point { (m = mod(g * m)), (m = mod(m + l)), new Point(d, u, m) - ); + ) } mul(t, n = !0) { - if (!n && 0n === t) return I; - if ((ge(t) || err("invalid scalar"), this.equals(G))) return wNAF(t).p; + if (!n && 0n === t) return I + if ((ge(t) || err('invalid scalar'), this.equals(G))) return wNAF(t).p let e = I, - r = G; + r = G for (let o = this; t > 0n; o = o.double(), t >>= 1n) - 1n & t ? (e = e.add(o)) : n && (r = r.add(o)); - return e; + 1n & t ? (e = e.add(o)) : n && (r = r.add(o)) + return e } mulAddQUns(t, n, e) { - return this.mul(n, !1).add(t.mul(e, !1)).ok(); + return this.mul(n, !1).add(t.mul(e, !1)).ok() } toAffine() { - const { px: t, py: n, pz: e } = this; - if (this.equals(I)) return { x: 0n, y: 0n }; - if (1n === e) return { x: t, y: n }; - const r = inv(e); + const {px: t, py: n, pz: e} = this + if (this.equals(I)) return {x: 0n, y: 0n} + if (1n === e) return {x: t, y: n} + const r = inv(e) return ( - 1n !== mod(e * r) && err("invalid inverse"), - { x: mod(t * r), y: mod(n * r) } - ); + 1n !== mod(e * r) && err('invalid inverse'), + {x: mod(t * r), y: mod(n * r)} + ) } assertValidity() { - const { x: t, y: n } = this.aff(); + const {x: t, y: n} = this.aff() return ( - (fe(t) && fe(n)) || err("Point invalid: x or y"), - mod(n * n) === crv(t) ? this : err("Point invalid: not on curve") - ); + (fe(t) && fe(n)) || err('Point invalid: x or y'), + mod(n * n) === crv(t) ? this : err('Point invalid: not on curve') + ) } multiply(t) { - return this.mul(t); + return this.mul(t) } aff() { - return this.toAffine(); + return this.toAffine() } ok() { - return this.assertValidity(); + return this.assertValidity() } toHex(t = !0) { - const { x: n, y: e } = this.aff(); + const {x: n, y: e} = this.aff() return ( - (t ? (0n === (1n & e) ? "02" : "03") : "04") + n2h(n) + (t ? "" : n2h(e)) - ); + (t ? (0n === (1n & e) ? '02' : '03') : '04') + n2h(n) + (t ? '' : n2h(e)) + ) } toRawBytes(t = !0) { - return h2b(this.toHex(t)); + return h2b(this.toHex(t)) } } -(Point.BASE = new Point(Gx, Gy, 1n)), (Point.ZERO = new Point(0n, 1n, 0n)); -const { BASE: G, ZERO: I } = Point, - padh = (t, n) => t.toString(16).padStart(n, "0"), - b2h = (t) => +;((Point.BASE = new Point(Gx, Gy, 1n)), (Point.ZERO = new Point(0n, 1n, 0n))) +const {BASE: G, ZERO: I} = Point, + padh = (t, n) => t.toString(16).padStart(n, '0'), + b2h = t => Array.from(t) - .map((t) => padh(t, 2)) - .join(""), - h2b = (t) => { - const n = t.length; - (!str(t) || n % 2) && err("hex invalid 1"); - const e = u8n(n / 2); + .map(t => padh(t, 2)) + .join(''), + h2b = t => { + const n = t.length + ;(!str(t) || n % 2) && err('hex invalid 1') + const e = u8n(n / 2) for (let n = 0; n < e.length; n++) { const r = 2 * n, o = t.slice(r, r + 2), - i = Number.parseInt(o, 16); - (Number.isNaN(i) || i < 0) && err("hex invalid 2"), (e[n] = i); + i = Number.parseInt(o, 16) + ;((Number.isNaN(i) || i < 0) && err('hex invalid 2'), (e[n] = i)) } - return e; + return e }, - b2n = (t) => BigInt("0x" + (b2h(t) || "0")), + b2n = t => BigInt('0x' + (b2h(t) || '0')), slcNum = (t, n, e) => b2n(t.slice(n, e)), - n2b = (t) => - big(t) && t >= 0n && t < B256 ? h2b(padh(t, 64)) : err("bigint expected"), - n2h = (t) => b2h(n2b(t)), + n2b = t => + big(t) && t >= 0n && t < B256 ? h2b(padh(t, 64)) : err('bigint expected'), + n2h = t => b2h(n2b(t)), concatB = (...t) => { - const n = u8n(t.reduce((t, n) => t + au8(n).length, 0)); - let e = 0; + const n = u8n(t.reduce((t, n) => t + au8(n).length, 0)) + let e = 0 return ( - t.forEach((t) => { - n.set(t, e), (e += t.length); + t.forEach(t => { + ;(n.set(t, e), (e += t.length)) }), n - ); + ) }, inv = (t, n = P) => { - (0n === t || n <= 0n) && err("no inverse n=" + t + " mod=" + n); + ;(0n === t || n <= 0n) && err('no inverse n=' + t + ' mod=' + n) let e = mod(t, n), r = n, o = 0n, i = 1n, s = 1n, - a = 0n; + a = 0n for (; 0n !== e; ) { const t = r / e, n = r % e, c = o - s * t, - d = i - a * t; - (r = e), (e = n), (o = s), (i = a), (s = c), (a = d); + d = i - a * t + ;((r = e), (e = n), (o = s), (i = a), (s = c), (a = d)) } - return 1n === r ? mod(o, n) : err("no inverse"); + return 1n === r ? mod(o, n) : err('no inverse') }, - sqrt = (t) => { - let n = 1n; + sqrt = t => { + let n = 1n for (let e = t, r = (P + 1n) / 4n; r > 0n; r >>= 1n) - 1n & r && (n = (n * e) % P), (e = (e * e) % P); - return mod(n * n) === t ? n : err("sqrt invalid"); + (1n & r && (n = (n * e) % P), (e = (e * e) % P)) + return mod(n * n) === t ? n : err('sqrt invalid') }, - toPriv = (t) => ( + toPriv = t => ( big(t) || (t = b2n(toU8(t, 32))), - ge(t) ? t : err("private key out of range") + ge(t) ? t : err('private key out of range') ), - moreThanHalfN = (t) => t > N >> 1n, - getPublicKey = (t, n = !0) => Point.fromPrivateKey(t).toRawBytes(n); + moreThanHalfN = t => t > N >> 1n, + getPublicKey = (t, n = !0) => Point.fromPrivateKey(t).toRawBytes(n) class Signature { constructor(t, n, e) { - (this.r = t), (this.s = n), (this.recovery = e), this.assertValidity(); + ;((this.r = t), (this.s = n), (this.recovery = e), this.assertValidity()) } static fromCompact(t) { return ( - (t = toU8(t, 64)), new Signature(slcNum(t, 0, 32), slcNum(t, 32, 64)) - ); + (t = toU8(t, 64)), + new Signature(slcNum(t, 0, 32), slcNum(t, 32, 64)) + ) } assertValidity() { - return ge(this.r) && ge(this.s) ? this : err(); + return ge(this.r) && ge(this.s) ? this : err() } addRecoveryBit(t) { - return new Signature(this.r, this.s, t); + return new Signature(this.r, this.s, t) } hasHighS() { - return moreThanHalfN(this.s); + return moreThanHalfN(this.s) } normalizeS() { return this.hasHighS() ? new Signature(this.r, mod(this.s, N), this.recovery) - : this; + : this } recoverPublicKey(t) { - const { r: n, s: e, recovery: r } = this; - [0, 1, 2, 3].includes(r) || err("recovery id invalid"); + const {r: n, s: e, recovery: r} = this + ;[0, 1, 2, 3].includes(r) || err('recovery id invalid') const o = bits2int_modN(toU8(t, 32)), - i = 2 === r || 3 === r ? n + N : n; - i >= P && err("q.x invalid"); - const s = 1 & r ? "03" : "02", + i = 2 === r || 3 === r ? n + N : n + i >= P && err('q.x invalid') + const s = 1 & r ? '03' : '02', a = Point.fromHex(s + n2h(i)), c = inv(i, N), d = mod(-o * c, N), - u = mod(e * c, N); - return G.mulAddQUns(a, d, u); + u = mod(e * c, N) + return G.mulAddQUns(a, d, u) } toCompactRawBytes() { - return h2b(this.toCompactHex()); + return h2b(this.toCompactHex()) } toCompactHex() { - return n2h(this.r) + n2h(this.s); + return n2h(this.r) + n2h(this.s) } } -const bits2int = (t) => { +const bits2int = t => { const n = 8 * t.length - 256, - e = b2n(t); - return n > 0 ? e >> BigInt(n) : e; + e = b2n(t) + return n > 0 ? e >> BigInt(n) : e }, - bits2int_modN = (t) => mod(bits2int(t), N), - i2o = (t) => n2b(t), + bits2int_modN = t => mod(bits2int(t), N), + i2o = t => n2b(t), cr = () => - "object" == typeof globalThis && "crypto" in globalThis + 'object' == typeof globalThis && 'crypto' in globalThis ? globalThis.crypto - : void 0; -let _hmacSync; -const optS = { lowS: !0 }, - optV = { lowS: !0 }, + : void 0 +let _hmacSync +const optS = {lowS: !0}, + optV = {lowS: !0}, prepSig = (t, n, e = optS) => { - ["der", "recovered", "canonical"].some((t) => t in e) && - err("sign() legacy options not supported"); - let { lowS: r } = e; - null == r && (r = !0); + ;['der', 'recovered', 'canonical'].some(t => t in e) && + err('sign() legacy options not supported') + let {lowS: r} = e + null == r && (r = !0) const o = bits2int_modN(toU8(t)), i = i2o(o), s = toPriv(n), - a = [i2o(s), i]; - let c = e.extraEntropy; + a = [i2o(s), i] + let c = e.extraEntropy if (c) { - !0 === c && (c = etc.randomBytes(32)); - const t = toU8(c); - 32 !== t.length && err(), a.push(t); + !0 === c && (c = etc.randomBytes(32)) + const t = toU8(c) + ;(32 !== t.length && err(), a.push(t)) } - const d = o; + const d = o return { seed: concatB(...a), - k2sig: (t) => { - const n = bits2int(t); - if (!ge(n)) return; + k2sig: t => { + const n = bits2int(t) + if (!ge(n)) return const e = inv(n, N), o = G.mul(n).aff(), - i = mod(o.x, N); - if (0n === i) return; - const a = mod(e * mod(d + mod(s * i, N), N), N); - if (0n === a) return; + i = mod(o.x, N) + if (0n === i) return + const a = mod(e * mod(d + mod(s * i, N), N), N) + if (0n === a) return let c = a, - u = (o.x === i ? 0 : 2) | Number(1n & o.y); + u = (o.x === i ? 0 : 2) | Number(1n & o.y) return ( r && moreThanHalfN(a) && ((c = mod(-a, N)), (u ^= 1)), new Signature(i, c, u) - ); - }, - }; - }; + ) + } + } + } function hmacDrbg(t) { let n = u8n(32), e = u8n(32), - r = 0; + r = 0 const o = () => { - n.fill(1), e.fill(0), (r = 0); + ;(n.fill(1), e.fill(0), (r = 0)) }, - i = "drbg: tried 1000 values"; + i = 'drbg: tried 1000 values' if (t) { const t = (...t) => etc.hmacSha256Async(e, n, ...t), s = async (r = u8n()) => { - (e = await t(u8n([0]), r)), + ;((e = await t(u8n([0]), r)), (n = await t()), - 0 !== r.length && ((e = await t(u8n([1]), r)), (n = await t())); + 0 !== r.length && ((e = await t(u8n([1]), r)), (n = await t()))) }, - a = async () => (r++ >= 1e3 && err(i), (n = await t()), n); + a = async () => (r++ >= 1e3 && err(i), (n = await t()), n) return async (t, n) => { - let e; - for (o(), await s(t); !(e = n(await a())); ) await s(); - return o(), e; - }; + let e + for (o(), await s(t); !(e = n(await a())); ) await s() + return (o(), e) + } } { const t = (...t) => { - const r = _hmacSync; - return r || err("etc.hmacSha256Sync not set"), r(e, n, ...t); + const r = _hmacSync + return (r || err('etc.hmacSha256Sync not set'), r(e, n, ...t)) }, s = (r = u8n()) => { - (e = t(u8n([0]), r)), + ;((e = t(u8n([0]), r)), (n = t()), - 0 !== r.length && ((e = t(u8n([1]), r)), (n = t())); + 0 !== r.length && ((e = t(u8n([1]), r)), (n = t()))) }, - a = () => (r++ >= 1e3 && err(i), (n = t()), n); + a = () => (r++ >= 1e3 && err(i), (n = t()), n) return (t, n) => { - let e; - for (o(), s(t); !(e = n(a())); ) s(); - return o(), e; - }; + let e + for (o(), s(t); !(e = n(a())); ) s() + return (o(), e) + } } } const signAsync = async (t, n, e = optS) => { - const { seed: r, k2sig: o } = prepSig(t, n, e); - return hmacDrbg(!0)(r, o); + const {seed: r, k2sig: o} = prepSig(t, n, e) + return hmacDrbg(!0)(r, o) }, sign = (t, n, e = optS) => { - const { seed: r, k2sig: o } = prepSig(t, n, e); - return hmacDrbg(!1)(r, o); + const {seed: r, k2sig: o} = prepSig(t, n, e) + return hmacDrbg(!1)(r, o) }, verify = (t, n, e, r = optV) => { let o, i, s, - { lowS: a } = r; - null == a && (a = !0), - "strict" in r && err("verify() legacy options not supported"); - const c = t && "object" == typeof t && "r" in t; - c || 64 === toU8(t).length || err("signature must be 64 bytes"); + {lowS: a} = r + ;(null == a && (a = !0), + 'strict' in r && err('verify() legacy options not supported')) + const c = t && 'object' == typeof t && 'r' in t + c || 64 === toU8(t).length || err('signature must be 64 bytes') try { - (o = c + ;((o = c ? new Signature(t.r, t.s).assertValidity() : Signature.fromCompact(t)), (i = bits2int_modN(toU8(n))), - (s = e instanceof Point ? e.ok() : Point.fromHex(e)); + (s = e instanceof Point ? e.ok() : Point.fromHex(e))) } catch (t) { - return !1; + return !1 } - if (!o) return !1; - const { r: d, s: u } = o; - if (a && moreThanHalfN(u)) return !1; - let m; + if (!o) return !1 + const {r: d, s: u} = o + if (a && moreThanHalfN(u)) return !1 + let m try { const t = inv(u, N), n = mod(i * t, N), - e = mod(d * t, N); - m = G.mulAddQUns(s, n, e).aff(); + e = mod(d * t, N) + m = G.mulAddQUns(s, n, e).aff() } catch (t) { - return !1; + return !1 } - if (!m) return !1; - return mod(m.x, N) === d; + if (!m) return !1 + return mod(m.x, N) === d }, getSharedSecret = (t, n, e = !0) => Point.fromHex(n).mul(toPriv(t)).toRawBytes(e), - hashToPrivateKey = (t) => { - ((t = toU8(t)).length < 40 || t.length > 1024) && - err("expected proper params"); - const n = mod(b2n(t), N - 1n) + 1n; - return n2b(n); + hashToPrivateKey = t => { + ;((t = toU8(t)).length < 40 || t.length > 1024) && + err('expected proper params') + const n = mod(b2n(t), N - 1n) + 1n + return n2b(n) }, etc = { hexToBytes: h2b, @@ -428,84 +429,84 @@ const signAsync = async (t, n, e = optS) => { invert: inv, hmacSha256Async: async (t, ...n) => { const e = cr(), - r = e && e.subtle; - if (!r) return err("etc.hmacSha256Async not set"); + r = e && e.subtle + if (!r) return err('etc.hmacSha256Async not set') const o = await r.importKey( - "raw", + 'raw', t, - { name: "HMAC", hash: { name: "SHA-256" } }, + {name: 'HMAC', hash: {name: 'SHA-256'}}, !1, - ["sign"], - ); - return u8n(await r.sign("HMAC", o, concatB(...n))); + ['sign'] + ) + return u8n(await r.sign('HMAC', o, concatB(...n))) }, hmacSha256Sync: _hmacSync, hashToPrivateKey, randomBytes: (t = 32) => { - const n = cr(); + const n = cr() return ( (n && n.getRandomValues) || - err("crypto.getRandomValues must be defined"), + err('crypto.getRandomValues must be defined'), n.getRandomValues(u8n(t)) - ); - }, + ) + } }, utils = { normPrivateKeyToScalar: toPriv, - isValidPrivateKey: (t) => { + isValidPrivateKey: t => { try { - return !!toPriv(t); + return !!toPriv(t) } catch (t) { - return !1; + return !1 } }, randomPrivateKey: () => hashToPrivateKey(etc.randomBytes(48)), - precompute: (t = 8, n = G) => (n.multiply(3n), n), - }; + precompute: (t = 8, n = G) => (n.multiply(3n), n) + } Object.defineProperties(etc, { hmacSha256Sync: { configurable: !1, get: () => _hmacSync, set(t) { - _hmacSync || (_hmacSync = t); - }, - }, -}); + _hmacSync || (_hmacSync = t) + } + } +}) const W = 8, precompute = () => { - const t = []; + const t = [] let n = G, - e = n; + e = n for (let r = 0; r < 33; r++) { - (e = n), t.push(e); - for (let r = 1; r < 128; r++) (e = e.add(n)), t.push(e); - n = e.double(); + ;((e = n), t.push(e)) + for (let r = 1; r < 128; r++) ((e = e.add(n)), t.push(e)) + n = e.double() } - return t; - }; -let Gpows; -const wNAF = (t) => { + return t + } +let Gpows +const wNAF = t => { const n = Gpows || (Gpows = precompute()), e = (t, n) => { - let e = n.negate(); - return t ? e : n; - }; + let e = n.negate() + return t ? e : n + } let r = I, - o = G; + o = G const i = BigInt(255), - s = BigInt(8); + s = BigInt(8) for (let a = 0; a < 33; a++) { - const c = 128 * a; - let d = Number(t & i); - (t >>= s), d > 128 && ((d -= 256), (t += 1n)); + const c = 128 * a + let d = Number(t & i) + ;((t >>= s), d > 128 && ((d -= 256), (t += 1n))) const u = c, m = c + Math.abs(d) - 1, h = a % 2 != 0, - l = d < 0; - 0 === d ? (o = o.add(e(h, n[u]))) : (r = r.add(e(l, n[m]))); + l = d < 0 + 0 === d ? (o = o.add(e(h, n[u]))) : (r = r.add(e(l, n[m]))) } - return { p: r, f: o }; -}; + return {p: r, f: o} +} export { getPublicKey, sign, @@ -516,5 +517,5 @@ export { etc, utils, Point as ProjectivePoint, - Signature, -}; + Signature +} diff --git a/tasks.py b/tasks.py index 1fa9c92..a19a0d8 100644 --- a/tasks.py +++ b/tasks.py @@ -1,7 +1,7 @@ import asyncio import time from math import ceil -from typing import Any, Dict, List, Optional, Tuple +from typing import Any from bolt11 import decode as bolt11_decode from lnbits.core.crud import get_payments, get_wallet, get_wallet_payment @@ -35,7 +35,7 @@ from .paranoia import ( from .permission import nwc_permissions -async def _check(nwc: Optional[NWCKey], method: str) -> Optional[Dict]: +async def _check(nwc: NWCKey | None, method: str) -> dict | None: # check if not nwc: return { @@ -46,8 +46,8 @@ async def _check(nwc: Optional[NWCKey], method: str) -> Optional[Dict]: allowed = False permissions = nwc.get_permissions() for p in permissions: - permissions_data: Dict[str, Any] = nwc_permissions.get(p, {}) - allowed_methods: List[str] = permissions_data.get("methods", []) + permissions_data: dict[str, Any] = nwc_permissions.get(p, {}) + allowed_methods: list[str] = permissions_data.get("methods", []) if method in allowed_methods: allowed = True break @@ -64,7 +64,7 @@ async def _process_invoice( pubkey: str, invoice: str, amount_msats: int, - description: Optional[str] = None, + description: str | None = None, ): # hardening # @@ -80,7 +80,7 @@ async def _process_invoice( payment = await pay_invoice( wallet_id=wallet_id, payment_request=invoice, - max_sat=int(ceil(amount_msats / 1000)), + max_sat=ceil(amount_msats / 1000), description=description or "", ) return payment.payment_hash @@ -109,7 +109,7 @@ async def _process_invoice( wait_for_preimage = ( True # currently required by nip 47 specs, might change in future ) - payment_status: Optional[PaymentStatus] = None + payment_status: PaymentStatus | None = None while wait_for_preimage: payment_status = await check_transaction_status(wallet_id, payment_hash) if payment_status.success: @@ -128,8 +128,8 @@ async def _process_invoice( async def _on_pay_invoice( - sp: NWCServiceProvider, pubkey: str, payload: Dict -) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + sp: NWCServiceProvider, pubkey: str, payload: dict +) -> list[tuple[dict | None, dict | None, list]]: # hardening # assert_valid_pubkey(pubkey) @@ -169,8 +169,8 @@ async def _on_pay_invoice( async def _on_multi_pay_invoice( - sp: NWCServiceProvider, pubkey: str, payload: Dict -) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + sp: NWCServiceProvider, pubkey: str, payload: dict +) -> list[tuple[dict | None, dict | None, list]]: # hardening # assert_valid_pubkey(pubkey) @@ -184,7 +184,7 @@ async def _on_multi_pay_invoice( raise Exception("Pubkey has no associated wallet") params = payload.get("params", {}) invoices = params.get("invoices", []) - results: List[Tuple[Optional[Dict], Optional[Dict], List]] = [] + results: list[tuple[dict | None, dict | None, list]] = [] # Ensures all invoices are provided for i in invoices: @@ -228,8 +228,8 @@ async def _on_multi_pay_invoice( async def _on_make_invoice( - sp: NWCServiceProvider, pubkey: str, payload: Dict -) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + sp: NWCServiceProvider, pubkey: str, payload: dict +) -> list[tuple[dict | None, dict | None, list]]: # hardening # assert_valid_pubkey(pubkey) @@ -298,8 +298,8 @@ async def _on_make_invoice( async def _on_lookup_invoice( - sp: NWCServiceProvider, pubkey: str, payload: Dict -) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + sp: NWCServiceProvider, pubkey: str, payload: dict +) -> list[tuple[dict | None, dict | None, list]]: # hardening # assert_valid_pubkey(pubkey) @@ -336,12 +336,12 @@ async def _on_lookup_invoice( invoice_data = bolt11_decode(payment.bolt11) is_settled = not payment.pending timestamp = int(payment.time.timestamp()) or int(invoice_data.date) - expiry = int(payment.expiry.timestamp()) or timestamp + 3600 + expiry = int(payment.expiry.timestamp()) if payment.expiry else timestamp + 3600 preimage = ( payment.preimage or "0000000000000000000000000000000000000000000000000000000000000000" ) - res: Dict = { + res: dict = { "type": "outgoing" if payment.is_out else "incoming", "invoice": payment.bolt11, "description": ( @@ -363,8 +363,8 @@ async def _on_lookup_invoice( async def _on_list_transactions( - sp: NWCServiceProvider, pubkey: str, payload: Dict -) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + sp: NWCServiceProvider, pubkey: str, payload: dict +) -> list[tuple[dict | None, dict | None, list]]: # hardening # assert_valid_pubkey(pubkey) # ## # @@ -392,11 +392,9 @@ async def _on_list_transactions( assert_sane_string(tx_type) # ## # - values = [] filters: Filters = Filters() - filters.where(["time <= ?"]) - values.append(tuntil) - filters.values(values) + filters.where(["time <= :tuntil"]) + filters.values({"tuntil": tuntil}) history = await get_payments( wallet_id=nwc.wallet, complete=True, @@ -409,7 +407,7 @@ async def _on_list_transactions( limit=limit, offset=offset, ) - transactions: List[Dict] = [] + transactions: list[dict] = [] p: Payment for p in history: invoice_data = bolt11_decode(p.bolt11) @@ -435,8 +433,8 @@ async def _on_list_transactions( async def _on_get_balance( - sp: NWCServiceProvider, pubkey: str, payload: Dict -) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + sp: NWCServiceProvider, pubkey: str, payload: dict +) -> list[tuple[dict | None, dict | None, list]]: # hardening # assert_valid_pubkey(pubkey) @@ -458,8 +456,8 @@ async def _on_get_balance( async def _on_get_info( - sp: NWCServiceProvider, pubkey: str, payload: Dict -) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + sp: NWCServiceProvider, pubkey: str, payload: dict +) -> list[tuple[dict | None, dict | None, list]]: # hardening # assert_valid_pubkey(pubkey) @@ -477,8 +475,8 @@ async def _on_get_info( account_methods = [] for spm in sp_methods: for p in permissions: - permissions_data: Dict[str, Any] = nwc_permissions.get(p, {}) - allowed_methods: List[str] = permissions_data.get("methods", []) + permissions_data: dict[str, Any] = nwc_permissions.get(p, {}) + allowed_methods: list[str] = permissions_data.get("methods", []) if spm in allowed_methods: account_methods.append(spm) break diff --git a/templates/nwcprovider/index.html b/templates/nwcprovider/index.html index 143c7af..3c6ecf1 100644 --- a/templates/nwcprovider/index.html +++ b/templates/nwcprovider/index.html @@ -1,8 +1,8 @@ {% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} {% block scripts %} {{ window_vars(user) }} {% endblock %} {% block page %} diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index 854aef4..2273126 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -4,17 +4,17 @@ import hashlib import json import random import time -from typing import Dict, List, Optional, Union +from typing import Union import bolt11 import httpx import pytest import secp256k1 -import websockets.client as websockets from Cryptodome import Random from Cryptodome.Cipher import AES from Cryptodome.Util.Padding import pad, unpad from loguru import logger +from websockets.legacy.client import connect wallets = { "wallet1": { @@ -107,8 +107,8 @@ def gen_keypair(): async def create_nwc( w: str, desc: str, - permissions: List[str], - budgets: List[Dict[str, int]], + permissions: list[str], + budgets: list[dict[str, int]], expiration: int = 0, ): keypair = gen_keypair() @@ -210,7 +210,7 @@ class NWCWallet: async def _run(self): while True: try: - async with websockets.connect(self.relay) as ws: + async with connect(self.relay) as ws: self.ws = ws self.connected = True self.sub_id = self._get_new_subid() @@ -244,7 +244,7 @@ class NWCWallet: break def _encrypt_content( - self, content: str, pubkey_hex: str, iv_seed: Optional[int] = None + self, content: str, pubkey_hex: str, iv_seed: int | None = None ) -> str: pubkey = secp256k1.PublicKey(bytes.fromhex("02" + pubkey_hex), True) shared = pubkey.tweak_mul(bytes.fromhex(self.private_key_hex)).serialize()[1:] @@ -273,7 +273,7 @@ class NWCWallet: decrypted = decrypted_bytes.decode("utf-8") return decrypted - async def _on_message(self, ws, message: str): + async def _on_message(self, _, message: str): logger.debug("Received message: " + message) msg = json.loads(message) if msg[0] == "EVENT": # Event message @@ -292,12 +292,12 @@ class NWCWallet: } ) - def _json_dumps(self, data: Union[Dict, list]) -> str: - if isinstance(data, Dict): + def _json_dumps(self, data: Union[dict, list]) -> str: + if isinstance(data, dict): data = {k: v for k, v in data.items() if v is not None} return json.dumps(data, separators=(",", ":"), ensure_ascii=False) - def _sign_event(self, event: Dict) -> Dict: + def _sign_event(self, event: dict) -> dict: signature_data = self._json_dumps( [ 0, @@ -386,14 +386,14 @@ async def test_make_invoice(): await wallet1.send_event( "make_invoice", {"amount": 1, "description": "test 123", "expiry": 1000} ) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") logger.info(error) assert error, "Expected internal error, because amount is too low" await wallet1.send_event( "make_invoice", {"amount": 123000, "description": "test 123", "expiry": 1000} ) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") assert not error assert result["type"] == "incoming" assert result["description"] == "test 123" @@ -424,7 +424,7 @@ async def test_lookup_invoice(): await wallet1.send_event( "make_invoice", {"amount": 123000, "description": "test 123", "expiry": 1000} ) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") assert not error assert result["type"] == "incoming" assert result["description"] == "test 123" @@ -440,7 +440,7 @@ async def test_lookup_invoice(): await wallet2.start() await wallet2.send_event("lookup_invoice", {"invoice": result["invoice"]}) - result, tags, error = await wallet2.wait_for("lookup_invoice") + result, _, error = await wallet2.wait_for("lookup_invoice") assert not error assert result["type"] == "incoming" assert result["description"] == "test 123" @@ -465,7 +465,7 @@ async def test_get_info(): await wallet1.start() await wallet1.send_event("get_info", {}) - result, tags, error = await wallet1.wait_for("get_info") + result, _, error = await wallet1.wait_for("get_info") assert not error assert result["alias"] == "LNBits_NWC_SP" assert result["color"] == "" @@ -492,33 +492,33 @@ async def test_permisions(): await wallet1.start() await wallet1.send_event("get_info", {}) - result, tags, error = await wallet1.wait_for("get_info") + result, _, error = await wallet1.wait_for("get_info") assert not error await wallet1.send_event( "make_invoice", {"amount": 123000, "description": "test 123", "expiry": 1000} ) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") assert error await wallet1.close() await wallet2.start() await wallet2.send_event("get_info", {}) - result, tags, error = await wallet2.wait_for("get_info") + result, _, error = await wallet2.wait_for("get_info") assert error await wallet2.send_event( "make_invoice", {"amount": 123000, "description": "test 123", "expiry": 1000} ) - result, tags, error = await wallet2.wait_for("make_invoice") + result, _, error = await wallet2.wait_for("make_invoice") assert not error await wallet2.close() await wallet3.start() await wallet3.send_event("get_info", {}) - result, tags, error = await wallet3.wait_for("get_info") + result, _, error = await wallet3.wait_for("get_info") assert not error assert "make_invoice" in result["methods"] assert "pay_invoice" in result["methods"] @@ -548,7 +548,7 @@ async def test_pay_invoice_and_balance(): "make_invoice", {"amount": 123000, "description": "test 123"} ) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") assert not error assert result["invoice"] @@ -557,7 +557,7 @@ async def test_pay_invoice_and_balance(): await wallet2.start() await wallet2.send_event("pay_invoice", {"invoice": invoice}) - result, tags, error = await wallet2.wait_for("pay_invoice") + result, _, error = await wallet2.wait_for("pay_invoice") assert not error assert result["preimage"] @@ -569,12 +569,12 @@ async def test_pay_invoice_and_balance(): assert wallet2_balance_new == wallet2_balance - 123000 await wallet1.send_event("get_balance", {}) - result, tags, error = await wallet1.wait_for("get_balance") + result, _, error = await wallet1.wait_for("get_balance") assert not error assert result["balance"] == wallet1_balance_new await wallet2.send_event("get_balance", {}) - result, tags, error = await wallet2.wait_for("get_balance") + result, _, error = await wallet2.wait_for("get_balance") assert not error assert result["balance"] == wallet2_balance_new @@ -703,13 +703,13 @@ async def test_insufficient_balance(): await wallet2.send_event( "make_invoice", {"amount": amount_to_spend, "description": "test 123"} ) - result, tags, error = await wallet2.wait_for("make_invoice") + result, _, error = await wallet2.wait_for("make_invoice") assert not error assert result["invoice"] invoice = result["invoice"] await wallet1.send_event("pay_invoice", {"invoice": invoice}) - result, tags, error = await wallet1.wait_for("pay_invoice") + result, _, error = await wallet1.wait_for("pay_invoice") logger.info(error) logger.info(result) logger.info(amount_to_spend) @@ -735,7 +735,7 @@ async def test_expiry(): await wallet3.send_event( "make_invoice", {"amount": 123000, "description": "test 123"} ) - result, tags, error = await wallet3.wait_for("make_invoice") + _, _, error = await wallet3.wait_for("make_invoice") assert error assert ( error["code"] == "UNAUTHORIZED" @@ -768,22 +768,22 @@ async def test_budget(): await wallet1.send_event( "make_invoice", {"amount": 101000, "description": "Invalid"} ) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") assert not error await wallet3.send_event("pay_invoice", {"invoice": result["invoice"]}) - result, tags, error = await wallet3.wait_for("pay_invoice") + result, _, error = await wallet3.wait_for("pay_invoice") assert error assert ( error["code"] == "QUOTA_EXCEEDED" ), "Expected QUOTA_EXCEEDED error, because the budget was exceeded" await wallet1.send_event("make_invoice", {"amount": 99000, "description": "Valid"}) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") assert not error await wallet3.send_event("pay_invoice", {"invoice": result["invoice"]}) - result, tags, error = await wallet3.wait_for("pay_invoice") + result, _, error = await wallet3.wait_for("pay_invoice") assert not error, "Expected successful payment, because the budget was not exceeded" assert result["preimage"] @@ -791,11 +791,11 @@ async def test_budget(): "make_invoice", {"amount": 100000 - 99000 + 1000, "description": "Invalid"} ) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") assert not error await wallet3.send_event("pay_invoice", {"invoice": result["invoice"]}) - result, tags, error = await wallet3.wait_for("pay_invoice") + result, _, error = await wallet3.wait_for("pay_invoice") assert error assert ( error["code"] == "QUOTA_EXCEEDED" @@ -824,21 +824,21 @@ async def test_budget_refresh(): await wallet1.send_event( "make_invoice", {"amount": 100000, "description": "Invalid"} ) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") assert not error await wallet1.send_event( "make_invoice", {"amount": 100000, "description": "Invalid"} ) - result2, tags, error = await wallet1.wait_for("make_invoice") + result2, _, error = await wallet1.wait_for("make_invoice") assert not error await wallet3.send_event("pay_invoice", {"invoice": result["invoice"]}) - result, tags, error = await wallet3.wait_for("pay_invoice") + result, _, error = await wallet3.wait_for("pay_invoice") assert not error, "Expected successful payment, because the budget was not exceeded" await wallet3.send_event("pay_invoice", {"invoice": result2["invoice"]}) - result, tags, error = await wallet3.wait_for("pay_invoice") + result, _, error = await wallet3.wait_for("pay_invoice") assert error assert ( error["code"] == "QUOTA_EXCEEDED" @@ -846,11 +846,11 @@ async def test_budget_refresh(): await asyncio.sleep(5) await wallet1.send_event("make_invoice", {"amount": 100000, "description": "Valid"}) - result, tags, error = await wallet1.wait_for("make_invoice") + result, _, error = await wallet1.wait_for("make_invoice") assert not error await wallet3.send_event("pay_invoice", {"invoice": result["invoice"]}) - result, tags, error = await wallet3.wait_for("pay_invoice") + result, _, error = await wallet3.wait_for("pay_invoice") assert not error, "Expected successful payment, because the budget was refreshed" await wallet3.close() @@ -916,6 +916,7 @@ async def test_invalid_invoice_handling(): # Send invalid invoice await wallet.send_event("pay_invoice", {"invoice": "invalid_lninvoice"}) _, _, error = await wallet.wait_for("pay_invoice") + assert error assert error["code"] == "INTERNAL" @@ -935,6 +936,7 @@ async def test_replay_attack(): # Replay same message await wallet.send_event("pay_invoice", {"invoice": valid_invoice}) _, _, error = await wallet.wait_for("pay_invoice") + assert error assert error["code"] == "PAYMENT_FAILED" @@ -967,6 +969,7 @@ async def test_budget_bypass(): invoice2 = await create_valid_invoice(wallet, 60000) await wallet.send_event("pay_invoice", {"invoice": invoice2}) _, _, error = await wallet.wait_for("pay_invoice") + assert error assert error["code"] == "QUOTA_EXCEEDED" @@ -992,28 +995,37 @@ async def create_valid_invoice(wallet, amount=1000): await wallet.send_event( "make_invoice", {"amount": amount, "description": "test invoice"} ) - result, tags, error = await wallet.wait_for("make_invoice") + result, _, error = await wallet.wait_for("make_invoice") if error: raise Exception(f"Failed to create invoice: {error}") return result["invoice"] + @pytest.mark.asyncio async def test_list_transactions(): # Create wallets with required permissions nwc1 = await create_nwc( - "wallet1", "test_list_transactions", ["invoice", "pay", "balance", "history"], [], 0 + "wallet1", + "test_list_transactions", + ["invoice", "pay", "balance", "history"], + [], + 0, ) nwc2 = await create_nwc( - "wallet2", "test_list_transactions", ["invoice", "pay", "balance", "history"], [], 0 + "wallet2", + "test_list_transactions", + ["invoice", "pay", "balance", "history"], + [], + 0, ) - + wallet1 = NWCWallet(nwc1["pairing"]) wallet2 = NWCWallet(nwc2["pairing"]) - + try: await wallet1.start() await wallet2.start() - + # First invoice await wallet1.send_event( "make_invoice", {"amount": 1000, "description": "test invoice 1"} @@ -1021,12 +1033,12 @@ async def test_list_transactions(): result1, _, error = await wallet1.wait_for("make_invoice") assert not error invoice1 = result1["invoice"] - + # Pay first invoice await wallet2.send_event("pay_invoice", {"invoice": invoice1}) _, _, error = await wallet2.wait_for("pay_invoice") assert not error - + # Second invoice await wallet1.send_event( "make_invoice", {"amount": 2000, "description": "test invoice 2"} @@ -1034,12 +1046,12 @@ async def test_list_transactions(): result2, _, error = await wallet1.wait_for("make_invoice") assert not error invoice2 = result2["invoice"] - + # Pay second invoice await wallet2.send_event("pay_invoice", {"invoice": invoice2}) _, _, error = await wallet2.wait_for("pay_invoice") assert not error - + # Test basic transaction listing await wallet1.send_event("list_transactions", {}) result, _, error = await wallet1.wait_for("list_transactions") @@ -1047,14 +1059,14 @@ async def test_list_transactions(): assert "transactions" in result transactions = result["transactions"] assert len(transactions) >= 2 - + # Test limit await wallet1.send_event("list_transactions", {"limit": 1}) result, _, error = await wallet1.wait_for("list_transactions") assert not error limited_txs = result["transactions"] assert len(limited_txs) == 1 - + finally: await wallet1.close() - await wallet2.close() \ No newline at end of file + await wallet2.close() diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/test_nwcp.py b/tests/unit/test_nwcp.py index f9a650e..ebc3d75 100644 --- a/tests/unit/test_nwcp.py +++ b/tests/unit/test_nwcp.py @@ -1,18 +1,11 @@ import json -import os -import sys - -from loguru import logger - -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) -#### - import random import string import pytest +from loguru import logger -from nwcp import NWCServiceProvider +from ...nwcp import NWCServiceProvider @pytest.fixture diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..304ae08 --- /dev/null +++ b/uv.lock @@ -0,0 +1,2276 @@ +version = 1 +revision = 3 +requires-python = ">=3.10, <3.13" + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.12.15" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "async-timeout", marker = "python_full_version < '3.11'" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9b/e7/d92a237d8802ca88483906c388f7c201bbe96cd80a165ffd0ac2f6a8d59f/aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2", size = 7823716, upload-time = "2025-07-29T05:52:32.215Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/dc/ef9394bde9080128ad401ac7ede185267ed637df03b51f05d14d1c99ad67/aiohttp-3.12.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b6fc902bff74d9b1879ad55f5404153e2b33a82e72a95c89cec5eb6cc9e92fbc", size = 703921, upload-time = "2025-07-29T05:49:43.584Z" }, + { url = "https://files.pythonhosted.org/packages/8f/42/63fccfc3a7ed97eb6e1a71722396f409c46b60a0552d8a56d7aad74e0df5/aiohttp-3.12.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:098e92835b8119b54c693f2f88a1dec690e20798ca5f5fe5f0520245253ee0af", size = 480288, upload-time = "2025-07-29T05:49:47.851Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a2/7b8a020549f66ea2a68129db6960a762d2393248f1994499f8ba9728bbed/aiohttp-3.12.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:40b3fee496a47c3b4a39a731954c06f0bd9bd3e8258c059a4beb76ac23f8e421", size = 468063, upload-time = "2025-07-29T05:49:49.789Z" }, + { url = "https://files.pythonhosted.org/packages/8f/f5/d11e088da9176e2ad8220338ae0000ed5429a15f3c9dfd983f39105399cd/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ce13fcfb0bb2f259fb42106cdc63fa5515fb85b7e87177267d89a771a660b79", size = 1650122, upload-time = "2025-07-29T05:49:51.874Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6b/b60ce2757e2faed3d70ed45dafee48cee7bfb878785a9423f7e883f0639c/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3beb14f053222b391bf9cf92ae82e0171067cc9c8f52453a0f1ec7c37df12a77", size = 1624176, upload-time = "2025-07-29T05:49:53.805Z" }, + { url = "https://files.pythonhosted.org/packages/dd/de/8c9fde2072a1b72c4fadecf4f7d4be7a85b1d9a4ab333d8245694057b4c6/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c39e87afe48aa3e814cac5f535bc6199180a53e38d3f51c5e2530f5aa4ec58c", size = 1696583, upload-time = "2025-07-29T05:49:55.338Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ad/07f863ca3d895a1ad958a54006c6dafb4f9310f8c2fdb5f961b8529029d3/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5f1b4ce5bc528a6ee38dbf5f39bbf11dd127048726323b72b8e85769319ffc4", size = 1738896, upload-time = "2025-07-29T05:49:57.045Z" }, + { url = "https://files.pythonhosted.org/packages/20/43/2bd482ebe2b126533e8755a49b128ec4e58f1a3af56879a3abdb7b42c54f/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1004e67962efabbaf3f03b11b4c43b834081c9e3f9b32b16a7d97d4708a9abe6", size = 1643561, upload-time = "2025-07-29T05:49:58.762Z" }, + { url = "https://files.pythonhosted.org/packages/23/40/2fa9f514c4cf4cbae8d7911927f81a1901838baf5e09a8b2c299de1acfe5/aiohttp-3.12.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8faa08fcc2e411f7ab91d1541d9d597d3a90e9004180edb2072238c085eac8c2", size = 1583685, upload-time = "2025-07-29T05:50:00.375Z" }, + { url = "https://files.pythonhosted.org/packages/b8/c3/94dc7357bc421f4fb978ca72a201a6c604ee90148f1181790c129396ceeb/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fe086edf38b2222328cdf89af0dde2439ee173b8ad7cb659b4e4c6f385b2be3d", size = 1627533, upload-time = "2025-07-29T05:50:02.306Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3f/1f8911fe1844a07001e26593b5c255a685318943864b27b4e0267e840f95/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:79b26fe467219add81d5e47b4a4ba0f2394e8b7c7c3198ed36609f9ba161aecb", size = 1638319, upload-time = "2025-07-29T05:50:04.282Z" }, + { url = "https://files.pythonhosted.org/packages/4e/46/27bf57a99168c4e145ffee6b63d0458b9c66e58bb70687c23ad3d2f0bd17/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b761bac1192ef24e16706d761aefcb581438b34b13a2f069a6d343ec8fb693a5", size = 1613776, upload-time = "2025-07-29T05:50:05.863Z" }, + { url = "https://files.pythonhosted.org/packages/0f/7e/1d2d9061a574584bb4ad3dbdba0da90a27fdc795bc227def3a46186a8bc1/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e153e8adacfe2af562861b72f8bc47f8a5c08e010ac94eebbe33dc21d677cd5b", size = 1693359, upload-time = "2025-07-29T05:50:07.563Z" }, + { url = "https://files.pythonhosted.org/packages/08/98/bee429b52233c4a391980a5b3b196b060872a13eadd41c3a34be9b1469ed/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fc49c4de44977aa8601a00edbf157e9a421f227aa7eb477d9e3df48343311065", size = 1716598, upload-time = "2025-07-29T05:50:09.33Z" }, + { url = "https://files.pythonhosted.org/packages/57/39/b0314c1ea774df3392751b686104a3938c63ece2b7ce0ba1ed7c0b4a934f/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2776c7ec89c54a47029940177e75c8c07c29c66f73464784971d6a81904ce9d1", size = 1644940, upload-time = "2025-07-29T05:50:11.334Z" }, + { url = "https://files.pythonhosted.org/packages/1b/83/3dacb8d3f8f512c8ca43e3fa8a68b20583bd25636ffa4e56ee841ffd79ae/aiohttp-3.12.15-cp310-cp310-win32.whl", hash = "sha256:2c7d81a277fa78b2203ab626ced1487420e8c11a8e373707ab72d189fcdad20a", size = 429239, upload-time = "2025-07-29T05:50:12.803Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f9/470b5daba04d558c9673ca2034f28d067f3202a40e17804425f0c331c89f/aiohttp-3.12.15-cp310-cp310-win_amd64.whl", hash = "sha256:83603f881e11f0f710f8e2327817c82e79431ec976448839f3cd05d7afe8f830", size = 452297, upload-time = "2025-07-29T05:50:14.266Z" }, + { url = "https://files.pythonhosted.org/packages/20/19/9e86722ec8e835959bd97ce8c1efa78cf361fa4531fca372551abcc9cdd6/aiohttp-3.12.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d3ce17ce0220383a0f9ea07175eeaa6aa13ae5a41f30bc61d84df17f0e9b1117", size = 711246, upload-time = "2025-07-29T05:50:15.937Z" }, + { url = "https://files.pythonhosted.org/packages/71/f9/0a31fcb1a7d4629ac9d8f01f1cb9242e2f9943f47f5d03215af91c3c1a26/aiohttp-3.12.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:010cc9bbd06db80fe234d9003f67e97a10fe003bfbedb40da7d71c1008eda0fe", size = 483515, upload-time = "2025-07-29T05:50:17.442Z" }, + { url = "https://files.pythonhosted.org/packages/62/6c/94846f576f1d11df0c2e41d3001000527c0fdf63fce7e69b3927a731325d/aiohttp-3.12.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f9d7c55b41ed687b9d7165b17672340187f87a773c98236c987f08c858145a9", size = 471776, upload-time = "2025-07-29T05:50:19.568Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6c/f766d0aaafcee0447fad0328da780d344489c042e25cd58fde566bf40aed/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc4fbc61bb3548d3b482f9ac7ddd0f18c67e4225aaa4e8552b9f1ac7e6bda9e5", size = 1741977, upload-time = "2025-07-29T05:50:21.665Z" }, + { url = "https://files.pythonhosted.org/packages/17/e5/fb779a05ba6ff44d7bc1e9d24c644e876bfff5abe5454f7b854cace1b9cc/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbc8a7c410bb3ad5d595bb7118147dfbb6449d862cc1125cf8867cb337e8728", size = 1690645, upload-time = "2025-07-29T05:50:23.333Z" }, + { url = "https://files.pythonhosted.org/packages/37/4e/a22e799c2035f5d6a4ad2cf8e7c1d1bd0923192871dd6e367dafb158b14c/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74dad41b3458dbb0511e760fb355bb0b6689e0630de8a22b1b62a98777136e16", size = 1789437, upload-time = "2025-07-29T05:50:25.007Z" }, + { url = "https://files.pythonhosted.org/packages/28/e5/55a33b991f6433569babb56018b2fb8fb9146424f8b3a0c8ecca80556762/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b6f0af863cf17e6222b1735a756d664159e58855da99cfe965134a3ff63b0b0", size = 1828482, upload-time = "2025-07-29T05:50:26.693Z" }, + { url = "https://files.pythonhosted.org/packages/c6/82/1ddf0ea4f2f3afe79dffed5e8a246737cff6cbe781887a6a170299e33204/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5b7fe4972d48a4da367043b8e023fb70a04d1490aa7d68800e465d1b97e493b", size = 1730944, upload-time = "2025-07-29T05:50:28.382Z" }, + { url = "https://files.pythonhosted.org/packages/1b/96/784c785674117b4cb3877522a177ba1b5e4db9ce0fd519430b5de76eec90/aiohttp-3.12.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6443cca89553b7a5485331bc9bedb2342b08d073fa10b8c7d1c60579c4a7b9bd", size = 1668020, upload-time = "2025-07-29T05:50:30.032Z" }, + { url = "https://files.pythonhosted.org/packages/12/8a/8b75f203ea7e5c21c0920d84dd24a5c0e971fe1e9b9ebbf29ae7e8e39790/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c5f40ec615e5264f44b4282ee27628cea221fcad52f27405b80abb346d9f3f8", size = 1716292, upload-time = "2025-07-29T05:50:31.983Z" }, + { url = "https://files.pythonhosted.org/packages/47/0b/a1451543475bb6b86a5cfc27861e52b14085ae232896a2654ff1231c0992/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:2abbb216a1d3a2fe86dbd2edce20cdc5e9ad0be6378455b05ec7f77361b3ab50", size = 1711451, upload-time = "2025-07-29T05:50:33.989Z" }, + { url = "https://files.pythonhosted.org/packages/55/fd/793a23a197cc2f0d29188805cfc93aa613407f07e5f9da5cd1366afd9d7c/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:db71ce547012a5420a39c1b744d485cfb823564d01d5d20805977f5ea1345676", size = 1691634, upload-time = "2025-07-29T05:50:35.846Z" }, + { url = "https://files.pythonhosted.org/packages/ca/bf/23a335a6670b5f5dfc6d268328e55a22651b440fca341a64fccf1eada0c6/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ced339d7c9b5030abad5854aa5413a77565e5b6e6248ff927d3e174baf3badf7", size = 1785238, upload-time = "2025-07-29T05:50:37.597Z" }, + { url = "https://files.pythonhosted.org/packages/57/4f/ed60a591839a9d85d40694aba5cef86dde9ee51ce6cca0bb30d6eb1581e7/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7c7dd29c7b5bda137464dc9bfc738d7ceea46ff70309859ffde8c022e9b08ba7", size = 1805701, upload-time = "2025-07-29T05:50:39.591Z" }, + { url = "https://files.pythonhosted.org/packages/85/e0/444747a9455c5de188c0f4a0173ee701e2e325d4b2550e9af84abb20cdba/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:421da6fd326460517873274875c6c5a18ff225b40da2616083c5a34a7570b685", size = 1718758, upload-time = "2025-07-29T05:50:41.292Z" }, + { url = "https://files.pythonhosted.org/packages/36/ab/1006278d1ffd13a698e5dd4bfa01e5878f6bddefc296c8b62649753ff249/aiohttp-3.12.15-cp311-cp311-win32.whl", hash = "sha256:4420cf9d179ec8dfe4be10e7d0fe47d6d606485512ea2265b0d8c5113372771b", size = 428868, upload-time = "2025-07-29T05:50:43.063Z" }, + { url = "https://files.pythonhosted.org/packages/10/97/ad2b18700708452400278039272032170246a1bf8ec5d832772372c71f1a/aiohttp-3.12.15-cp311-cp311-win_amd64.whl", hash = "sha256:edd533a07da85baa4b423ee8839e3e91681c7bfa19b04260a469ee94b778bf6d", size = 453273, upload-time = "2025-07-29T05:50:44.613Z" }, + { url = "https://files.pythonhosted.org/packages/63/97/77cb2450d9b35f517d6cf506256bf4f5bda3f93a66b4ad64ba7fc917899c/aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7", size = 702333, upload-time = "2025-07-29T05:50:46.507Z" }, + { url = "https://files.pythonhosted.org/packages/83/6d/0544e6b08b748682c30b9f65640d006e51f90763b41d7c546693bc22900d/aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444", size = 476948, upload-time = "2025-07-29T05:50:48.067Z" }, + { url = "https://files.pythonhosted.org/packages/3a/1d/c8c40e611e5094330284b1aea8a4b02ca0858f8458614fa35754cab42b9c/aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d", size = 469787, upload-time = "2025-07-29T05:50:49.669Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/b76438e70319796bfff717f325d97ce2e9310f752a267bfdf5192ac6082b/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c", size = 1716590, upload-time = "2025-07-29T05:50:51.368Z" }, + { url = "https://files.pythonhosted.org/packages/79/b1/60370d70cdf8b269ee1444b390cbd72ce514f0d1cd1a715821c784d272c9/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0", size = 1699241, upload-time = "2025-07-29T05:50:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2b/4968a7b8792437ebc12186db31523f541943e99bda8f30335c482bea6879/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab", size = 1754335, upload-time = "2025-07-29T05:50:55.394Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c1/49524ed553f9a0bec1a11fac09e790f49ff669bcd14164f9fab608831c4d/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb", size = 1800491, upload-time = "2025-07-29T05:50:57.202Z" }, + { url = "https://files.pythonhosted.org/packages/de/5e/3bf5acea47a96a28c121b167f5ef659cf71208b19e52a88cdfa5c37f1fcc/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545", size = 1719929, upload-time = "2025-07-29T05:50:59.192Z" }, + { url = "https://files.pythonhosted.org/packages/39/94/8ae30b806835bcd1cba799ba35347dee6961a11bd507db634516210e91d8/aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c", size = 1635733, upload-time = "2025-07-29T05:51:01.394Z" }, + { url = "https://files.pythonhosted.org/packages/7a/46/06cdef71dd03acd9da7f51ab3a9107318aee12ad38d273f654e4f981583a/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd", size = 1696790, upload-time = "2025-07-29T05:51:03.657Z" }, + { url = "https://files.pythonhosted.org/packages/02/90/6b4cfaaf92ed98d0ec4d173e78b99b4b1a7551250be8937d9d67ecb356b4/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f", size = 1718245, upload-time = "2025-07-29T05:51:05.911Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e6/2593751670fa06f080a846f37f112cbe6f873ba510d070136a6ed46117c6/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d", size = 1658899, upload-time = "2025-07-29T05:51:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/8f/28/c15bacbdb8b8eb5bf39b10680d129ea7410b859e379b03190f02fa104ffd/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519", size = 1738459, upload-time = "2025-07-29T05:51:09.56Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/c269cbc4faa01fb10f143b1670633a8ddd5b2e1ffd0548f7aa49cb5c70e2/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea", size = 1766434, upload-time = "2025-07-29T05:51:11.423Z" }, + { url = "https://files.pythonhosted.org/packages/52/b0/4ff3abd81aa7d929b27d2e1403722a65fc87b763e3a97b3a2a494bfc63bc/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3", size = 1726045, upload-time = "2025-07-29T05:51:13.689Z" }, + { url = "https://files.pythonhosted.org/packages/71/16/949225a6a2dd6efcbd855fbd90cf476052e648fb011aa538e3b15b89a57a/aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1", size = 423591, upload-time = "2025-07-29T05:51:15.452Z" }, + { url = "https://files.pythonhosted.org/packages/2b/d8/fa65d2a349fe938b76d309db1a56a75c4fb8cc7b17a398b698488a939903/aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34", size = 450266, upload-time = "2025-07-29T05:51:17.239Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "aiosqlite" +version = "0.21.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/13/7d/8bca2bf9a247c2c5dfeec1d7a5f40db6518f88d314b8bca9da29670d2671/aiosqlite-0.21.0.tar.gz", hash = "sha256:131bb8056daa3bc875608c631c678cda73922a2d4ba8aec373b19f18c17e7aa3", size = 13454, upload-time = "2025-02-03T07:30:16.235Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0", size = 15792, upload-time = "2025-02-03T07:30:13.6Z" }, +] + +[[package]] +name = "anyio" +version = "4.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "sniffio" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6", size = 213252, upload-time = "2025-08-04T08:54:26.451Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" }, +] + +[[package]] +name = "asn1crypto" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/de/cf/d547feed25b5244fcb9392e288ff9fdc3280b10260362fc45d37a798a6ee/asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c", size = 121080, upload-time = "2022-03-15T14:46:52.889Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67", size = 105045, upload-time = "2022-03-15T14:46:51.055Z" }, +] + +[[package]] +name = "async-timeout" +version = "5.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274, upload-time = "2024-11-06T16:41:39.6Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233, upload-time = "2024-11-06T16:41:37.9Z" }, +] + +[[package]] +name = "asyncpg" +version = "0.30.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-timeout", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746, upload-time = "2024-10-20T00:30:41.127Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/07/1650a8c30e3a5c625478fa8aafd89a8dd7d85999bf7169b16f54973ebf2c/asyncpg-0.30.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfb4dd5ae0699bad2b233672c8fc5ccbd9ad24b89afded02341786887e37927e", size = 673143, upload-time = "2024-10-20T00:29:08.846Z" }, + { url = "https://files.pythonhosted.org/packages/a0/9a/568ff9b590d0954553c56806766914c149609b828c426c5118d4869111d3/asyncpg-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc1f62c792752a49f88b7e6f774c26077091b44caceb1983509edc18a2222ec0", size = 645035, upload-time = "2024-10-20T00:29:12.02Z" }, + { url = "https://files.pythonhosted.org/packages/de/11/6f2fa6c902f341ca10403743701ea952bca896fc5b07cc1f4705d2bb0593/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3152fef2e265c9c24eec4ee3d22b4f4d2703d30614b0b6753e9ed4115c8a146f", size = 2912384, upload-time = "2024-10-20T00:29:13.644Z" }, + { url = "https://files.pythonhosted.org/packages/83/83/44bd393919c504ffe4a82d0aed8ea0e55eb1571a1dea6a4922b723f0a03b/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7255812ac85099a0e1ffb81b10dc477b9973345793776b128a23e60148dd1af", size = 2947526, upload-time = "2024-10-20T00:29:15.871Z" }, + { url = "https://files.pythonhosted.org/packages/08/85/e23dd3a2b55536eb0ded80c457b0693352262dc70426ef4d4a6fc994fa51/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:578445f09f45d1ad7abddbff2a3c7f7c291738fdae0abffbeb737d3fc3ab8b75", size = 2895390, upload-time = "2024-10-20T00:29:19.346Z" }, + { url = "https://files.pythonhosted.org/packages/9b/26/fa96c8f4877d47dc6c1864fef5500b446522365da3d3d0ee89a5cce71a3f/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c42f6bb65a277ce4d93f3fba46b91a265631c8df7250592dd4f11f8b0152150f", size = 3015630, upload-time = "2024-10-20T00:29:21.186Z" }, + { url = "https://files.pythonhosted.org/packages/34/00/814514eb9287614188a5179a8b6e588a3611ca47d41937af0f3a844b1b4b/asyncpg-0.30.0-cp310-cp310-win32.whl", hash = "sha256:aa403147d3e07a267ada2ae34dfc9324e67ccc4cdca35261c8c22792ba2b10cf", size = 568760, upload-time = "2024-10-20T00:29:22.769Z" }, + { url = "https://files.pythonhosted.org/packages/f0/28/869a7a279400f8b06dd237266fdd7220bc5f7c975348fea5d1e6909588e9/asyncpg-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb622c94db4e13137c4c7f98834185049cc50ee01d8f657ef898b6407c7b9c50", size = 625764, upload-time = "2024-10-20T00:29:25.882Z" }, + { url = "https://files.pythonhosted.org/packages/4c/0e/f5d708add0d0b97446c402db7e8dd4c4183c13edaabe8a8500b411e7b495/asyncpg-0.30.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5e0511ad3dec5f6b4f7a9e063591d407eee66b88c14e2ea636f187da1dcfff6a", size = 674506, upload-time = "2024-10-20T00:29:27.988Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a0/67ec9a75cb24a1d99f97b8437c8d56da40e6f6bd23b04e2f4ea5d5ad82ac/asyncpg-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:915aeb9f79316b43c3207363af12d0e6fd10776641a7de8a01212afd95bdf0ed", size = 645922, upload-time = "2024-10-20T00:29:29.391Z" }, + { url = "https://files.pythonhosted.org/packages/5c/d9/a7584f24174bd86ff1053b14bb841f9e714380c672f61c906eb01d8ec433/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c198a00cce9506fcd0bf219a799f38ac7a237745e1d27f0e1f66d3707c84a5a", size = 3079565, upload-time = "2024-10-20T00:29:30.832Z" }, + { url = "https://files.pythonhosted.org/packages/a0/d7/a4c0f9660e333114bdb04d1a9ac70db690dd4ae003f34f691139a5cbdae3/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3326e6d7381799e9735ca2ec9fd7be4d5fef5dcbc3cb555d8a463d8460607956", size = 3109962, upload-time = "2024-10-20T00:29:33.114Z" }, + { url = "https://files.pythonhosted.org/packages/3c/21/199fd16b5a981b1575923cbb5d9cf916fdc936b377e0423099f209e7e73d/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51da377487e249e35bd0859661f6ee2b81db11ad1f4fc036194bc9cb2ead5056", size = 3064791, upload-time = "2024-10-20T00:29:34.677Z" }, + { url = "https://files.pythonhosted.org/packages/77/52/0004809b3427534a0c9139c08c87b515f1c77a8376a50ae29f001e53962f/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc6d84136f9c4d24d358f3b02be4b6ba358abd09f80737d1ac7c444f36108454", size = 3188696, upload-time = "2024-10-20T00:29:36.389Z" }, + { url = "https://files.pythonhosted.org/packages/52/cb/fbad941cd466117be58b774a3f1cc9ecc659af625f028b163b1e646a55fe/asyncpg-0.30.0-cp311-cp311-win32.whl", hash = "sha256:574156480df14f64c2d76450a3f3aaaf26105869cad3865041156b38459e935d", size = 567358, upload-time = "2024-10-20T00:29:37.915Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0a/0a32307cf166d50e1ad120d9b81a33a948a1a5463ebfa5a96cc5606c0863/asyncpg-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:3356637f0bd830407b5597317b3cb3571387ae52ddc3bca6233682be88bbbc1f", size = 629375, upload-time = "2024-10-20T00:29:39.987Z" }, + { url = "https://files.pythonhosted.org/packages/4b/64/9d3e887bb7b01535fdbc45fbd5f0a8447539833b97ee69ecdbb7a79d0cb4/asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e", size = 673162, upload-time = "2024-10-20T00:29:41.88Z" }, + { url = "https://files.pythonhosted.org/packages/6e/eb/8b236663f06984f212a087b3e849731f917ab80f84450e943900e8ca4052/asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a", size = 637025, upload-time = "2024-10-20T00:29:43.352Z" }, + { url = "https://files.pythonhosted.org/packages/cc/57/2dc240bb263d58786cfaa60920779af6e8d32da63ab9ffc09f8312bd7a14/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3", size = 3496243, upload-time = "2024-10-20T00:29:44.922Z" }, + { url = "https://files.pythonhosted.org/packages/f4/40/0ae9d061d278b10713ea9021ef6b703ec44698fe32178715a501ac696c6b/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737", size = 3575059, upload-time = "2024-10-20T00:29:46.891Z" }, + { url = "https://files.pythonhosted.org/packages/c3/75/d6b895a35a2c6506952247640178e5f768eeb28b2e20299b6a6f1d743ba0/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a", size = 3473596, upload-time = "2024-10-20T00:29:49.201Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e7/3693392d3e168ab0aebb2d361431375bd22ffc7b4a586a0fc060d519fae7/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af", size = 3641632, upload-time = "2024-10-20T00:29:50.768Z" }, + { url = "https://files.pythonhosted.org/packages/32/ea/15670cea95745bba3f0352341db55f506a820b21c619ee66b7d12ea7867d/asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e", size = 560186, upload-time = "2024-10-20T00:29:52.394Z" }, + { url = "https://files.pythonhosted.org/packages/7e/6b/fe1fad5cee79ca5f5c27aed7bd95baee529c1bf8a387435c8ba4fe53d5c1/asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305", size = 621064, upload-time = "2024-10-20T00:29:53.757Z" }, +] + +[[package]] +name = "attrs" +version = "25.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, +] + +[[package]] +name = "backports-asyncio-runner" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893, upload-time = "2025-07-02T02:27:15.685Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, +] + +[[package]] +name = "backports-datetime-fromisoformat" +version = "2.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/81/eff3184acb1d9dc3ce95a98b6f3c81a49b4be296e664db8e1c2eeabef3d9/backports_datetime_fromisoformat-2.0.3.tar.gz", hash = "sha256:b58edc8f517b66b397abc250ecc737969486703a66eb97e01e6d51291b1a139d", size = 23588, upload-time = "2024-12-28T20:18:15.017Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/4b/d6b051ca4b3d76f23c2c436a9669f3be616b8cf6461a7e8061c7c4269642/backports_datetime_fromisoformat-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f681f638f10588fa3c101ee9ae2b63d3734713202ddfcfb6ec6cea0778a29d4", size = 27561, upload-time = "2024-12-28T20:16:47.974Z" }, + { url = "https://files.pythonhosted.org/packages/6d/40/e39b0d471e55eb1b5c7c81edab605c02f71c786d59fb875f0a6f23318747/backports_datetime_fromisoformat-2.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:cd681460e9142f1249408e5aee6d178c6d89b49e06d44913c8fdfb6defda8d1c", size = 34448, upload-time = "2024-12-28T20:16:50.712Z" }, + { url = "https://files.pythonhosted.org/packages/f2/28/7a5c87c5561d14f1c9af979231fdf85d8f9fad7a95ff94e56d2205e2520a/backports_datetime_fromisoformat-2.0.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:ee68bc8735ae5058695b76d3bb2aee1d137c052a11c8303f1e966aa23b72b65b", size = 27093, upload-time = "2024-12-28T20:16:52.994Z" }, + { url = "https://files.pythonhosted.org/packages/80/ba/f00296c5c4536967c7d1136107fdb91c48404fe769a4a6fd5ab045629af8/backports_datetime_fromisoformat-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8273fe7932db65d952a43e238318966eab9e49e8dd546550a41df12175cc2be4", size = 52836, upload-time = "2024-12-28T20:16:55.283Z" }, + { url = "https://files.pythonhosted.org/packages/e3/92/bb1da57a069ddd601aee352a87262c7ae93467e66721d5762f59df5021a6/backports_datetime_fromisoformat-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39d57ea50aa5a524bb239688adc1d1d824c31b6094ebd39aa164d6cadb85de22", size = 52798, upload-time = "2024-12-28T20:16:56.64Z" }, + { url = "https://files.pythonhosted.org/packages/df/ef/b6cfd355982e817ccdb8d8d109f720cab6e06f900784b034b30efa8fa832/backports_datetime_fromisoformat-2.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ac6272f87693e78209dc72e84cf9ab58052027733cd0721c55356d3c881791cf", size = 52891, upload-time = "2024-12-28T20:16:58.887Z" }, + { url = "https://files.pythonhosted.org/packages/37/39/b13e3ae8a7c5d88b68a6e9248ffe7066534b0cfe504bf521963e61b6282d/backports_datetime_fromisoformat-2.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:44c497a71f80cd2bcfc26faae8857cf8e79388e3d5fbf79d2354b8c360547d58", size = 52955, upload-time = "2024-12-28T20:17:00.028Z" }, + { url = "https://files.pythonhosted.org/packages/1e/e4/70cffa3ce1eb4f2ff0c0d6f5d56285aacead6bd3879b27a2ba57ab261172/backports_datetime_fromisoformat-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:6335a4c9e8af329cb1ded5ab41a666e1448116161905a94e054f205aa6d263bc", size = 29323, upload-time = "2024-12-28T20:17:01.125Z" }, + { url = "https://files.pythonhosted.org/packages/62/f5/5bc92030deadf34c365d908d4533709341fb05d0082db318774fdf1b2bcb/backports_datetime_fromisoformat-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2e4b66e017253cdbe5a1de49e0eecff3f66cd72bcb1229d7db6e6b1832c0443", size = 27626, upload-time = "2024-12-28T20:17:03.448Z" }, + { url = "https://files.pythonhosted.org/packages/28/45/5885737d51f81dfcd0911dd5c16b510b249d4c4cf6f4a991176e0358a42a/backports_datetime_fromisoformat-2.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:43e2d648e150777e13bbc2549cc960373e37bf65bd8a5d2e0cef40e16e5d8dd0", size = 34588, upload-time = "2024-12-28T20:17:04.459Z" }, + { url = "https://files.pythonhosted.org/packages/bc/6d/bd74de70953f5dd3e768c8fc774af942af0ce9f211e7c38dd478fa7ea910/backports_datetime_fromisoformat-2.0.3-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:4ce6326fd86d5bae37813c7bf1543bae9e4c215ec6f5afe4c518be2635e2e005", size = 27162, upload-time = "2024-12-28T20:17:06.752Z" }, + { url = "https://files.pythonhosted.org/packages/47/ba/1d14b097f13cce45b2b35db9898957578b7fcc984e79af3b35189e0d332f/backports_datetime_fromisoformat-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7c8fac333bf860208fd522a5394369ee3c790d0aa4311f515fcc4b6c5ef8d75", size = 54482, upload-time = "2024-12-28T20:17:08.15Z" }, + { url = "https://files.pythonhosted.org/packages/25/e9/a2a7927d053b6fa148b64b5e13ca741ca254c13edca99d8251e9a8a09cfe/backports_datetime_fromisoformat-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24a4da5ab3aa0cc293dc0662a0c6d1da1a011dc1edcbc3122a288cfed13a0b45", size = 54362, upload-time = "2024-12-28T20:17:10.605Z" }, + { url = "https://files.pythonhosted.org/packages/c1/99/394fb5e80131a7d58c49b89e78a61733a9994885804a0bb582416dd10c6f/backports_datetime_fromisoformat-2.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:58ea11e3bf912bd0a36b0519eae2c5b560b3cb972ea756e66b73fb9be460af01", size = 54162, upload-time = "2024-12-28T20:17:12.301Z" }, + { url = "https://files.pythonhosted.org/packages/88/25/1940369de573c752889646d70b3fe8645e77b9e17984e72a554b9b51ffc4/backports_datetime_fromisoformat-2.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8a375c7dbee4734318714a799b6c697223e4bbb57232af37fbfff88fb48a14c6", size = 54118, upload-time = "2024-12-28T20:17:13.609Z" }, + { url = "https://files.pythonhosted.org/packages/b7/46/f275bf6c61683414acaf42b2df7286d68cfef03e98b45c168323d7707778/backports_datetime_fromisoformat-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:ac677b1664c4585c2e014739f6678137c8336815406052349c85898206ec7061", size = 29329, upload-time = "2024-12-28T20:17:16.124Z" }, + { url = "https://files.pythonhosted.org/packages/a2/0f/69bbdde2e1e57c09b5f01788804c50e68b29890aada999f2b1a40519def9/backports_datetime_fromisoformat-2.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66ce47ee1ba91e146149cf40565c3d750ea1be94faf660ca733d8601e0848147", size = 27630, upload-time = "2024-12-28T20:17:19.442Z" }, + { url = "https://files.pythonhosted.org/packages/d5/1d/1c84a50c673c87518b1adfeafcfd149991ed1f7aedc45d6e5eac2f7d19d7/backports_datetime_fromisoformat-2.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:8b7e069910a66b3bba61df35b5f879e5253ff0821a70375b9daf06444d046fa4", size = 34707, upload-time = "2024-12-28T20:17:21.79Z" }, + { url = "https://files.pythonhosted.org/packages/71/44/27eae384e7e045cda83f70b551d04b4a0b294f9822d32dea1cbf1592de59/backports_datetime_fromisoformat-2.0.3-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:a3b5d1d04a9e0f7b15aa1e647c750631a873b298cdd1255687bb68779fe8eb35", size = 27280, upload-time = "2024-12-28T20:17:24.503Z" }, + { url = "https://files.pythonhosted.org/packages/a7/7a/a4075187eb6bbb1ff6beb7229db5f66d1070e6968abeb61e056fa51afa5e/backports_datetime_fromisoformat-2.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec1b95986430e789c076610aea704db20874f0781b8624f648ca9fb6ef67c6e1", size = 55094, upload-time = "2024-12-28T20:17:25.546Z" }, + { url = "https://files.pythonhosted.org/packages/71/03/3fced4230c10af14aacadc195fe58e2ced91d011217b450c2e16a09a98c8/backports_datetime_fromisoformat-2.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffe5f793db59e2f1d45ec35a1cf51404fdd69df9f6952a0c87c3060af4c00e32", size = 55605, upload-time = "2024-12-28T20:17:29.208Z" }, + { url = "https://files.pythonhosted.org/packages/f6/0a/4b34a838c57bd16d3e5861ab963845e73a1041034651f7459e9935289cfd/backports_datetime_fromisoformat-2.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:620e8e73bd2595dfff1b4d256a12b67fce90ece3de87b38e1dde46b910f46f4d", size = 55353, upload-time = "2024-12-28T20:17:32.433Z" }, + { url = "https://files.pythonhosted.org/packages/d9/68/07d13c6e98e1cad85606a876367ede2de46af859833a1da12c413c201d78/backports_datetime_fromisoformat-2.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4cf9c0a985d68476c1cabd6385c691201dda2337d7453fb4da9679ce9f23f4e7", size = 55298, upload-time = "2024-12-28T20:17:34.919Z" }, + { url = "https://files.pythonhosted.org/packages/60/33/45b4d5311f42360f9b900dea53ab2bb20a3d61d7f9b7c37ddfcb3962f86f/backports_datetime_fromisoformat-2.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:d144868a73002e6e2e6fef72333e7b0129cecdd121aa8f1edba7107fd067255d", size = 29375, upload-time = "2024-12-28T20:17:36.018Z" }, + { url = "https://files.pythonhosted.org/packages/be/03/7eaa9f9bf290395d57fd30d7f1f2f9dff60c06a31c237dc2beb477e8f899/backports_datetime_fromisoformat-2.0.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90e202e72a3d5aae673fcc8c9a4267d56b2f532beeb9173361293625fe4d2039", size = 28980, upload-time = "2024-12-28T20:18:06.554Z" }, + { url = "https://files.pythonhosted.org/packages/47/80/a0ecf33446c7349e79f54cc532933780341d20cff0ee12b5bfdcaa47067e/backports_datetime_fromisoformat-2.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2df98ef1b76f5a58bb493dda552259ba60c3a37557d848e039524203951c9f06", size = 28449, upload-time = "2024-12-28T20:18:07.77Z" }, +] + +[[package]] +name = "base58" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7f/45/8ae61209bb9015f516102fa559a2914178da1d5868428bd86a1b4421141d/base58-2.1.1.tar.gz", hash = "sha256:c5d0cb3f5b6e81e8e35da5754388ddcc6d0d14b6c6a132cb93d69ed580a7278c", size = 6528, upload-time = "2021-10-30T22:12:17.858Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/45/ec96b29162a402fc4c1c5512d114d7b3787b9d1c2ec241d9568b4816ee23/base58-2.1.1-py3-none-any.whl", hash = "sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2", size = 5621, upload-time = "2021-10-30T22:12:16.658Z" }, +] + +[[package]] +name = "bcrypt" +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/5d/6d7433e0f3cd46ce0b43cd65e1db465ea024dbb8216fb2404e919c2ad77b/bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18", size = 25697, upload-time = "2025-02-28T01:24:09.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/22/5ada0b9af72b60cbc4c9a399fdde4af0feaa609d27eb0adc61607997a3fa/bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d", size = 498019, upload-time = "2025-02-28T01:23:05.838Z" }, + { url = "https://files.pythonhosted.org/packages/b8/8c/252a1edc598dc1ce57905be173328eda073083826955ee3c97c7ff5ba584/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b", size = 279174, upload-time = "2025-02-28T01:23:07.274Z" }, + { url = "https://files.pythonhosted.org/packages/29/5b/4547d5c49b85f0337c13929f2ccbe08b7283069eea3550a457914fc078aa/bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e", size = 283870, upload-time = "2025-02-28T01:23:09.151Z" }, + { url = "https://files.pythonhosted.org/packages/be/21/7dbaf3fa1745cb63f776bb046e481fbababd7d344c5324eab47f5ca92dd2/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59", size = 279601, upload-time = "2025-02-28T01:23:11.461Z" }, + { url = "https://files.pythonhosted.org/packages/6d/64/e042fc8262e971347d9230d9abbe70d68b0a549acd8611c83cebd3eaec67/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753", size = 297660, upload-time = "2025-02-28T01:23:12.989Z" }, + { url = "https://files.pythonhosted.org/packages/50/b8/6294eb84a3fef3b67c69b4470fcdd5326676806bf2519cda79331ab3c3a9/bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761", size = 284083, upload-time = "2025-02-28T01:23:14.5Z" }, + { url = "https://files.pythonhosted.org/packages/62/e6/baff635a4f2c42e8788fe1b1633911c38551ecca9a749d1052d296329da6/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb", size = 279237, upload-time = "2025-02-28T01:23:16.686Z" }, + { url = "https://files.pythonhosted.org/packages/39/48/46f623f1b0c7dc2e5de0b8af5e6f5ac4cc26408ac33f3d424e5ad8da4a90/bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d", size = 283737, upload-time = "2025-02-28T01:23:18.897Z" }, + { url = "https://files.pythonhosted.org/packages/49/8b/70671c3ce9c0fca4a6cc3cc6ccbaa7e948875a2e62cbd146e04a4011899c/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f", size = 312741, upload-time = "2025-02-28T01:23:21.041Z" }, + { url = "https://files.pythonhosted.org/packages/27/fb/910d3a1caa2d249b6040a5caf9f9866c52114d51523ac2fb47578a27faee/bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732", size = 316472, upload-time = "2025-02-28T01:23:23.183Z" }, + { url = "https://files.pythonhosted.org/packages/dc/cf/7cf3a05b66ce466cfb575dbbda39718d45a609daa78500f57fa9f36fa3c0/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef", size = 343606, upload-time = "2025-02-28T01:23:25.361Z" }, + { url = "https://files.pythonhosted.org/packages/e3/b8/e970ecc6d7e355c0d892b7f733480f4aa8509f99b33e71550242cf0b7e63/bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304", size = 362867, upload-time = "2025-02-28T01:23:26.875Z" }, + { url = "https://files.pythonhosted.org/packages/a9/97/8d3118efd8354c555a3422d544163f40d9f236be5b96c714086463f11699/bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51", size = 160589, upload-time = "2025-02-28T01:23:28.381Z" }, + { url = "https://files.pythonhosted.org/packages/29/07/416f0b99f7f3997c69815365babbc2e8754181a4b1899d921b3c7d5b6f12/bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62", size = 152794, upload-time = "2025-02-28T01:23:30.187Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c1/3fa0e9e4e0bfd3fd77eb8b52ec198fd6e1fd7e9402052e43f23483f956dd/bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3", size = 498969, upload-time = "2025-02-28T01:23:31.945Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d4/755ce19b6743394787fbd7dff6bf271b27ee9b5912a97242e3caf125885b/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24", size = 279158, upload-time = "2025-02-28T01:23:34.161Z" }, + { url = "https://files.pythonhosted.org/packages/9b/5d/805ef1a749c965c46b28285dfb5cd272a7ed9fa971f970435a5133250182/bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef", size = 284285, upload-time = "2025-02-28T01:23:35.765Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2b/698580547a4a4988e415721b71eb45e80c879f0fb04a62da131f45987b96/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b", size = 279583, upload-time = "2025-02-28T01:23:38.021Z" }, + { url = "https://files.pythonhosted.org/packages/f2/87/62e1e426418204db520f955ffd06f1efd389feca893dad7095bf35612eec/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676", size = 297896, upload-time = "2025-02-28T01:23:39.575Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c6/8fedca4c2ada1b6e889c52d2943b2f968d3427e5d65f595620ec4c06fa2f/bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1", size = 284492, upload-time = "2025-02-28T01:23:40.901Z" }, + { url = "https://files.pythonhosted.org/packages/4d/4d/c43332dcaaddb7710a8ff5269fcccba97ed3c85987ddaa808db084267b9a/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe", size = 279213, upload-time = "2025-02-28T01:23:42.653Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/1e36379e169a7df3a14a1c160a49b7b918600a6008de43ff20d479e6f4b5/bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0", size = 284162, upload-time = "2025-02-28T01:23:43.964Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0a/644b2731194b0d7646f3210dc4d80c7fee3ecb3a1f791a6e0ae6bb8684e3/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f", size = 312856, upload-time = "2025-02-28T01:23:46.011Z" }, + { url = "https://files.pythonhosted.org/packages/dc/62/2a871837c0bb6ab0c9a88bf54de0fc021a6a08832d4ea313ed92a669d437/bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23", size = 316726, upload-time = "2025-02-28T01:23:47.575Z" }, + { url = "https://files.pythonhosted.org/packages/0c/a1/9898ea3faac0b156d457fd73a3cb9c2855c6fd063e44b8522925cdd8ce46/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe", size = 343664, upload-time = "2025-02-28T01:23:49.059Z" }, + { url = "https://files.pythonhosted.org/packages/40/f2/71b4ed65ce38982ecdda0ff20c3ad1b15e71949c78b2c053df53629ce940/bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505", size = 363128, upload-time = "2025-02-28T01:23:50.399Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/12f6a58eca6dea4be992d6c681b7ec9410a1d9f5cf368c61437e31daa879/bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a", size = 160598, upload-time = "2025-02-28T01:23:51.775Z" }, + { url = "https://files.pythonhosted.org/packages/a9/cf/45fb5261ece3e6b9817d3d82b2f343a505fd58674a92577923bc500bd1aa/bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b", size = 152799, upload-time = "2025-02-28T01:23:53.139Z" }, + { url = "https://files.pythonhosted.org/packages/55/2d/0c7e5ab0524bf1a443e34cdd3926ec6f5879889b2f3c32b2f5074e99ed53/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c950d682f0952bafcceaf709761da0a32a942272fad381081b51096ffa46cea1", size = 275367, upload-time = "2025-02-28T01:23:54.578Z" }, + { url = "https://files.pythonhosted.org/packages/10/4f/f77509f08bdff8806ecc4dc472b6e187c946c730565a7470db772d25df70/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:107d53b5c67e0bbc3f03ebf5b030e0403d24dda980f8e244795335ba7b4a027d", size = 280644, upload-time = "2025-02-28T01:23:56.547Z" }, + { url = "https://files.pythonhosted.org/packages/35/18/7d9dc16a3a4d530d0a9b845160e9e5d8eb4f00483e05d44bb4116a1861da/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b693dbb82b3c27a1604a3dff5bfc5418a7e6a781bb795288141e5f80cf3a3492", size = 274881, upload-time = "2025-02-28T01:23:57.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/c4/ae6921088adf1e37f2a3a6a688e72e7d9e45fdd3ae5e0bc931870c1ebbda/bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:b6354d3760fcd31994a14c89659dee887f1351a06e5dac3c1142307172a79f90", size = 280203, upload-time = "2025-02-28T01:23:59.331Z" }, + { url = "https://files.pythonhosted.org/packages/4c/b1/1289e21d710496b88340369137cc4c5f6ee036401190ea116a7b4ae6d32a/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a839320bf27d474e52ef8cb16449bb2ce0ba03ca9f44daba6d93fa1d8828e48a", size = 275103, upload-time = "2025-02-28T01:24:00.764Z" }, + { url = "https://files.pythonhosted.org/packages/94/41/19be9fe17e4ffc5d10b7b67f10e459fc4eee6ffe9056a88de511920cfd8d/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:bdc6a24e754a555d7316fa4774e64c6c3997d27ed2d1964d55920c7c227bc4ce", size = 280513, upload-time = "2025-02-28T01:24:02.243Z" }, + { url = "https://files.pythonhosted.org/packages/aa/73/05687a9ef89edebdd8ad7474c16d8af685eb4591c3c38300bb6aad4f0076/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:55a935b8e9a1d2def0626c4269db3fcd26728cbff1e84f0341465c31c4ee56d8", size = 274685, upload-time = "2025-02-28T01:24:04.512Z" }, + { url = "https://files.pythonhosted.org/packages/63/13/47bba97924ebe86a62ef83dc75b7c8a881d53c535f83e2c54c4bd701e05c/bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:57967b7a28d855313a963aaea51bf6df89f833db4320da458e5b3c5ab6d4c938", size = 280110, upload-time = "2025-02-28T01:24:05.896Z" }, +] + +[[package]] +name = "bech32" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/fe/b67ac9b123e25a3c1b8fc3f3c92648804516ab44215adb165284e024c43f/bech32-1.2.0.tar.gz", hash = "sha256:7d6db8214603bd7871fcfa6c0826ef68b85b0abd90fa21c285a9c5e21d2bd899", size = 3695, upload-time = "2020-02-17T15:31:09.763Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/41/7022a226e5a6ac7091a95ba36bad057012ab7330b9894ad4e14e31d0b858/bech32-1.2.0-py3-none-any.whl", hash = "sha256:990dc8e5a5e4feabbdf55207b5315fdd9b73db40be294a19b3752cde9e79d981", size = 4587, upload-time = "2020-02-17T15:31:08.299Z" }, +] + +[[package]] +name = "bip32" +version = "4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coincurve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4a/37/b69968b1b6eaea1fedb8efdb1862d86e92b6f68e182f39c764f894984db5/bip32-4.0.tar.gz", hash = "sha256:8035588f252f569bb414bc60df151ae431fc1c6789a19488a32890532ef3a2fc", size = 21662, upload-time = "2024-09-07T12:40:26.388Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/bd/dcf1650776a241c10a2bc6826b6e23ff63bf55373bb053b716c69c463758/bip32-4.0-py3-none-any.whl", hash = "sha256:9728b38336129c00e1f870bbb3e328c9632d51c1bddeef4011fd3115cb3aeff9", size = 12898, upload-time = "2024-09-07T12:40:25.358Z" }, +] + +[[package]] +name = "bitarray" +version = "3.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/99/b6/282f5f0331b3877d4e79a8aa1cf63b5113a10f035a39bef1fa1dfe9e9e09/bitarray-3.7.1.tar.gz", hash = "sha256:795b1760418ab750826420ae24f06f392c08e21dc234f0a369a69cc00444f8ec", size = 150474, upload-time = "2025-08-28T22:18:15.346Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/98/bafe556fe4d97a975fa5c31965aaa282388cc91073aca57a2de206745b11/bitarray-3.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a05982bb49c73463cb0f0f4bed2d8da82631708a2c2d1926107ba99651b419ec", size = 147651, upload-time = "2025-08-28T22:14:53.043Z" }, + { url = "https://files.pythonhosted.org/packages/03/87/639c1e4d869ecd7c23d517c326bfee7ab43ade5d5bd0f6ad3373edc861a8/bitarray-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d30e7daaf228e3d69cdd8b02c0dd4199cec034c4b93c80109f56f4675a6db957", size = 143967, upload-time = "2025-08-28T22:14:55.333Z" }, + { url = "https://files.pythonhosted.org/packages/24/e9/8248a05b35f3e3667ceb103febb0d687d3f7314e4692b2048d21ed943a4e/bitarray-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:160f449bb91686f8fc9984200e78b8d793b79e382decf7eb1dc9948d7c21b36f", size = 319901, upload-time = "2025-08-28T22:14:56.742Z" }, + { url = "https://files.pythonhosted.org/packages/de/e8/47f9d8eebb793b6828baf76027b9eefc4e5e09f32b84a25821c4bc19c3c4/bitarray-3.7.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6542e1cfe060badd160cd383ad93a84871595c14bb05fb8129f963248affd946", size = 339005, upload-time = "2025-08-28T22:14:58.291Z" }, + { url = "https://files.pythonhosted.org/packages/61/73/2c4695e5acd89d9904c5b3bea7b5b06df86dea15653eee6008881d18a632/bitarray-3.7.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b723f9d10f7d8259f010b87fa66e924bb4d67927d9dcff4526a755e9ee84fef4", size = 329495, upload-time = "2025-08-28T22:14:59.722Z" }, + { url = "https://files.pythonhosted.org/packages/0f/d9/dc17b9f5b7b750dc9183db0520e197f1ca635dedd48e37ad00ca450d2fab/bitarray-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca4b6298c89b92d6b0a67dfc5f98d68ae92b08101d227263ef2033b9c9a03a72", size = 322141, upload-time = "2025-08-28T22:15:00.829Z" }, + { url = "https://files.pythonhosted.org/packages/a7/45/8fb00265c1b0313070e0a4b09a2f585fd3ee174aaa5352d971069983c983/bitarray-3.7.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:567d6891cb1ddbfd0051fcff3cb1bb86efc82ec818d9c5f98c37d59c1d23cc96", size = 310422, upload-time = "2025-08-28T22:15:01.964Z" }, + { url = "https://files.pythonhosted.org/packages/f6/77/04cb016694ae16ffe1a146f1a764b79e71f3ddbc7b9d78069594507c9762/bitarray-3.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:37a6a8382864a1defb5b370b66a635e04358c7334054457bbbb8645610cd95b2", size = 314796, upload-time = "2025-08-28T22:15:04.468Z" }, + { url = "https://files.pythonhosted.org/packages/b5/4f/8e15934995c5362e645ea27d9521e6b29953dc9f8df59e74525c8022e347/bitarray-3.7.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:01e3ba46c2dee6d47a4ab22561a01d8ee6772f681defc9fcb357097a055e48cf", size = 311222, upload-time = "2025-08-28T22:15:05.846Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d2/9cc6df1ab5b9d10904bf78820e2427cf9b373376ca82af64a0b31eff7b31/bitarray-3.7.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:477b9456eb7d70f385dc8f097a1d66ee40771b62e47b3b3e33406dcfbc1c6a3b", size = 339685, upload-time = "2025-08-28T22:15:06.992Z" }, + { url = "https://files.pythonhosted.org/packages/ed/6d/b79e5e545a928270445c6916cf2d7613a8a8434eee8de023c900a0a08e15/bitarray-3.7.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2965fd8ba31b04c42e4b696fad509dc5ab50663efca6eb06bb3b6d08587f3a09", size = 339660, upload-time = "2025-08-28T22:15:08.068Z" }, + { url = "https://files.pythonhosted.org/packages/e9/33/8b836518ba16a85c75c177aa0d6658e843b4b0c1ec5994fb9f1b28e9440d/bitarray-3.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc76ad7453816318d794248fba4032967eaffd992d76e5d1af10ef9d46589770", size = 320079, upload-time = "2025-08-28T22:15:09.276Z" }, + { url = "https://files.pythonhosted.org/packages/7b/8e/87603ccf798c99296fdb26b9297350f44f87cb2aced76d3b8b0446ac8cd2/bitarray-3.7.1-cp310-cp310-win32.whl", hash = "sha256:d3f38373d9b2629dedc559e647010541cc4ec4ad9bea560e2eb1017e6a00d9ef", size = 141228, upload-time = "2025-08-28T22:15:10.383Z" }, + { url = "https://files.pythonhosted.org/packages/50/06/7003c5520d2bb36edb68b016b1a83ddd5946da67b9d9982b12a8ef68d706/bitarray-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:e39f5e85e1e3d7d84ac2217cd095b3678306c979e991532df47012880e02215d", size = 147988, upload-time = "2025-08-28T22:15:11.718Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0b/6fc7221d6d6508b2648f2b99dda9188dc46640023e6c2d3fb78070013901/bitarray-3.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac39319e6322c2c093a660c02cea6bb3b1ae53d049b573d4781df8896e443e04", size = 147645, upload-time = "2025-08-28T22:15:12.966Z" }, + { url = "https://files.pythonhosted.org/packages/43/96/122ef83579cde311e77d5da284b71dfb5ab1c38250b6a97a4f4adae4ef5a/bitarray-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a43f4631ecb87bedc510568fef67db53f2a20c4a5953a9d1e07457e7b1d14911", size = 143971, upload-time = "2025-08-28T22:15:14.374Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f9/cd0e27f8399b930fcea8b87b36de0ba8c88e8f953dbc98e81ca322352d24/bitarray-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd112646486a31ea5a45aa1eca0e2cd90b6a12f67e848e50349e324c24cc2e7", size = 327521, upload-time = "2025-08-28T22:15:15.381Z" }, + { url = "https://files.pythonhosted.org/packages/35/ad/f64f4be628536404c9576a0a40b10f5304bb37a69fb6cb37987e9ae92782/bitarray-3.7.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db0441e80773d747a1ed9edfb9f75e7acb68ce8627583bbb6f770b7ec49f0064", size = 347583, upload-time = "2025-08-28T22:15:16.708Z" }, + { url = "https://files.pythonhosted.org/packages/e6/82/98774e33b3286fd83c6e48f5fb4e362d39b531011b4e1dd5aeba9dfdd3b8/bitarray-3.7.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef5a99a8d1a5c47b4cf85925d1420fc4ee584c98be8efc548651447b3047242f", size = 338572, upload-time = "2025-08-28T22:15:20.235Z" }, + { url = "https://files.pythonhosted.org/packages/02/cc/aadc3bf1382d9660f755d74b3275c866a20e01ad2062cc777b2378423e97/bitarray-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb7af369df317527d697c5bb37ab944bb9a17ea1a5e82e47d5c7c638f3ccdd6", size = 329984, upload-time = "2025-08-28T22:15:21.684Z" }, + { url = "https://files.pythonhosted.org/packages/42/ba/f9db45b9d6d01793afe62190c3f58bfe1969bd5798612663225560c24d94/bitarray-3.7.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eda67136343db96752e58ef36ac37116f36cba40961e79fd0e9bd858f5a09b38", size = 318777, upload-time = "2025-08-28T22:15:22.816Z" }, + { url = "https://files.pythonhosted.org/packages/5e/1b/18d11fe8f3192be5c2986d0faada5b3c9c0e43082ba031c12c75ebc64fd2/bitarray-3.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:79038bf1a7b13d243e51f4b6909c6997c2ba2bffc45bcae264704308a2d17198", size = 322772, upload-time = "2025-08-28T22:15:24.063Z" }, + { url = "https://files.pythonhosted.org/packages/dc/20/3aaf1c21af0f8dca623d06f12ce44fb45f94c10c6550e8d2e57d811b1881/bitarray-3.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d12c45da97b2f31d0233e15f8d68731cfa86264c9f04b2669b9fdf46aaf68e1f", size = 318773, upload-time = "2025-08-28T22:15:25.536Z" }, + { url = "https://files.pythonhosted.org/packages/b0/80/2d066264b1f3b3c495e12c55a9d0955733e890388d63ba75c408bb936fb7/bitarray-3.7.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:64d1143e90299ba8c967324840912a63a903494b1870a52f6675bda53dc332f7", size = 347391, upload-time = "2025-08-28T22:15:26.646Z" }, + { url = "https://files.pythonhosted.org/packages/e6/4b/819d5614433881ae779a6b23dd74d399c790777e3f084a270851059a77b2/bitarray-3.7.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c4e04c12f507942f1ddf215cb3a08c244d24051cdd2ba571060166ce8a92be16", size = 347719, upload-time = "2025-08-28T22:15:27.851Z" }, + { url = "https://files.pythonhosted.org/packages/52/63/a278c08f1e47711f71e396135c0d6d38811f551613b84af8ac7901bfaea9/bitarray-3.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ddc646cec4899a137c134b13818469e4178a251d77f9f4b23229267e3da78cfb", size = 328197, upload-time = "2025-08-28T22:15:29.392Z" }, + { url = "https://files.pythonhosted.org/packages/aa/73/6a74193cf565b01747ebd7979752060128e6c1423378471b04d8ed28b6f0/bitarray-3.7.1-cp311-cp311-win32.whl", hash = "sha256:a23b5f13f9b292004e94b0b13fead4dae79c7512db04dc817ff2c2478298e04a", size = 141377, upload-time = "2025-08-28T22:15:30.471Z" }, + { url = "https://files.pythonhosted.org/packages/13/03/7bbaadf90b282c7f1bc21c3c4855ce869d3ecd444071b1dab55baaec9328/bitarray-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:acc56700963f63307ac096689d4547e8061028a66bb78b90e42c5da2898898fb", size = 148203, upload-time = "2025-08-28T22:15:31.525Z" }, + { url = "https://files.pythonhosted.org/packages/89/27/46b5b4dabecf84f750587cded3640658448d27c59f4dd2cbaa589085f43a/bitarray-3.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b99a0347bc6131046c19e056a113daa34d7df99f1f45510161bc78bc8461a470", size = 147349, upload-time = "2025-08-28T22:15:32.729Z" }, + { url = "https://files.pythonhosted.org/packages/f9/1e/7f61150577127a1540136ba8a63ba17c661a17e721e03404fcd5833a4a05/bitarray-3.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d7e274ac1975e55ebfb8166cce27e13dc99120c1d6ce9e490d7a716b9be9abb5", size = 143922, upload-time = "2025-08-28T22:15:33.963Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b2/7c852472df8c644d05530bc0ad586fead5f23a9d176873c2c54f57e16b4e/bitarray-3.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b9a2eb7d2e0e9c2f25256d2663c0a2a4798fe3110e3ddbbb1a7b71740b4de08", size = 330277, upload-time = "2025-08-28T22:15:34.997Z" }, + { url = "https://files.pythonhosted.org/packages/7b/38/681340eea0997c48ef2dbf1acb0786090518704ca32f9a2c3c669bdea08e/bitarray-3.7.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e15e70a3cf5bb519e2448524d689c02ff6bcd4750587a517e2bffee06065bf27", size = 349562, upload-time = "2025-08-28T22:15:36.554Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f4/6fc43f896af85c5b10a74b1d8a87c05915464869594131a2d7731707a108/bitarray-3.7.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c65257899bb8faf6a111297b4ff0066324a6b901318582c0453a01422c3bcd5a", size = 341249, upload-time = "2025-08-28T22:15:37.774Z" }, + { url = "https://files.pythonhosted.org/packages/89/c7/1f71164799cacd44964ead87e1fc7e2f0ddec6d0519515a82d54eb8c8a13/bitarray-3.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38b0261483c59bb39ae9300ad46bf0bbf431ab604266382d986a349c96171b36", size = 332874, upload-time = "2025-08-28T22:15:38.935Z" }, + { url = "https://files.pythonhosted.org/packages/95/cd/4d7c19064fa7fe94c2818712695fa186a1d0bb9c5cb0cf34693df81d3202/bitarray-3.7.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2b1ed363a4ef5622dccbf7822f01b51195062c4f382b28c9bd125d046d0324c", size = 321107, upload-time = "2025-08-28T22:15:40.071Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d2/7d5ffe491c70614c0eb4a0186666efe925a02e25ed80ebd19c5fcb1c62e8/bitarray-3.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:dfde50ae55e075dcd5801e2c3ea0e749c849ed2cbbee991af0f97f1bdbadb2a6", size = 324999, upload-time = "2025-08-28T22:15:41.241Z" }, + { url = "https://files.pythonhosted.org/packages/11/d9/95fb87ec72c01169dad574baf7bc9e0d2bb73975d7ea29a83920a38646f4/bitarray-3.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:45660e2fabcdc1bab9699a468b312f47956300d41d6a2ea91c8f067572aaf38a", size = 321816, upload-time = "2025-08-28T22:15:42.417Z" }, + { url = "https://files.pythonhosted.org/packages/6b/3d/57ac96bbd125df75219c59afa297242054c09f22548aff028a8cefa8f120/bitarray-3.7.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7b4a41dc183d7d16750634f65566205990f94144755a39f33da44c0350c3e1a8", size = 349342, upload-time = "2025-08-28T22:15:43.997Z" }, + { url = "https://files.pythonhosted.org/packages/a9/14/d28f7456d2c3b3f7898186498b6d7fd3eecab267c300fb333fc2a8d55965/bitarray-3.7.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8b8e07374d60040b24d1a158895d9758424db13be63d4b2fe1870e37f9dec009", size = 350501, upload-time = "2025-08-28T22:15:45.377Z" }, + { url = "https://files.pythonhosted.org/packages/bb/a4/0f803dc446e602b21e61315f5fa2cdec02a65340147b08f7efadba559f38/bitarray-3.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f31d8c2168bf2a52e4539232392352832c2296e07e0e14b6e06a44da574099ba", size = 331362, upload-time = "2025-08-28T22:15:46.577Z" }, + { url = "https://files.pythonhosted.org/packages/c9/03/25e4c4b91a33f1eae0a9e9b2b11f1eaed14e37499abbde154ff33888f5f5/bitarray-3.7.1-cp312-cp312-win32.whl", hash = "sha256:fe1f1f4010244cb07f6a079854a12e1627e4fb9ea99d672f2ceccaf6653ca514", size = 141474, upload-time = "2025-08-28T22:15:48.185Z" }, + { url = "https://files.pythonhosted.org/packages/25/53/98efa8ee389e4cbd91fc7c87bfebd4e11d6f8a027eb3f9be42d1addf1f51/bitarray-3.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:f41a4b57cbc128a699e9d716a56c90c7fc76554e680fe2962f49cc4d8688b051", size = 148458, upload-time = "2025-08-28T22:15:49.256Z" }, + { url = "https://files.pythonhosted.org/packages/58/1f/80316ba4ed605d005efeb0b09c97cecde2c66ac4deae9d1d698670e1525f/bitarray-3.7.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c9bf2bf29854f165a47917b8782b6cf3a7d602971bf454806208d0cbb96f797a", size = 143423, upload-time = "2025-08-28T22:17:37.879Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c3/52a491e18ba41911455f145906b20898fe8e7955d0bcc5b20207bf2aba09/bitarray-3.7.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:002b73bf4a9f7b3ecb02260bd4dd332a6ee4d7f74ee9779a1ef342a36244d0cf", size = 139870, upload-time = "2025-08-28T22:17:39.266Z" }, + { url = "https://files.pythonhosted.org/packages/46/df/4674d16f39841fc71db6ecc6298390cbb91a7dd8c4eccd55248a4ddced06/bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:481239cd0966f965c2b8fa78b88614be5f12a64e7773bb5feecc567d39bb2dd5", size = 148773, upload-time = "2025-08-28T22:17:40.81Z" }, + { url = "https://files.pythonhosted.org/packages/9b/85/9cd8bc811ab446491a5bdc47a70d6d51adb21e3b005b549d2fd5e04f5c7f/bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f583a1fb180a123c00064fab1a3bfb9d43e574b6474be1be3f6469e0331e3e2e", size = 149609, upload-time = "2025-08-28T22:17:42.308Z" }, + { url = "https://files.pythonhosted.org/packages/ea/84/e413c51313a4093ed67f657d21519c5fc592bdb9129c0ab8c7bad226e2b8/bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3db0648536f3e08afa7ceb928153c39913f98fd50a5c3adf92a4d0d4268f213e", size = 151343, upload-time = "2025-08-28T22:17:43.749Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4f/921176e539866a8f7428d92962861bbfa6104f2cea0cbdd578abe5768a83/bitarray-3.7.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3875578748b484638f6ea776f534e9088cfb15eee131aac051036cba40fd5d05", size = 146847, upload-time = "2025-08-28T22:17:45.209Z" }, +] + +[[package]] +name = "bitstring" +version = "4.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "bitarray" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/15/a8/a80c890db75d5bdd5314b5de02c4144c7de94fd0cefcae51acaeb14c6a3f/bitstring-4.3.1.tar.gz", hash = "sha256:a08bc09d3857216d4c0f412a1611056f1cc2b64fd254fb1e8a0afba7cfa1a95a", size = 251426, upload-time = "2025-03-22T09:39:06.978Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/2d/174566b533755ddf8efb32a5503af61c756a983de379f8ad3aed6a982d38/bitstring-4.3.1-py3-none-any.whl", hash = "sha256:69d1587f0ac18dc7d93fc7e80d5f447161a33e57027e726dc18a0a8bacf1711a", size = 71930, upload-time = "2025-03-22T09:39:05.163Z" }, +] + +[[package]] +name = "black" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload-time = "2025-01-29T04:15:40.373Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/3b/4ba3f93ac8d90410423fdd31d7541ada9bcee1df32fb90d26de41ed40e1d/black-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759e7ec1e050a15f89b770cefbf91ebee8917aac5c20483bc2d80a6c3a04df32", size = 1629419, upload-time = "2025-01-29T05:37:06.642Z" }, + { url = "https://files.pythonhosted.org/packages/b4/02/0bde0485146a8a5e694daed47561785e8b77a0466ccc1f3e485d5ef2925e/black-25.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e519ecf93120f34243e6b0054db49c00a35f84f195d5bce7e9f5cfc578fc2da", size = 1461080, upload-time = "2025-01-29T05:37:09.321Z" }, + { url = "https://files.pythonhosted.org/packages/52/0e/abdf75183c830eaca7589144ff96d49bce73d7ec6ad12ef62185cc0f79a2/black-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:055e59b198df7ac0b7efca5ad7ff2516bca343276c466be72eb04a3bcc1f82d7", size = 1766886, upload-time = "2025-01-29T04:18:24.432Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a6/97d8bb65b1d8a41f8a6736222ba0a334db7b7b77b8023ab4568288f23973/black-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:db8ea9917d6f8fc62abd90d944920d95e73c83a5ee3383493e35d271aca872e9", size = 1419404, upload-time = "2025-01-29T04:19:04.296Z" }, + { url = "https://files.pythonhosted.org/packages/7e/4f/87f596aca05c3ce5b94b8663dbfe242a12843caaa82dd3f85f1ffdc3f177/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0", size = 1614372, upload-time = "2025-01-29T05:37:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/e7/d0/2c34c36190b741c59c901e56ab7f6e54dad8df05a6272a9747ecef7c6036/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299", size = 1442865, upload-time = "2025-01-29T05:37:14.309Z" }, + { url = "https://files.pythonhosted.org/packages/21/d4/7518c72262468430ead45cf22bd86c883a6448b9eb43672765d69a8f1248/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096", size = 1749699, upload-time = "2025-01-29T04:18:17.688Z" }, + { url = "https://files.pythonhosted.org/packages/58/db/4f5beb989b547f79096e035c4981ceb36ac2b552d0ac5f2620e941501c99/black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2", size = 1428028, upload-time = "2025-01-29T04:18:51.711Z" }, + { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988, upload-time = "2025-01-29T05:37:16.707Z" }, + { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985, upload-time = "2025-01-29T05:37:18.273Z" }, + { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816, upload-time = "2025-01-29T04:18:33.823Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860, upload-time = "2025-01-29T04:19:12.944Z" }, + { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload-time = "2025-01-29T04:15:38.082Z" }, +] + +[[package]] +name = "bolt11" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "base58" }, + { name = "bech32" }, + { name = "bitstring" }, + { name = "click" }, + { name = "coincurve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/39/4b151129bac9a5a7bce390531659de760b065c679d6a47b20f9fa034f4e1/bolt11-2.1.1.tar.gz", hash = "sha256:4e903d77208bfc4de8fc7e183a0689ea54afe874c91d62524d3b8c09492fa7ea", size = 13872, upload-time = "2025-03-12T13:33:09.668Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/9e/78e59887cbf94116bdc890af7726ae264d55df14f1c777724c656e8a35fe/bolt11-2.1.1-py3-none-any.whl", hash = "sha256:fd4edb9e73e27bf5e017f47c97f7c6827b523fcf9cab152b123961ca78323e2d", size = 17102, upload-time = "2025-03-12T13:33:08.142Z" }, +] + +[[package]] +name = "certifi" +version = "2025.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", size = 184283, upload-time = "2025-09-08T23:22:08.01Z" }, + { url = "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", size = 180504, upload-time = "2025-09-08T23:22:10.637Z" }, + { url = "https://files.pythonhosted.org/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", size = 208811, upload-time = "2025-09-08T23:22:12.267Z" }, + { url = "https://files.pythonhosted.org/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", size = 216402, upload-time = "2025-09-08T23:22:13.455Z" }, + { url = "https://files.pythonhosted.org/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", size = 203217, upload-time = "2025-09-08T23:22:14.596Z" }, + { url = "https://files.pythonhosted.org/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", size = 203079, upload-time = "2025-09-08T23:22:15.769Z" }, + { url = "https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", size = 216475, upload-time = "2025-09-08T23:22:17.427Z" }, + { url = "https://files.pythonhosted.org/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", size = 218829, upload-time = "2025-09-08T23:22:19.069Z" }, + { url = "https://files.pythonhosted.org/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", size = 211211, upload-time = "2025-09-08T23:22:20.588Z" }, + { url = "https://files.pythonhosted.org/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", size = 218036, upload-time = "2025-09-08T23:22:22.143Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", size = 172184, upload-time = "2025-09-08T23:22:23.328Z" }, + { url = "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790, upload-time = "2025-09-08T23:22:24.752Z" }, + { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, + { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, + { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, + { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, + { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, + { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/98/f3b8013223728a99b908c9344da3aa04ee6e3fa235f19409033eda92fb78/charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", size = 207695, upload-time = "2025-08-09T07:55:36.452Z" }, + { url = "https://files.pythonhosted.org/packages/21/40/5188be1e3118c82dcb7c2a5ba101b783822cfb413a0268ed3be0468532de/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", size = 147153, upload-time = "2025-08-09T07:55:38.467Z" }, + { url = "https://files.pythonhosted.org/packages/37/60/5d0d74bc1e1380f0b72c327948d9c2aca14b46a9efd87604e724260f384c/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", size = 160428, upload-time = "2025-08-09T07:55:40.072Z" }, + { url = "https://files.pythonhosted.org/packages/85/9a/d891f63722d9158688de58d050c59dc3da560ea7f04f4c53e769de5140f5/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", size = 157627, upload-time = "2025-08-09T07:55:41.706Z" }, + { url = "https://files.pythonhosted.org/packages/65/1a/7425c952944a6521a9cfa7e675343f83fd82085b8af2b1373a2409c683dc/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", size = 152388, upload-time = "2025-08-09T07:55:43.262Z" }, + { url = "https://files.pythonhosted.org/packages/f0/c9/a2c9c2a355a8594ce2446085e2ec97fd44d323c684ff32042e2a6b718e1d/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", size = 150077, upload-time = "2025-08-09T07:55:44.903Z" }, + { url = "https://files.pythonhosted.org/packages/3b/38/20a1f44e4851aa1c9105d6e7110c9d020e093dfa5836d712a5f074a12bf7/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", size = 161631, upload-time = "2025-08-09T07:55:46.346Z" }, + { url = "https://files.pythonhosted.org/packages/a4/fa/384d2c0f57edad03d7bec3ebefb462090d8905b4ff5a2d2525f3bb711fac/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", size = 159210, upload-time = "2025-08-09T07:55:47.539Z" }, + { url = "https://files.pythonhosted.org/packages/33/9e/eca49d35867ca2db336b6ca27617deed4653b97ebf45dfc21311ce473c37/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", size = 153739, upload-time = "2025-08-09T07:55:48.744Z" }, + { url = "https://files.pythonhosted.org/packages/2a/91/26c3036e62dfe8de8061182d33be5025e2424002125c9500faff74a6735e/charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", size = 99825, upload-time = "2025-08-09T07:55:50.305Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c6/f05db471f81af1fa01839d44ae2a8bfeec8d2a8b4590f16c4e7393afd323/charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", size = 107452, upload-time = "2025-08-09T07:55:51.461Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, + { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, + { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, + { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, + { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, + { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, + { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, + { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, + { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, + { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, + { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, + { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, + { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, + { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, + { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, + { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, + { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, + { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, +] + +[[package]] +name = "click" +version = "8.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, +] + +[[package]] +name = "coincurve" +version = "20.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asn1crypto" }, + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/4c/9e5e51e6c12cec6444c86697992f9c6ccffa19f84d042ff939c8b89206ff/coincurve-20.0.0.tar.gz", hash = "sha256:872419e404300302e938849b6b92a196fabdad651060b559dc310e52f8392829", size = 122865, upload-time = "2024-06-02T18:15:50.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/0c/f6a8b06f461089aeab441824134ea5d5824dba3acaac0a9dbf8444cbe1d6/coincurve-20.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d559b22828638390118cae9372a1bb6f6594f5584c311deb1de6a83163a0919b", size = 1255634, upload-time = "2024-06-02T18:14:26.381Z" }, + { url = "https://files.pythonhosted.org/packages/62/c2/0dbabd2c6648f49f730fdcbba84c53b5ffaf452fca85c750633141fe049c/coincurve-20.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33d7f6ebd90fcc550f819f7f2cce2af525c342aac07f0ccda46ad8956ad9d99b", size = 1255532, upload-time = "2024-06-02T18:14:28.792Z" }, + { url = "https://files.pythonhosted.org/packages/f5/77/c4fa50f8cb5d050a9bcab806503acdd1705b0dfb5c554eed15cc18bc12e8/coincurve-20.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22d70dd55d13fd427418eb41c20fde0a20a5e5f016e2b1bb94710701e759e7e0", size = 1191928, upload-time = "2024-06-02T18:14:30.874Z" }, + { url = "https://files.pythonhosted.org/packages/a3/11/6254ea354a32a3a1d70722daf58f2ebf0f689f0940eaced5127233416553/coincurve-20.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46f18d481eaae72c169f334cde1fd22011a884e0c9c6adc3fdc1fd13df8236a3", size = 1194364, upload-time = "2024-06-02T18:14:32.684Z" }, + { url = "https://files.pythonhosted.org/packages/a7/a9/d8717d41eb02688691adc30d7348f7c5fdc78e977f4cea83ee84622050b5/coincurve-20.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9de1ec57f43c3526bc462be58fb97910dc1fdd5acab6c71eda9f9719a5bd7489", size = 1204658, upload-time = "2024-06-02T18:14:33.919Z" }, + { url = "https://files.pythonhosted.org/packages/55/13/40923832d99c18fb01a00f83e5f6f702156e71cc0eb5d6281535eee662af/coincurve-20.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a6f007c44c726b5c0b3724093c0d4fb8e294f6b6869beb02d7473b21777473a3", size = 1215298, upload-time = "2024-06-02T18:14:35.318Z" }, + { url = "https://files.pythonhosted.org/packages/4d/87/646462a7a7810c7a3dcadae8969e1b78d535bcff072c26b17588e93a39b8/coincurve-20.0.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0ff1f3b81330db5092c24da2102e4fcba5094f14945b3eb40746456ceabdd6d9", size = 1204504, upload-time = "2024-06-02T18:14:36.567Z" }, + { url = "https://files.pythonhosted.org/packages/01/58/fbb9a312d559aee701491435b691e409fb0efa12eabf269ff651d537fed4/coincurve-20.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82f7de97694d9343f26bd1c8e081b168e5f525894c12445548ce458af227f536", size = 1209298, upload-time = "2024-06-02T18:14:38.384Z" }, + { url = "https://files.pythonhosted.org/packages/ee/d0/1d5679c000b31f3b32512632d98571f2bb752cd25c127d6f5bf3711b6eae/coincurve-20.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:e905b4b084b4f3b61e5a5d58ac2632fd1d07b7b13b4c6d778335a6ca1dafd7a3", size = 1198934, upload-time = "2024-06-02T18:14:39.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/f6/8c1499f730fac49ec13740fb1c015ce8082fa6b917790056988559f22212/coincurve-20.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:3657bb5ed0baf1cf8cf356e7d44aa90a7902cc3dd4a435c6d4d0bed0553ad4f7", size = 1193319, upload-time = "2024-06-02T18:14:41.165Z" }, + { url = "https://files.pythonhosted.org/packages/24/a7/d60a41b3f0a546854c9b7ca65ab99a5fdf1c9e158ae264a580de8f23fd1c/coincurve-20.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:44087d1126d43925bf9a2391ce5601bf30ce0dba4466c239172dc43226696018", size = 1255635, upload-time = "2024-06-02T18:14:42.483Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4a/727fab66c0fbecfd7beeb38467910bd3652a77df649565e30160a9d2bae2/coincurve-20.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ccf0ba38b0f307a9b3ce28933f6c71dc12ef3a0985712ca09f48591afd597c8", size = 1255536, upload-time = "2024-06-02T18:14:44.077Z" }, + { url = "https://files.pythonhosted.org/packages/0f/8b/25d4ae5bb60665023e6d71681fada88ee95b5010dae6fc0b44d8b23b8df1/coincurve-20.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:566bc5986debdf8572b6be824fd4de03d533c49f3de778e29f69017ae3fe82d8", size = 1191928, upload-time = "2024-06-02T18:14:45.739Z" }, + { url = "https://files.pythonhosted.org/packages/0d/86/8c32c512fa27bfe7cfe70329fd43ebac23c0c8cec202cf6e4f52854e7ce3/coincurve-20.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4d70283168e146f025005c15406086513d5d35e89a60cf4326025930d45013a", size = 1194365, upload-time = "2024-06-02T18:14:47.008Z" }, + { url = "https://files.pythonhosted.org/packages/fe/74/fefbe512f54df7d02a7ea4821b87cf199a91b3565cdf0c94448b3f6b1af1/coincurve-20.0.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:763c6122dd7d5e7a81c86414ce360dbe9a2d4afa1ca6c853ee03d63820b3d0c5", size = 1204658, upload-time = "2024-06-02T18:14:48.348Z" }, + { url = "https://files.pythonhosted.org/packages/09/68/05b29f881f628ce8e8468f5f7420f6c4d7c129f43964e81d15bf388ae67a/coincurve-20.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f00c361c356bcea386d47a191bb8ac60429f4b51c188966a201bfecaf306ff7f", size = 1215301, upload-time = "2024-06-02T18:14:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/ee/5d/d91549cf5a163797b0724dc2dcd551b908b6beddb6598b37743df7f6f3ec/coincurve-20.0.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4af57bdadd2e64d117dd0b33cfefe76e90c7a6c496a7b034fc65fd01ec249b15", size = 1204505, upload-time = "2024-06-02T18:14:51.816Z" }, + { url = "https://files.pythonhosted.org/packages/37/0f/898022e08760fb57d281f3695576e859b0f8a8ac629670223d9066c3f60d/coincurve-20.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a26437b7cbde13fb6e09261610b788ca2a0ca2195c62030afd1e1e0d1a62e035", size = 1209305, upload-time = "2024-06-02T18:14:53.39Z" }, + { url = "https://files.pythonhosted.org/packages/57/b9/643567d3f680ddf8d1bf10a56112ae7755296500d8eaaef498be637a8533/coincurve-20.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ed51f8bba35e6c7676ad65539c3dbc35acf014fc402101fa24f6b0a15a74ab9e", size = 1198932, upload-time = "2024-06-02T18:14:54.751Z" }, + { url = "https://files.pythonhosted.org/packages/b3/3a/898f5c12469b292042608dd0702bcb0420ec32bac6b1ca2a0dd790f922bd/coincurve-20.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:594b840fc25d74118407edbbbc754b815f1bba9759dbf4f67f1c2b78396df2d3", size = 1193318, upload-time = "2024-06-02T18:14:55.981Z" }, + { url = "https://files.pythonhosted.org/packages/8f/24/e1bf259dd57186fbdc7cec51909db320884162cfad5ec72cbaa63573ff9d/coincurve-20.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4df4416a6c0370d777aa725a25b14b04e45aa228da1251c258ff91444643f688", size = 1255671, upload-time = "2024-06-02T18:14:57.863Z" }, + { url = "https://files.pythonhosted.org/packages/0a/c5/1817f87d1cd5ff50d8537fe60fb96f66b76dd02da885d970952e6189a801/coincurve-20.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1ccc3e4db55abf3fc0e604a187fdb05f0702bc5952e503d9a75f4ae6eeb4cb3a", size = 1255565, upload-time = "2024-06-02T18:14:59.128Z" }, + { url = "https://files.pythonhosted.org/packages/90/9f/35e15f993717ed1dcc4c26d9771f073a1054af26808a0f421783bb4cd7e0/coincurve-20.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8335b1658a2ef5b3eb66d52647742fe8c6f413ad5b9d5310d7ea6d8060d40f", size = 1191953, upload-time = "2024-06-02T18:15:01.047Z" }, + { url = "https://files.pythonhosted.org/packages/4a/3d/6a9bc32e69b738b5e05f5027bace1da6722352a4a447e495d3c03a601d99/coincurve-20.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ac025e485a0229fd5394e0bf6b4a75f8a4f6cee0dcf6f0b01a2ef05c5210ff", size = 1194425, upload-time = "2024-06-02T18:15:02.919Z" }, + { url = "https://files.pythonhosted.org/packages/1a/a6/15424973dc47fc7c87e3c0f8859f6f1b1032582ee9f1b85fdd5d1e33d630/coincurve-20.0.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e46e3f1c21b3330857bcb1a3a5b942f645c8bce912a8a2b252216f34acfe4195", size = 1204678, upload-time = "2024-06-02T18:15:04.308Z" }, + { url = "https://files.pythonhosted.org/packages/6a/e7/71ddb4d66c11c4ad13e729362f8852e048ae452eba3dfcf57751842bb292/coincurve-20.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:df9ff9b17a1d27271bf476cf3fa92df4c151663b11a55d8cea838b8f88d83624", size = 1215395, upload-time = "2024-06-02T18:15:05.701Z" }, + { url = "https://files.pythonhosted.org/packages/b9/7d/03e0a19cfff1d86f5d019afc69cfbff02caada701ed5a4a50abc63d4261c/coincurve-20.0.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4155759f071375699282e03b3d95fb473ee05c022641c077533e0d906311e57a", size = 1204552, upload-time = "2024-06-02T18:15:07.107Z" }, + { url = "https://files.pythonhosted.org/packages/07/cd/e9bd4ca7d931653a35c74194da04191a9aecc54b8f48a554cd538dc810e4/coincurve-20.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0530b9dd02fc6f6c2916716974b79bdab874227f560c422801ade290e3fc5013", size = 1209392, upload-time = "2024-06-02T18:15:08.663Z" }, + { url = "https://files.pythonhosted.org/packages/99/54/260053f14f74b99b645084231e1c76994134ded49407a3bba23a8ffc0ff6/coincurve-20.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:eacf9c0ce8739c84549a89c083b1f3526c8780b84517ee75d6b43d276e55f8a0", size = 1198932, upload-time = "2024-06-02T18:15:10.786Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b5/c465e09345dd38b9415f5d47ae7683b3f461db02fcc03e699b6b5687ab2b/coincurve-20.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:52a67bfddbd6224dfa42085c88ad176559801b57d6a8bd30d92ee040de88b7b3", size = 1193324, upload-time = "2024-06-02T18:15:12.511Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "cryptography" +version = "45.0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/35/c495bffc2056f2dadb32434f1feedd79abde2a7f8363e1974afa9c33c7e2/cryptography-45.0.7.tar.gz", hash = "sha256:4b1654dfc64ea479c242508eb8c724044f1e964a47d1d1cacc5132292d851971", size = 744980, upload-time = "2025-09-01T11:15:03.146Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/91/925c0ac74362172ae4516000fe877912e33b5983df735ff290c653de4913/cryptography-45.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:3be4f21c6245930688bd9e162829480de027f8bf962ede33d4f8ba7d67a00cee", size = 7041105, upload-time = "2025-09-01T11:13:59.684Z" }, + { url = "https://files.pythonhosted.org/packages/fc/63/43641c5acce3a6105cf8bd5baeceeb1846bb63067d26dae3e5db59f1513a/cryptography-45.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:67285f8a611b0ebc0857ced2081e30302909f571a46bfa7a3cc0ad303fe015c6", size = 4205799, upload-time = "2025-09-01T11:14:02.517Z" }, + { url = "https://files.pythonhosted.org/packages/bc/29/c238dd9107f10bfde09a4d1c52fd38828b1aa353ced11f358b5dd2507d24/cryptography-45.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:577470e39e60a6cd7780793202e63536026d9b8641de011ed9d8174da9ca5339", size = 4430504, upload-time = "2025-09-01T11:14:04.522Z" }, + { url = "https://files.pythonhosted.org/packages/62/62/24203e7cbcc9bd7c94739428cd30680b18ae6b18377ae66075c8e4771b1b/cryptography-45.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4bd3e5c4b9682bc112d634f2c6ccc6736ed3635fc3319ac2bb11d768cc5a00d8", size = 4209542, upload-time = "2025-09-01T11:14:06.309Z" }, + { url = "https://files.pythonhosted.org/packages/cd/e3/e7de4771a08620eef2389b86cd87a2c50326827dea5528feb70595439ce4/cryptography-45.0.7-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:465ccac9d70115cd4de7186e60cfe989de73f7bb23e8a7aa45af18f7412e75bf", size = 3889244, upload-time = "2025-09-01T11:14:08.152Z" }, + { url = "https://files.pythonhosted.org/packages/96/b8/bca71059e79a0bb2f8e4ec61d9c205fbe97876318566cde3b5092529faa9/cryptography-45.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:16ede8a4f7929b4b7ff3642eba2bf79aa1d71f24ab6ee443935c0d269b6bc513", size = 4461975, upload-time = "2025-09-01T11:14:09.755Z" }, + { url = "https://files.pythonhosted.org/packages/58/67/3f5b26937fe1218c40e95ef4ff8d23c8dc05aa950d54200cc7ea5fb58d28/cryptography-45.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8978132287a9d3ad6b54fcd1e08548033cc09dc6aacacb6c004c73c3eb5d3ac3", size = 4209082, upload-time = "2025-09-01T11:14:11.229Z" }, + { url = "https://files.pythonhosted.org/packages/0e/e4/b3e68a4ac363406a56cf7b741eeb80d05284d8c60ee1a55cdc7587e2a553/cryptography-45.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b6a0e535baec27b528cb07a119f321ac024592388c5681a5ced167ae98e9fff3", size = 4460397, upload-time = "2025-09-01T11:14:12.924Z" }, + { url = "https://files.pythonhosted.org/packages/22/49/2c93f3cd4e3efc8cb22b02678c1fad691cff9dd71bb889e030d100acbfe0/cryptography-45.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a24ee598d10befaec178efdff6054bc4d7e883f615bfbcd08126a0f4931c83a6", size = 4337244, upload-time = "2025-09-01T11:14:14.431Z" }, + { url = "https://files.pythonhosted.org/packages/04/19/030f400de0bccccc09aa262706d90f2ec23d56bc4eb4f4e8268d0ddf3fb8/cryptography-45.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:fa26fa54c0a9384c27fcdc905a2fb7d60ac6e47d14bc2692145f2b3b1e2cfdbd", size = 4568862, upload-time = "2025-09-01T11:14:16.185Z" }, + { url = "https://files.pythonhosted.org/packages/29/56/3034a3a353efa65116fa20eb3c990a8c9f0d3db4085429040a7eef9ada5f/cryptography-45.0.7-cp311-abi3-win32.whl", hash = "sha256:bef32a5e327bd8e5af915d3416ffefdbe65ed975b646b3805be81b23580b57b8", size = 2936578, upload-time = "2025-09-01T11:14:17.638Z" }, + { url = "https://files.pythonhosted.org/packages/b3/61/0ab90f421c6194705a99d0fa9f6ee2045d916e4455fdbb095a9c2c9a520f/cryptography-45.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:3808e6b2e5f0b46d981c24d79648e5c25c35e59902ea4391a0dcb3e667bf7443", size = 3405400, upload-time = "2025-09-01T11:14:18.958Z" }, + { url = "https://files.pythonhosted.org/packages/63/e8/c436233ddf19c5f15b25ace33979a9dd2e7aa1a59209a0ee8554179f1cc0/cryptography-45.0.7-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bfb4c801f65dd61cedfc61a83732327fafbac55a47282e6f26f073ca7a41c3b2", size = 7021824, upload-time = "2025-09-01T11:14:20.954Z" }, + { url = "https://files.pythonhosted.org/packages/bc/4c/8f57f2500d0ccd2675c5d0cc462095adf3faa8c52294ba085c036befb901/cryptography-45.0.7-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:81823935e2f8d476707e85a78a405953a03ef7b7b4f55f93f7c2d9680e5e0691", size = 4202233, upload-time = "2025-09-01T11:14:22.454Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ac/59b7790b4ccaed739fc44775ce4645c9b8ce54cbec53edf16c74fd80cb2b/cryptography-45.0.7-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3994c809c17fc570c2af12c9b840d7cea85a9fd3e5c0e0491f4fa3c029216d59", size = 4423075, upload-time = "2025-09-01T11:14:24.287Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/d4f07ea21434bf891faa088a6ac15d6d98093a66e75e30ad08e88aa2b9ba/cryptography-45.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dad43797959a74103cb59c5dac71409f9c27d34c8a05921341fb64ea8ccb1dd4", size = 4204517, upload-time = "2025-09-01T11:14:25.679Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ac/924a723299848b4c741c1059752c7cfe09473b6fd77d2920398fc26bfb53/cryptography-45.0.7-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ce7a453385e4c4693985b4a4a3533e041558851eae061a58a5405363b098fcd3", size = 3882893, upload-time = "2025-09-01T11:14:27.1Z" }, + { url = "https://files.pythonhosted.org/packages/83/dc/4dab2ff0a871cc2d81d3ae6d780991c0192b259c35e4d83fe1de18b20c70/cryptography-45.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b04f85ac3a90c227b6e5890acb0edbaf3140938dbecf07bff618bf3638578cf1", size = 4450132, upload-time = "2025-09-01T11:14:28.58Z" }, + { url = "https://files.pythonhosted.org/packages/12/dd/b2882b65db8fc944585d7fb00d67cf84a9cef4e77d9ba8f69082e911d0de/cryptography-45.0.7-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:48c41a44ef8b8c2e80ca4527ee81daa4c527df3ecbc9423c41a420a9559d0e27", size = 4204086, upload-time = "2025-09-01T11:14:30.572Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fa/1d5745d878048699b8eb87c984d4ccc5da4f5008dfd3ad7a94040caca23a/cryptography-45.0.7-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f3df7b3d0f91b88b2106031fd995802a2e9ae13e02c36c1fc075b43f420f3a17", size = 4449383, upload-time = "2025-09-01T11:14:32.046Z" }, + { url = "https://files.pythonhosted.org/packages/36/8b/fc61f87931bc030598e1876c45b936867bb72777eac693e905ab89832670/cryptography-45.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd342f085542f6eb894ca00ef70236ea46070c8a13824c6bde0dfdcd36065b9b", size = 4332186, upload-time = "2025-09-01T11:14:33.95Z" }, + { url = "https://files.pythonhosted.org/packages/0b/11/09700ddad7443ccb11d674efdbe9a832b4455dc1f16566d9bd3834922ce5/cryptography-45.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1993a1bb7e4eccfb922b6cd414f072e08ff5816702a0bdb8941c247a6b1b287c", size = 4561639, upload-time = "2025-09-01T11:14:35.343Z" }, + { url = "https://files.pythonhosted.org/packages/71/ed/8f4c1337e9d3b94d8e50ae0b08ad0304a5709d483bfcadfcc77a23dbcb52/cryptography-45.0.7-cp37-abi3-win32.whl", hash = "sha256:18fcf70f243fe07252dcb1b268a687f2358025ce32f9f88028ca5c364b123ef5", size = 2926552, upload-time = "2025-09-01T11:14:36.929Z" }, + { url = "https://files.pythonhosted.org/packages/bc/ff/026513ecad58dacd45d1d24ebe52b852165a26e287177de1d545325c0c25/cryptography-45.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:7285a89df4900ed3bfaad5679b1e668cb4b38a8de1ccbfc84b05f34512da0a90", size = 3392742, upload-time = "2025-09-01T11:14:38.368Z" }, + { url = "https://files.pythonhosted.org/packages/13/3e/e42f1528ca1ea82256b835191eab1be014e0f9f934b60d98b0be8a38ed70/cryptography-45.0.7-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:de58755d723e86175756f463f2f0bddd45cc36fbd62601228a3f8761c9f58252", size = 3572442, upload-time = "2025-09-01T11:14:39.836Z" }, + { url = "https://files.pythonhosted.org/packages/59/aa/e947693ab08674a2663ed2534cd8d345cf17bf6a1facf99273e8ec8986dc/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a20e442e917889d1a6b3c570c9e3fa2fdc398c20868abcea268ea33c024c4083", size = 4142233, upload-time = "2025-09-01T11:14:41.305Z" }, + { url = "https://files.pythonhosted.org/packages/24/06/09b6f6a2fc43474a32b8fe259038eef1500ee3d3c141599b57ac6c57612c/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:258e0dff86d1d891169b5af222d362468a9570e2532923088658aa866eb11130", size = 4376202, upload-time = "2025-09-01T11:14:43.047Z" }, + { url = "https://files.pythonhosted.org/packages/00/f2/c166af87e95ce6ae6d38471a7e039d3a0549c2d55d74e059680162052824/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d97cf502abe2ab9eff8bd5e4aca274da8d06dd3ef08b759a8d6143f4ad65d4b4", size = 4141900, upload-time = "2025-09-01T11:14:45.089Z" }, + { url = "https://files.pythonhosted.org/packages/16/b9/e96e0b6cb86eae27ea51fa8a3151535a18e66fe7c451fa90f7f89c85f541/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:c987dad82e8c65ebc985f5dae5e74a3beda9d0a2a4daf8a1115f3772b59e5141", size = 4375562, upload-time = "2025-09-01T11:14:47.166Z" }, + { url = "https://files.pythonhosted.org/packages/36/d0/36e8ee39274e9d77baf7d0dafda680cba6e52f3936b846f0d56d64fec915/cryptography-45.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c13b1e3afd29a5b3b2656257f14669ca8fa8d7956d509926f0b130b600b50ab7", size = 3322781, upload-time = "2025-09-01T11:14:48.747Z" }, + { url = "https://files.pythonhosted.org/packages/99/4e/49199a4c82946938a3e05d2e8ad9482484ba48bbc1e809e3d506c686d051/cryptography-45.0.7-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a862753b36620af6fc54209264f92c716367f2f0ff4624952276a6bbd18cbde", size = 3584634, upload-time = "2025-09-01T11:14:50.593Z" }, + { url = "https://files.pythonhosted.org/packages/16/ce/5f6ff59ea9c7779dba51b84871c19962529bdcc12e1a6ea172664916c550/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:06ce84dc14df0bf6ea84666f958e6080cdb6fe1231be2a51f3fc1267d9f3fb34", size = 4149533, upload-time = "2025-09-01T11:14:52.091Z" }, + { url = "https://files.pythonhosted.org/packages/ce/13/b3cfbd257ac96da4b88b46372e662009b7a16833bfc5da33bb97dd5631ae/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d0c5c6bac22b177bf8da7435d9d27a6834ee130309749d162b26c3105c0795a9", size = 4385557, upload-time = "2025-09-01T11:14:53.551Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c5/8c59d6b7c7b439ba4fc8d0cab868027fd095f215031bc123c3a070962912/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:2f641b64acc00811da98df63df7d59fd4706c0df449da71cb7ac39a0732b40ae", size = 4149023, upload-time = "2025-09-01T11:14:55.022Z" }, + { url = "https://files.pythonhosted.org/packages/55/32/05385c86d6ca9ab0b4d5bb442d2e3d85e727939a11f3e163fc776ce5eb40/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:f5414a788ecc6ee6bc58560e85ca624258a55ca434884445440a810796ea0e0b", size = 4385722, upload-time = "2025-09-01T11:14:57.319Z" }, + { url = "https://files.pythonhosted.org/packages/23/87/7ce86f3fa14bc11a5a48c30d8103c26e09b6465f8d8e9d74cf7a0714f043/cryptography-45.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:1f3d56f73595376f4244646dd5c5870c14c196949807be39e79e7bd9bac3da63", size = 3332908, upload-time = "2025-09-01T11:14:58.78Z" }, +] + +[[package]] +name = "deprecated" +version = "1.2.18" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/97/06afe62762c9a8a86af0cfb7bfdab22a43ad17138b07af5b1a58442690a2/deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d", size = 2928744, upload-time = "2025-01-27T10:46:25.7Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec", size = 9998, upload-time = "2025-01-27T10:46:09.186Z" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, +] + +[[package]] +name = "dnspython" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, +] + +[[package]] +name = "ecdsa" +version = "0.19.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/1f/924e3caae75f471eae4b26bd13b698f6af2c44279f67af317439c2f4c46a/ecdsa-0.19.1.tar.gz", hash = "sha256:478cba7b62555866fcb3bb3fe985e06decbdb68ef55713c4e5ab98c57d508e61", size = 201793, upload-time = "2025-03-13T11:52:43.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/a3/460c57f094a4a165c84a1341c373b0a4f5ec6ac244b998d5021aade89b77/ecdsa-0.19.1-py2.py3-none-any.whl", hash = "sha256:30638e27cf77b7e15c4c4cc1973720149e1033827cfd00661ca5c8cc0cdb24c3", size = 150607, upload-time = "2025-03-13T11:52:41.757Z" }, +] + +[[package]] +name = "email-validator" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dnspython" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, +] + +[[package]] +name = "embit" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/88/b054b00ade6d2a41749e15976cdcec4b7ec4656ac1cb917ce3de395528d1/embit-0.8.0.tar.gz", hash = "sha256:8bf4b10073c67400370ce523fb16f035fe759f6fdd987c579bdcc268d75ed770", size = 763120, upload-time = "2024-05-30T10:56:48.944Z" } + +[[package]] +name = "environs" +version = "14.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "marshmallow" }, + { name = "python-dotenv" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/eb/805549ab44db6a9a8206973e8283b49734b903f85d3fed549db78b0817fc/environs-14.2.0.tar.gz", hash = "sha256:2b6c78a77dfefb57ca30d43a232270ecc82adabf67ab318e018084b9a3529e9b", size = 32317, upload-time = "2025-05-22T19:25:01.614Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/75/e309b90c6f95a6e01aa86425ff567d3c634eea33bde915f3ceb910092461/environs-14.2.0-py3-none-any.whl", hash = "sha256:22669a58d53c5b86a25d0231c4a41a6ebeb82d3942b8fbd9cf645890c92a1843", size = 15733, upload-time = "2025-05-22T19:24:59.666Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, +] + +[[package]] +name = "fastapi" +version = "0.116.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/d7/6c8b3bfe33eeffa208183ec037fee0cce9f7f024089ab1c5d12ef04bd27c/fastapi-0.116.1.tar.gz", hash = "sha256:ed52cbf946abfd70c5a0dccb24673f0670deeb517a88b3544d03c2a6bf283143", size = 296485, upload-time = "2025-07-11T16:22:32.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/47/d63c60f59a59467fda0f93f46335c9d18526d7071f025cb5b89d5353ea42/fastapi-0.116.1-py3-none-any.whl", hash = "sha256:c46ac7c312df840f0c9e220f7964bada936781bc4e2e6eb71f1c4d7553786565", size = 95631, upload-time = "2025-07-11T16:22:30.485Z" }, +] + +[[package]] +name = "fastapi-sso" +version = "0.18.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastapi" }, + { name = "httpx" }, + { name = "oauthlib" }, + { name = "pydantic", extra = ["email"] }, + { name = "pyjwt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d2/57/cc971c018af5d09eb5f8d1cd12abdd99ab4c59ea5c0b0b1b96349ffe117d/fastapi_sso-0.18.0.tar.gz", hash = "sha256:d8df5a686af7a6a7be248817544b405cf77f7e9ffcd5d0d7d2a196fd071964bc", size = 16811, upload-time = "2025-03-20T17:09:09.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/03/70ca13994f5569d343a9f99dba2930c8ae3471171f161b8887d44b6c526f/fastapi_sso-0.18.0-py3-none-any.whl", hash = "sha256:727754ad770b70690f1471f7b0a9e17c6dfd8ebd6e477616d3bde1eaf62e53dc", size = 26103, upload-time = "2025-03-20T17:09:08.656Z" }, +] + +[[package]] +name = "filelock" +version = "3.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, +] + +[[package]] +name = "filetype" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/29/745f7d30d47fe0f251d3ad3dc2978a23141917661998763bebb6da007eb1/filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb", size = 998020, upload-time = "2022-11-02T17:34:04.141Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/79/1b8fa1bb3568781e84c9200f951c735f3f157429f44be0495da55894d620/filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25", size = 19970, upload-time = "2022-11-02T17:34:01.425Z" }, +] + +[[package]] +name = "frozenlist" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078, upload-time = "2025-06-09T23:02:35.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/36/0da0a49409f6b47cc2d060dc8c9040b897b5902a8a4e37d9bc1deb11f680/frozenlist-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc4df77d638aa2ed703b878dd093725b72a824c3c546c076e8fdf276f78ee84a", size = 81304, upload-time = "2025-06-09T22:59:46.226Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/77c11d13d39513b298e267b22eb6cb559c103d56f155aa9a49097221f0b6/frozenlist-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:716a9973a2cc963160394f701964fe25012600f3d311f60c790400b00e568b61", size = 47735, upload-time = "2025-06-09T22:59:48.133Z" }, + { url = "https://files.pythonhosted.org/packages/37/12/9d07fa18971a44150593de56b2f2947c46604819976784bcf6ea0d5db43b/frozenlist-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0fd1bad056a3600047fb9462cff4c5322cebc59ebf5d0a3725e0ee78955001d", size = 46775, upload-time = "2025-06-09T22:59:49.564Z" }, + { url = "https://files.pythonhosted.org/packages/70/34/f73539227e06288fcd1f8a76853e755b2b48bca6747e99e283111c18bcd4/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3789ebc19cb811163e70fe2bd354cea097254ce6e707ae42e56f45e31e96cb8e", size = 224644, upload-time = "2025-06-09T22:59:51.35Z" }, + { url = "https://files.pythonhosted.org/packages/fb/68/c1d9c2f4a6e438e14613bad0f2973567586610cc22dcb1e1241da71de9d3/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af369aa35ee34f132fcfad5be45fbfcde0e3a5f6a1ec0712857f286b7d20cca9", size = 222125, upload-time = "2025-06-09T22:59:52.884Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d0/98e8f9a515228d708344d7c6986752be3e3192d1795f748c24bcf154ad99/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac64b6478722eeb7a3313d494f8342ef3478dff539d17002f849101b212ef97c", size = 233455, upload-time = "2025-06-09T22:59:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/79/df/8a11bcec5600557f40338407d3e5bea80376ed1c01a6c0910fcfdc4b8993/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f89f65d85774f1797239693cef07ad4c97fdd0639544bad9ac4b869782eb1981", size = 227339, upload-time = "2025-06-09T22:59:56.187Z" }, + { url = "https://files.pythonhosted.org/packages/50/82/41cb97d9c9a5ff94438c63cc343eb7980dac4187eb625a51bdfdb7707314/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1073557c941395fdfcfac13eb2456cb8aad89f9de27bae29fabca8e563b12615", size = 212969, upload-time = "2025-06-09T22:59:57.604Z" }, + { url = "https://files.pythonhosted.org/packages/13/47/f9179ee5ee4f55629e4f28c660b3fdf2775c8bfde8f9c53f2de2d93f52a9/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed8d2fa095aae4bdc7fdd80351009a48d286635edffee66bf865e37a9125c50", size = 222862, upload-time = "2025-06-09T22:59:59.498Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/df81e41ec6b953902c8b7e3a83bee48b195cb0e5ec2eabae5d8330c78038/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:24c34bea555fe42d9f928ba0a740c553088500377448febecaa82cc3e88aa1fa", size = 222492, upload-time = "2025-06-09T23:00:01.026Z" }, + { url = "https://files.pythonhosted.org/packages/84/17/30d6ea87fa95a9408245a948604b82c1a4b8b3e153cea596421a2aef2754/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:69cac419ac6a6baad202c85aaf467b65ac860ac2e7f2ac1686dc40dbb52f6577", size = 238250, upload-time = "2025-06-09T23:00:03.401Z" }, + { url = "https://files.pythonhosted.org/packages/8f/00/ecbeb51669e3c3df76cf2ddd66ae3e48345ec213a55e3887d216eb4fbab3/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:960d67d0611f4c87da7e2ae2eacf7ea81a5be967861e0c63cf205215afbfac59", size = 218720, upload-time = "2025-06-09T23:00:05.282Z" }, + { url = "https://files.pythonhosted.org/packages/1a/c0/c224ce0e0eb31cc57f67742071bb470ba8246623c1823a7530be0e76164c/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:41be2964bd4b15bf575e5daee5a5ce7ed3115320fb3c2b71fca05582ffa4dc9e", size = 232585, upload-time = "2025-06-09T23:00:07.962Z" }, + { url = "https://files.pythonhosted.org/packages/55/3c/34cb694abf532f31f365106deebdeac9e45c19304d83cf7d51ebbb4ca4d1/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46d84d49e00c9429238a7ce02dc0be8f6d7cd0cd405abd1bebdc991bf27c15bd", size = 234248, upload-time = "2025-06-09T23:00:09.428Z" }, + { url = "https://files.pythonhosted.org/packages/98/c0/2052d8b6cecda2e70bd81299e3512fa332abb6dcd2969b9c80dfcdddbf75/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15900082e886edb37480335d9d518cec978afc69ccbc30bd18610b7c1b22a718", size = 221621, upload-time = "2025-06-09T23:00:11.32Z" }, + { url = "https://files.pythonhosted.org/packages/c5/bf/7dcebae315436903b1d98ffb791a09d674c88480c158aa171958a3ac07f0/frozenlist-1.7.0-cp310-cp310-win32.whl", hash = "sha256:400ddd24ab4e55014bba442d917203c73b2846391dd42ca5e38ff52bb18c3c5e", size = 39578, upload-time = "2025-06-09T23:00:13.526Z" }, + { url = "https://files.pythonhosted.org/packages/8f/5f/f69818f017fa9a3d24d1ae39763e29b7f60a59e46d5f91b9c6b21622f4cd/frozenlist-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:6eb93efb8101ef39d32d50bce242c84bcbddb4f7e9febfa7b524532a239b4464", size = 43830, upload-time = "2025-06-09T23:00:14.98Z" }, + { url = "https://files.pythonhosted.org/packages/34/7e/803dde33760128acd393a27eb002f2020ddb8d99d30a44bfbaab31c5f08a/frozenlist-1.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa51e147a66b2d74de1e6e2cf5921890de6b0f4820b257465101d7f37b49fb5a", size = 82251, upload-time = "2025-06-09T23:00:16.279Z" }, + { url = "https://files.pythonhosted.org/packages/75/a9/9c2c5760b6ba45eae11334db454c189d43d34a4c0b489feb2175e5e64277/frozenlist-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b35db7ce1cd71d36ba24f80f0c9e7cff73a28d7a74e91fe83e23d27c7828750", size = 48183, upload-time = "2025-06-09T23:00:17.698Z" }, + { url = "https://files.pythonhosted.org/packages/47/be/4038e2d869f8a2da165f35a6befb9158c259819be22eeaf9c9a8f6a87771/frozenlist-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34a69a85e34ff37791e94542065c8416c1afbf820b68f720452f636d5fb990cd", size = 47107, upload-time = "2025-06-09T23:00:18.952Z" }, + { url = "https://files.pythonhosted.org/packages/79/26/85314b8a83187c76a37183ceed886381a5f992975786f883472fcb6dc5f2/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a646531fa8d82c87fe4bb2e596f23173caec9185bfbca5d583b4ccfb95183e2", size = 237333, upload-time = "2025-06-09T23:00:20.275Z" }, + { url = "https://files.pythonhosted.org/packages/1f/fd/e5b64f7d2c92a41639ffb2ad44a6a82f347787abc0c7df5f49057cf11770/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:79b2ffbba483f4ed36a0f236ccb85fbb16e670c9238313709638167670ba235f", size = 231724, upload-time = "2025-06-09T23:00:21.705Z" }, + { url = "https://files.pythonhosted.org/packages/20/fb/03395c0a43a5976af4bf7534759d214405fbbb4c114683f434dfdd3128ef/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26f205c9ca5829cbf82bb2a84b5c36f7184c4316617d7ef1b271a56720d6b30", size = 245842, upload-time = "2025-06-09T23:00:23.148Z" }, + { url = "https://files.pythonhosted.org/packages/d0/15/c01c8e1dffdac5d9803507d824f27aed2ba76b6ed0026fab4d9866e82f1f/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcacfad3185a623fa11ea0e0634aac7b691aa925d50a440f39b458e41c561d98", size = 239767, upload-time = "2025-06-09T23:00:25.103Z" }, + { url = "https://files.pythonhosted.org/packages/14/99/3f4c6fe882c1f5514b6848aa0a69b20cb5e5d8e8f51a339d48c0e9305ed0/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72c1b0fe8fe451b34f12dce46445ddf14bd2a5bcad7e324987194dc8e3a74c86", size = 224130, upload-time = "2025-06-09T23:00:27.061Z" }, + { url = "https://files.pythonhosted.org/packages/4d/83/220a374bd7b2aeba9d0725130665afe11de347d95c3620b9b82cc2fcab97/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d1a5baeaac6c0798ff6edfaeaa00e0e412d49946c53fae8d4b8e8b3566c4ae", size = 235301, upload-time = "2025-06-09T23:00:29.02Z" }, + { url = "https://files.pythonhosted.org/packages/03/3c/3e3390d75334a063181625343e8daab61b77e1b8214802cc4e8a1bb678fc/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7edf5c043c062462f09b6820de9854bf28cc6cc5b6714b383149745e287181a8", size = 234606, upload-time = "2025-06-09T23:00:30.514Z" }, + { url = "https://files.pythonhosted.org/packages/23/1e/58232c19608b7a549d72d9903005e2d82488f12554a32de2d5fb59b9b1ba/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d50ac7627b3a1bd2dcef6f9da89a772694ec04d9a61b66cf87f7d9446b4a0c31", size = 248372, upload-time = "2025-06-09T23:00:31.966Z" }, + { url = "https://files.pythonhosted.org/packages/c0/a4/e4a567e01702a88a74ce8a324691e62a629bf47d4f8607f24bf1c7216e7f/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce48b2fece5aeb45265bb7a58259f45027db0abff478e3077e12b05b17fb9da7", size = 229860, upload-time = "2025-06-09T23:00:33.375Z" }, + { url = "https://files.pythonhosted.org/packages/73/a6/63b3374f7d22268b41a9db73d68a8233afa30ed164c46107b33c4d18ecdd/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:fe2365ae915a1fafd982c146754e1de6ab3478def8a59c86e1f7242d794f97d5", size = 245893, upload-time = "2025-06-09T23:00:35.002Z" }, + { url = "https://files.pythonhosted.org/packages/6d/eb/d18b3f6e64799a79673c4ba0b45e4cfbe49c240edfd03a68be20002eaeaa/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:45a6f2fdbd10e074e8814eb98b05292f27bad7d1883afbe009d96abdcf3bc898", size = 246323, upload-time = "2025-06-09T23:00:36.468Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f5/720f3812e3d06cd89a1d5db9ff6450088b8f5c449dae8ffb2971a44da506/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:21884e23cffabb157a9dd7e353779077bf5b8f9a58e9b262c6caad2ef5f80a56", size = 233149, upload-time = "2025-06-09T23:00:37.963Z" }, + { url = "https://files.pythonhosted.org/packages/69/68/03efbf545e217d5db8446acfd4c447c15b7c8cf4dbd4a58403111df9322d/frozenlist-1.7.0-cp311-cp311-win32.whl", hash = "sha256:284d233a8953d7b24f9159b8a3496fc1ddc00f4db99c324bd5fb5f22d8698ea7", size = 39565, upload-time = "2025-06-09T23:00:39.753Z" }, + { url = "https://files.pythonhosted.org/packages/58/17/fe61124c5c333ae87f09bb67186d65038834a47d974fc10a5fadb4cc5ae1/frozenlist-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:387cbfdcde2f2353f19c2f66bbb52406d06ed77519ac7ee21be0232147c2592d", size = 44019, upload-time = "2025-06-09T23:00:40.988Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424, upload-time = "2025-06-09T23:00:42.24Z" }, + { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952, upload-time = "2025-06-09T23:00:43.481Z" }, + { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688, upload-time = "2025-06-09T23:00:44.793Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084, upload-time = "2025-06-09T23:00:46.125Z" }, + { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524, upload-time = "2025-06-09T23:00:47.73Z" }, + { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493, upload-time = "2025-06-09T23:00:49.742Z" }, + { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116, upload-time = "2025-06-09T23:00:51.352Z" }, + { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557, upload-time = "2025-06-09T23:00:52.855Z" }, + { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820, upload-time = "2025-06-09T23:00:54.43Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542, upload-time = "2025-06-09T23:00:56.409Z" }, + { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350, upload-time = "2025-06-09T23:00:58.468Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093, upload-time = "2025-06-09T23:01:00.015Z" }, + { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482, upload-time = "2025-06-09T23:01:01.474Z" }, + { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590, upload-time = "2025-06-09T23:01:02.961Z" }, + { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785, upload-time = "2025-06-09T23:01:05.095Z" }, + { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487, upload-time = "2025-06-09T23:01:06.54Z" }, + { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874, upload-time = "2025-06-09T23:01:07.752Z" }, + { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106, upload-time = "2025-06-09T23:02:34.204Z" }, +] + +[[package]] +name = "greenlet" +version = "3.2.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260, upload-time = "2025-08-07T13:24:33.51Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/ed/6bfa4109fcb23a58819600392564fea69cdc6551ffd5e69ccf1d52a40cbc/greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c", size = 271061, upload-time = "2025-08-07T13:17:15.373Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fc/102ec1a2fc015b3a7652abab7acf3541d58c04d3d17a8d3d6a44adae1eb1/greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590", size = 629475, upload-time = "2025-08-07T13:42:54.009Z" }, + { url = "https://files.pythonhosted.org/packages/c5/26/80383131d55a4ac0fb08d71660fd77e7660b9db6bdb4e8884f46d9f2cc04/greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c", size = 640802, upload-time = "2025-08-07T13:45:25.52Z" }, + { url = "https://files.pythonhosted.org/packages/9f/7c/e7833dbcd8f376f3326bd728c845d31dcde4c84268d3921afcae77d90d08/greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b", size = 636703, upload-time = "2025-08-07T13:53:12.622Z" }, + { url = "https://files.pythonhosted.org/packages/e9/49/547b93b7c0428ede7b3f309bc965986874759f7d89e4e04aeddbc9699acb/greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31", size = 635417, upload-time = "2025-08-07T13:18:25.189Z" }, + { url = "https://files.pythonhosted.org/packages/7f/91/ae2eb6b7979e2f9b035a9f612cf70f1bf54aad4e1d125129bef1eae96f19/greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d", size = 584358, upload-time = "2025-08-07T13:18:23.708Z" }, + { url = "https://files.pythonhosted.org/packages/f7/85/433de0c9c0252b22b16d413c9407e6cb3b41df7389afc366ca204dbc1393/greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5", size = 1113550, upload-time = "2025-08-07T13:42:37.467Z" }, + { url = "https://files.pythonhosted.org/packages/a1/8d/88f3ebd2bc96bf7747093696f4335a0a8a4c5acfcf1b757717c0d2474ba3/greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f", size = 1137126, upload-time = "2025-08-07T13:18:20.239Z" }, + { url = "https://files.pythonhosted.org/packages/d6/6f/b60b0291d9623c496638c582297ead61f43c4b72eef5e9c926ef4565ec13/greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c", size = 298654, upload-time = "2025-08-07T13:50:00.469Z" }, + { url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" }, + { url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/95d48d7e3d433e6dae5b1682e4292242a53f22df82e6d3dda81b1701a960/greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3", size = 644646, upload-time = "2025-08-07T13:45:26.523Z" }, + { url = "https://files.pythonhosted.org/packages/d5/5e/405965351aef8c76b8ef7ad370e5da58d57ef6068df197548b015464001a/greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633", size = 640519, upload-time = "2025-08-07T13:53:13.928Z" }, + { url = "https://files.pythonhosted.org/packages/25/5d/382753b52006ce0218297ec1b628e048c4e64b155379331f25a7316eb749/greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079", size = 639707, upload-time = "2025-08-07T13:18:27.146Z" }, + { url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" }, + { url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" }, + { url = "https://files.pythonhosted.org/packages/3f/cc/b07000438a29ac5cfb2194bfc128151d52f333cee74dd7dfe3fb733fc16c/greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa", size = 1142073, upload-time = "2025-08-07T13:18:21.737Z" }, + { url = "https://files.pythonhosted.org/packages/d8/0f/30aef242fcab550b0b3520b8e3561156857c94288f0332a79928c31a52cf/greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9", size = 299100, upload-time = "2025-08-07T13:44:12.287Z" }, + { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, + { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, + { url = "https://files.pythonhosted.org/packages/3b/16/035dcfcc48715ccd345f3a93183267167cdd162ad123cd93067d86f27ce4/greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968", size = 655185, upload-time = "2025-08-07T13:45:27.624Z" }, + { url = "https://files.pythonhosted.org/packages/31/da/0386695eef69ffae1ad726881571dfe28b41970173947e7c558d9998de0f/greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9", size = 649926, upload-time = "2025-08-07T13:53:15.251Z" }, + { url = "https://files.pythonhosted.org/packages/68/88/69bf19fd4dc19981928ceacbc5fd4bb6bc2215d53199e367832e98d1d8fe/greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6", size = 651839, upload-time = "2025-08-07T13:18:30.281Z" }, + { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, + { url = "https://files.pythonhosted.org/packages/3f/c7/12381b18e21aef2c6bd3a636da1088b888b97b7a0362fac2e4de92405f97/greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f", size = 1151142, upload-time = "2025-08-07T13:18:22.981Z" }, + { url = "https://files.pythonhosted.org/packages/e9/08/b0814846b79399e585f974bbeebf5580fbe59e258ea7be64d9dfb253c84f/greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02", size = 299899, upload-time = "2025-08-07T13:38:53.448Z" }, +] + +[[package]] +name = "grpcio" +version = "1.69.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/87/06a145284cbe86c91ca517fe6b57be5efbb733c0d6374b407f0992054d18/grpcio-1.69.0.tar.gz", hash = "sha256:936fa44241b5379c5afc344e1260d467bee495747eaf478de825bab2791da6f5", size = 12738244, upload-time = "2025-01-05T05:53:20.27Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/6e/2f8ee5fb65aef962d0bd7e46b815e7b52820687e29c138eaee207a688abc/grpcio-1.69.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:2060ca95a8db295ae828d0fc1c7f38fb26ccd5edf9aa51a0f44251f5da332e97", size = 5190753, upload-time = "2025-01-05T05:45:05.892Z" }, + { url = "https://files.pythonhosted.org/packages/89/07/028dcda44d40f9488f0a0de79c5ffc80e2c1bc5ed89da9483932e3ea67cf/grpcio-1.69.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2e52e107261fd8fa8fa457fe44bfadb904ae869d87c1280bf60f93ecd3e79278", size = 11096752, upload-time = "2025-01-05T05:45:11.517Z" }, + { url = "https://files.pythonhosted.org/packages/99/a0/c727041b1410605ba38b585b6b52c1a289d7fcd70a41bccbc2c58fc643b2/grpcio-1.69.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:316463c0832d5fcdb5e35ff2826d9aa3f26758d29cdfb59a368c1d6c39615a11", size = 5705442, upload-time = "2025-01-05T05:45:18.828Z" }, + { url = "https://files.pythonhosted.org/packages/7a/2f/1c53f5d127ff882443b19c757d087da1908f41c58c4b098e8eaf6b2bb70a/grpcio-1.69.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26c9a9c4ac917efab4704b18eed9082ed3b6ad19595f047e8173b5182fec0d5e", size = 6333796, upload-time = "2025-01-05T05:45:23.431Z" }, + { url = "https://files.pythonhosted.org/packages/cc/f6/2017da2a1b64e896af710253e5bfbb4188605cdc18bce3930dae5cdbf502/grpcio-1.69.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90b3646ced2eae3a0599658eeccc5ba7f303bf51b82514c50715bdd2b109e5ec", size = 5954245, upload-time = "2025-01-05T05:45:27.374Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/1395bec928e99ba600464fb01b541e7e4cdd462e6db25259d755ef9f8d02/grpcio-1.69.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3b75aea7c6cb91b341c85e7c1d9db1e09e1dd630b0717f836be94971e015031e", size = 6664854, upload-time = "2025-01-05T05:45:32.031Z" }, + { url = "https://files.pythonhosted.org/packages/40/57/8b3389cfeb92056c8b44288c9c4ed1d331bcad0215c4eea9ae4629e156d9/grpcio-1.69.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5cfd14175f9db33d4b74d63de87c64bb0ee29ce475ce3c00c01ad2a3dc2a9e51", size = 6226854, upload-time = "2025-01-05T05:45:36.915Z" }, + { url = "https://files.pythonhosted.org/packages/cc/61/1f2bbeb7c15544dffc98b3f65c093e746019995e6f1e21dc3655eec3dc23/grpcio-1.69.0-cp310-cp310-win32.whl", hash = "sha256:9031069d36cb949205293cf0e243abd5e64d6c93e01b078c37921493a41b72dc", size = 3662734, upload-time = "2025-01-05T05:45:40.798Z" }, + { url = "https://files.pythonhosted.org/packages/ef/ba/bf1a6d9f5c17d2da849793d72039776c56c98c889c9527f6721b6ee57e6e/grpcio-1.69.0-cp310-cp310-win_amd64.whl", hash = "sha256:cc89b6c29f3dccbe12d7a3b3f1b3999db4882ae076c1c1f6df231d55dbd767a5", size = 4410306, upload-time = "2025-01-05T05:45:45.299Z" }, + { url = "https://files.pythonhosted.org/packages/8d/cd/ca256aeef64047881586331347cd5a68a4574ba1a236e293cd8eba34e355/grpcio-1.69.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:8de1b192c29b8ce45ee26a700044717bcbbd21c697fa1124d440548964328561", size = 5198734, upload-time = "2025-01-05T05:45:49.29Z" }, + { url = "https://files.pythonhosted.org/packages/37/3f/10c1e5e0150bf59aa08ea6aebf38f87622f95f7f33f98954b43d1b2a3200/grpcio-1.69.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:7e76accf38808f5c5c752b0ab3fd919eb14ff8fafb8db520ad1cc12afff74de6", size = 11135285, upload-time = "2025-01-05T05:45:53.724Z" }, + { url = "https://files.pythonhosted.org/packages/08/61/61cd116a572203a740684fcba3fef37a3524f1cf032b6568e1e639e59db0/grpcio-1.69.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:d5658c3c2660417d82db51e168b277e0ff036d0b0f859fa7576c0ffd2aec1442", size = 5699468, upload-time = "2025-01-05T05:45:58.69Z" }, + { url = "https://files.pythonhosted.org/packages/01/f1/a841662e8e2465ba171c973b77d18fa7438ced535519b3c53617b7e6e25c/grpcio-1.69.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5494d0e52bf77a2f7eb17c6da662886ca0a731e56c1c85b93505bece8dc6cf4c", size = 6332337, upload-time = "2025-01-05T05:46:05.323Z" }, + { url = "https://files.pythonhosted.org/packages/62/b1/c30e932e02c2e0bfdb8df46fe3b0c47f518fb04158ebdc0eb96cc97d642f/grpcio-1.69.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ed866f9edb574fd9be71bf64c954ce1b88fc93b2a4cbf94af221e9426eb14d6", size = 5949844, upload-time = "2025-01-05T05:46:09.727Z" }, + { url = "https://files.pythonhosted.org/packages/5e/cb/55327d43b6286100ffae7d1791be6178d13c917382f3e9f43f82e8b393cf/grpcio-1.69.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c5ba38aeac7a2fe353615c6b4213d1fbb3a3c34f86b4aaa8be08baaaee8cc56d", size = 6661828, upload-time = "2025-01-05T05:46:14.937Z" }, + { url = "https://files.pythonhosted.org/packages/6f/e4/120d72ae982d51cb9cabcd9672f8a1c6d62011b493a4d049d2abdf564db0/grpcio-1.69.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f79e05f5bbf551c4057c227d1b041ace0e78462ac8128e2ad39ec58a382536d2", size = 6226026, upload-time = "2025-01-05T05:46:17.465Z" }, + { url = "https://files.pythonhosted.org/packages/96/e8/2cc15f11db506d7b1778f0587fa7bdd781602b05b3c4d75b7ca13de33d62/grpcio-1.69.0-cp311-cp311-win32.whl", hash = "sha256:bf1f8be0da3fcdb2c1e9f374f3c2d043d606d69f425cd685110dd6d0d2d61258", size = 3662653, upload-time = "2025-01-05T05:46:19.797Z" }, + { url = "https://files.pythonhosted.org/packages/42/78/3c5216829a48237fcb71a077f891328a435e980d9757a9ebc49114d88768/grpcio-1.69.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb9302afc3a0e4ba0b225cd651ef8e478bf0070cf11a529175caecd5ea2474e7", size = 4412824, upload-time = "2025-01-05T05:46:22.421Z" }, + { url = "https://files.pythonhosted.org/packages/61/1d/8f28f147d7f3f5d6b6082f14e1e0f40d58e50bc2bd30d2377c730c57a286/grpcio-1.69.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:fc18a4de8c33491ad6f70022af5c460b39611e39578a4d84de0fe92f12d5d47b", size = 5161414, upload-time = "2025-01-05T05:46:27.03Z" }, + { url = "https://files.pythonhosted.org/packages/35/4b/9ab8ea65e515e1844feced1ef9e7a5d8359c48d986c93f3d2a2006fbdb63/grpcio-1.69.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:0f0270bd9ffbff6961fe1da487bdcd594407ad390cc7960e738725d4807b18c4", size = 11108909, upload-time = "2025-01-05T05:46:31.986Z" }, + { url = "https://files.pythonhosted.org/packages/99/68/1856fde2b3c3162bdfb9845978608deef3606e6907fdc2c87443fce6ecd0/grpcio-1.69.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:dc48f99cc05e0698e689b51a05933253c69a8c8559a47f605cff83801b03af0e", size = 5658302, upload-time = "2025-01-05T05:46:37.05Z" }, + { url = "https://files.pythonhosted.org/packages/3e/21/3fa78d38dc5080d0d677103fad3a8cd55091635cc2069a7c06c7a54e6c4d/grpcio-1.69.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e925954b18d41aeb5ae250262116d0970893b38232689c4240024e4333ac084", size = 6306201, upload-time = "2025-01-05T05:46:41.138Z" }, + { url = "https://files.pythonhosted.org/packages/f3/cb/5c47b82fd1baf43dba973ae399095d51aaf0085ab0439838b4cbb1e87e3c/grpcio-1.69.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d222569273720366f68a99cb62e6194681eb763ee1d3b1005840678d4884f9", size = 5919649, upload-time = "2025-01-05T05:46:45.366Z" }, + { url = "https://files.pythonhosted.org/packages/c6/67/59d1a56a0f9508a29ea03e1ce800bdfacc1f32b4f6b15274b2e057bf8758/grpcio-1.69.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b62b0f41e6e01a3e5082000b612064c87c93a49b05f7602fe1b7aa9fd5171a1d", size = 6648974, upload-time = "2025-01-05T05:46:48.208Z" }, + { url = "https://files.pythonhosted.org/packages/f8/fe/ca70c14d98c6400095f19a0f4df8273d09c2106189751b564b26019f1dbe/grpcio-1.69.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:db6f9fd2578dbe37db4b2994c94a1d9c93552ed77dca80e1657bb8a05b898b55", size = 6215144, upload-time = "2025-01-05T05:46:50.891Z" }, + { url = "https://files.pythonhosted.org/packages/b3/94/b2b0a9fd487fc8262e20e6dd0ec90d9fa462c82a43b4855285620f6e9d01/grpcio-1.69.0-cp312-cp312-win32.whl", hash = "sha256:b192b81076073ed46f4b4dd612b8897d9a1e39d4eabd822e5da7b38497ed77e1", size = 3644552, upload-time = "2025-01-05T05:46:55.811Z" }, + { url = "https://files.pythonhosted.org/packages/93/99/81aec9f85412e3255a591ae2ccb799238e074be774e5f741abae08a23418/grpcio-1.69.0-cp312-cp312-win_amd64.whl", hash = "sha256:1227ff7836f7b3a4ab04e5754f1d001fa52a730685d3dc894ed8bc262cc96c01", size = 4399532, upload-time = "2025-01-05T05:46:58.348Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "http-ece" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/af/249d1576653b69c20b9ac30e284b63bd94af6a175d72d87813235caf2482/http_ece-1.2.1.tar.gz", hash = "sha256:8c6ab23116bbf6affda894acfd5f2ca0fb8facbcbb72121c11c75c33e7ce8cff", size = 8830, upload-time = "2024-08-08T00:10:47.301Z" } + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, + { name = "sniffio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c339f240c1802f2e82d55e50bd39c5a881f47f0/httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5", size = 126413, upload-time = "2024-02-21T13:07:52.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/7b/ddacf6dcebb42466abd03f368782142baa82e08fc0c1f8eaa05b4bae87d5/httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5", size = 75590, upload-time = "2024-02-21T13:07:50.455Z" }, +] + +[[package]] +name = "identify" +version = "2.6.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/c4/62963f25a678f6a050fb0505a65e9e726996171e6dbe1547f79619eefb15/identify-2.6.14.tar.gz", hash = "sha256:663494103b4f717cb26921c52f8751363dc89db64364cd836a9bf1535f53cd6a", size = 99283, upload-time = "2025-09-06T19:30:52.938Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/ae/2ad30f4652712c82f1c23423d79136fbce338932ad166d70c1efb86a5998/identify-2.6.14-py2.py3-none-any.whl", hash = "sha256:11a073da82212c6646b1f39bb20d4483bfb9543bd5566fec60053c4bb309bf2e", size = 99172, upload-time = "2025-09-06T19:30:51.759Z" }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, +] + +[[package]] +name = "itsdangerous" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jsonpath-ng" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ply" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/86/08646239a313f895186ff0a4573452038eed8c86f54380b3ebac34d32fb2/jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c", size = 37838, upload-time = "2024-10-11T15:41:42.404Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/5a/73ecb3d82f8615f32ccdadeb9356726d6cae3a4bbc840b437ceb95708063/jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6", size = 30105, upload-time = "2024-11-20T17:58:30.418Z" }, +] + +[[package]] +name = "limits" +version = "5.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "deprecated" }, + { name = "packaging" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/17/7a2e9378c8b8bd4efe3573fd18d2793ad2a37051af5ccce94550a4e5d62d/limits-5.5.0.tar.gz", hash = "sha256:ee269fedb078a904608b264424d9ef4ab10555acc8d090b6fc1db70e913327ea", size = 95514, upload-time = "2025-08-05T18:23:54.771Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/68/ee314018c28da75ece5a639898b4745bd0687c0487fc465811f0c4b9cd44/limits-5.5.0-py3-none-any.whl", hash = "sha256:57217d01ffa5114f7e233d1f5e5bdc6fe60c9b24ade387bf4d5e83c5cf929bae", size = 60948, upload-time = "2025-08-05T18:23:53.335Z" }, +] + +[[package]] +name = "lnbits" +version = "1.3.0rc6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiosqlite" }, + { name = "asyncpg" }, + { name = "bcrypt" }, + { name = "bech32" }, + { name = "bolt11" }, + { name = "click" }, + { name = "ecdsa" }, + { name = "embit" }, + { name = "environs" }, + { name = "fastapi" }, + { name = "fastapi-sso" }, + { name = "filetype" }, + { name = "grpcio" }, + { name = "httpx" }, + { name = "itsdangerous" }, + { name = "jinja2" }, + { name = "jsonpath-ng" }, + { name = "lnurl" }, + { name = "loguru" }, + { name = "nostr-sdk" }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "pycryptodomex" }, + { name = "pydantic" }, + { name = "pyjwt" }, + { name = "pyln-client" }, + { name = "pynostr" }, + { name = "pyqrcode" }, + { name = "python-crontab" }, + { name = "python-multipart" }, + { name = "pywebpush" }, + { name = "secp256k1" }, + { name = "shortuuid" }, + { name = "slowapi" }, + { name = "sqlalchemy" }, + { name = "sse-starlette" }, + { name = "starlette" }, + { name = "typing-extensions" }, + { name = "uvicorn" }, + { name = "uvloop" }, + { name = "websocket-client" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/60/c2f1aa29e2f6716a2583f614aa1808ea6c2b4321d3ff8df082b8228ecdaf/lnbits-1.3.0rc6.tar.gz", hash = "sha256:bd13dd5322354907684a82b301c9a24a7b66e43b1f28dc8e7e5a4c87bd8e32a7", size = 3684527, upload-time = "2025-09-02T16:55:50.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/57/7cc2f76cda6aa098dd42cddc9ed81da248bf25afcd3d2ec93377bb947f90/lnbits-1.3.0rc6-py3-none-any.whl", hash = "sha256:3d4c5ac7a12964374589890445e70ec1e1734117f67f1665ca5ac076169d3abf", size = 3343640, upload-time = "2025-09-02T16:55:49.369Z" }, +] + +[[package]] +name = "lnurl" +version = "0.8.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "bech32" }, + { name = "bip32" }, + { name = "bolt11" }, + { name = "ecdsa" }, + { name = "httpx" }, + { name = "pycryptodomex" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/32/b611804e96fd1e76e9bdf306395e4a9e52f9343994b65fd9646e48318107/lnurl-0.8.1.tar.gz", hash = "sha256:7d2412c309227a3148510cbed92c3500c9366c624354eef2fc205bdf30d4655c", size = 17096, upload-time = "2025-08-27T05:50:19.948Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/bf/6061b01bfc62ad3d1f82d8546dc543fc2ccc391f0911d5718abe578b0661/lnurl-0.8.1-py3-none-any.whl", hash = "sha256:a451f1b78c62146fda7a17954e2eaa1de994092a19266b5c64c25577ecd66eae", size = 17382, upload-time = "2025-08-27T05:50:19.013Z" }, +] + +[[package]] +name = "loguru" +version = "0.7.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "win32-setctime", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357, upload-time = "2024-10-18T15:20:51.44Z" }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393, upload-time = "2024-10-18T15:20:52.426Z" }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732, upload-time = "2024-10-18T15:20:53.578Z" }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866, upload-time = "2024-10-18T15:20:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964, upload-time = "2024-10-18T15:20:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977, upload-time = "2024-10-18T15:20:57.189Z" }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366, upload-time = "2024-10-18T15:20:58.235Z" }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091, upload-time = "2024-10-18T15:20:59.235Z" }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065, upload-time = "2024-10-18T15:21:00.307Z" }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514, upload-time = "2024-10-18T15:21:01.122Z" }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, +] + +[[package]] +name = "marshmallow" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "backports-datetime-fromisoformat", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/ff/8f092fe402ef12aa71b7f4ceba0c557ce4d5876a9cf421e01a67b7210560/marshmallow-4.0.1.tar.gz", hash = "sha256:e1d860bd262737cb2d34e1541b84cb52c32c72c9474e3fe6f30f137ef8b0d97f", size = 220453, upload-time = "2025-08-28T15:01:37.044Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/18/297efc62b3539b9cd379fc49be3740a02e4c8a43e486f50322cfe0b9568a/marshmallow-4.0.1-py3-none-any.whl", hash = "sha256:72f14ef346f81269dbddee891bac547dda1501e9e08b6a809756ea3dbb7936a1", size = 48414, upload-time = "2025-08-28T15:01:35.221Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "multidict" +version = "6.6.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/7f/0652e6ed47ab288e3756ea9c0df8b14950781184d4bd7883f4d87dd41245/multidict-6.6.4.tar.gz", hash = "sha256:d2d4e4787672911b48350df02ed3fa3fffdc2f2e8ca06dd6afdf34189b76a9dd", size = 101843, upload-time = "2025-08-11T12:08:48.217Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/6b/86f353088c1358e76fd30b0146947fddecee812703b604ee901e85cd2a80/multidict-6.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b8aa6f0bd8125ddd04a6593437bad6a7e70f300ff4180a531654aa2ab3f6d58f", size = 77054, upload-time = "2025-08-11T12:06:02.99Z" }, + { url = "https://files.pythonhosted.org/packages/19/5d/c01dc3d3788bb877bd7f5753ea6eb23c1beeca8044902a8f5bfb54430f63/multidict-6.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b9e5853bbd7264baca42ffc53391b490d65fe62849bf2c690fa3f6273dbcd0cb", size = 44914, upload-time = "2025-08-11T12:06:05.264Z" }, + { url = "https://files.pythonhosted.org/packages/46/44/964dae19ea42f7d3e166474d8205f14bb811020e28bc423d46123ddda763/multidict-6.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0af5f9dee472371e36d6ae38bde009bd8ce65ac7335f55dcc240379d7bed1495", size = 44601, upload-time = "2025-08-11T12:06:06.627Z" }, + { url = "https://files.pythonhosted.org/packages/31/20/0616348a1dfb36cb2ab33fc9521de1f27235a397bf3f59338e583afadd17/multidict-6.6.4-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:d24f351e4d759f5054b641c81e8291e5d122af0fca5c72454ff77f7cbe492de8", size = 224821, upload-time = "2025-08-11T12:06:08.06Z" }, + { url = "https://files.pythonhosted.org/packages/14/26/5d8923c69c110ff51861af05bd27ca6783011b96725d59ccae6d9daeb627/multidict-6.6.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db6a3810eec08280a172a6cd541ff4a5f6a97b161d93ec94e6c4018917deb6b7", size = 242608, upload-time = "2025-08-11T12:06:09.697Z" }, + { url = "https://files.pythonhosted.org/packages/5c/cc/e2ad3ba9459aa34fa65cf1f82a5c4a820a2ce615aacfb5143b8817f76504/multidict-6.6.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a1b20a9d56b2d81e2ff52ecc0670d583eaabaa55f402e8d16dd062373dbbe796", size = 222324, upload-time = "2025-08-11T12:06:10.905Z" }, + { url = "https://files.pythonhosted.org/packages/19/db/4ed0f65701afbc2cb0c140d2d02928bb0fe38dd044af76e58ad7c54fd21f/multidict-6.6.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8c9854df0eaa610a23494c32a6f44a3a550fb398b6b51a56e8c6b9b3689578db", size = 253234, upload-time = "2025-08-11T12:06:12.658Z" }, + { url = "https://files.pythonhosted.org/packages/94/c1/5160c9813269e39ae14b73debb907bfaaa1beee1762da8c4fb95df4764ed/multidict-6.6.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4bb7627fd7a968f41905a4d6343b0d63244a0623f006e9ed989fa2b78f4438a0", size = 251613, upload-time = "2025-08-11T12:06:13.97Z" }, + { url = "https://files.pythonhosted.org/packages/05/a9/48d1bd111fc2f8fb98b2ed7f9a115c55a9355358432a19f53c0b74d8425d/multidict-6.6.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caebafea30ed049c57c673d0b36238b1748683be2593965614d7b0e99125c877", size = 241649, upload-time = "2025-08-11T12:06:15.204Z" }, + { url = "https://files.pythonhosted.org/packages/85/2a/f7d743df0019408768af8a70d2037546a2be7b81fbb65f040d76caafd4c5/multidict-6.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ad887a8250eb47d3ab083d2f98db7f48098d13d42eb7a3b67d8a5c795f224ace", size = 239238, upload-time = "2025-08-11T12:06:16.467Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b8/4f4bb13323c2d647323f7919201493cf48ebe7ded971717bfb0f1a79b6bf/multidict-6.6.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:ed8358ae7d94ffb7c397cecb62cbac9578a83ecefc1eba27b9090ee910e2efb6", size = 233517, upload-time = "2025-08-11T12:06:18.107Z" }, + { url = "https://files.pythonhosted.org/packages/33/29/4293c26029ebfbba4f574febd2ed01b6f619cfa0d2e344217d53eef34192/multidict-6.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ecab51ad2462197a4c000b6d5701fc8585b80eecb90583635d7e327b7b6923eb", size = 243122, upload-time = "2025-08-11T12:06:19.361Z" }, + { url = "https://files.pythonhosted.org/packages/20/60/a1c53628168aa22447bfde3a8730096ac28086704a0d8c590f3b63388d0c/multidict-6.6.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c5c97aa666cf70e667dfa5af945424ba1329af5dd988a437efeb3a09430389fb", size = 248992, upload-time = "2025-08-11T12:06:20.661Z" }, + { url = "https://files.pythonhosted.org/packages/a3/3b/55443a0c372f33cae5d9ec37a6a973802884fa0ab3586659b197cf8cc5e9/multidict-6.6.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9a950b7cf54099c1209f455ac5970b1ea81410f2af60ed9eb3c3f14f0bfcf987", size = 243708, upload-time = "2025-08-11T12:06:21.891Z" }, + { url = "https://files.pythonhosted.org/packages/7c/60/a18c6900086769312560b2626b18e8cca22d9e85b1186ba77f4755b11266/multidict-6.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:163c7ea522ea9365a8a57832dea7618e6cbdc3cd75f8c627663587459a4e328f", size = 237498, upload-time = "2025-08-11T12:06:23.206Z" }, + { url = "https://files.pythonhosted.org/packages/11/3d/8bdd8bcaff2951ce2affccca107a404925a2beafedd5aef0b5e4a71120a6/multidict-6.6.4-cp310-cp310-win32.whl", hash = "sha256:17d2cbbfa6ff20821396b25890f155f40c986f9cfbce5667759696d83504954f", size = 41415, upload-time = "2025-08-11T12:06:24.77Z" }, + { url = "https://files.pythonhosted.org/packages/c0/53/cab1ad80356a4cd1b685a254b680167059b433b573e53872fab245e9fc95/multidict-6.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:ce9a40fbe52e57e7edf20113a4eaddfacac0561a0879734e636aa6d4bb5e3fb0", size = 46046, upload-time = "2025-08-11T12:06:25.893Z" }, + { url = "https://files.pythonhosted.org/packages/cf/9a/874212b6f5c1c2d870d0a7adc5bb4cfe9b0624fa15cdf5cf757c0f5087ae/multidict-6.6.4-cp310-cp310-win_arm64.whl", hash = "sha256:01d0959807a451fe9fdd4da3e139cb5b77f7328baf2140feeaf233e1d777b729", size = 43147, upload-time = "2025-08-11T12:06:27.534Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7f/90a7f01e2d005d6653c689039977f6856718c75c5579445effb7e60923d1/multidict-6.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c7a0e9b561e6460484318a7612e725df1145d46b0ef57c6b9866441bf6e27e0c", size = 76472, upload-time = "2025-08-11T12:06:29.006Z" }, + { url = "https://files.pythonhosted.org/packages/54/a3/bed07bc9e2bb302ce752f1dabc69e884cd6a676da44fb0e501b246031fdd/multidict-6.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6bf2f10f70acc7a2446965ffbc726e5fc0b272c97a90b485857e5c70022213eb", size = 44634, upload-time = "2025-08-11T12:06:30.374Z" }, + { url = "https://files.pythonhosted.org/packages/a7/4b/ceeb4f8f33cf81277da464307afeaf164fb0297947642585884f5cad4f28/multidict-6.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66247d72ed62d5dd29752ffc1d3b88f135c6a8de8b5f63b7c14e973ef5bda19e", size = 44282, upload-time = "2025-08-11T12:06:31.958Z" }, + { url = "https://files.pythonhosted.org/packages/03/35/436a5da8702b06866189b69f655ffdb8f70796252a8772a77815f1812679/multidict-6.6.4-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:105245cc6b76f51e408451a844a54e6823bbd5a490ebfe5bdfc79798511ceded", size = 229696, upload-time = "2025-08-11T12:06:33.087Z" }, + { url = "https://files.pythonhosted.org/packages/b6/0e/915160be8fecf1fca35f790c08fb74ca684d752fcba62c11daaf3d92c216/multidict-6.6.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cbbc54e58b34c3bae389ef00046be0961f30fef7cb0dd9c7756aee376a4f7683", size = 246665, upload-time = "2025-08-11T12:06:34.448Z" }, + { url = "https://files.pythonhosted.org/packages/08/ee/2f464330acd83f77dcc346f0b1a0eaae10230291450887f96b204b8ac4d3/multidict-6.6.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:56c6b3652f945c9bc3ac6c8178cd93132b8d82dd581fcbc3a00676c51302bc1a", size = 225485, upload-time = "2025-08-11T12:06:35.672Z" }, + { url = "https://files.pythonhosted.org/packages/71/cc/9a117f828b4d7fbaec6adeed2204f211e9caf0a012692a1ee32169f846ae/multidict-6.6.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b95494daf857602eccf4c18ca33337dd2be705bccdb6dddbfc9d513e6addb9d9", size = 257318, upload-time = "2025-08-11T12:06:36.98Z" }, + { url = "https://files.pythonhosted.org/packages/25/77/62752d3dbd70e27fdd68e86626c1ae6bccfebe2bb1f84ae226363e112f5a/multidict-6.6.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e5b1413361cef15340ab9dc61523e653d25723e82d488ef7d60a12878227ed50", size = 254689, upload-time = "2025-08-11T12:06:38.233Z" }, + { url = "https://files.pythonhosted.org/packages/00/6e/fac58b1072a6fc59af5e7acb245e8754d3e1f97f4f808a6559951f72a0d4/multidict-6.6.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e167bf899c3d724f9662ef00b4f7fef87a19c22b2fead198a6f68b263618df52", size = 246709, upload-time = "2025-08-11T12:06:39.517Z" }, + { url = "https://files.pythonhosted.org/packages/01/ef/4698d6842ef5e797c6db7744b0081e36fb5de3d00002cc4c58071097fac3/multidict-6.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aaea28ba20a9026dfa77f4b80369e51cb767c61e33a2d4043399c67bd95fb7c6", size = 243185, upload-time = "2025-08-11T12:06:40.796Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c9/d82e95ae1d6e4ef396934e9b0e942dfc428775f9554acf04393cce66b157/multidict-6.6.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8c91cdb30809a96d9ecf442ec9bc45e8cfaa0f7f8bdf534e082c2443a196727e", size = 237838, upload-time = "2025-08-11T12:06:42.595Z" }, + { url = "https://files.pythonhosted.org/packages/57/cf/f94af5c36baaa75d44fab9f02e2a6bcfa0cd90acb44d4976a80960759dbc/multidict-6.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1a0ccbfe93ca114c5d65a2471d52d8829e56d467c97b0e341cf5ee45410033b3", size = 246368, upload-time = "2025-08-11T12:06:44.304Z" }, + { url = "https://files.pythonhosted.org/packages/4a/fe/29f23460c3d995f6a4b678cb2e9730e7277231b981f0b234702f0177818a/multidict-6.6.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:55624b3f321d84c403cb7d8e6e982f41ae233d85f85db54ba6286f7295dc8a9c", size = 253339, upload-time = "2025-08-11T12:06:45.597Z" }, + { url = "https://files.pythonhosted.org/packages/29/b6/fd59449204426187b82bf8a75f629310f68c6adc9559dc922d5abe34797b/multidict-6.6.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4a1fb393a2c9d202cb766c76208bd7945bc194eba8ac920ce98c6e458f0b524b", size = 246933, upload-time = "2025-08-11T12:06:46.841Z" }, + { url = "https://files.pythonhosted.org/packages/19/52/d5d6b344f176a5ac3606f7a61fb44dc746e04550e1a13834dff722b8d7d6/multidict-6.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:43868297a5759a845fa3a483fb4392973a95fb1de891605a3728130c52b8f40f", size = 242225, upload-time = "2025-08-11T12:06:48.588Z" }, + { url = "https://files.pythonhosted.org/packages/ec/d3/5b2281ed89ff4d5318d82478a2a2450fcdfc3300da48ff15c1778280ad26/multidict-6.6.4-cp311-cp311-win32.whl", hash = "sha256:ed3b94c5e362a8a84d69642dbeac615452e8af9b8eb825b7bc9f31a53a1051e2", size = 41306, upload-time = "2025-08-11T12:06:49.95Z" }, + { url = "https://files.pythonhosted.org/packages/74/7d/36b045c23a1ab98507aefd44fd8b264ee1dd5e5010543c6fccf82141ccef/multidict-6.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:d8c112f7a90d8ca5d20213aa41eac690bb50a76da153e3afb3886418e61cb22e", size = 46029, upload-time = "2025-08-11T12:06:51.082Z" }, + { url = "https://files.pythonhosted.org/packages/0f/5e/553d67d24432c5cd52b49047f2d248821843743ee6d29a704594f656d182/multidict-6.6.4-cp311-cp311-win_arm64.whl", hash = "sha256:3bb0eae408fa1996d87247ca0d6a57b7fc1dcf83e8a5c47ab82c558c250d4adf", size = 43017, upload-time = "2025-08-11T12:06:52.243Z" }, + { url = "https://files.pythonhosted.org/packages/05/f6/512ffd8fd8b37fb2680e5ac35d788f1d71bbaf37789d21a820bdc441e565/multidict-6.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0ffb87be160942d56d7b87b0fdf098e81ed565add09eaa1294268c7f3caac4c8", size = 76516, upload-time = "2025-08-11T12:06:53.393Z" }, + { url = "https://files.pythonhosted.org/packages/99/58/45c3e75deb8855c36bd66cc1658007589662ba584dbf423d01df478dd1c5/multidict-6.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d191de6cbab2aff5de6c5723101705fd044b3e4c7cfd587a1929b5028b9714b3", size = 45394, upload-time = "2025-08-11T12:06:54.555Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/e8c4472a93a26e4507c0b8e1f0762c0d8a32de1328ef72fd704ef9cc5447/multidict-6.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38a0956dd92d918ad5feff3db8fcb4a5eb7dba114da917e1a88475619781b57b", size = 43591, upload-time = "2025-08-11T12:06:55.672Z" }, + { url = "https://files.pythonhosted.org/packages/05/51/edf414f4df058574a7265034d04c935aa84a89e79ce90fcf4df211f47b16/multidict-6.6.4-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6865f6d3b7900ae020b495d599fcf3765653bc927951c1abb959017f81ae8287", size = 237215, upload-time = "2025-08-11T12:06:57.213Z" }, + { url = "https://files.pythonhosted.org/packages/c8/45/8b3d6dbad8cf3252553cc41abea09ad527b33ce47a5e199072620b296902/multidict-6.6.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a2088c126b6f72db6c9212ad827d0ba088c01d951cee25e758c450da732c138", size = 258299, upload-time = "2025-08-11T12:06:58.946Z" }, + { url = "https://files.pythonhosted.org/packages/3c/e8/8ca2e9a9f5a435fc6db40438a55730a4bf4956b554e487fa1b9ae920f825/multidict-6.6.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0f37bed7319b848097085d7d48116f545985db988e2256b2e6f00563a3416ee6", size = 242357, upload-time = "2025-08-11T12:07:00.301Z" }, + { url = "https://files.pythonhosted.org/packages/0f/84/80c77c99df05a75c28490b2af8f7cba2a12621186e0a8b0865d8e745c104/multidict-6.6.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:01368e3c94032ba6ca0b78e7ccb099643466cf24f8dc8eefcfdc0571d56e58f9", size = 268369, upload-time = "2025-08-11T12:07:01.638Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e9/920bfa46c27b05fb3e1ad85121fd49f441492dca2449c5bcfe42e4565d8a/multidict-6.6.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fe323540c255db0bffee79ad7f048c909f2ab0edb87a597e1c17da6a54e493c", size = 269341, upload-time = "2025-08-11T12:07:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/af/65/753a2d8b05daf496f4a9c367fe844e90a1b2cac78e2be2c844200d10cc4c/multidict-6.6.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8eb3025f17b0a4c3cd08cda49acf312a19ad6e8a4edd9dbd591e6506d999402", size = 256100, upload-time = "2025-08-11T12:07:04.564Z" }, + { url = "https://files.pythonhosted.org/packages/09/54/655be13ae324212bf0bc15d665a4e34844f34c206f78801be42f7a0a8aaa/multidict-6.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bbc14f0365534d35a06970d6a83478b249752e922d662dc24d489af1aa0d1be7", size = 253584, upload-time = "2025-08-11T12:07:05.914Z" }, + { url = "https://files.pythonhosted.org/packages/5c/74/ab2039ecc05264b5cec73eb018ce417af3ebb384ae9c0e9ed42cb33f8151/multidict-6.6.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:75aa52fba2d96bf972e85451b99d8e19cc37ce26fd016f6d4aa60da9ab2b005f", size = 251018, upload-time = "2025-08-11T12:07:08.301Z" }, + { url = "https://files.pythonhosted.org/packages/af/0a/ccbb244ac848e56c6427f2392741c06302bbfba49c0042f1eb3c5b606497/multidict-6.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4fefd4a815e362d4f011919d97d7b4a1e566f1dde83dc4ad8cfb5b41de1df68d", size = 251477, upload-time = "2025-08-11T12:07:10.248Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b0/0ed49bba775b135937f52fe13922bc64a7eaf0a3ead84a36e8e4e446e096/multidict-6.6.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:db9801fe021f59a5b375ab778973127ca0ac52429a26e2fd86aa9508f4d26eb7", size = 263575, upload-time = "2025-08-11T12:07:11.928Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d9/7fb85a85e14de2e44dfb6a24f03c41e2af8697a6df83daddb0e9b7569f73/multidict-6.6.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a650629970fa21ac1fb06ba25dabfc5b8a2054fcbf6ae97c758aa956b8dba802", size = 259649, upload-time = "2025-08-11T12:07:13.244Z" }, + { url = "https://files.pythonhosted.org/packages/03/9e/b3a459bcf9b6e74fa461a5222a10ff9b544cb1cd52fd482fb1b75ecda2a2/multidict-6.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:452ff5da78d4720d7516a3a2abd804957532dd69296cb77319c193e3ffb87e24", size = 251505, upload-time = "2025-08-11T12:07:14.57Z" }, + { url = "https://files.pythonhosted.org/packages/86/a2/8022f78f041dfe6d71e364001a5cf987c30edfc83c8a5fb7a3f0974cff39/multidict-6.6.4-cp312-cp312-win32.whl", hash = "sha256:8c2fcb12136530ed19572bbba61b407f655e3953ba669b96a35036a11a485793", size = 41888, upload-time = "2025-08-11T12:07:15.904Z" }, + { url = "https://files.pythonhosted.org/packages/c7/eb/d88b1780d43a56db2cba24289fa744a9d216c1a8546a0dc3956563fd53ea/multidict-6.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:047d9425860a8c9544fed1b9584f0c8bcd31bcde9568b047c5e567a1025ecd6e", size = 46072, upload-time = "2025-08-11T12:07:17.045Z" }, + { url = "https://files.pythonhosted.org/packages/9f/16/b929320bf5750e2d9d4931835a4c638a19d2494a5b519caaaa7492ebe105/multidict-6.6.4-cp312-cp312-win_arm64.whl", hash = "sha256:14754eb72feaa1e8ae528468f24250dd997b8e2188c3d2f593f9eba259e4b364", size = 43222, upload-time = "2025-08-11T12:07:18.328Z" }, + { url = "https://files.pythonhosted.org/packages/fd/69/b547032297c7e63ba2af494edba695d781af8a0c6e89e4d06cf848b21d80/multidict-6.6.4-py3-none-any.whl", hash = "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c", size = 12313, upload-time = "2025-08-11T12:08:46.891Z" }, +] + +[[package]] +name = "mypy" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8e/22/ea637422dedf0bf36f3ef238eab4e455e2a0dcc3082b5cc067615347ab8e/mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01", size = 3352570, upload-time = "2025-07-31T07:54:19.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/a9/3d7aa83955617cdf02f94e50aab5c830d205cfa4320cf124ff64acce3a8e/mypy-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972", size = 11003299, upload-time = "2025-07-31T07:54:06.425Z" }, + { url = "https://files.pythonhosted.org/packages/83/e8/72e62ff837dd5caaac2b4a5c07ce769c8e808a00a65e5d8f94ea9c6f20ab/mypy-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7", size = 10125451, upload-time = "2025-07-31T07:53:52.974Z" }, + { url = "https://files.pythonhosted.org/packages/7d/10/f3f3543f6448db11881776f26a0ed079865926b0c841818ee22de2c6bbab/mypy-1.17.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df", size = 11916211, upload-time = "2025-07-31T07:53:18.879Z" }, + { url = "https://files.pythonhosted.org/packages/06/bf/63e83ed551282d67bb3f7fea2cd5561b08d2bb6eb287c096539feb5ddbc5/mypy-1.17.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390", size = 12652687, upload-time = "2025-07-31T07:53:30.544Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/68f2eeef11facf597143e85b694a161868b3b006a5fbad50e09ea117ef24/mypy-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94", size = 12896322, upload-time = "2025-07-31T07:53:50.74Z" }, + { url = "https://files.pythonhosted.org/packages/a3/87/8e3e9c2c8bd0d7e071a89c71be28ad088aaecbadf0454f46a540bda7bca6/mypy-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b", size = 9507962, upload-time = "2025-07-31T07:53:08.431Z" }, + { url = "https://files.pythonhosted.org/packages/46/cf/eadc80c4e0a70db1c08921dcc220357ba8ab2faecb4392e3cebeb10edbfa/mypy-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58", size = 10921009, upload-time = "2025-07-31T07:53:23.037Z" }, + { url = "https://files.pythonhosted.org/packages/5d/c1/c869d8c067829ad30d9bdae051046561552516cfb3a14f7f0347b7d973ee/mypy-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5", size = 10047482, upload-time = "2025-07-31T07:53:26.151Z" }, + { url = "https://files.pythonhosted.org/packages/98/b9/803672bab3fe03cee2e14786ca056efda4bb511ea02dadcedde6176d06d0/mypy-1.17.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd", size = 11832883, upload-time = "2025-07-31T07:53:47.948Z" }, + { url = "https://files.pythonhosted.org/packages/88/fb/fcdac695beca66800918c18697b48833a9a6701de288452b6715a98cfee1/mypy-1.17.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b", size = 12566215, upload-time = "2025-07-31T07:54:04.031Z" }, + { url = "https://files.pythonhosted.org/packages/7f/37/a932da3d3dace99ee8eb2043b6ab03b6768c36eb29a02f98f46c18c0da0e/mypy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5", size = 12751956, upload-time = "2025-07-31T07:53:36.263Z" }, + { url = "https://files.pythonhosted.org/packages/8c/cf/6438a429e0f2f5cab8bc83e53dbebfa666476f40ee322e13cac5e64b79e7/mypy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b", size = 9507307, upload-time = "2025-07-31T07:53:59.734Z" }, + { url = "https://files.pythonhosted.org/packages/17/a2/7034d0d61af8098ec47902108553122baa0f438df8a713be860f7407c9e6/mypy-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb", size = 11086295, upload-time = "2025-07-31T07:53:28.124Z" }, + { url = "https://files.pythonhosted.org/packages/14/1f/19e7e44b594d4b12f6ba8064dbe136505cec813549ca3e5191e40b1d3cc2/mypy-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403", size = 10112355, upload-time = "2025-07-31T07:53:21.121Z" }, + { url = "https://files.pythonhosted.org/packages/5b/69/baa33927e29e6b4c55d798a9d44db5d394072eef2bdc18c3e2048c9ed1e9/mypy-1.17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056", size = 11875285, upload-time = "2025-07-31T07:53:55.293Z" }, + { url = "https://files.pythonhosted.org/packages/90/13/f3a89c76b0a41e19490b01e7069713a30949d9a6c147289ee1521bcea245/mypy-1.17.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341", size = 12737895, upload-time = "2025-07-31T07:53:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/23/a1/c4ee79ac484241301564072e6476c5a5be2590bc2e7bfd28220033d2ef8f/mypy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb", size = 12931025, upload-time = "2025-07-31T07:54:17.125Z" }, + { url = "https://files.pythonhosted.org/packages/89/b8/7409477be7919a0608900e6320b155c72caab4fef46427c5cc75f85edadd/mypy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19", size = 9584664, upload-time = "2025-07-31T07:54:12.842Z" }, + { url = "https://files.pythonhosted.org/packages/1d/f3/8fcd2af0f5b806f6cf463efaffd3c9548a28f84220493ecd38d127b6b66d/mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9", size = 2283411, upload-time = "2025-07-31T07:53:24.664Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, +] + +[[package]] +name = "nostr-sdk" +version = "0.42.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/4e/d413f3620707daad7649a7e83be7b395a0b4130372fb7dc90850e6eb4988/nostr_sdk-0.42.1-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:57ac8b7a6f56bb619a3ef58fbfe1bd93e180d5cd73681b45eeaf5ae2dd45d345", size = 3925439, upload-time = "2025-05-26T09:08:53.522Z" }, + { url = "https://files.pythonhosted.org/packages/e5/2b/ae1dadd3390846d067bd6602f484e690232f868dc30f11d138262ec9ca97/nostr_sdk-0.42.1-cp39-abi3-macosx_11_0_x86_64.whl", hash = "sha256:8897a4c3c34aa3cf4d500e570a1697ba253f89223e8548d2b75da2006fc730eb", size = 3988204, upload-time = "2025-05-26T09:09:06.853Z" }, + { url = "https://files.pythonhosted.org/packages/e9/8d/f0f8def4999384df6739dd5dce8166454a6bacf73d374e5984b3f1d25e79/nostr_sdk-0.42.1-cp39-abi3-manylinux_2_17_aarch64.whl", hash = "sha256:166f1c7b1901813ad9a6296641384cbcc7e35c18ccdf3229d88fcd1e0b51d6ee", size = 3673138, upload-time = "2025-05-26T09:08:42.03Z" }, + { url = "https://files.pythonhosted.org/packages/fb/50/2fea941dcfcd311250f181913dd23031ad8422820acefe86914935c09a6e/nostr_sdk-0.42.1-cp39-abi3-manylinux_2_17_armv7l.whl", hash = "sha256:f2b86bc50805be59113c974665bdf4dcaaf76a1f591a9dba41f1d50acb674b3c", size = 3420691, upload-time = "2025-05-26T09:08:49.608Z" }, + { url = "https://files.pythonhosted.org/packages/cd/cf/cdf16f83a5ed1bfe88512fb4a899ec395296c6b63bb19d329d3cb51f20f6/nostr_sdk-0.42.1-cp39-abi3-manylinux_2_17_i686.whl", hash = "sha256:73b0c16494221a0faf8ec369a2609faba3f17ffd0f03620baa0ec83c58c49b71", size = 3706012, upload-time = "2025-05-26T09:08:57.181Z" }, + { url = "https://files.pythonhosted.org/packages/4a/ee/9b1e90670fe32bb4d520c73dfe25035dc989518f43ae9facf7d4e286179e/nostr_sdk-0.42.1-cp39-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:f68663073630c8edee55d9bec689f019ea616ef6482857e7f72ba1dc1b4fa9cc", size = 3817054, upload-time = "2025-05-26T09:09:11.778Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f3/8b62b3bc24c63a5c165669dfb444c877275959fe7983a80a5e0c60e8ff42/nostr_sdk-0.42.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b6659308d7629e23be252455c46d81549fe6bf945915ec4a0cba2c4b61815c07", size = 3670777, upload-time = "2025-05-26T09:09:02.686Z" }, + { url = "https://files.pythonhosted.org/packages/62/14/78851a956ab8dae47c28812a89c93e883aeadf2655596522a72030943541/nostr_sdk-0.42.1-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:1fa8a8688cf17e838c31caf5c8a357b7c7c2ba3b6ee85e39c05c93e80d999b99", size = 3419180, upload-time = "2025-05-26T09:09:16.714Z" }, + { url = "https://files.pythonhosted.org/packages/b4/06/41bad843700ce7d47c2ef2a17ccd823db9e10504c4d368168f24c91f2d81/nostr_sdk-0.42.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:0a89ae1c7b2c36025024511240aa10540aade2551e8b97d40b4a0b88feaabe8c", size = 3571964, upload-time = "2025-05-26T09:08:45.516Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ea/d62f311a90faae44d4e0c0d6646c5a8dca10124bd5706fa3fa51156d892c/nostr_sdk-0.42.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e3dda5d65591158a0c9794aa79a2f2ea7bbe3cfcba236645fbff8291d94946f1", size = 3822060, upload-time = "2025-05-26T09:08:39.336Z" }, + { url = "https://files.pythonhosted.org/packages/f3/39/935f70ee05a25de220d236774a1258d13b470595954bd5fd1ffcf4f5df2a/nostr_sdk-0.42.1-cp39-abi3-win32.whl", hash = "sha256:d20988c0d6dd16c183607dfdbd243e4f5cc9d8a4faa0c498df546fa8383da902", size = 3254061, upload-time = "2025-05-26T09:09:14.515Z" }, + { url = "https://files.pythonhosted.org/packages/7f/9e/d509f09b98c4d91f339bd68d3a9d6c313161e54554e392d001466206ca67/nostr_sdk-0.42.1-cp39-abi3-win_amd64.whl", hash = "sha256:35978a8e526e66d05a346546391c28d643dfca31117a95c51c940c994c422d7d", size = 3500340, upload-time = "2025-05-26T09:09:00.279Z" }, + { url = "https://files.pythonhosted.org/packages/bc/0f/f704d328499458434b45c54ef88bdfee803366e0c9ef32f3377e2f396921/nostr_sdk-0.42.1-cp39-abi3-win_arm64.whl", hash = "sha256:802c74f903b120b74bf501bf68c81d5ee1dc9f7f57801a53a507044a14b9a840", size = 3303179, upload-time = "2025-05-26T09:09:09.122Z" }, +] + +[[package]] +name = "nwcprovider" +version = "0.0.0" +source = { virtual = "." } +dependencies = [ + { name = "lnbits" }, +] + +[package.dev-dependencies] +dev = [ + { name = "black" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-md" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [{ name = "lnbits", specifier = ">1" }] + +[package.metadata.requires-dev] +dev = [ + { name = "black" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-md" }, + { name = "ruff" }, +] + +[[package]] +name = "oauthlib" +version = "3.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/5f/19930f824ffeb0ad4372da4812c50edbd1434f678c90c2733e1188edfc63/oauthlib-3.3.1.tar.gz", hash = "sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9", size = 185918, upload-time = "2025-06-19T22:48:08.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl", hash = "sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1", size = 160065, upload-time = "2025-06-19T22:48:06.508Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "ply" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/69/882ee5c9d017149285cab114ebeab373308ef0f874fcdac9beb90e0ac4da/ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3", size = 159130, upload-time = "2018-02-15T19:01:31.097Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce", size = 49567, upload-time = "2018-02-15T19:01:27.172Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/29/7cf5bbc236333876e4b41f56e06857a87937ce4bf91e117a6991a2dbb02a/pre_commit-4.3.0.tar.gz", hash = "sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16", size = 193792, upload-time = "2025-08-09T18:56:14.651Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/a5/987a405322d78a73b66e39e4a90e4ef156fd7141bf71df987e50717c321b/pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8", size = 220965, upload-time = "2025-08-09T18:56:13.192Z" }, +] + +[[package]] +name = "propcache" +version = "0.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139, upload-time = "2025-06-09T22:56:06.081Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/14/510deed325e262afeb8b360043c5d7c960da7d3ecd6d6f9496c9c56dc7f4/propcache-0.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:22d9962a358aedbb7a2e36187ff273adeaab9743373a272976d2e348d08c7770", size = 73178, upload-time = "2025-06-09T22:53:40.126Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4e/ad52a7925ff01c1325653a730c7ec3175a23f948f08626a534133427dcff/propcache-0.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d0fda578d1dc3f77b6b5a5dce3b9ad69a8250a891760a548df850a5e8da87f3", size = 43133, upload-time = "2025-06-09T22:53:41.965Z" }, + { url = "https://files.pythonhosted.org/packages/63/7c/e9399ba5da7780871db4eac178e9c2e204c23dd3e7d32df202092a1ed400/propcache-0.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3def3da3ac3ce41562d85db655d18ebac740cb3fa4367f11a52b3da9d03a5cc3", size = 43039, upload-time = "2025-06-09T22:53:43.268Z" }, + { url = "https://files.pythonhosted.org/packages/22/e1/58da211eb8fdc6fc854002387d38f415a6ca5f5c67c1315b204a5d3e9d7a/propcache-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bec58347a5a6cebf239daba9bda37dffec5b8d2ce004d9fe4edef3d2815137e", size = 201903, upload-time = "2025-06-09T22:53:44.872Z" }, + { url = "https://files.pythonhosted.org/packages/c4/0a/550ea0f52aac455cb90111c8bab995208443e46d925e51e2f6ebdf869525/propcache-0.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ffda449a507e9fbd4aca1a7d9aa6753b07d6166140e5a18d2ac9bc49eac220", size = 213362, upload-time = "2025-06-09T22:53:46.707Z" }, + { url = "https://files.pythonhosted.org/packages/5a/af/9893b7d878deda9bb69fcf54600b247fba7317761b7db11fede6e0f28bd0/propcache-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a67fb39229a8a8491dd42f864e5e263155e729c2e7ff723d6e25f596b1e8cb", size = 210525, upload-time = "2025-06-09T22:53:48.547Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bb/38fd08b278ca85cde36d848091ad2b45954bc5f15cce494bb300b9285831/propcache-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da1cf97b92b51253d5b68cf5a2b9e0dafca095e36b7f2da335e27dc6172a614", size = 198283, upload-time = "2025-06-09T22:53:50.067Z" }, + { url = "https://files.pythonhosted.org/packages/78/8c/9fe55bd01d362bafb413dfe508c48753111a1e269737fa143ba85693592c/propcache-0.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f559e127134b07425134b4065be45b166183fdcb433cb6c24c8e4149056ad50", size = 191872, upload-time = "2025-06-09T22:53:51.438Z" }, + { url = "https://files.pythonhosted.org/packages/54/14/4701c33852937a22584e08abb531d654c8bcf7948a8f87ad0a4822394147/propcache-0.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aff2e4e06435d61f11a428360a932138d0ec288b0a31dd9bd78d200bd4a2b339", size = 199452, upload-time = "2025-06-09T22:53:53.229Z" }, + { url = "https://files.pythonhosted.org/packages/16/44/447f2253d859602095356007657ee535e0093215ea0b3d1d6a41d16e5201/propcache-0.3.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4927842833830942a5d0a56e6f4839bc484785b8e1ce8d287359794818633ba0", size = 191567, upload-time = "2025-06-09T22:53:54.541Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b3/e4756258749bb2d3b46defcff606a2f47410bab82be5824a67e84015b267/propcache-0.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6107ddd08b02654a30fb8ad7a132021759d750a82578b94cd55ee2772b6ebea2", size = 193015, upload-time = "2025-06-09T22:53:56.44Z" }, + { url = "https://files.pythonhosted.org/packages/1e/df/e6d3c7574233164b6330b9fd697beeac402afd367280e6dc377bb99b43d9/propcache-0.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:70bd8b9cd6b519e12859c99f3fc9a93f375ebd22a50296c3a295028bea73b9e7", size = 204660, upload-time = "2025-06-09T22:53:57.839Z" }, + { url = "https://files.pythonhosted.org/packages/b2/53/e4d31dd5170b4a0e2e6b730f2385a96410633b4833dc25fe5dffd1f73294/propcache-0.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2183111651d710d3097338dd1893fcf09c9f54e27ff1a8795495a16a469cc90b", size = 206105, upload-time = "2025-06-09T22:53:59.638Z" }, + { url = "https://files.pythonhosted.org/packages/7f/fe/74d54cf9fbe2a20ff786e5f7afcfde446588f0cf15fb2daacfbc267b866c/propcache-0.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fb075ad271405dcad8e2a7ffc9a750a3bf70e533bd86e89f0603e607b93aa64c", size = 196980, upload-time = "2025-06-09T22:54:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/22/ec/c469c9d59dada8a7679625e0440b544fe72e99311a4679c279562051f6fc/propcache-0.3.2-cp310-cp310-win32.whl", hash = "sha256:404d70768080d3d3bdb41d0771037da19d8340d50b08e104ca0e7f9ce55fce70", size = 37679, upload-time = "2025-06-09T22:54:03.003Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/07a471371ac89d418f8d0b699c75ea6dca2041fbda360823de21f6a9ce0a/propcache-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:7435d766f978b4ede777002e6b3b6641dd229cd1da8d3d3106a45770365f9ad9", size = 41459, upload-time = "2025-06-09T22:54:04.134Z" }, + { url = "https://files.pythonhosted.org/packages/80/8d/e8b436717ab9c2cfc23b116d2c297305aa4cd8339172a456d61ebf5669b8/propcache-0.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b8d2f607bd8f80ddc04088bc2a037fdd17884a6fcadc47a96e334d72f3717be", size = 74207, upload-time = "2025-06-09T22:54:05.399Z" }, + { url = "https://files.pythonhosted.org/packages/d6/29/1e34000e9766d112171764b9fa3226fa0153ab565d0c242c70e9945318a7/propcache-0.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06766d8f34733416e2e34f46fea488ad5d60726bb9481d3cddf89a6fa2d9603f", size = 43648, upload-time = "2025-06-09T22:54:08.023Z" }, + { url = "https://files.pythonhosted.org/packages/46/92/1ad5af0df781e76988897da39b5f086c2bf0f028b7f9bd1f409bb05b6874/propcache-0.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2dc1f4a1df4fecf4e6f68013575ff4af84ef6f478fe5344317a65d38a8e6dc9", size = 43496, upload-time = "2025-06-09T22:54:09.228Z" }, + { url = "https://files.pythonhosted.org/packages/b3/ce/e96392460f9fb68461fabab3e095cb00c8ddf901205be4eae5ce246e5b7e/propcache-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be29c4f4810c5789cf10ddf6af80b041c724e629fa51e308a7a0fb19ed1ef7bf", size = 217288, upload-time = "2025-06-09T22:54:10.466Z" }, + { url = "https://files.pythonhosted.org/packages/c5/2a/866726ea345299f7ceefc861a5e782b045545ae6940851930a6adaf1fca6/propcache-0.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d61f6970ecbd8ff2e9360304d5c8876a6abd4530cb752c06586849ac8a9dc9", size = 227456, upload-time = "2025-06-09T22:54:11.828Z" }, + { url = "https://files.pythonhosted.org/packages/de/03/07d992ccb6d930398689187e1b3c718339a1c06b8b145a8d9650e4726166/propcache-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62180e0b8dbb6b004baec00a7983e4cc52f5ada9cd11f48c3528d8cfa7b96a66", size = 225429, upload-time = "2025-06-09T22:54:13.823Z" }, + { url = "https://files.pythonhosted.org/packages/5d/e6/116ba39448753b1330f48ab8ba927dcd6cf0baea8a0ccbc512dfb49ba670/propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c144ca294a204c470f18cf4c9d78887810d04a3e2fbb30eea903575a779159df", size = 213472, upload-time = "2025-06-09T22:54:15.232Z" }, + { url = "https://files.pythonhosted.org/packages/a6/85/f01f5d97e54e428885a5497ccf7f54404cbb4f906688a1690cd51bf597dc/propcache-0.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5c2a784234c28854878d68978265617aa6dc0780e53d44b4d67f3651a17a9a2", size = 204480, upload-time = "2025-06-09T22:54:17.104Z" }, + { url = "https://files.pythonhosted.org/packages/e3/79/7bf5ab9033b8b8194cc3f7cf1aaa0e9c3256320726f64a3e1f113a812dce/propcache-0.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5745bc7acdafa978ca1642891b82c19238eadc78ba2aaa293c6863b304e552d7", size = 214530, upload-time = "2025-06-09T22:54:18.512Z" }, + { url = "https://files.pythonhosted.org/packages/31/0b/bd3e0c00509b609317df4a18e6b05a450ef2d9a963e1d8bc9c9415d86f30/propcache-0.3.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c0075bf773d66fa8c9d41f66cc132ecc75e5bb9dd7cce3cfd14adc5ca184cb95", size = 205230, upload-time = "2025-06-09T22:54:19.947Z" }, + { url = "https://files.pythonhosted.org/packages/7a/23/fae0ff9b54b0de4e819bbe559508da132d5683c32d84d0dc2ccce3563ed4/propcache-0.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5f57aa0847730daceff0497f417c9de353c575d8da3579162cc74ac294c5369e", size = 206754, upload-time = "2025-06-09T22:54:21.716Z" }, + { url = "https://files.pythonhosted.org/packages/b7/7f/ad6a3c22630aaa5f618b4dc3c3598974a72abb4c18e45a50b3cdd091eb2f/propcache-0.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:eef914c014bf72d18efb55619447e0aecd5fb7c2e3fa7441e2e5d6099bddff7e", size = 218430, upload-time = "2025-06-09T22:54:23.17Z" }, + { url = "https://files.pythonhosted.org/packages/5b/2c/ba4f1c0e8a4b4c75910742f0d333759d441f65a1c7f34683b4a74c0ee015/propcache-0.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a4092e8549031e82facf3decdbc0883755d5bbcc62d3aea9d9e185549936dcf", size = 223884, upload-time = "2025-06-09T22:54:25.539Z" }, + { url = "https://files.pythonhosted.org/packages/88/e4/ebe30fc399e98572019eee82ad0caf512401661985cbd3da5e3140ffa1b0/propcache-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85871b050f174bc0bfb437efbdb68aaf860611953ed12418e4361bc9c392749e", size = 211480, upload-time = "2025-06-09T22:54:26.892Z" }, + { url = "https://files.pythonhosted.org/packages/96/0a/7d5260b914e01d1d0906f7f38af101f8d8ed0dc47426219eeaf05e8ea7c2/propcache-0.3.2-cp311-cp311-win32.whl", hash = "sha256:36c8d9b673ec57900c3554264e630d45980fd302458e4ac801802a7fd2ef7897", size = 37757, upload-time = "2025-06-09T22:54:28.241Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2d/89fe4489a884bc0da0c3278c552bd4ffe06a1ace559db5ef02ef24ab446b/propcache-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53af8cb6a781b02d2ea079b5b853ba9430fcbe18a8e3ce647d5982a3ff69f39", size = 41500, upload-time = "2025-06-09T22:54:29.4Z" }, + { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674, upload-time = "2025-06-09T22:54:30.551Z" }, + { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570, upload-time = "2025-06-09T22:54:32.296Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094, upload-time = "2025-06-09T22:54:33.929Z" }, + { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958, upload-time = "2025-06-09T22:54:35.186Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894, upload-time = "2025-06-09T22:54:36.708Z" }, + { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672, upload-time = "2025-06-09T22:54:38.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395, upload-time = "2025-06-09T22:54:39.634Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510, upload-time = "2025-06-09T22:54:41.565Z" }, + { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949, upload-time = "2025-06-09T22:54:43.038Z" }, + { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258, upload-time = "2025-06-09T22:54:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036, upload-time = "2025-06-09T22:54:46.243Z" }, + { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684, upload-time = "2025-06-09T22:54:47.63Z" }, + { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562, upload-time = "2025-06-09T22:54:48.982Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142, upload-time = "2025-06-09T22:54:50.424Z" }, + { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711, upload-time = "2025-06-09T22:54:52.072Z" }, + { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479, upload-time = "2025-06-09T22:54:53.234Z" }, + { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, +] + +[[package]] +name = "protobuf" +version = "5.29.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/29/d09e70352e4e88c9c7a198d5645d7277811448d76c23b00345670f7c8a38/protobuf-5.29.5.tar.gz", hash = "sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84", size = 425226, upload-time = "2025-05-28T23:51:59.82Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/11/6e40e9fc5bba02988a214c07cf324595789ca7820160bfd1f8be96e48539/protobuf-5.29.5-cp310-abi3-win32.whl", hash = "sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079", size = 422963, upload-time = "2025-05-28T23:51:41.204Z" }, + { url = "https://files.pythonhosted.org/packages/81/7f/73cefb093e1a2a7c3ffd839e6f9fcafb7a427d300c7f8aef9c64405d8ac6/protobuf-5.29.5-cp310-abi3-win_amd64.whl", hash = "sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc", size = 434818, upload-time = "2025-05-28T23:51:44.297Z" }, + { url = "https://files.pythonhosted.org/packages/dd/73/10e1661c21f139f2c6ad9b23040ff36fee624310dc28fba20d33fdae124c/protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671", size = 418091, upload-time = "2025-05-28T23:51:45.907Z" }, + { url = "https://files.pythonhosted.org/packages/6c/04/98f6f8cf5b07ab1294c13f34b4e69b3722bb609c5b701d6c169828f9f8aa/protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015", size = 319824, upload-time = "2025-05-28T23:51:47.545Z" }, + { url = "https://files.pythonhosted.org/packages/85/e4/07c80521879c2d15f321465ac24c70efe2381378c00bf5e56a0f4fbac8cd/protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61", size = 319942, upload-time = "2025-05-28T23:51:49.11Z" }, + { url = "https://files.pythonhosted.org/packages/7e/cc/7e77861000a0691aeea8f4566e5d3aa716f2b1dece4a24439437e41d3d25/protobuf-5.29.5-py3-none-any.whl", hash = "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5", size = 172823, upload-time = "2025-05-28T23:51:58.157Z" }, +] + +[[package]] +name = "py-vapid" +version = "1.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/57/5c1c61f27ce01f939443cf3f6c279a295f7ec0327b18a1cbbcfefe0b5456/py_vapid-1.9.2.tar.gz", hash = "sha256:3c8973b6cf8384ad0c9ae64d6270ccc480e0b92c702d8f5ea2cc03e6b51247f9", size = 20300, upload-time = "2024-11-19T21:55:41.859Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/fb/b877a221b09dabcebeb073d5e7f19244f3fa1d5aec87092c359a6049a006/py_vapid-1.9.2-py3-none-any.whl", hash = "sha256:4ccf8a00fc54f1f99f66fb543c96f2c82622508ad814b6e9225f2c26948934d7", size = 21492, upload-time = "2024-11-19T21:55:40.832Z" }, +] + +[[package]] +name = "pycparser" +version = "2.23" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, +] + +[[package]] +name = "pycryptodomex" +version = "3.23.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/85/e24bf90972a30b0fcd16c73009add1d7d7cd9140c2498a68252028899e41/pycryptodomex-3.23.0.tar.gz", hash = "sha256:71909758f010c82bc99b0abf4ea12012c98962fbf0583c2164f8b84533c2e4da", size = 4922157, upload-time = "2025-05-17T17:23:41.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/9c/1a8f35daa39784ed8adf93a694e7e5dc15c23c741bbda06e1d45f8979e9e/pycryptodomex-3.23.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:06698f957fe1ab229a99ba2defeeae1c09af185baa909a31a5d1f9d42b1aaed6", size = 2499240, upload-time = "2025-05-17T17:22:46.953Z" }, + { url = "https://files.pythonhosted.org/packages/7a/62/f5221a191a97157d240cf6643747558759126c76ee92f29a3f4aee3197a5/pycryptodomex-3.23.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b2c2537863eccef2d41061e82a881dcabb04944c5c06c5aa7110b577cc487545", size = 1644042, upload-time = "2025-05-17T17:22:49.098Z" }, + { url = "https://files.pythonhosted.org/packages/8c/fd/5a054543c8988d4ed7b612721d7e78a4b9bf36bc3c5ad45ef45c22d0060e/pycryptodomex-3.23.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43c446e2ba8df8889e0e16f02211c25b4934898384c1ec1ec04d7889c0333587", size = 2186227, upload-time = "2025-05-17T17:22:51.139Z" }, + { url = "https://files.pythonhosted.org/packages/c8/a9/8862616a85cf450d2822dbd4fff1fcaba90877907a6ff5bc2672cafe42f8/pycryptodomex-3.23.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f489c4765093fb60e2edafdf223397bc716491b2b69fe74367b70d6999257a5c", size = 2272578, upload-time = "2025-05-17T17:22:53.676Z" }, + { url = "https://files.pythonhosted.org/packages/46/9f/bda9c49a7c1842820de674ab36c79f4fbeeee03f8ff0e4f3546c3889076b/pycryptodomex-3.23.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdc69d0d3d989a1029df0eed67cc5e8e5d968f3724f4519bd03e0ec68df7543c", size = 2312166, upload-time = "2025-05-17T17:22:56.585Z" }, + { url = "https://files.pythonhosted.org/packages/03/cc/870b9bf8ca92866ca0186534801cf8d20554ad2a76ca959538041b7a7cf4/pycryptodomex-3.23.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6bbcb1dd0f646484939e142462d9e532482bc74475cecf9c4903d4e1cd21f003", size = 2185467, upload-time = "2025-05-17T17:22:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/96/e3/ce9348236d8e669fea5dd82a90e86be48b9c341210f44e25443162aba187/pycryptodomex-3.23.0-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:8a4fcd42ccb04c31268d1efeecfccfd1249612b4de6374205376b8f280321744", size = 2346104, upload-time = "2025-05-17T17:23:02.112Z" }, + { url = "https://files.pythonhosted.org/packages/a5/e9/e869bcee87beb89040263c416a8a50204f7f7a83ac11897646c9e71e0daf/pycryptodomex-3.23.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:55ccbe27f049743a4caf4f4221b166560d3438d0b1e5ab929e07ae1702a4d6fd", size = 2271038, upload-time = "2025-05-17T17:23:04.872Z" }, + { url = "https://files.pythonhosted.org/packages/8d/67/09ee8500dd22614af5fbaa51a4aee6e342b5fa8aecf0a6cb9cbf52fa6d45/pycryptodomex-3.23.0-cp37-abi3-win32.whl", hash = "sha256:189afbc87f0b9f158386bf051f720e20fa6145975f1e76369303d0f31d1a8d7c", size = 1771969, upload-time = "2025-05-17T17:23:07.115Z" }, + { url = "https://files.pythonhosted.org/packages/69/96/11f36f71a865dd6df03716d33bd07a67e9d20f6b8d39820470b766af323c/pycryptodomex-3.23.0-cp37-abi3-win_amd64.whl", hash = "sha256:52e5ca58c3a0b0bd5e100a9fbc8015059b05cffc6c66ce9d98b4b45e023443b9", size = 1803124, upload-time = "2025-05-17T17:23:09.267Z" }, + { url = "https://files.pythonhosted.org/packages/f9/93/45c1cdcbeb182ccd2e144c693eaa097763b08b38cded279f0053ed53c553/pycryptodomex-3.23.0-cp37-abi3-win_arm64.whl", hash = "sha256:02d87b80778c171445d67e23d1caef279bf4b25c3597050ccd2e13970b57fd51", size = 1707161, upload-time = "2025-05-17T17:23:11.414Z" }, + { url = "https://files.pythonhosted.org/packages/f3/b8/3e76d948c3c4ac71335bbe75dac53e154b40b0f8f1f022dfa295257a0c96/pycryptodomex-3.23.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ebfff755c360d674306e5891c564a274a47953562b42fb74a5c25b8fc1fb1cb5", size = 1627695, upload-time = "2025-05-17T17:23:17.38Z" }, + { url = "https://files.pythonhosted.org/packages/6a/cf/80f4297a4820dfdfd1c88cf6c4666a200f204b3488103d027b5edd9176ec/pycryptodomex-3.23.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eca54f4bb349d45afc17e3011ed4264ef1cc9e266699874cdd1349c504e64798", size = 1675772, upload-time = "2025-05-17T17:23:19.202Z" }, + { url = "https://files.pythonhosted.org/packages/d1/42/1e969ee0ad19fe3134b0e1b856c39bd0b70d47a4d0e81c2a8b05727394c9/pycryptodomex-3.23.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2596e643d4365e14d0879dc5aafe6355616c61c2176009270f3048f6d9a61f", size = 1668083, upload-time = "2025-05-17T17:23:21.867Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c3/1de4f7631fea8a992a44ba632aa40e0008764c0fb9bf2854b0acf78c2cf2/pycryptodomex-3.23.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdfac7cda115bca3a5abb2f9e43bc2fb66c2b65ab074913643803ca7083a79ea", size = 1706056, upload-time = "2025-05-17T17:23:24.031Z" }, + { url = "https://files.pythonhosted.org/packages/f2/5f/af7da8e6f1e42b52f44a24d08b8e4c726207434e2593732d39e7af5e7256/pycryptodomex-3.23.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:14c37aaece158d0ace436f76a7bb19093db3b4deade9797abfc39ec6cd6cc2fe", size = 1806478, upload-time = "2025-05-17T17:23:26.066Z" }, +] + +[[package]] +name = "pydantic" +version = "1.10.22" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/57/5996c63f0deec09e9e901a2b838247c97c6844999562eac4e435bcb83938/pydantic-1.10.22.tar.gz", hash = "sha256:ee1006cebd43a8e7158fb7190bb8f4e2da9649719bff65d0c287282ec38dec6d", size = 356771, upload-time = "2025-04-24T13:38:43.605Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/92/91eb5c75a1460292e1f2f3e577122574ebb942fbac19ad2369ff00b9eb24/pydantic-1.10.22-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:57889565ccc1e5b7b73343329bbe6198ebc472e3ee874af2fa1865cfe7048228", size = 2852481, upload-time = "2025-04-24T13:36:55.045Z" }, + { url = "https://files.pythonhosted.org/packages/08/f3/dd54b49fc5caaed06f5a0d0a5ec35a81cf722cd6b42455f408dad1ef3f7d/pydantic-1.10.22-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90729e22426de79bc6a3526b4c45ec4400caf0d4f10d7181ba7f12c01bb3897d", size = 2585586, upload-time = "2025-04-24T13:36:58.453Z" }, + { url = "https://files.pythonhosted.org/packages/ec/9b/48d10180cc614ffb66da486e99bc1f8b639fb44edf322864f2fb161e2351/pydantic-1.10.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8684d347f351554ec94fdcb507983d3116dc4577fb8799fed63c65869a2d10", size = 3336974, upload-time = "2025-04-24T13:37:00.652Z" }, + { url = "https://files.pythonhosted.org/packages/ff/80/b55ad0029ae8e7b8b5c81ad7c4e800774a52107d26f70c6696857dc733d5/pydantic-1.10.22-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8dad498ceff2d9ef1d2e2bc6608f5b59b8e1ba2031759b22dfb8c16608e1802", size = 3362338, upload-time = "2025-04-24T13:37:02.42Z" }, + { url = "https://files.pythonhosted.org/packages/65/e0/8a5cd2cd29a5632581ba466f5792194b2a568aa052ce9da9ba98b634debf/pydantic-1.10.22-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fac529cc654d4575cf8de191cce354b12ba705f528a0a5c654de6d01f76cd818", size = 3519505, upload-time = "2025-04-24T13:37:04.322Z" }, + { url = "https://files.pythonhosted.org/packages/38/c5/c776d03ec374f22860802b2cee057b41e866be3c80826b53d4c001692db3/pydantic-1.10.22-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4148232aded8dd1dd13cf910a01b32a763c34bd79a0ab4d1ee66164fcb0b7b9d", size = 3485878, upload-time = "2025-04-24T13:37:06.102Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a2/1efd064513a2c1bcb5c2b0e022cdf77d132ef7f7f20d91bb439d759f6a88/pydantic-1.10.22-cp310-cp310-win_amd64.whl", hash = "sha256:ece68105d9e436db45d8650dc375c760cc85a6793ae019c08769052902dca7db", size = 2299673, upload-time = "2025-04-24T13:37:07.969Z" }, + { url = "https://files.pythonhosted.org/packages/42/03/e435ed85a9abda29e3fbdb49c572fe4131a68c6daf3855a01eebda9e1b27/pydantic-1.10.22-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e530a8da353f791ad89e701c35787418605d35085f4bdda51b416946070e938", size = 2845682, upload-time = "2025-04-24T13:37:10.142Z" }, + { url = "https://files.pythonhosted.org/packages/72/ea/4a625035672f6c06d3f1c7e33aa0af6bf1929991e27017e98b9c2064ae0b/pydantic-1.10.22-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:654322b85642e9439d7de4c83cb4084ddd513df7ff8706005dada43b34544946", size = 2553286, upload-time = "2025-04-24T13:37:11.946Z" }, + { url = "https://files.pythonhosted.org/packages/a4/f0/424ad837746e69e9f061ba9be68c2a97aef7376d1911692904d8efbcd322/pydantic-1.10.22-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8bece75bd1b9fc1c32b57a32831517943b1159ba18b4ba32c0d431d76a120ae", size = 3141232, upload-time = "2025-04-24T13:37:14.394Z" }, + { url = "https://files.pythonhosted.org/packages/14/67/4979c19e8cfd092085a292485e0b42d74e4eeefbb8cd726aa8ba38d06294/pydantic-1.10.22-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eccb58767f13c6963dcf96d02cb8723ebb98b16692030803ac075d2439c07b0f", size = 3214272, upload-time = "2025-04-24T13:37:16.201Z" }, + { url = "https://files.pythonhosted.org/packages/1a/04/32339ce43e97519d19e7759902515c750edbf4832a13063a4ab157f83f42/pydantic-1.10.22-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7778e6200ff8ed5f7052c1516617423d22517ad36cc7a3aedd51428168e3e5e8", size = 3321646, upload-time = "2025-04-24T13:37:19.086Z" }, + { url = "https://files.pythonhosted.org/packages/92/35/dffc1b29cb7198aadab68d75447191e59bdbc1f1d2d51826c9a4460d372f/pydantic-1.10.22-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bffe02767d27c39af9ca7dc7cd479c00dda6346bb62ffc89e306f665108317a2", size = 3244258, upload-time = "2025-04-24T13:37:20.929Z" }, + { url = "https://files.pythonhosted.org/packages/11/c5/c4ce6ebe7f528a879441eabd2c6dd9e2e4c54f320a8c9344ba93b3aa8701/pydantic-1.10.22-cp311-cp311-win_amd64.whl", hash = "sha256:23bc19c55427091b8e589bc08f635ab90005f2dc99518f1233386f46462c550a", size = 2309702, upload-time = "2025-04-24T13:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/f6/a3/ec66239ed7c9e90edfb85b23b6b18eb290ed7aa05f54837cdcb6a14faa98/pydantic-1.10.22-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:92d0f97828a075a71d9efc65cf75db5f149b4d79a38c89648a63d2932894d8c9", size = 2794865, upload-time = "2025-04-24T13:37:25.087Z" }, + { url = "https://files.pythonhosted.org/packages/49/6a/99cf3fee612d93210c85f45a161e98c1c5b45b6dcadb21c9f1f838fa9e28/pydantic-1.10.22-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af5a2811b6b95b58b829aeac5996d465a5f0c7ed84bd871d603cf8646edf6ff", size = 2534212, upload-time = "2025-04-24T13:37:26.848Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e6/0f8882775cd9a60b221103ee7d6a89e10eb5a892d877c398df0da7140704/pydantic-1.10.22-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cf06d8d40993e79af0ab2102ef5da77b9ddba51248e4cb27f9f3f591fbb096e", size = 2994027, upload-time = "2025-04-24T13:37:28.683Z" }, + { url = "https://files.pythonhosted.org/packages/e7/a3/f20fdecbaa2a2721a6a8ee9e4f344d1f72bd7d56e679371c3f2be15eb8c8/pydantic-1.10.22-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:184b7865b171a6057ad97f4a17fbac81cec29bd103e996e7add3d16b0d95f609", size = 3036716, upload-time = "2025-04-24T13:37:30.547Z" }, + { url = "https://files.pythonhosted.org/packages/1f/83/dab34436d830c38706685acc77219fc2a209fea2a2301a1b05a2865b28bf/pydantic-1.10.22-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:923ad861677ab09d89be35d36111156063a7ebb44322cdb7b49266e1adaba4bb", size = 3171801, upload-time = "2025-04-24T13:37:32.474Z" }, + { url = "https://files.pythonhosted.org/packages/1e/6e/b64deccb8a7304d584088972437ea3091e9d99d27a8e7bf2bd08e29ae84e/pydantic-1.10.22-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:82d9a3da1686443fb854c8d2ab9a473251f8f4cdd11b125522efb4d7c646e7bc", size = 3123560, upload-time = "2025-04-24T13:37:34.855Z" }, + { url = "https://files.pythonhosted.org/packages/08/9a/90d1ab704329a7ae8666354be84b5327d655764003974364767c9d307d3a/pydantic-1.10.22-cp312-cp312-win_amd64.whl", hash = "sha256:1612604929af4c602694a7f3338b18039d402eb5ddfbf0db44f1ebfaf07f93e7", size = 2191378, upload-time = "2025-04-24T13:37:36.649Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e0/1ed151a56869be1588ad2d8cda9f8c1d95b16f74f09a7cea879ca9b63a8b/pydantic-1.10.22-py3-none-any.whl", hash = "sha256:343037d608bcbd34df937ac259708bfc83664dadf88afe8516c4f282d7d471a9", size = 166503, upload-time = "2025-04-24T13:38:41.374Z" }, +] + +[package.optional-dependencies] +email = [ + { name = "email-validator" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pyjwt" +version = "2.10.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785, upload-time = "2024-11-28T03:43:29.933Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997, upload-time = "2024-11-28T03:43:27.893Z" }, +] + +[[package]] +name = "pyln-bolt7" +version = "1.0.246" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/3c/6d1d6643c6a501e998c17c25d40c3b68ab75be1d16d9055e6a9ffba30fe4/pyln-bolt7-1.0.246.tar.gz", hash = "sha256:2b53744fa21c1b12d2c9c9df153651b122e38fa65d4a5c3f2957317ee148e089", size = 17905, upload-time = "2022-08-31T17:28:20.093Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/f1/30b626e7cec279a2f84084898594c8e84537d6d9af9afbe9858f9a6d8e13/pyln_bolt7-1.0.246-py3-none-any.whl", hash = "sha256:54d48ec27fdc8751762cb068b0a9f2757a58fb57933c6d8f8255d02c27eb63c5", size = 18811, upload-time = "2022-08-31T17:28:22.137Z" }, +] + +[[package]] +name = "pyln-client" +version = "25.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyln-bolt7" }, + { name = "pyln-proto" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/f5/70dae7e6985ba44f53e1c634e204ecc4e9ccde8de6cd90e009672203023f/pyln_client-25.5.tar.gz", hash = "sha256:18656e667c7218f8b40c70f893b936aef4518e87e3ce99081bd52f89e6e5af85", size = 36015, upload-time = "2025-06-16T18:13:48.973Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/45/c504ed8ea59577d8093d377e2f657482f08e87b93aaa039e64421297ff55/pyln_client-25.5-py3-none-any.whl", hash = "sha256:269f9ab346ff679b532af2d24c2a524201884efc5b4781dd40685c8ccaec9507", size = 37362, upload-time = "2025-06-16T18:13:47.394Z" }, +] + +[[package]] +name = "pyln-proto" +version = "25.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "base58" }, + { name = "bitstring" }, + { name = "coincurve" }, + { name = "cryptography" }, + { name = "pysocks" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/bb/b87df0a8d27bb7a019a95b6e14a197292c4f63d132ea88d103a773621df3/pyln_proto-25.9.tar.gz", hash = "sha256:df309cf715e92049bb82cc0db994060c7313f545cf62f4ae252a04a810067c57", size = 44929, upload-time = "2025-09-02T16:46:19.964Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/74/80/19851847ea4be5b64d4f9a5b68ed84e7b82abbb1f9edf62f664d0ded38dc/pyln_proto-25.9-py3-none-any.whl", hash = "sha256:41965d96b7fe62323cb6b2fe8953d82f004a2a06ba1c009f91cd5e899ed5575e", size = 32043, upload-time = "2025-09-02T16:46:18.771Z" }, +] + +[[package]] +name = "pynostr" +version = "0.6.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coincurve" }, + { name = "cryptography" }, + { name = "requests" }, + { name = "rich" }, + { name = "tlv8" }, + { name = "tornado" }, + { name = "typer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/08/b6/818c072bd98c6472c305fa0ce9822592a3c8601ebe550b02465404fa629b/pynostr-0.6.2.tar.gz", hash = "sha256:2974ea05b3ff41a1a4060e3b1813eb0ce0e60c0b81fbe668afaa65164c7f82f4", size = 52310, upload-time = "2023-03-16T20:54:02.826Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/4c/d76378abc44c15375708cb3eb8ee9f199879b905b4c2ceda9ea108dfae79/pynostr-0.6.2-py3-none-any.whl", hash = "sha256:d43fb236c73174093275ee0080b2f8ed17e974b2b516f0d73da4c9a3e908ddc5", size = 36301, upload-time = "2023-03-16T20:54:01.055Z" }, +] + +[[package]] +name = "pyqrcode" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/37/61/f07226075c347897937d4086ef8e55f0a62ae535e28069884ac68d979316/PyQRCode-1.2.1.tar.gz", hash = "sha256:fdbf7634733e56b72e27f9bce46e4550b75a3a2c420414035cae9d9d26b234d5", size = 36989, upload-time = "2016-06-20T03:28:03.411Z" } + +[[package]] +name = "pysocks" +version = "1.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0", size = 284429, upload-time = "2019-09-20T02:07:35.714Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/59/b4572118e098ac8e46e399a1dd0f2d85403ce8bbaad9ec79373ed6badaf9/PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", size = 16725, upload-time = "2019-09-20T02:06:22.938Z" }, +] + +[[package]] +name = "pytest" +version = "8.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" }, +] + +[[package]] +name = "pytest-md" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/55/1d4248f08a97255abb23b05d8ba07586333194fadb17beda96b707aebecd/pytest-md-0.2.0.tar.gz", hash = "sha256:3b248d5b360ea5198e05b4f49c7442234812809a63137ec6cdd3643a40cf0112", size = 5985, upload-time = "2019-07-11T08:15:59.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/71/23d03f57c18116c6770141478e33b3500c4e92500cf4b49a396e9226733f/pytest_md-0.2.0-py3-none-any.whl", hash = "sha256:4c4cd16fea6d1485e87ee254558712c804a96d2aa9674b780e7eb8fb6526e1d1", size = 6117, upload-time = "2019-07-11T08:15:57.829Z" }, +] + +[[package]] +name = "python-crontab" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e2/f0/25775565c133d4e29eeb607bf9ddba0075f3af36041a1844dd207881047f/python_crontab-3.2.0.tar.gz", hash = "sha256:40067d1dd39ade3460b2ad8557c7651514cd3851deffff61c5c60e1227c5c36b", size = 57001, upload-time = "2024-07-01T22:29:10.903Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/91/832fb3b3a1f62bd2ab4924f6be0c7736c9bc4f84d3b153b74efcf6d4e4a1/python_crontab-3.2.0-py3-none-any.whl", hash = "sha256:82cb9b6a312d41ff66fd3caf3eed7115c28c195bfb50711bc2b4b9592feb9fe5", size = 27351, upload-time = "2024-07-01T22:29:08.549Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978, upload-time = "2025-06-24T04:21:07.341Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, +] + +[[package]] +name = "pywebpush" +version = "2.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "cryptography" }, + { name = "http-ece" }, + { name = "py-vapid" }, + { name = "requests" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/ca/6e669bf676916d66c8c7adedc291e9a9758650f9d85ec040fda13e3c82f4/pywebpush-2.0.3.tar.gz", hash = "sha256:584878e3c243e873a22db8895505d95715bc796ef74cc1b8fe99f596174161e3", size = 25874, upload-time = "2024-11-19T21:30:20.444Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/8a/ecaa2a589338a038b89148b01a5db2dac53e45918342da69baca1fb058fc/pywebpush-2.0.3-py3-none-any.whl", hash = "sha256:04666441715bc547918d7668b2ac7ad5c4b5de7d0a6cf528daf61e0c4bc5431c", size = 21364, upload-time = "2024-11-19T21:30:19.312Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload-time = "2024-08-06T20:31:40.178Z" }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758, upload-time = "2024-08-06T20:31:42.173Z" }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463, upload-time = "2024-08-06T20:31:44.263Z" }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280, upload-time = "2024-08-06T20:31:50.199Z" }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239, upload-time = "2024-08-06T20:31:52.292Z" }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802, upload-time = "2024-08-06T20:31:53.836Z" }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527, upload-time = "2024-08-06T20:31:55.565Z" }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052, upload-time = "2024-08-06T20:31:56.914Z" }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774, upload-time = "2024-08-06T20:31:58.304Z" }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "rich" +version = "14.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441, upload-time = "2025-07-25T07:32:58.125Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" }, +] + +[[package]] +name = "ruff" +version = "0.12.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a8/f0/e0965dd709b8cabe6356811c0ee8c096806bb57d20b5019eb4e48a117410/ruff-0.12.12.tar.gz", hash = "sha256:b86cd3415dbe31b3b46a71c598f4c4b2f550346d1ccf6326b347cc0c8fd063d6", size = 5359915, upload-time = "2025-09-04T16:50:18.273Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/79/8d3d687224d88367b51c7974cec1040c4b015772bfbeffac95face14c04a/ruff-0.12.12-py3-none-linux_armv6l.whl", hash = "sha256:de1c4b916d98ab289818e55ce481e2cacfaad7710b01d1f990c497edf217dafc", size = 12116602, upload-time = "2025-09-04T16:49:18.892Z" }, + { url = "https://files.pythonhosted.org/packages/c3/c3/6e599657fe192462f94861a09aae935b869aea8a1da07f47d6eae471397c/ruff-0.12.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7acd6045e87fac75a0b0cdedacf9ab3e1ad9d929d149785903cff9bb69ad9727", size = 12868393, upload-time = "2025-09-04T16:49:23.043Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/9e3e40d399abc95336b1843f52fc0daaceb672d0e3c9290a28ff1a96f79d/ruff-0.12.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:abf4073688d7d6da16611f2f126be86523a8ec4343d15d276c614bda8ec44edb", size = 12036967, upload-time = "2025-09-04T16:49:26.04Z" }, + { url = "https://files.pythonhosted.org/packages/e9/03/6816b2ed08836be272e87107d905f0908be5b4a40c14bfc91043e76631b8/ruff-0.12.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:968e77094b1d7a576992ac078557d1439df678a34c6fe02fd979f973af167577", size = 12276038, upload-time = "2025-09-04T16:49:29.056Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d5/707b92a61310edf358a389477eabd8af68f375c0ef858194be97ca5b6069/ruff-0.12.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42a67d16e5b1ffc6d21c5f67851e0e769517fb57a8ebad1d0781b30888aa704e", size = 11901110, upload-time = "2025-09-04T16:49:32.07Z" }, + { url = "https://files.pythonhosted.org/packages/9d/3d/f8b1038f4b9822e26ec3d5b49cf2bc313e3c1564cceb4c1a42820bf74853/ruff-0.12.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b216ec0a0674e4b1214dcc998a5088e54eaf39417327b19ffefba1c4a1e4971e", size = 13668352, upload-time = "2025-09-04T16:49:35.148Z" }, + { url = "https://files.pythonhosted.org/packages/98/0e/91421368ae6c4f3765dd41a150f760c5f725516028a6be30e58255e3c668/ruff-0.12.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:59f909c0fdd8f1dcdbfed0b9569b8bf428cf144bec87d9de298dcd4723f5bee8", size = 14638365, upload-time = "2025-09-04T16:49:38.892Z" }, + { url = "https://files.pythonhosted.org/packages/74/5d/88f3f06a142f58ecc8ecb0c2fe0b82343e2a2b04dcd098809f717cf74b6c/ruff-0.12.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ac93d87047e765336f0c18eacad51dad0c1c33c9df7484c40f98e1d773876f5", size = 14060812, upload-time = "2025-09-04T16:49:42.732Z" }, + { url = "https://files.pythonhosted.org/packages/13/fc/8962e7ddd2e81863d5c92400820f650b86f97ff919c59836fbc4c1a6d84c/ruff-0.12.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:01543c137fd3650d322922e8b14cc133b8ea734617c4891c5a9fccf4bfc9aa92", size = 13050208, upload-time = "2025-09-04T16:49:46.434Z" }, + { url = "https://files.pythonhosted.org/packages/53/06/8deb52d48a9a624fd37390555d9589e719eac568c020b27e96eed671f25f/ruff-0.12.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afc2fa864197634e549d87fb1e7b6feb01df0a80fd510d6489e1ce8c0b1cc45", size = 13311444, upload-time = "2025-09-04T16:49:49.931Z" }, + { url = "https://files.pythonhosted.org/packages/2a/81/de5a29af7eb8f341f8140867ffb93f82e4fde7256dadee79016ac87c2716/ruff-0.12.12-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0c0945246f5ad776cb8925e36af2438e66188d2b57d9cf2eed2c382c58b371e5", size = 13279474, upload-time = "2025-09-04T16:49:53.465Z" }, + { url = "https://files.pythonhosted.org/packages/7f/14/d9577fdeaf791737ada1b4f5c6b59c21c3326f3f683229096cccd7674e0c/ruff-0.12.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a0fbafe8c58e37aae28b84a80ba1817f2ea552e9450156018a478bf1fa80f4e4", size = 12070204, upload-time = "2025-09-04T16:49:56.882Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/a910078284b47fad54506dc0af13839c418ff704e341c176f64e1127e461/ruff-0.12.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b9c456fb2fc8e1282affa932c9e40f5ec31ec9cbb66751a316bd131273b57c23", size = 11880347, upload-time = "2025-09-04T16:49:59.729Z" }, + { url = "https://files.pythonhosted.org/packages/df/58/30185fcb0e89f05e7ea82e5817b47798f7fa7179863f9d9ba6fd4fe1b098/ruff-0.12.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5f12856123b0ad0147d90b3961f5c90e7427f9acd4b40050705499c98983f489", size = 12891844, upload-time = "2025-09-04T16:50:02.591Z" }, + { url = "https://files.pythonhosted.org/packages/21/9c/28a8dacce4855e6703dcb8cdf6c1705d0b23dd01d60150786cd55aa93b16/ruff-0.12.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:26a1b5a2bf7dd2c47e3b46d077cd9c0fc3b93e6c6cc9ed750bd312ae9dc302ee", size = 13360687, upload-time = "2025-09-04T16:50:05.8Z" }, + { url = "https://files.pythonhosted.org/packages/c8/fa/05b6428a008e60f79546c943e54068316f32ec8ab5c4f73e4563934fbdc7/ruff-0.12.12-py3-none-win32.whl", hash = "sha256:173be2bfc142af07a01e3a759aba6f7791aa47acf3604f610b1c36db888df7b1", size = 12052870, upload-time = "2025-09-04T16:50:09.121Z" }, + { url = "https://files.pythonhosted.org/packages/85/60/d1e335417804df452589271818749d061b22772b87efda88354cf35cdb7a/ruff-0.12.12-py3-none-win_amd64.whl", hash = "sha256:e99620bf01884e5f38611934c09dd194eb665b0109104acae3ba6102b600fd0d", size = 13178016, upload-time = "2025-09-04T16:50:12.559Z" }, + { url = "https://files.pythonhosted.org/packages/28/7e/61c42657f6e4614a4258f1c3b0c5b93adc4d1f8575f5229d1906b483099b/ruff-0.12.12-py3-none-win_arm64.whl", hash = "sha256:2a8199cab4ce4d72d158319b63370abf60991495fb733db96cd923a34c52d093", size = 12256762, upload-time = "2025-09-04T16:50:15.737Z" }, +] + +[[package]] +name = "secp256k1" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9b/41/bb668a6e4192303542d2d90c3b38d564af3c17c61bd7d4039af4f29405fe/secp256k1-0.14.0.tar.gz", hash = "sha256:82c06712d69ef945220c8b53c1a0d424c2ff6a1f64aee609030df79ad8383397", size = 2420607, upload-time = "2021-11-06T01:36:10.707Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/46/5d3ca364058d39160e3623f0babafe78c2236d359e86924aa07524377c98/secp256k1-0.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f666c67dcf1dc69e1448b2ede5e12aaf382b600204a61dbc65e4f82cea444405", size = 1376587, upload-time = "2022-01-24T12:36:39.127Z" }, + { url = "https://files.pythonhosted.org/packages/ce/e2/5b1616593ed1fa0e07e87b9f5118dc098bd1ddb2a6a7698d82b0ff85ad3f/secp256k1-0.14.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fcabb3c3497a902fb61eec72d1b69bf72747d7bcc2a732d56d9319a1e8322262", size = 1362187, upload-time = "2022-01-24T12:36:41.677Z" }, + { url = "https://files.pythonhosted.org/packages/c9/9c/8148f74dd1fc65d0b97c8cbb101b468e27a2e93a3f291807d0d8ebe4bbf3/secp256k1-0.14.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a27c479ab60571502516a1506a562d0a9df062de8ad645313fabfcc97252816", size = 1376363, upload-time = "2022-01-24T12:36:44.314Z" }, + { url = "https://files.pythonhosted.org/packages/64/11/ff6d18314bc05a8f66619959a61be2fb6f37793d73e1dd106954b0978d92/secp256k1-0.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f4b9306bff6dde020444dfee9ca9b9f5b20ca53a2c0b04898361a3f43d5daf2e", size = 1369109, upload-time = "2022-01-24T12:36:46.782Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "shortuuid" +version = "1.0.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/e2/bcf761f3bff95856203f9559baf3741c416071dd200c0fc19fad7f078f86/shortuuid-1.0.13.tar.gz", hash = "sha256:3bb9cf07f606260584b1df46399c0b87dd84773e7b25912b7e391e30797c5e72", size = 9662, upload-time = "2024-03-11T20:11:06.879Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/44/21d6bf170bf40b41396480d8d49ad640bca3f2b02139cd52aa1e272830a5/shortuuid-1.0.13-py3-none-any.whl", hash = "sha256:a482a497300b49b4953e15108a7913244e1bb0d41f9d332f5e9925dba33a3c5a", size = 10529, upload-time = "2024-03-11T20:11:04.807Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "slowapi" +version = "0.1.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "limits" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/99/adfc7f94ca024736f061257d39118e1542bade7a52e86415a4c4ae92d8ff/slowapi-0.1.9.tar.gz", hash = "sha256:639192d0f1ca01b1c6d95bf6c71d794c3a9ee189855337b4821f7f457dddad77", size = 14028, upload-time = "2024-02-05T12:11:52.13Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2b/bb/f71c4b7d7e7eb3fc1e8c0458a8979b912f40b58002b9fbf37729b8cb464b/slowapi-0.1.9-py3-none-any.whl", hash = "sha256:cfad116cfb84ad9d763ee155c1e5c5cbf00b0d47399a769b227865f5df576e36", size = 14670, upload-time = "2024-02-05T12:11:50.898Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "1.4.54" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/af/20290b55d469e873cba9d41c0206ab5461ff49d759989b3fe65010f9d265/sqlalchemy-1.4.54.tar.gz", hash = "sha256:4470fbed088c35dc20b78a39aaf4ae54fe81790c783b3264872a0224f437c31a", size = 8470350, upload-time = "2024-09-05T15:54:10.398Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/7f/f7c1e0b65790649bd573f201aa958263a389f336d6e000a569275ff9bd97/SQLAlchemy-1.4.54-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:af00236fe21c4d4f4c227b6ccc19b44c594160cc3ff28d104cdce85855369277", size = 1573472, upload-time = "2024-09-05T17:38:45.351Z" }, + { url = "https://files.pythonhosted.org/packages/e1/da/ff7f0fe50844496db523613979651f076f44da8625b8ad89c503dcff0a52/SQLAlchemy-1.4.54-cp310-cp310-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1183599e25fa38a1a322294b949da02b4f0da13dbc2688ef9dbe746df573f8a6", size = 1639088, upload-time = "2024-09-05T17:46:37.726Z" }, + { url = "https://files.pythonhosted.org/packages/04/45/3a35bb156aa2fd87b66a4992bb8d65593efd7e16ca2e0597e68c32c29037/SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1990d5a6a5dc358a0894c8ca02043fb9a5ad9538422001fb2826e91c50f1d539", size = 1627447, upload-time = "2024-09-05T17:45:32.379Z" }, + { url = "https://files.pythonhosted.org/packages/fe/5b/ed36a50e7147d0d090cd8e35de3b18d2c69a3e85df3be5fe42a570d6c331/SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:14b3f4783275339170984cadda66e3ec011cce87b405968dc8d51cf0f9997b0d", size = 1639081, upload-time = "2024-09-05T17:46:39.895Z" }, + { url = "https://files.pythonhosted.org/packages/4b/75/bfbdeb5dece7bc98acb414751a62ee43398b34b10133b1853f4282597757/SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b24364150738ce488333b3fb48bfa14c189a66de41cd632796fbcacb26b4585", size = 1638975, upload-time = "2024-09-05T17:46:41.569Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/358a9291d2fc3d51ad50557e126ad5f48200f199878437f7cb38817d607b/SQLAlchemy-1.4.54-cp310-cp310-win32.whl", hash = "sha256:a8a72259a1652f192c68377be7011eac3c463e9892ef2948828c7d58e4829988", size = 1591719, upload-time = "2024-09-05T17:52:26.646Z" }, + { url = "https://files.pythonhosted.org/packages/10/ad/87cd5578efdcef43a08ce4a21448192abf46bf69a5678ac0039e44364914/SQLAlchemy-1.4.54-cp310-cp310-win_amd64.whl", hash = "sha256:b67589f7955924865344e6eacfdcf70675e64f36800a576aa5e961f0008cde2a", size = 1593512, upload-time = "2024-09-05T17:51:21.402Z" }, + { url = "https://files.pythonhosted.org/packages/da/49/fb98983b5568e93696a25fd5bec1b789095b79a72d5f57c6effddaa81d0a/SQLAlchemy-1.4.54-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b05e0626ec1c391432eabb47a8abd3bf199fb74bfde7cc44a26d2b1b352c2c6e", size = 1589301, upload-time = "2024-09-05T19:22:42.197Z" }, + { url = "https://files.pythonhosted.org/packages/03/98/5a81430bbd646991346cb088a2bdc84d1bcd3dbe6b0cfc1aaa898370e5c7/SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13e91d6892b5fcb94a36ba061fb7a1f03d0185ed9d8a77c84ba389e5bb05e936", size = 1629553, upload-time = "2024-09-05T17:49:18.846Z" }, + { url = "https://files.pythonhosted.org/packages/f1/17/14e35db2b0d6deaa27691d014addbb0dd6f7e044f7ee465446a3c0c71404/SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb59a11689ff3c58e7652260127f9e34f7f45478a2f3ef831ab6db7bcd72108f", size = 1627640, upload-time = "2024-09-05T17:48:01.558Z" }, + { url = "https://files.pythonhosted.org/packages/98/62/335006a8f2c98f704f391e1a0cc01446d1b1b9c198f579f03599f55bd860/SQLAlchemy-1.4.54-cp311-cp311-win32.whl", hash = "sha256:1390ca2d301a2708fd4425c6d75528d22f26b8f5cbc9faba1ddca136671432bc", size = 1591723, upload-time = "2024-09-05T17:53:17.486Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/6b4b8c07082920f5445ec65c221fa33baab102aced5dcc2d87a15d3f8db4/SQLAlchemy-1.4.54-cp311-cp311-win_amd64.whl", hash = "sha256:2b37931eac4b837c45e2522066bda221ac6d80e78922fb77c75eb12e4dbcdee5", size = 1593511, upload-time = "2024-09-05T17:51:50.947Z" }, + { url = "https://files.pythonhosted.org/packages/a5/1b/aa9b99be95d1615f058b5827447c18505b7b3f1dfcbd6ce1b331c2107152/SQLAlchemy-1.4.54-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3f01c2629a7d6b30d8afe0326b8c649b74825a0e1ebdcb01e8ffd1c920deb07d", size = 1589983, upload-time = "2024-09-05T17:39:02.132Z" }, + { url = "https://files.pythonhosted.org/packages/59/47/cb0fc64e5344f0a3d02216796c342525ab283f8f052d1c31a1d487d08aa0/SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c24dd161c06992ed16c5e528a75878edbaeced5660c3db88c820f1f0d3fe1f4", size = 1630158, upload-time = "2024-09-05T17:50:13.255Z" }, + { url = "https://files.pythonhosted.org/packages/c0/8b/f45dd378f6c97e8ff9332ff3d03ecb0b8c491be5bb7a698783b5a2f358ec/SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5e0d47d619c739bdc636bbe007da4519fc953393304a5943e0b5aec96c9877c", size = 1629232, upload-time = "2024-09-05T17:48:15.514Z" }, + { url = "https://files.pythonhosted.org/packages/0d/3c/884fe389f5bec86a310b81e79abaa1e26e5d78dc10a84d544a6822833e47/SQLAlchemy-1.4.54-cp312-cp312-win32.whl", hash = "sha256:12bc0141b245918b80d9d17eca94663dbd3f5266ac77a0be60750f36102bbb0f", size = 1592027, upload-time = "2024-09-05T17:54:02.253Z" }, + { url = "https://files.pythonhosted.org/packages/01/c3/c690d037be57efd3a69cde16a2ef1bd2a905dafe869434d33836de0983d0/SQLAlchemy-1.4.54-cp312-cp312-win_amd64.whl", hash = "sha256:f941aaf15f47f316123e1933f9ea91a6efda73a161a6ab6046d1cde37be62c88", size = 1593827, upload-time = "2024-09-05T17:52:07.454Z" }, +] + +[[package]] +name = "sse-starlette" +version = "2.3.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8c/f4/989bc70cb8091eda43a9034ef969b25145291f3601703b82766e5172dfed/sse_starlette-2.3.6.tar.gz", hash = "sha256:0382336f7d4ec30160cf9ca0518962905e1b69b72d6c1c995131e0a703b436e3", size = 18284, upload-time = "2025-05-30T13:34:12.914Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/05/78850ac6e79af5b9508f8841b0f26aa9fd329a1ba00bf65453c2d312bcc8/sse_starlette-2.3.6-py3-none-any.whl", hash = "sha256:d49a8285b182f6e2228e2609c350398b2ca2c36216c2675d875f81e93548f760", size = 10606, upload-time = "2025-05-30T13:34:11.703Z" }, +] + +[[package]] +name = "starlette" +version = "0.47.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/69/662169fdb92fb96ec3eaee218cf540a629d629c86d7993d9651226a6789b/starlette-0.47.1.tar.gz", hash = "sha256:aef012dd2b6be325ffa16698f9dc533614fb1cebd593a906b90dc1025529a79b", size = 2583072, upload-time = "2025-06-21T04:03:17.337Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/95/38ef0cd7fa11eaba6a99b3c4f5ac948d8bc6ff199aabd327a29cc000840c/starlette-0.47.1-py3-none-any.whl", hash = "sha256:5e11c9f5c7c3f24959edbf2dffdc01bba860228acf657129467d8a7468591527", size = 72747, upload-time = "2025-06-21T04:03:15.705Z" }, +] + +[[package]] +name = "tlv8" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/89/6df40b0c5fd9a1c30711f569bd31446f89d1de6d23948b391775f6784d94/tlv8-0.10.0.tar.gz", hash = "sha256:7930a590267b809952272ac2a27ee81b99ec5191fa2eba08050e0daee4262684", size = 16054, upload-time = "2022-04-12T07:47:19.102Z" } + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/ce/1eb500eae19f4648281bb2186927bb062d2438c2e5093d1360391afd2f90/tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0", size = 510821, upload-time = "2025-08-08T18:27:00.78Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6", size = 442563, upload-time = "2025-08-08T18:26:42.945Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef", size = 440729, upload-time = "2025-08-08T18:26:44.473Z" }, + { url = "https://files.pythonhosted.org/packages/1b/4e/619174f52b120efcf23633c817fd3fed867c30bff785e2cd5a53a70e483c/tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e", size = 444295, upload-time = "2025-08-08T18:26:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/95/fa/87b41709552bbd393c85dd18e4e3499dcd8983f66e7972926db8d96aa065/tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882", size = 443644, upload-time = "2025-08-08T18:26:47.625Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108", size = 443878, upload-time = "2025-08-08T18:26:50.599Z" }, + { url = "https://files.pythonhosted.org/packages/11/92/fe6d57da897776ad2e01e279170ea8ae726755b045fe5ac73b75357a5a3f/tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c", size = 444549, upload-time = "2025-08-08T18:26:51.864Z" }, + { url = "https://files.pythonhosted.org/packages/9b/02/c8f4f6c9204526daf3d760f4aa555a7a33ad0e60843eac025ccfd6ff4a93/tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4", size = 443973, upload-time = "2025-08-08T18:26:53.625Z" }, + { url = "https://files.pythonhosted.org/packages/ae/2d/f5f5707b655ce2317190183868cd0f6822a1121b4baeae509ceb9590d0bd/tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04", size = 443954, upload-time = "2025-08-08T18:26:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/e8/59/593bd0f40f7355806bf6573b47b8c22f8e1374c9b6fd03114bd6b7a3dcfd/tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0", size = 445023, upload-time = "2025-08-08T18:26:56.677Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f", size = 445427, upload-time = "2025-08-08T18:26:57.91Z" }, + { url = "https://files.pythonhosted.org/packages/5e/4f/e1f65e8f8c76d73658b33d33b81eed4322fb5085350e4328d5c956f0c8f9/tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af", size = 444456, upload-time = "2025-08-08T18:26:59.207Z" }, +] + +[[package]] +name = "typer" +version = "0.17.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/92/e8/2a73ccf9874ec4c7638f172efc8972ceab13a0e3480b389d6ed822f7a822/typer-0.17.4.tar.gz", hash = "sha256:b77dc07d849312fd2bb5e7f20a7af8985c7ec360c45b051ed5412f64d8dc1580", size = 103734, upload-time = "2025-09-05T18:14:40.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/72/6b3e70d32e89a5cbb6a4513726c1ae8762165b027af569289e19ec08edd8/typer-0.17.4-py3-none-any.whl", hash = "sha256:015534a6edaa450e7007eba705d5c18c3349dcea50a6ad79a5ed530967575824", size = 46643, upload-time = "2025-09-05T18:14:39.166Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", size = 107423, upload-time = "2025-06-02T14:52:11.399Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af", size = 43839, upload-time = "2025-06-02T14:52:10.026Z" }, +] + +[[package]] +name = "urllib3" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.34.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631, upload-time = "2025-06-01T07:48:17.531Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431, upload-time = "2025-06-01T07:48:15.664Z" }, +] + +[[package]] +name = "uvloop" +version = "0.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741, upload-time = "2024-10-14T23:38:35.489Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/76/44a55515e8c9505aa1420aebacf4dd82552e5e15691654894e90d0bd051a/uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f", size = 1442019, upload-time = "2024-10-14T23:37:20.068Z" }, + { url = "https://files.pythonhosted.org/packages/35/5a/62d5800358a78cc25c8a6c72ef8b10851bdb8cca22e14d9c74167b7f86da/uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d", size = 801898, upload-time = "2024-10-14T23:37:22.663Z" }, + { url = "https://files.pythonhosted.org/packages/f3/96/63695e0ebd7da6c741ccd4489b5947394435e198a1382349c17b1146bb97/uvloop-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26", size = 3827735, upload-time = "2024-10-14T23:37:25.129Z" }, + { url = "https://files.pythonhosted.org/packages/61/e0/f0f8ec84979068ffae132c58c79af1de9cceeb664076beea86d941af1a30/uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb", size = 3825126, upload-time = "2024-10-14T23:37:27.59Z" }, + { url = "https://files.pythonhosted.org/packages/bf/fe/5e94a977d058a54a19df95f12f7161ab6e323ad49f4dabc28822eb2df7ea/uvloop-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f", size = 3705789, upload-time = "2024-10-14T23:37:29.385Z" }, + { url = "https://files.pythonhosted.org/packages/26/dd/c7179618e46092a77e036650c1f056041a028a35c4d76945089fcfc38af8/uvloop-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c", size = 3800523, upload-time = "2024-10-14T23:37:32.048Z" }, + { url = "https://files.pythonhosted.org/packages/57/a7/4cf0334105c1160dd6819f3297f8700fda7fc30ab4f61fbf3e725acbc7cc/uvloop-0.21.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", size = 1447410, upload-time = "2024-10-14T23:37:33.612Z" }, + { url = "https://files.pythonhosted.org/packages/8c/7c/1517b0bbc2dbe784b563d6ab54f2ef88c890fdad77232c98ed490aa07132/uvloop-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", size = 805476, upload-time = "2024-10-14T23:37:36.11Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ea/0bfae1aceb82a503f358d8d2fa126ca9dbdb2ba9c7866974faec1cb5875c/uvloop-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", size = 3960855, upload-time = "2024-10-14T23:37:37.683Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ca/0864176a649838b838f36d44bf31c451597ab363b60dc9e09c9630619d41/uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", size = 3973185, upload-time = "2024-10-14T23:37:40.226Z" }, + { url = "https://files.pythonhosted.org/packages/30/bf/08ad29979a936d63787ba47a540de2132169f140d54aa25bc8c3df3e67f4/uvloop-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", size = 3820256, upload-time = "2024-10-14T23:37:42.839Z" }, + { url = "https://files.pythonhosted.org/packages/da/e2/5cf6ef37e3daf2f06e651aae5ea108ad30df3cb269102678b61ebf1fdf42/uvloop-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", size = 3937323, upload-time = "2024-10-14T23:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/8c/4c/03f93178830dc7ce8b4cdee1d36770d2f5ebb6f3d37d354e061eefc73545/uvloop-0.21.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c", size = 1471284, upload-time = "2024-10-14T23:37:47.833Z" }, + { url = "https://files.pythonhosted.org/packages/43/3e/92c03f4d05e50f09251bd8b2b2b584a2a7f8fe600008bcc4523337abe676/uvloop-0.21.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2", size = 821349, upload-time = "2024-10-14T23:37:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/a6/ef/a02ec5da49909dbbfb1fd205a9a1ac4e88ea92dcae885e7c961847cd51e2/uvloop-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d", size = 4580089, upload-time = "2024-10-14T23:37:51.703Z" }, + { url = "https://files.pythonhosted.org/packages/06/a7/b4e6a19925c900be9f98bec0a75e6e8f79bb53bdeb891916609ab3958967/uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc", size = 4693770, upload-time = "2024-10-14T23:37:54.122Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0c/f07435a18a4b94ce6bd0677d8319cd3de61f3a9eeb1e5f8ab4e8b5edfcb3/uvloop-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb", size = 4451321, upload-time = "2024-10-14T23:37:55.766Z" }, + { url = "https://files.pythonhosted.org/packages/8f/eb/f7032be105877bcf924709c97b1bf3b90255b4ec251f9340cef912559f28/uvloop-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f", size = 4659022, upload-time = "2024-10-14T23:37:58.195Z" }, +] + +[[package]] +name = "virtualenv" +version = "20.34.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/14/37fcdba2808a6c615681cd216fecae00413c9dab44fb2e57805ecf3eaee3/virtualenv-20.34.0.tar.gz", hash = "sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a", size = 6003808, upload-time = "2025-08-13T14:24:07.464Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/06/04c8e804f813cf972e3262f3f8584c232de64f0cde9f703b46cf53a45090/virtualenv-20.34.0-py3-none-any.whl", hash = "sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026", size = 5983279, upload-time = "2025-08-13T14:24:05.111Z" }, +] + +[[package]] +name = "websocket-client" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648, upload-time = "2024-04-23T22:16:16.976Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload-time = "2024-04-23T22:16:14.422Z" }, +] + +[[package]] +name = "websockets" +version = "15.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", size = 175423, upload-time = "2025-03-05T20:01:35.363Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", size = 173080, upload-time = "2025-03-05T20:01:37.304Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", size = 173329, upload-time = "2025-03-05T20:01:39.668Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", size = 182312, upload-time = "2025-03-05T20:01:41.815Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", size = 181319, upload-time = "2025-03-05T20:01:43.967Z" }, + { url = "https://files.pythonhosted.org/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", size = 181631, upload-time = "2025-03-05T20:01:46.104Z" }, + { url = "https://files.pythonhosted.org/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", size = 182016, upload-time = "2025-03-05T20:01:47.603Z" }, + { url = "https://files.pythonhosted.org/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", size = 181426, upload-time = "2025-03-05T20:01:48.949Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", size = 181360, upload-time = "2025-03-05T20:01:50.938Z" }, + { url = "https://files.pythonhosted.org/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", size = 176388, upload-time = "2025-03-05T20:01:52.213Z" }, + { url = "https://files.pythonhosted.org/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", size = 176830, upload-time = "2025-03-05T20:01:53.922Z" }, + { url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423, upload-time = "2025-03-05T20:01:56.276Z" }, + { url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082, upload-time = "2025-03-05T20:01:57.563Z" }, + { url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330, upload-time = "2025-03-05T20:01:59.063Z" }, + { url = "https://files.pythonhosted.org/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878, upload-time = "2025-03-05T20:02:00.305Z" }, + { url = "https://files.pythonhosted.org/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883, upload-time = "2025-03-05T20:02:03.148Z" }, + { url = "https://files.pythonhosted.org/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252, upload-time = "2025-03-05T20:02:05.29Z" }, + { url = "https://files.pythonhosted.org/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521, upload-time = "2025-03-05T20:02:07.458Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958, upload-time = "2025-03-05T20:02:09.842Z" }, + { url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918, upload-time = "2025-03-05T20:02:11.968Z" }, + { url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388, upload-time = "2025-03-05T20:02:13.32Z" }, + { url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828, upload-time = "2025-03-05T20:02:14.585Z" }, + { url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload-time = "2025-03-05T20:02:16.706Z" }, + { url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload-time = "2025-03-05T20:02:18.832Z" }, + { url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload-time = "2025-03-05T20:02:20.187Z" }, + { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" }, + { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" }, + { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" }, + { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" }, + { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109, upload-time = "2025-03-05T20:03:17.769Z" }, + { url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343, upload-time = "2025-03-05T20:03:19.094Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599, upload-time = "2025-03-05T20:03:21.1Z" }, + { url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207, upload-time = "2025-03-05T20:03:23.221Z" }, + { url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155, upload-time = "2025-03-05T20:03:25.321Z" }, + { url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884, upload-time = "2025-03-05T20:03:27.934Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, +] + +[[package]] +name = "win32-setctime" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, +] + +[[package]] +name = "wrapt" +version = "1.17.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/23/bb82321b86411eb51e5a5db3fb8f8032fd30bd7c2d74bfe936136b2fa1d6/wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04", size = 53482, upload-time = "2025-08-12T05:51:44.467Z" }, + { url = "https://files.pythonhosted.org/packages/45/69/f3c47642b79485a30a59c63f6d739ed779fb4cc8323205d047d741d55220/wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2", size = 38676, upload-time = "2025-08-12T05:51:32.636Z" }, + { url = "https://files.pythonhosted.org/packages/d1/71/e7e7f5670c1eafd9e990438e69d8fb46fa91a50785332e06b560c869454f/wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c", size = 38957, upload-time = "2025-08-12T05:51:54.655Z" }, + { url = "https://files.pythonhosted.org/packages/de/17/9f8f86755c191d6779d7ddead1a53c7a8aa18bccb7cea8e7e72dfa6a8a09/wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775", size = 81975, upload-time = "2025-08-12T05:52:30.109Z" }, + { url = "https://files.pythonhosted.org/packages/f2/15/dd576273491f9f43dd09fce517f6c2ce6eb4fe21681726068db0d0467096/wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd", size = 83149, upload-time = "2025-08-12T05:52:09.316Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c4/5eb4ce0d4814521fee7aa806264bf7a114e748ad05110441cd5b8a5c744b/wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05", size = 82209, upload-time = "2025-08-12T05:52:10.331Z" }, + { url = "https://files.pythonhosted.org/packages/31/4b/819e9e0eb5c8dc86f60dfc42aa4e2c0d6c3db8732bce93cc752e604bb5f5/wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418", size = 81551, upload-time = "2025-08-12T05:52:31.137Z" }, + { url = "https://files.pythonhosted.org/packages/f8/83/ed6baf89ba3a56694700139698cf703aac9f0f9eb03dab92f57551bd5385/wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390", size = 36464, upload-time = "2025-08-12T05:53:01.204Z" }, + { url = "https://files.pythonhosted.org/packages/2f/90/ee61d36862340ad7e9d15a02529df6b948676b9a5829fd5e16640156627d/wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6", size = 38748, upload-time = "2025-08-12T05:53:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c3/cefe0bd330d389c9983ced15d326f45373f4073c9f4a8c2f99b50bfea329/wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18", size = 36810, upload-time = "2025-08-12T05:52:51.906Z" }, + { url = "https://files.pythonhosted.org/packages/52/db/00e2a219213856074a213503fdac0511203dceefff26e1daa15250cc01a0/wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7", size = 53482, upload-time = "2025-08-12T05:51:45.79Z" }, + { url = "https://files.pythonhosted.org/packages/5e/30/ca3c4a5eba478408572096fe9ce36e6e915994dd26a4e9e98b4f729c06d9/wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85", size = 38674, upload-time = "2025-08-12T05:51:34.629Z" }, + { url = "https://files.pythonhosted.org/packages/31/25/3e8cc2c46b5329c5957cec959cb76a10718e1a513309c31399a4dad07eb3/wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f", size = 38959, upload-time = "2025-08-12T05:51:56.074Z" }, + { url = "https://files.pythonhosted.org/packages/5d/8f/a32a99fc03e4b37e31b57cb9cefc65050ea08147a8ce12f288616b05ef54/wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311", size = 82376, upload-time = "2025-08-12T05:52:32.134Z" }, + { url = "https://files.pythonhosted.org/packages/31/57/4930cb8d9d70d59c27ee1332a318c20291749b4fba31f113c2f8ac49a72e/wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1", size = 83604, upload-time = "2025-08-12T05:52:11.663Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f3/1afd48de81d63dd66e01b263a6fbb86e1b5053b419b9b33d13e1f6d0f7d0/wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5", size = 82782, upload-time = "2025-08-12T05:52:12.626Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d7/4ad5327612173b144998232f98a85bb24b60c352afb73bc48e3e0d2bdc4e/wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2", size = 82076, upload-time = "2025-08-12T05:52:33.168Z" }, + { url = "https://files.pythonhosted.org/packages/bb/59/e0adfc831674a65694f18ea6dc821f9fcb9ec82c2ce7e3d73a88ba2e8718/wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89", size = 36457, upload-time = "2025-08-12T05:53:03.936Z" }, + { url = "https://files.pythonhosted.org/packages/83/88/16b7231ba49861b6f75fc309b11012ede4d6b0a9c90969d9e0db8d991aeb/wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77", size = 38745, upload-time = "2025-08-12T05:53:02.885Z" }, + { url = "https://files.pythonhosted.org/packages/9a/1e/c4d4f3398ec073012c51d1c8d87f715f56765444e1a4b11e5180577b7e6e/wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a", size = 36806, upload-time = "2025-08-12T05:52:53.368Z" }, + { url = "https://files.pythonhosted.org/packages/9f/41/cad1aba93e752f1f9268c77270da3c469883d56e2798e7df6240dcb2287b/wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0", size = 53998, upload-time = "2025-08-12T05:51:47.138Z" }, + { url = "https://files.pythonhosted.org/packages/60/f8/096a7cc13097a1869fe44efe68dace40d2a16ecb853141394047f0780b96/wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba", size = 39020, upload-time = "2025-08-12T05:51:35.906Z" }, + { url = "https://files.pythonhosted.org/packages/33/df/bdf864b8997aab4febb96a9ae5c124f700a5abd9b5e13d2a3214ec4be705/wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd", size = 39098, upload-time = "2025-08-12T05:51:57.474Z" }, + { url = "https://files.pythonhosted.org/packages/9f/81/5d931d78d0eb732b95dc3ddaeeb71c8bb572fb01356e9133916cd729ecdd/wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828", size = 88036, upload-time = "2025-08-12T05:52:34.784Z" }, + { url = "https://files.pythonhosted.org/packages/ca/38/2e1785df03b3d72d34fc6252d91d9d12dc27a5c89caef3335a1bbb8908ca/wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9", size = 88156, upload-time = "2025-08-12T05:52:13.599Z" }, + { url = "https://files.pythonhosted.org/packages/b3/8b/48cdb60fe0603e34e05cffda0b2a4adab81fd43718e11111a4b0100fd7c1/wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396", size = 87102, upload-time = "2025-08-12T05:52:14.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/51/d81abca783b58f40a154f1b2c56db1d2d9e0d04fa2d4224e357529f57a57/wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc", size = 87732, upload-time = "2025-08-12T05:52:36.165Z" }, + { url = "https://files.pythonhosted.org/packages/9e/b1/43b286ca1392a006d5336412d41663eeef1ad57485f3e52c767376ba7e5a/wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe", size = 36705, upload-time = "2025-08-12T05:53:07.123Z" }, + { url = "https://files.pythonhosted.org/packages/28/de/49493f962bd3c586ab4b88066e967aa2e0703d6ef2c43aa28cb83bf7b507/wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c", size = 38877, upload-time = "2025-08-12T05:53:05.436Z" }, + { url = "https://files.pythonhosted.org/packages/f1/48/0f7102fe9cb1e8a5a77f80d4f0956d62d97034bbe88d33e94699f99d181d/wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6", size = 36885, upload-time = "2025-08-12T05:52:54.367Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" }, +] + +[[package]] +name = "yarl" +version = "1.20.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428, upload-time = "2025-06-10T00:46:09.923Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/65/7fed0d774abf47487c64be14e9223749468922817b5e8792b8a64792a1bb/yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4", size = 132910, upload-time = "2025-06-10T00:42:31.108Z" }, + { url = "https://files.pythonhosted.org/packages/8a/7b/988f55a52da99df9e56dc733b8e4e5a6ae2090081dc2754fc8fd34e60aa0/yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a", size = 90644, upload-time = "2025-06-10T00:42:33.851Z" }, + { url = "https://files.pythonhosted.org/packages/f7/de/30d98f03e95d30c7e3cc093759982d038c8833ec2451001d45ef4854edc1/yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed", size = 89322, upload-time = "2025-06-10T00:42:35.688Z" }, + { url = "https://files.pythonhosted.org/packages/e0/7a/f2f314f5ebfe9200724b0b748de2186b927acb334cf964fd312eb86fc286/yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e", size = 323786, upload-time = "2025-06-10T00:42:37.817Z" }, + { url = "https://files.pythonhosted.org/packages/15/3f/718d26f189db96d993d14b984ce91de52e76309d0fd1d4296f34039856aa/yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73", size = 319627, upload-time = "2025-06-10T00:42:39.937Z" }, + { url = "https://files.pythonhosted.org/packages/a5/76/8fcfbf5fa2369157b9898962a4a7d96764b287b085b5b3d9ffae69cdefd1/yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e", size = 339149, upload-time = "2025-06-10T00:42:42.627Z" }, + { url = "https://files.pythonhosted.org/packages/3c/95/d7fc301cc4661785967acc04f54a4a42d5124905e27db27bb578aac49b5c/yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8", size = 333327, upload-time = "2025-06-10T00:42:44.842Z" }, + { url = "https://files.pythonhosted.org/packages/65/94/e21269718349582eee81efc5c1c08ee71c816bfc1585b77d0ec3f58089eb/yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23", size = 326054, upload-time = "2025-06-10T00:42:47.149Z" }, + { url = "https://files.pythonhosted.org/packages/32/ae/8616d1f07853704523519f6131d21f092e567c5af93de7e3e94b38d7f065/yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70", size = 315035, upload-time = "2025-06-10T00:42:48.852Z" }, + { url = "https://files.pythonhosted.org/packages/48/aa/0ace06280861ef055855333707db5e49c6e3a08840a7ce62682259d0a6c0/yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb", size = 338962, upload-time = "2025-06-10T00:42:51.024Z" }, + { url = "https://files.pythonhosted.org/packages/20/52/1e9d0e6916f45a8fb50e6844f01cb34692455f1acd548606cbda8134cd1e/yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2", size = 335399, upload-time = "2025-06-10T00:42:53.007Z" }, + { url = "https://files.pythonhosted.org/packages/f2/65/60452df742952c630e82f394cd409de10610481d9043aa14c61bf846b7b1/yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30", size = 338649, upload-time = "2025-06-10T00:42:54.964Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f5/6cd4ff38dcde57a70f23719a838665ee17079640c77087404c3d34da6727/yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309", size = 358563, upload-time = "2025-06-10T00:42:57.28Z" }, + { url = "https://files.pythonhosted.org/packages/d1/90/c42eefd79d0d8222cb3227bdd51b640c0c1d0aa33fe4cc86c36eccba77d3/yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24", size = 357609, upload-time = "2025-06-10T00:42:59.055Z" }, + { url = "https://files.pythonhosted.org/packages/03/c8/cea6b232cb4617514232e0f8a718153a95b5d82b5290711b201545825532/yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13", size = 350224, upload-time = "2025-06-10T00:43:01.248Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a3/eaa0ab9712f1f3d01faf43cf6f1f7210ce4ea4a7e9b28b489a2261ca8db9/yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8", size = 81753, upload-time = "2025-06-10T00:43:03.486Z" }, + { url = "https://files.pythonhosted.org/packages/8f/34/e4abde70a9256465fe31c88ed02c3f8502b7b5dead693a4f350a06413f28/yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16", size = 86817, upload-time = "2025-06-10T00:43:05.231Z" }, + { url = "https://files.pythonhosted.org/packages/b1/18/893b50efc2350e47a874c5c2d67e55a0ea5df91186b2a6f5ac52eff887cd/yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e", size = 133833, upload-time = "2025-06-10T00:43:07.393Z" }, + { url = "https://files.pythonhosted.org/packages/89/ed/b8773448030e6fc47fa797f099ab9eab151a43a25717f9ac043844ad5ea3/yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b", size = 91070, upload-time = "2025-06-10T00:43:09.538Z" }, + { url = "https://files.pythonhosted.org/packages/e3/e3/409bd17b1e42619bf69f60e4f031ce1ccb29bd7380117a55529e76933464/yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b", size = 89818, upload-time = "2025-06-10T00:43:11.575Z" }, + { url = "https://files.pythonhosted.org/packages/f8/77/64d8431a4d77c856eb2d82aa3de2ad6741365245a29b3a9543cd598ed8c5/yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4", size = 347003, upload-time = "2025-06-10T00:43:14.088Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d2/0c7e4def093dcef0bd9fa22d4d24b023788b0a33b8d0088b51aa51e21e99/yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1", size = 336537, upload-time = "2025-06-10T00:43:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f3/fc514f4b2cf02cb59d10cbfe228691d25929ce8f72a38db07d3febc3f706/yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833", size = 362358, upload-time = "2025-06-10T00:43:18.704Z" }, + { url = "https://files.pythonhosted.org/packages/ea/6d/a313ac8d8391381ff9006ac05f1d4331cee3b1efaa833a53d12253733255/yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d", size = 357362, upload-time = "2025-06-10T00:43:20.888Z" }, + { url = "https://files.pythonhosted.org/packages/00/70/8f78a95d6935a70263d46caa3dd18e1f223cf2f2ff2037baa01a22bc5b22/yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8", size = 348979, upload-time = "2025-06-10T00:43:23.169Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/42773027968968f4f15143553970ee36ead27038d627f457cc44bbbeecf3/yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf", size = 337274, upload-time = "2025-06-10T00:43:27.111Z" }, + { url = "https://files.pythonhosted.org/packages/05/be/665634aa196954156741ea591d2f946f1b78ceee8bb8f28488bf28c0dd62/yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e", size = 363294, upload-time = "2025-06-10T00:43:28.96Z" }, + { url = "https://files.pythonhosted.org/packages/eb/90/73448401d36fa4e210ece5579895731f190d5119c4b66b43b52182e88cd5/yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389", size = 358169, upload-time = "2025-06-10T00:43:30.701Z" }, + { url = "https://files.pythonhosted.org/packages/c3/b0/fce922d46dc1eb43c811f1889f7daa6001b27a4005587e94878570300881/yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f", size = 362776, upload-time = "2025-06-10T00:43:32.51Z" }, + { url = "https://files.pythonhosted.org/packages/f1/0d/b172628fce039dae8977fd22caeff3eeebffd52e86060413f5673767c427/yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845", size = 381341, upload-time = "2025-06-10T00:43:34.543Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9b/5b886d7671f4580209e855974fe1cecec409aa4a89ea58b8f0560dc529b1/yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1", size = 379988, upload-time = "2025-06-10T00:43:36.489Z" }, + { url = "https://files.pythonhosted.org/packages/73/be/75ef5fd0fcd8f083a5d13f78fd3f009528132a1f2a1d7c925c39fa20aa79/yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e", size = 371113, upload-time = "2025-06-10T00:43:38.592Z" }, + { url = "https://files.pythonhosted.org/packages/50/4f/62faab3b479dfdcb741fe9e3f0323e2a7d5cd1ab2edc73221d57ad4834b2/yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773", size = 81485, upload-time = "2025-06-10T00:43:41.038Z" }, + { url = "https://files.pythonhosted.org/packages/f0/09/d9c7942f8f05c32ec72cd5c8e041c8b29b5807328b68b4801ff2511d4d5e/yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e", size = 86686, upload-time = "2025-06-10T00:43:42.692Z" }, + { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667, upload-time = "2025-06-10T00:43:44.369Z" }, + { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025, upload-time = "2025-06-10T00:43:46.295Z" }, + { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709, upload-time = "2025-06-10T00:43:48.22Z" }, + { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287, upload-time = "2025-06-10T00:43:49.924Z" }, + { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429, upload-time = "2025-06-10T00:43:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429, upload-time = "2025-06-10T00:43:53.494Z" }, + { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862, upload-time = "2025-06-10T00:43:55.766Z" }, + { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616, upload-time = "2025-06-10T00:43:58.056Z" }, + { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954, upload-time = "2025-06-10T00:43:59.773Z" }, + { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575, upload-time = "2025-06-10T00:44:02.051Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061, upload-time = "2025-06-10T00:44:04.196Z" }, + { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142, upload-time = "2025-06-10T00:44:06.527Z" }, + { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894, upload-time = "2025-06-10T00:44:08.379Z" }, + { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378, upload-time = "2025-06-10T00:44:10.51Z" }, + { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069, upload-time = "2025-06-10T00:44:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249, upload-time = "2025-06-10T00:44:14.731Z" }, + { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710, upload-time = "2025-06-10T00:44:16.716Z" }, + { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, +] diff --git a/views_api.py b/views_api.py index c29c60c..810f8ca 100644 --- a/views_api.py +++ b/views_api.py @@ -1,5 +1,4 @@ from http import HTTPStatus -from typing import Dict, List, Optional import secp256k1 from fastapi import APIRouter, Depends, Request @@ -38,20 +37,18 @@ nwcprovider_api_router = APIRouter() # Get supported permissions -@nwcprovider_api_router.get("/api/v1/permissions", status_code=HTTPStatus.OK) -async def api_get_permissions() -> Dict: +@nwcprovider_api_router.get("/api/v1/permissions") +async def api_get_permissions() -> dict: return nwc_permissions ## Get nwc keys associated with the wallet -@nwcprovider_api_router.get( - "/api/v1/nwc", status_code=HTTPStatus.OK, response_model=List[NWCGetResponse] -) +@nwcprovider_api_router.get("/api/v1/nwc") async def api_get_nwcs( include_expired: bool = False, calculate_spent_budget: bool = False, wallet: WalletTypeInfo = Depends(require_admin_key), -): +) -> list[NWCGetResponse]: wallet_id = wallet.wallet.id # hardening # @@ -74,9 +71,7 @@ async def api_get_nwcs( # Get a nwc key -@nwcprovider_api_router.get( - "/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK, response_model=NWCGetResponse -) +@nwcprovider_api_router.get("/api/v1/nwc/{pubkey}") async def api_get_nwc( pubkey: str, include_expired: bool = False, @@ -102,22 +97,20 @@ async def api_get_nwc( # Get pairing url for given secret -@nwcprovider_api_router.get( - "/api/v1/pairing/{secret}", status_code=HTTPStatus.OK, response_model=str -) +@nwcprovider_api_router.get("/api/v1/pairing/{secret}") async def api_get_pairing_url(req: Request, secret: str) -> str: # hardening # assert_sane_string(secret) # ## # - pprivkey: Optional[str] = await get_config_nwc("provider_key") + pprivkey: str | None = await get_config_nwc("provider_key") if not pprivkey: raise Exception("Extension is not configured") relay = await get_config_nwc("relay") if not relay: raise Exception("Extension is not configured") - relay_alias: Optional[str] = await get_config_nwc("relay_alias") + relay_alias: str | None = await get_config_nwc("relay_alias") if relay_alias: relay = relay_alias else: @@ -147,13 +140,12 @@ async def api_get_pairing_url(req: Request, secret: str) -> str: @nwcprovider_api_router.put( "/api/v1/nwc/{pubkey}", status_code=HTTPStatus.CREATED, - response_model=NWCGetResponse, ) async def api_register_nwc( pubkey: str, data: NWCRegistrationRequest, wallet: WalletTypeInfo = Depends(require_admin_key), -): +) -> NWCGetResponse: wallet_id = wallet.wallet.id # hardening # @@ -177,7 +169,7 @@ async def api_register_nwc( # Delete a nwc key -@nwcprovider_api_router.delete("/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK) +@nwcprovider_api_router.delete("/api/v1/nwc/{pubkey}") async def api_delete_nwc( pubkey: str, wallet: WalletTypeInfo = Depends(require_admin_key) ): @@ -193,9 +185,7 @@ async def api_delete_nwc( # Get config -@nwcprovider_api_router.get( - "/api/v1/config", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] -) +@nwcprovider_api_router.get("/api/v1/config", dependencies=[Depends(check_admin)]) async def api_get_all_config_nwc(): config = await get_all_config_nwc() return config @@ -204,7 +194,6 @@ async def api_get_all_config_nwc(): # Get config @nwcprovider_api_router.get( "/api/v1/config/{key}", - status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)], ) async def api_get_config_nwc(key: str): @@ -215,9 +204,7 @@ async def api_get_config_nwc(key: str): # Set config -@nwcprovider_api_router.post( - "/api/v1/config", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] -) +@nwcprovider_api_router.post("/api/v1/config", dependencies=[Depends(check_admin)]) async def api_set_config_nwc(req: Request): data = await req.json() From 9d97745e708b903ba940398c905943cca1ff3442 Mon Sep 17 00:00:00 2001 From: blackcoffeexbt <87530449+blackcoffeexbt@users.noreply.github.com> Date: Tue, 4 Nov 2025 11:55:21 +0000 Subject: [PATCH 60/90] Improved user documentation (#7) --- README.md | 61 +++++++++++++++++++++++--------- templates/nwcprovider/index.html | 45 +++++++++++++++++++++-- 2 files changed, 86 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 24eb404..b222469 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,51 @@ Easily connect your LNbits wallets via [NWC](https://nwc.dev/). Install the extension via the .env file or through the admin UI on your LNbits server. More details can be found [here](https://github.com/lnbits/lnbits/wiki/LNbits-Extensions). -## Configuration +# Configuration -Configure the extension from the "Settings" page in the top right menu when logged in as admin inside the extension page. +The **LNbits NWC Service Provider** requires a one-time setup before it can be used. +It relies on a Nostr relay, which can be either: + +- The **LNbits Nostrclient** browser extension +- A **third-party Nostr relay** of your choice + +## Relay Configuration + +Before you can start using the extension, you need to configure a Nostr relay. + +### Option 1: Use a third-party Nostr relay (recommended) + +This is the easiest option for most users. It allows you to run LNbits on a private network while connecting to NWC apps through a public Nostr relay. + +1. Choose a Nostr relay that supports NWC connections. +2. Open the **NWC Service Provider settings** (gear icon in the top-right corner). + 1. Enter your chosen relay URL in the **Nostr Relay URL** field (e.g. `wss://relay.nostrconnect.com`). + 2. Click **Save**. + +### Option 2: Use the LNbits Nostrclient extension + +> **Note:** This option only works if your LNbits instance is publicly accessible on the internet. Refer to the [nostrclient documentation](https://github.com/lnbits/nostrclient) for more information. + +1. Install the **Nostrclient** extension in your browser. +2. Open the extension. + 1. Add at least one relay (e.g. `wss://relay.nostrconnect.com` is a good choice for NWC connections). + 2. Open **Settings** and enable **Expose Public WebSocket**. + +--- + +## Connecting a NWC App + +1. In the **NWC Service Provider** extension, select the wallet you want to connect. +2. Click the **+** button to add a new connection. +3. Enter a description, expiry date (optional), permissions, and limits. +4. Click **Connect** to create the connection. +5. Use the generated **pairing URL** or **QR code** to connect your chosen app. + +--- + +# Extension Configuration + +The "Configuration" page of the NWC Service Provider extension can be accessed by clicking the gear icon in the top-right corner of the extension page. ### Configuration Options: @@ -26,18 +68,3 @@ Configure the extension from the "Settings" page in the top right menu when logg > For example, in shared or community lnbits instances, where users are unaware of this functionality, they might assume a payment has failed and attempt to pay a new invoice with a different wallet, only for the instance to come back online and process the original payment request, potentially leading to duplicate payments. > > For this reason, unless you are trying to tackle this specific issue, it is recommended to leave this setting at `0`. - -### Using Nostrclient - -The extension is preconfigured to connect to the nostrclient extension. Install it on the same LNbits instance and configure it to expose public websocket endpoints. Refer to the [nostrclient documentation](https://github.com/lnbits/nostrclient) for more information. - -### Using a Custom Relay - -To use a custom relay, set the `relay` key to the relay URL (e.g., `wss://nostr.wine`) in the extension's Settings page. - -## Usage - -1. Go to the extension page. -2. Select a wallet and click the plus button to create a new NWC connection. -3. Configure expiration, limits, and permissions. -4. A pairing URL will be generated for you to open, copy, or scan with the NWC app. Note that the pairing URL is shown only once, but you can delete and recreate the connection to get a new one. diff --git a/templates/nwcprovider/index.html b/templates/nwcprovider/index.html index 3c6ecf1..0034330 100644 --- a/templates/nwcprovider/index.html +++ b/templates/nwcprovider/index.html @@ -99,12 +99,51 @@
-
NWC Service provider
+
NWC Service Provider

- Nostr Wallet Connect (NWC) is an open protocol to connect lightning - wallets to apps + Nostr Wallet Connect (NWC) is an open protocol to connect Lightning + wallets to apps. This extension allows you to use your LNbits wallet + with + any NWC compatible app.

+

+ Before you can use this extension, you need to configure it. + Read the User Guide + to get started. +

+ +
Connecting a NWC App
+

+ Once you have configured the extension, you can connect a NWC + compatible app by following these steps: +

+
    +
  1. + In the NWC Service Provider extension, select the + wallet you want to connect. +
  2. +
  3. Click the "+" button to add a new connection.
  4. +
  5. + Enter a description, expiry date (optional), permissions, and + limits. +
  6. +
  7. Click "Connect" to create the connection.
  8. +
  9. + Use the generated pairing URL or QR code to connect your chosen app. +
  10. +
+ From 667a4b0528fd929693dae2f1c52399badaf78b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Tue, 2 Dec 2025 21:04:55 +0100 Subject: [PATCH 61/90] refactor: use pynostr/coincurve instead of secp256k1 (#18) --------- Co-authored-by: Riccardo Balbo Co-authored-by: Vlad Stan --- .devcontainer/setup.sh | 14 +- migrations.py | 6 +- nwcp.py | 101 +- poetry.lock | 3054 +++++++++++++++++++++------------ pyproject.toml | 12 +- tests/integration/start.sh | 4 +- tests/integration/strfry.conf | 2 +- tests/integration/test_all.py | 63 +- tests/unit/test_nwcp.py | 21 +- views_api.py | 12 +- 10 files changed, 2054 insertions(+), 1235 deletions(-) diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index d2a2f72..261f66b 100644 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -5,23 +5,23 @@ cd $CONTAINER_WORKSPACE_FOLDER cd $HOME echo $PWD -if [ ! -d ./lnbits ] ; then +if [ ! -d ./lnbits ] ; then git clone https://github.com/lnbits/lnbits.git lnbits -fi +fi cd lnbits echo $PWD -git checkout v1.0.0-rc7 +git checkout dev poetry env use 3.12 POETRY_PYTHON_PATH=$(poetry env info -p)/bin/python ln -sf $POETRY_PYTHON_PATH /home/vscode/python make bundle -poetry install --no-interaction -mkdir -p lnbits/extensions/ -if [ ! -d lnbits/extensions/nwcprovider ] ; then +poetry install --no-interaction +mkdir -p lnbits/extensions/ +if [ ! -d lnbits/extensions/nwcprovider ] ; then ln -s $CONTAINER_WORKSPACE_FOLDER lnbits/extensions/nwcprovider fi cd $CONTAINER_WORKSPACE_FOLDER poetry install --no-interaction npm i prettier -npm i pyright \ No newline at end of file +npm i pyright diff --git a/migrations.py b/migrations.py index cb816db..1a3a9b7 100644 --- a/migrations.py +++ b/migrations.py @@ -1,4 +1,4 @@ -import secp256k1 +from coincurve import PrivateKey async def m001_initial(db): @@ -72,14 +72,14 @@ async def m003_default_config(db): ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """ ) - new_private_key = bytes.hex(secp256k1._gen_private_key()) + private_key = PrivateKey() await db.execute( """ INSERT INTO nwcprovider.config (key, value) VALUES ('provider_key', :provider_key) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; """, - {"provider_key": new_private_key}, + {"provider_key": private_key.to_hex()}, ) diff --git a/nwcp.py b/nwcp.py index 378acbd..26eeab3 100644 --- a/nwcp.py +++ b/nwcp.py @@ -1,5 +1,4 @@ import asyncio -import base64 import hashlib import json import random @@ -7,13 +6,11 @@ import time from collections.abc import Awaitable, Callable from typing import Any, Union -import secp256k1 -from Cryptodome import Random -from Cryptodome.Cipher import AES -from Cryptodome.Util.Padding import pad, unpad +from coincurve import PublicKeyXOnly from lnbits.helpers import encrypt_internal_message from lnbits.settings import settings from loguru import logger +from pynostr.key import PrivateKey from websockets.legacy.client import connect @@ -75,7 +72,7 @@ class MainSubscription: class NWCServiceProvider: def __init__( self, - private_key: str | None = None, + private_key_hex: str | None = None, relay: str | None = None, handle_missed_events: int = 0, ): @@ -90,15 +87,18 @@ class NWCServiceProvider: ) self.relay = relay - if not private_key: # Create random key - private_key = bytes.hex(secp256k1._gen_private_key()) + if not private_key_hex: # Create random key + self.private_key = PrivateKey() + self.private_key_hex = self.private_key.hex() + else: + self.private_key = PrivateKey.from_hex(private_key_hex) + self.private_key_hex = private_key_hex - self.private_key = secp256k1.PrivateKey(bytes.fromhex(private_key)) - self.private_key_hex = private_key - self.public_key = self.private_key.pubkey + self.public_key = self.private_key.public_key if not self.public_key: raise Exception("Invalid public key") - self.public_key_hex = self.public_key.serialize().hex()[2:] + + self.public_key_hex = self.public_key.hex() # List of supported methods self.supported_methods: list[str] = [] @@ -314,7 +314,7 @@ class NWCServiceProvider: nwc_pubkey = event["pubkey"] content = event["content"] # Decrypt the content - content = self._decrypt_content(content, nwc_pubkey) + content = self.private_key.decrypt_message(content, nwc_pubkey) # Deserialize content content = json.loads(content) # Handle request @@ -364,7 +364,9 @@ class NWCServiceProvider: # Reference user res["tags"].append(["p", nwc_pubkey]) # Finalize response event - res["content"] = self._encrypt_content(res["content"], nwc_pubkey) + res["content"] = self.private_key.encrypt_message( + res["content"], nwc_pubkey + ) self._sign_event(res) # Register response for this request, so we knows it is not stale @@ -513,65 +515,6 @@ class NWCServiceProvider: logger.debug("Reconnecting to NWC relay...") await self._ratelimit("connecting") - def _encrypt_content( - self, content: str, pubkey_hex: str, iv_seed: int | None = None - ) -> str: - """ - Encrypts the content for the given public key - - Args: - content (str): The content to be encrypted. - pubkey_hex (str): The public key in hex format. - - Returns: - str: The encrypted content. - """ - pubkey = secp256k1.PublicKey(bytes.fromhex("02" + pubkey_hex), True) - shared = pubkey.tweak_mul(bytes.fromhex(self.private_key_hex)).serialize()[1:] - # random iv (16B) - if not iv_seed: - iv = Random.new().read(AES.block_size) - else: - iv = hashlib.sha256(iv_seed.to_bytes(32, byteorder="big")).digest() - iv = iv[: AES.block_size] - - aes = AES.new(shared, AES.MODE_CBC, iv) - - content_bytes = content.encode("utf-8") - - # padding - content_bytes = pad(content_bytes, AES.block_size) - - encrypted_b64 = base64.b64encode(aes.encrypt(content_bytes)).decode("ascii") - iv_b64 = base64.b64encode(iv).decode("ascii") - encrypted_content = encrypted_b64 + "?iv=" + iv_b64 - return encrypted_content - - def _decrypt_content(self, content: str, pubkey_hex: str) -> str: - """ - Decrypts the content for the given public key - - Args: - content (str): The encrypted content. - pubkey_hex (str): The public key in hex format. - - Returns: - str: The decrypted content. - """ - pubkey = secp256k1.PublicKey(bytes.fromhex("02" + pubkey_hex), True) - - shared = pubkey.tweak_mul(bytes.fromhex(self.private_key_hex)).serialize()[1:] - # extract iv and content - (encrypted_content_b64, iv_b64) = content.split("?iv=") - encrypted_content = base64.b64decode(encrypted_content_b64.encode("ascii")) - iv = base64.b64decode(iv_b64.encode("ascii")) - # Decrypt - aes = AES.new(shared, AES.MODE_CBC, iv) - decrypted_bytes = aes.decrypt(encrypted_content) - decrypted_bytes = unpad(decrypted_bytes, AES.block_size) - decrypted = decrypted_bytes.decode("utf-8") - return decrypted - def _verify_event(self, event: dict) -> bool: """ Verify the event signature @@ -596,10 +539,8 @@ class NWCServiceProvider: if event_id != event["id"]: # Invalid event id return False pubkey_hex = event["pubkey"] - pubkey = secp256k1.PublicKey(bytes.fromhex("02" + pubkey_hex), True) - if not pubkey.schnorr_verify( - bytes.fromhex(event_id), bytes.fromhex(event["sig"]), None, raw=True - ): + pubkey = PublicKeyXOnly(bytes.fromhex(pubkey_hex)) + if not pubkey.verify(bytes.fromhex(event["sig"]), bytes.fromhex(event_id)): return False return True @@ -628,10 +569,8 @@ class NWCServiceProvider: event["id"] = event_id event["pubkey"] = self.public_key_hex - signature = ( - self.private_key.schnorr_sign(bytes.fromhex(event_id), None, raw=True) - ).hex() - event["sig"] = signature + signature = self.private_key.sign(bytes.fromhex(event_id)) + event["sig"] = signature.hex() # type: ignore return event async def cleanup(self): diff --git a/poetry.lock b/poetry.lock index 4248c68..304061c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -14,98 +14,132 @@ files = [ [[package]] name = "aiohttp" -version = "3.12.15" +version = "3.13.2" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "aiohttp-3.12.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b6fc902bff74d9b1879ad55f5404153e2b33a82e72a95c89cec5eb6cc9e92fbc"}, - {file = "aiohttp-3.12.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:098e92835b8119b54c693f2f88a1dec690e20798ca5f5fe5f0520245253ee0af"}, - {file = "aiohttp-3.12.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:40b3fee496a47c3b4a39a731954c06f0bd9bd3e8258c059a4beb76ac23f8e421"}, - {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ce13fcfb0bb2f259fb42106cdc63fa5515fb85b7e87177267d89a771a660b79"}, - {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3beb14f053222b391bf9cf92ae82e0171067cc9c8f52453a0f1ec7c37df12a77"}, - {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c39e87afe48aa3e814cac5f535bc6199180a53e38d3f51c5e2530f5aa4ec58c"}, - {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5f1b4ce5bc528a6ee38dbf5f39bbf11dd127048726323b72b8e85769319ffc4"}, - {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1004e67962efabbaf3f03b11b4c43b834081c9e3f9b32b16a7d97d4708a9abe6"}, - {file = "aiohttp-3.12.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8faa08fcc2e411f7ab91d1541d9d597d3a90e9004180edb2072238c085eac8c2"}, - {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fe086edf38b2222328cdf89af0dde2439ee173b8ad7cb659b4e4c6f385b2be3d"}, - {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:79b26fe467219add81d5e47b4a4ba0f2394e8b7c7c3198ed36609f9ba161aecb"}, - {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b761bac1192ef24e16706d761aefcb581438b34b13a2f069a6d343ec8fb693a5"}, - {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e153e8adacfe2af562861b72f8bc47f8a5c08e010ac94eebbe33dc21d677cd5b"}, - {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fc49c4de44977aa8601a00edbf157e9a421f227aa7eb477d9e3df48343311065"}, - {file = "aiohttp-3.12.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2776c7ec89c54a47029940177e75c8c07c29c66f73464784971d6a81904ce9d1"}, - {file = "aiohttp-3.12.15-cp310-cp310-win32.whl", hash = "sha256:2c7d81a277fa78b2203ab626ced1487420e8c11a8e373707ab72d189fcdad20a"}, - {file = "aiohttp-3.12.15-cp310-cp310-win_amd64.whl", hash = "sha256:83603f881e11f0f710f8e2327817c82e79431ec976448839f3cd05d7afe8f830"}, - {file = "aiohttp-3.12.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d3ce17ce0220383a0f9ea07175eeaa6aa13ae5a41f30bc61d84df17f0e9b1117"}, - {file = "aiohttp-3.12.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:010cc9bbd06db80fe234d9003f67e97a10fe003bfbedb40da7d71c1008eda0fe"}, - {file = "aiohttp-3.12.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f9d7c55b41ed687b9d7165b17672340187f87a773c98236c987f08c858145a9"}, - {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc4fbc61bb3548d3b482f9ac7ddd0f18c67e4225aaa4e8552b9f1ac7e6bda9e5"}, - {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbc8a7c410bb3ad5d595bb7118147dfbb6449d862cc1125cf8867cb337e8728"}, - {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74dad41b3458dbb0511e760fb355bb0b6689e0630de8a22b1b62a98777136e16"}, - {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b6f0af863cf17e6222b1735a756d664159e58855da99cfe965134a3ff63b0b0"}, - {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5b7fe4972d48a4da367043b8e023fb70a04d1490aa7d68800e465d1b97e493b"}, - {file = "aiohttp-3.12.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6443cca89553b7a5485331bc9bedb2342b08d073fa10b8c7d1c60579c4a7b9bd"}, - {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c5f40ec615e5264f44b4282ee27628cea221fcad52f27405b80abb346d9f3f8"}, - {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:2abbb216a1d3a2fe86dbd2edce20cdc5e9ad0be6378455b05ec7f77361b3ab50"}, - {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:db71ce547012a5420a39c1b744d485cfb823564d01d5d20805977f5ea1345676"}, - {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ced339d7c9b5030abad5854aa5413a77565e5b6e6248ff927d3e174baf3badf7"}, - {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7c7dd29c7b5bda137464dc9bfc738d7ceea46ff70309859ffde8c022e9b08ba7"}, - {file = "aiohttp-3.12.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:421da6fd326460517873274875c6c5a18ff225b40da2616083c5a34a7570b685"}, - {file = "aiohttp-3.12.15-cp311-cp311-win32.whl", hash = "sha256:4420cf9d179ec8dfe4be10e7d0fe47d6d606485512ea2265b0d8c5113372771b"}, - {file = "aiohttp-3.12.15-cp311-cp311-win_amd64.whl", hash = "sha256:edd533a07da85baa4b423ee8839e3e91681c7bfa19b04260a469ee94b778bf6d"}, - {file = "aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7"}, - {file = "aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444"}, - {file = "aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d"}, - {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c"}, - {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0"}, - {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab"}, - {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb"}, - {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545"}, - {file = "aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c"}, - {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd"}, - {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f"}, - {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d"}, - {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519"}, - {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea"}, - {file = "aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3"}, - {file = "aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1"}, - {file = "aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34"}, - {file = "aiohttp-3.12.15-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9f922ffd05034d439dde1c77a20461cf4a1b0831e6caa26151fe7aa8aaebc315"}, - {file = "aiohttp-3.12.15-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ee8a8ac39ce45f3e55663891d4b1d15598c157b4d494a4613e704c8b43112cd"}, - {file = "aiohttp-3.12.15-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3eae49032c29d356b94eee45a3f39fdf4b0814b397638c2f718e96cfadf4c4e4"}, - {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97752ff12cc12f46a9b20327104448042fce5c33a624f88c18f66f9368091c7"}, - {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:894261472691d6fe76ebb7fcf2e5870a2ac284c7406ddc95823c8598a1390f0d"}, - {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5fa5d9eb82ce98959fc1031c28198b431b4d9396894f385cb63f1e2f3f20ca6b"}, - {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0fa751efb11a541f57db59c1dd821bec09031e01452b2b6217319b3a1f34f3d"}, - {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5346b93e62ab51ee2a9d68e8f73c7cf96ffb73568a23e683f931e52450e4148d"}, - {file = "aiohttp-3.12.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:049ec0360f939cd164ecbfd2873eaa432613d5e77d6b04535e3d1fbae5a9e645"}, - {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b52dcf013b57464b6d1e51b627adfd69a8053e84b7103a7cd49c030f9ca44461"}, - {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9b2af240143dd2765e0fb661fd0361a1b469cab235039ea57663cda087250ea9"}, - {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ac77f709a2cde2cc71257ab2d8c74dd157c67a0558a0d2799d5d571b4c63d44d"}, - {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:47f6b962246f0a774fbd3b6b7be25d59b06fdb2f164cf2513097998fc6a29693"}, - {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:760fb7db442f284996e39cf9915a94492e1896baac44f06ae551974907922b64"}, - {file = "aiohttp-3.12.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad702e57dc385cae679c39d318def49aef754455f237499d5b99bea4ef582e51"}, - {file = "aiohttp-3.12.15-cp313-cp313-win32.whl", hash = "sha256:f813c3e9032331024de2eb2e32a88d86afb69291fbc37a3a3ae81cc9917fb3d0"}, - {file = "aiohttp-3.12.15-cp313-cp313-win_amd64.whl", hash = "sha256:1a649001580bdb37c6fdb1bebbd7e3bc688e8ec2b5c6f52edbb664662b17dc84"}, - {file = "aiohttp-3.12.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:691d203c2bdf4f4637792efbbcdcd157ae11e55eaeb5e9c360c1206fb03d4d98"}, - {file = "aiohttp-3.12.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e995e1abc4ed2a454c731385bf4082be06f875822adc4c6d9eaadf96e20d406"}, - {file = "aiohttp-3.12.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bd44d5936ab3193c617bfd6c9a7d8d1085a8dc8c3f44d5f1dcf554d17d04cf7d"}, - {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46749be6e89cd78d6068cdf7da51dbcfa4321147ab8e4116ee6678d9a056a0cf"}, - {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0c643f4d75adea39e92c0f01b3fb83d57abdec8c9279b3078b68a3a52b3933b6"}, - {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a23918fedc05806966a2438489dcffccbdf83e921a1170773b6178d04ade142"}, - {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74bdd8c864b36c3673741023343565d95bfbd778ffe1eb4d412c135a28a8dc89"}, - {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a146708808c9b7a988a4af3821379e379e0f0e5e466ca31a73dbdd0325b0263"}, - {file = "aiohttp-3.12.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7011a70b56facde58d6d26da4fec3280cc8e2a78c714c96b7a01a87930a9530"}, - {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3bdd6e17e16e1dbd3db74d7f989e8af29c4d2e025f9828e6ef45fbdee158ec75"}, - {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:57d16590a351dfc914670bd72530fd78344b885a00b250e992faea565b7fdc05"}, - {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:bc9a0f6569ff990e0bbd75506c8d8fe7214c8f6579cca32f0546e54372a3bb54"}, - {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:536ad7234747a37e50e7b6794ea868833d5220b49c92806ae2d7e8a9d6b5de02"}, - {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f0adb4177fa748072546fb650d9bd7398caaf0e15b370ed3317280b13f4083b0"}, - {file = "aiohttp-3.12.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:14954a2988feae3987f1eb49c706bff39947605f4b6fa4027c1d75743723eb09"}, - {file = "aiohttp-3.12.15-cp39-cp39-win32.whl", hash = "sha256:b784d6ed757f27574dca1c336f968f4e81130b27595e458e69457e6878251f5d"}, - {file = "aiohttp-3.12.15-cp39-cp39-win_amd64.whl", hash = "sha256:86ceded4e78a992f835209e236617bffae649371c4a50d5e5a3987f237db84b8"}, - {file = "aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2"}, + {file = "aiohttp-3.13.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2372b15a5f62ed37789a6b383ff7344fc5b9f243999b0cd9b629d8bc5f5b4155"}, + {file = "aiohttp-3.13.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7f8659a48995edee7229522984bd1009c1213929c769c2daa80b40fe49a180c"}, + {file = "aiohttp-3.13.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:939ced4a7add92296b0ad38892ce62b98c619288a081170695c6babe4f50e636"}, + {file = "aiohttp-3.13.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6315fb6977f1d0dd41a107c527fee2ed5ab0550b7d885bc15fee20ccb17891da"}, + {file = "aiohttp-3.13.2-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6e7352512f763f760baaed2637055c49134fd1d35b37c2dedfac35bfe5cf8725"}, + {file = "aiohttp-3.13.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e09a0a06348a2dd73e7213353c90d709502d9786219f69b731f6caa0efeb46f5"}, + {file = "aiohttp-3.13.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a09a6d073fb5789456545bdee2474d14395792faa0527887f2f4ec1a486a59d3"}, + {file = "aiohttp-3.13.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b59d13c443f8e049d9e94099c7e412e34610f1f49be0f230ec656a10692a5802"}, + {file = "aiohttp-3.13.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20db2d67985d71ca033443a1ba2001c4b5693fe09b0e29f6d9358a99d4d62a8a"}, + {file = "aiohttp-3.13.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:960c2fc686ba27b535f9fd2b52d87ecd7e4fd1cf877f6a5cba8afb5b4a8bd204"}, + {file = "aiohttp-3.13.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6c00dbcf5f0d88796151e264a8eab23de2997c9303dd7c0bf622e23b24d3ce22"}, + {file = "aiohttp-3.13.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fed38a5edb7945f4d1bcabe2fcd05db4f6ec7e0e82560088b754f7e08d93772d"}, + {file = "aiohttp-3.13.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:b395bbca716c38bef3c764f187860e88c724b342c26275bc03e906142fc5964f"}, + {file = "aiohttp-3.13.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:204ffff2426c25dfda401ba08da85f9c59525cdc42bda26660463dd1cbcfec6f"}, + {file = "aiohttp-3.13.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:05c4dd3c48fb5f15db31f57eb35374cb0c09afdde532e7fb70a75aede0ed30f6"}, + {file = "aiohttp-3.13.2-cp310-cp310-win32.whl", hash = "sha256:e574a7d61cf10351d734bcddabbe15ede0eaa8a02070d85446875dc11189a251"}, + {file = "aiohttp-3.13.2-cp310-cp310-win_amd64.whl", hash = "sha256:364f55663085d658b8462a1c3f17b2b84a5c2e1ba858e1b79bff7b2e24ad1514"}, + {file = "aiohttp-3.13.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4647d02df098f6434bafd7f32ad14942f05a9caa06c7016fdcc816f343997dd0"}, + {file = "aiohttp-3.13.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e3403f24bcb9c3b29113611c3c16a2a447c3953ecf86b79775e7be06f7ae7ccb"}, + {file = "aiohttp-3.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:43dff14e35aba17e3d6d5ba628858fb8cb51e30f44724a2d2f0c75be492c55e9"}, + {file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e2a9ea08e8c58bb17655630198833109227dea914cd20be660f52215f6de5613"}, + {file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53b07472f235eb80e826ad038c9d106c2f653584753f3ddab907c83f49eedead"}, + {file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e736c93e9c274fce6419af4aac199984d866e55f8a4cec9114671d0ea9688780"}, + {file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ff5e771f5dcbc81c64898c597a434f7682f2259e0cd666932a913d53d1341d1a"}, + {file = "aiohttp-3.13.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3b6fb0c207cc661fa0bf8c66d8d9b657331ccc814f4719468af61034b478592"}, + {file = "aiohttp-3.13.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:97a0895a8e840ab3520e2288db7cace3a1981300d48babeb50e7425609e2e0ab"}, + {file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9e8f8afb552297aca127c90cb840e9a1d4bfd6a10d7d8f2d9176e1acc69bad30"}, + {file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ed2f9c7216e53c3df02264f25d824b079cc5914f9e2deba94155190ef648ee40"}, + {file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:99c5280a329d5fa18ef30fd10c793a190d996567667908bef8a7f81f8202b948"}, + {file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2ca6ffef405fc9c09a746cb5d019c1672cd7f402542e379afc66b370833170cf"}, + {file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:47f438b1a28e926c37632bff3c44df7d27c9b57aaf4e34b1def3c07111fdb782"}, + {file = "aiohttp-3.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9acda8604a57bb60544e4646a4615c1866ee6c04a8edef9b8ee6fd1d8fa2ddc8"}, + {file = "aiohttp-3.13.2-cp311-cp311-win32.whl", hash = "sha256:868e195e39b24aaa930b063c08bb0c17924899c16c672a28a65afded9c46c6ec"}, + {file = "aiohttp-3.13.2-cp311-cp311-win_amd64.whl", hash = "sha256:7fd19df530c292542636c2a9a85854fab93474396a52f1695e799186bbd7f24c"}, + {file = "aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b"}, + {file = "aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc"}, + {file = "aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7"}, + {file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb"}, + {file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3"}, + {file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f"}, + {file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6"}, + {file = "aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e"}, + {file = "aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7"}, + {file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d"}, + {file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b"}, + {file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8"}, + {file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16"}, + {file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169"}, + {file = "aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248"}, + {file = "aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e"}, + {file = "aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45"}, + {file = "aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be"}, + {file = "aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742"}, + {file = "aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293"}, + {file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811"}, + {file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a"}, + {file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4"}, + {file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a"}, + {file = "aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e"}, + {file = "aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb"}, + {file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded"}, + {file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b"}, + {file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8"}, + {file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04"}, + {file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476"}, + {file = "aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23"}, + {file = "aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254"}, + {file = "aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a"}, + {file = "aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b"}, + {file = "aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61"}, + {file = "aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4"}, + {file = "aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b"}, + {file = "aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694"}, + {file = "aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906"}, + {file = "aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9"}, + {file = "aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011"}, + {file = "aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6"}, + {file = "aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213"}, + {file = "aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49"}, + {file = "aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae"}, + {file = "aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa"}, + {file = "aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4"}, + {file = "aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a"}, + {file = "aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940"}, + {file = "aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4"}, + {file = "aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673"}, + {file = "aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd"}, + {file = "aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3"}, + {file = "aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf"}, + {file = "aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e"}, + {file = "aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5"}, + {file = "aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad"}, + {file = "aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e"}, + {file = "aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61"}, + {file = "aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661"}, + {file = "aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98"}, + {file = "aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693"}, + {file = "aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a"}, + {file = "aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be"}, + {file = "aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c"}, + {file = "aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734"}, + {file = "aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f"}, + {file = "aiohttp-3.13.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7fbdf5ad6084f1940ce88933de34b62358d0f4a0b6ec097362dcd3e5a65a4989"}, + {file = "aiohttp-3.13.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7c3a50345635a02db61792c85bb86daffac05330f6473d524f1a4e3ef9d0046d"}, + {file = "aiohttp-3.13.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e87dff73f46e969af38ab3f7cb75316a7c944e2e574ff7c933bc01b10def7f5"}, + {file = "aiohttp-3.13.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2adebd4577724dcae085665f294cc57c8701ddd4d26140504db622b8d566d7aa"}, + {file = "aiohttp-3.13.2-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e036a3a645fe92309ec34b918394bb377950cbb43039a97edae6c08db64b23e2"}, + {file = "aiohttp-3.13.2-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:23ad365e30108c422d0b4428cf271156dd56790f6dd50d770b8e360e6c5ab2e6"}, + {file = "aiohttp-3.13.2-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1f9b2c2d4b9d958b1f9ae0c984ec1dd6b6689e15c75045be8ccb4011426268ca"}, + {file = "aiohttp-3.13.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a92cf4b9bea33e15ecbaa5c59921be0f23222608143d025c989924f7e3e0c07"}, + {file = "aiohttp-3.13.2-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:070599407f4954021509193404c4ac53153525a19531051661440644728ba9a7"}, + {file = "aiohttp-3.13.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:29562998ec66f988d49fb83c9b01694fa927186b781463f376c5845c121e4e0b"}, + {file = "aiohttp-3.13.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4dd3db9d0f4ebca1d887d76f7cdbcd1116ac0d05a9221b9dad82c64a62578c4d"}, + {file = "aiohttp-3.13.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d7bc4b7f9c4921eba72677cd9fedd2308f4a4ca3e12fab58935295ad9ea98700"}, + {file = "aiohttp-3.13.2-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:dacd50501cd017f8cccb328da0c90823511d70d24a323196826d923aad865901"}, + {file = "aiohttp-3.13.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:8b2f1414f6a1e0683f212ec80e813f4abef94c739fd090b66c9adf9d2a05feac"}, + {file = "aiohttp-3.13.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04c3971421576ed24c191f610052bcb2f059e395bc2489dd99e397f9bc466329"}, + {file = "aiohttp-3.13.2-cp39-cp39-win32.whl", hash = "sha256:9f377d0a924e5cc94dc620bc6366fc3e889586a7f18b748901cf016c916e2084"}, + {file = "aiohttp-3.13.2-cp39-cp39-win_amd64.whl", hash = "sha256:9c705601e16c03466cb72011bd1af55d68fa65b045356d8f96c216e5f6db0fa5"}, + {file = "aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca"}, ] [package.dependencies] @@ -119,7 +153,7 @@ propcache = ">=0.2.0" yarl = ">=1.17.0,<2.0" [package.extras] -speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns (>=3.3.0)", "brotlicffi ; platform_python_implementation != \"CPython\""] +speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns (>=3.3.0)", "backports.zstd ; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", "brotlicffi ; platform_python_implementation != \"CPython\""] [[package]] name = "aiosignal" @@ -158,24 +192,23 @@ docs = ["sphinx (==8.1.3)", "sphinx-mdinclude (==0.6.1)"] [[package]] name = "anyio" -version = "4.10.0" +version = "4.12.0" description = "High-level concurrency and networking framework on top of asyncio or Trio" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1"}, - {file = "anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6"}, + {file = "anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb"}, + {file = "anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" -sniffio = ">=1.1" typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -trio = ["trio (>=0.26.1)"] +trio = ["trio (>=0.31.0) ; python_version < \"3.10\"", "trio (>=0.32.0) ; python_version >= \"3.10\""] [[package]] name = "asn1crypto" @@ -271,23 +304,28 @@ test = ["distro (>=1.9.0,<1.10.0)", "flake8 (>=6.1,<7.0)", "flake8-pyi (>=24.1.0 [[package]] name = "attrs" -version = "25.3.0" +version = "25.4.0" description = "Classes Without Boilerplate" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, - {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, + {file = "attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373"}, + {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, ] -[package.extras] -benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] -cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] -dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] -tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""] +[[package]] +name = "backports-asyncio-runner" +version = "1.2.0" +description = "Backport of asyncio.Runner, a context manager that controls event loop life cycle." +optional = false +python-versions = "<3.11,>=3.8" +groups = ["dev"] +markers = "python_version == \"3.10\"" +files = [ + {file = "backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5"}, + {file = "backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162"}, +] [[package]] name = "backports-datetime-fromisoformat" @@ -362,6 +400,71 @@ files = [ [package.extras] tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", "pytest-cov", "pytest-flake8"] +[[package]] +name = "bcrypt" +version = "4.3.0" +description = "Modern password hashing for your software and your servers" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "bcrypt-4.3.0-cp313-cp313t-macosx_10_12_universal2.whl", hash = "sha256:f01e060f14b6b57bbb72fc5b4a83ac21c443c9a2ee708e04a10e9192f90a6281"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5eeac541cefd0bb887a371ef73c62c3cd78535e4887b310626036a7c0a817bb"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e1aa0e2cd871b08ca146ed08445038f42ff75968c7ae50d2fdd7860ade2180"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0042b2e342e9ae3d2ed22727c1262f76cc4f345683b5c1715f0250cf4277294f"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74a8d21a09f5e025a9a23e7c0fd2c7fe8e7503e4d356c0a2c1486ba010619f09"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0142b2cb84a009f8452c8c5a33ace5e3dfec4159e7735f5afe9a4d50a8ea722d"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_aarch64.whl", hash = "sha256:12fa6ce40cde3f0b899729dbd7d5e8811cb892d31b6f7d0334a1f37748b789fd"}, + {file = "bcrypt-4.3.0-cp313-cp313t-manylinux_2_34_x86_64.whl", hash = "sha256:5bd3cca1f2aa5dbcf39e2aa13dd094ea181f48959e1071265de49cc2b82525af"}, + {file = "bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:335a420cfd63fc5bc27308e929bee231c15c85cc4c496610ffb17923abf7f231"}, + {file = "bcrypt-4.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:0e30e5e67aed0187a1764911af023043b4542e70a7461ad20e837e94d23e1d6c"}, + {file = "bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b8d62290ebefd49ee0b3ce7500f5dbdcf13b81402c05f6dafab9a1e1b27212f"}, + {file = "bcrypt-4.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2ef6630e0ec01376f59a006dc72918b1bf436c3b571b80fa1968d775fa02fe7d"}, + {file = "bcrypt-4.3.0-cp313-cp313t-win32.whl", hash = "sha256:7a4be4cbf241afee43f1c3969b9103a41b40bcb3a3f467ab19f891d9bc4642e4"}, + {file = "bcrypt-4.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c1949bf259a388863ced887c7861da1df681cb2388645766c89fdfd9004c669"}, + {file = "bcrypt-4.3.0-cp38-abi3-macosx_10_12_universal2.whl", hash = "sha256:f81b0ed2639568bf14749112298f9e4e2b28853dab50a8b357e31798686a036d"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:864f8f19adbe13b7de11ba15d85d4a428c7e2f344bac110f667676a0ff84924b"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e36506d001e93bffe59754397572f21bb5dc7c83f54454c990c74a468cd589e"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:842d08d75d9fe9fb94b18b071090220697f9f184d4547179b60734846461ed59"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7c03296b85cb87db865d91da79bf63d5609284fc0cab9472fdd8367bbd830753"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:62f26585e8b219cdc909b6a0069efc5e4267e25d4a3770a364ac58024f62a761"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:beeefe437218a65322fbd0069eb437e7c98137e08f22c4660ac2dc795c31f8bb"}, + {file = "bcrypt-4.3.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:97eea7408db3a5bcce4a55d13245ab3fa566e23b4c67cd227062bb49e26c585d"}, + {file = "bcrypt-4.3.0-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:191354ebfe305e84f344c5964c7cd5f924a3bfc5d405c75ad07f232b6dffb49f"}, + {file = "bcrypt-4.3.0-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:41261d64150858eeb5ff43c753c4b216991e0ae16614a308a15d909503617732"}, + {file = "bcrypt-4.3.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:33752b1ba962ee793fa2b6321404bf20011fe45b9afd2a842139de3011898fef"}, + {file = "bcrypt-4.3.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:50e6e80a4bfd23a25f5c05b90167c19030cf9f87930f7cb2eacb99f45d1c3304"}, + {file = "bcrypt-4.3.0-cp38-abi3-win32.whl", hash = "sha256:67a561c4d9fb9465ec866177e7aebcad08fe23aaf6fbd692a6fab69088abfc51"}, + {file = "bcrypt-4.3.0-cp38-abi3-win_amd64.whl", hash = "sha256:584027857bc2843772114717a7490a37f68da563b3620f78a849bcb54dc11e62"}, + {file = "bcrypt-4.3.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:0d3efb1157edebfd9128e4e46e2ac1a64e0c1fe46fb023158a407c7892b0f8c3"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08bacc884fd302b611226c01014eca277d48f0a05187666bca23aac0dad6fe24"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6746e6fec103fcd509b96bacdfdaa2fbde9a553245dbada284435173a6f1aef"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:afe327968aaf13fc143a56a3360cb27d4ad0345e34da12c7290f1b00b8fe9a8b"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d9af79d322e735b1fc33404b5765108ae0ff232d4b54666d46730f8ac1a43676"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f1e3ffa1365e8702dc48c8b360fef8d7afeca482809c5e45e653af82ccd088c1"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3004df1b323d10021fda07a813fd33e0fd57bef0e9a480bb143877f6cba996fe"}, + {file = "bcrypt-4.3.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:531457e5c839d8caea9b589a1bcfe3756b0547d7814e9ce3d437f17da75c32b0"}, + {file = "bcrypt-4.3.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:17a854d9a7a476a89dcef6c8bd119ad23e0f82557afbd2c442777a16408e614f"}, + {file = "bcrypt-4.3.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6fb1fd3ab08c0cbc6826a2e0447610c6f09e983a281b919ed721ad32236b8b23"}, + {file = "bcrypt-4.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e965a9c1e9a393b8005031ff52583cedc15b7884fce7deb8b0346388837d6cfe"}, + {file = "bcrypt-4.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:79e70b8342a33b52b55d93b3a59223a844962bef479f6a0ea318ebbcadf71505"}, + {file = "bcrypt-4.3.0-cp39-abi3-win32.whl", hash = "sha256:b4d4e57f0a63fd0b358eb765063ff661328f69a04494427265950c71b992a39a"}, + {file = "bcrypt-4.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:e53e074b120f2877a35cc6c736b8eb161377caae8925c17688bd46ba56daaa5b"}, + {file = "bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c950d682f0952bafcceaf709761da0a32a942272fad381081b51096ffa46cea1"}, + {file = "bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:107d53b5c67e0bbc3f03ebf5b030e0403d24dda980f8e244795335ba7b4a027d"}, + {file = "bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b693dbb82b3c27a1604a3dff5bfc5418a7e6a781bb795288141e5f80cf3a3492"}, + {file = "bcrypt-4.3.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:b6354d3760fcd31994a14c89659dee887f1351a06e5dac3c1142307172a79f90"}, + {file = "bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a839320bf27d474e52ef8cb16449bb2ce0ba03ca9f44daba6d93fa1d8828e48a"}, + {file = "bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:bdc6a24e754a555d7316fa4774e64c6c3997d27ed2d1964d55920c7c227bc4ce"}, + {file = "bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:55a935b8e9a1d2def0626c4269db3fcd26728cbff1e84f0341465c31c4ee56d8"}, + {file = "bcrypt-4.3.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:57967b7a28d855313a963aaea51bf6df89f833db4320da458e5b3c5ab6d4c938"}, + {file = "bcrypt-4.3.0.tar.gz", hash = "sha256:3a3fd2204178b6d2adcf09cb4f6426ffef54762577a7c9b54c159008cb288c18"}, +] + +[package.extras] +tests = ["pytest (>=3.2.1,!=3.3.0)"] +typecheck = ["mypy"] + [[package]] name = "bech32" version = "1.2.0" @@ -374,148 +477,133 @@ files = [ {file = "bech32-1.2.0.tar.gz", hash = "sha256:7d6db8214603bd7871fcfa6c0826ef68b85b0abd90fa21c285a9c5e21d2bd899"}, ] +[[package]] +name = "bip32" +version = "4.0" +description = "Minimalistic implementation of the BIP32 key derivation scheme" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "bip32-4.0-py3-none-any.whl", hash = "sha256:9728b38336129c00e1f870bbb3e328c9632d51c1bddeef4011fd3115cb3aeff9"}, + {file = "bip32-4.0.tar.gz", hash = "sha256:8035588f252f569bb414bc60df151ae431fc1c6789a19488a32890532ef3a2fc"}, +] + +[package.dependencies] +coincurve = ">=15.0,<21" + [[package]] name = "bitarray" -version = "3.7.1" +version = "3.8.0" description = "efficient arrays of booleans -- C extension" optional = false python-versions = "*" groups = ["main"] files = [ - {file = "bitarray-3.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a05982bb49c73463cb0f0f4bed2d8da82631708a2c2d1926107ba99651b419ec"}, - {file = "bitarray-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d30e7daaf228e3d69cdd8b02c0dd4199cec034c4b93c80109f56f4675a6db957"}, - {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:160f449bb91686f8fc9984200e78b8d793b79e382decf7eb1dc9948d7c21b36f"}, - {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6542e1cfe060badd160cd383ad93a84871595c14bb05fb8129f963248affd946"}, - {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b723f9d10f7d8259f010b87fa66e924bb4d67927d9dcff4526a755e9ee84fef4"}, - {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca4b6298c89b92d6b0a67dfc5f98d68ae92b08101d227263ef2033b9c9a03a72"}, - {file = "bitarray-3.7.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:567d6891cb1ddbfd0051fcff3cb1bb86efc82ec818d9c5f98c37d59c1d23cc96"}, - {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:37a6a8382864a1defb5b370b66a635e04358c7334054457bbbb8645610cd95b2"}, - {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:01e3ba46c2dee6d47a4ab22561a01d8ee6772f681defc9fcb357097a055e48cf"}, - {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:477b9456eb7d70f385dc8f097a1d66ee40771b62e47b3b3e33406dcfbc1c6a3b"}, - {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2965fd8ba31b04c42e4b696fad509dc5ab50663efca6eb06bb3b6d08587f3a09"}, - {file = "bitarray-3.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc76ad7453816318d794248fba4032967eaffd992d76e5d1af10ef9d46589770"}, - {file = "bitarray-3.7.1-cp310-cp310-win32.whl", hash = "sha256:d3f38373d9b2629dedc559e647010541cc4ec4ad9bea560e2eb1017e6a00d9ef"}, - {file = "bitarray-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:e39f5e85e1e3d7d84ac2217cd095b3678306c979e991532df47012880e02215d"}, - {file = "bitarray-3.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac39319e6322c2c093a660c02cea6bb3b1ae53d049b573d4781df8896e443e04"}, - {file = "bitarray-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a43f4631ecb87bedc510568fef67db53f2a20c4a5953a9d1e07457e7b1d14911"}, - {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd112646486a31ea5a45aa1eca0e2cd90b6a12f67e848e50349e324c24cc2e7"}, - {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db0441e80773d747a1ed9edfb9f75e7acb68ce8627583bbb6f770b7ec49f0064"}, - {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef5a99a8d1a5c47b4cf85925d1420fc4ee584c98be8efc548651447b3047242f"}, - {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb7af369df317527d697c5bb37ab944bb9a17ea1a5e82e47d5c7c638f3ccdd6"}, - {file = "bitarray-3.7.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eda67136343db96752e58ef36ac37116f36cba40961e79fd0e9bd858f5a09b38"}, - {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:79038bf1a7b13d243e51f4b6909c6997c2ba2bffc45bcae264704308a2d17198"}, - {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d12c45da97b2f31d0233e15f8d68731cfa86264c9f04b2669b9fdf46aaf68e1f"}, - {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:64d1143e90299ba8c967324840912a63a903494b1870a52f6675bda53dc332f7"}, - {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c4e04c12f507942f1ddf215cb3a08c244d24051cdd2ba571060166ce8a92be16"}, - {file = "bitarray-3.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ddc646cec4899a137c134b13818469e4178a251d77f9f4b23229267e3da78cfb"}, - {file = "bitarray-3.7.1-cp311-cp311-win32.whl", hash = "sha256:a23b5f13f9b292004e94b0b13fead4dae79c7512db04dc817ff2c2478298e04a"}, - {file = "bitarray-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:acc56700963f63307ac096689d4547e8061028a66bb78b90e42c5da2898898fb"}, - {file = "bitarray-3.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b99a0347bc6131046c19e056a113daa34d7df99f1f45510161bc78bc8461a470"}, - {file = "bitarray-3.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d7e274ac1975e55ebfb8166cce27e13dc99120c1d6ce9e490d7a716b9be9abb5"}, - {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b9a2eb7d2e0e9c2f25256d2663c0a2a4798fe3110e3ddbbb1a7b71740b4de08"}, - {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e15e70a3cf5bb519e2448524d689c02ff6bcd4750587a517e2bffee06065bf27"}, - {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c65257899bb8faf6a111297b4ff0066324a6b901318582c0453a01422c3bcd5a"}, - {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38b0261483c59bb39ae9300ad46bf0bbf431ab604266382d986a349c96171b36"}, - {file = "bitarray-3.7.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2b1ed363a4ef5622dccbf7822f01b51195062c4f382b28c9bd125d046d0324c"}, - {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:dfde50ae55e075dcd5801e2c3ea0e749c849ed2cbbee991af0f97f1bdbadb2a6"}, - {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:45660e2fabcdc1bab9699a468b312f47956300d41d6a2ea91c8f067572aaf38a"}, - {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7b4a41dc183d7d16750634f65566205990f94144755a39f33da44c0350c3e1a8"}, - {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8b8e07374d60040b24d1a158895d9758424db13be63d4b2fe1870e37f9dec009"}, - {file = "bitarray-3.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f31d8c2168bf2a52e4539232392352832c2296e07e0e14b6e06a44da574099ba"}, - {file = "bitarray-3.7.1-cp312-cp312-win32.whl", hash = "sha256:fe1f1f4010244cb07f6a079854a12e1627e4fb9ea99d672f2ceccaf6653ca514"}, - {file = "bitarray-3.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:f41a4b57cbc128a699e9d716a56c90c7fc76554e680fe2962f49cc4d8688b051"}, - {file = "bitarray-3.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e62892645f6a214eefb58a42c3ed2501af2e40a797844e0e09ec1e400ce75f3d"}, - {file = "bitarray-3.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3092f6bbf4a75b1e6f14a5b1030e27c435f341afeb23987115e45a25cc68ba91"}, - {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:851398428f5604c53371b72c5e0a28163274264ada4a08cd1eafe65fde1f68d0"}, - {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa05460dc4f57358680b977b4a254d331b24c8beb501319b998625fd6a22654b"}, - {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ad0df7886cb9d6d2ff75e87d323108a0e32bdca5c9918071681864129ce8ea8"}, - {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55c31bc3d2c9e48741c812ee5ce4607c6f33e33f339831c214d923ffc7777d21"}, - {file = "bitarray-3.7.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44f468fb4857fff86c65bec5e2fb67067789e40dad69258e9bb78fc6a6df49e7"}, - {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:340c524c7c934b61d1985d805bffe7609180fb5d16ece6ce89b51aa535b936f2"}, - {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0751596f60f33df66245b2dafa3f7fbe13cb7ac91dd14ead87d8c2eec57cb3ed"}, - {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e501bd27c795105aaba02b5212ecd1bb552ca2ee2ede53e5a8cb74deee0e2052"}, - {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe2493d3f49e314e573022ead4d8c845c9748979b7eb95e815429fe947c4bde2"}, - {file = "bitarray-3.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f1575cc0f66aa70a0bb5cb57c8d9d1b7d541d920455169c6266919bf804dc20"}, - {file = "bitarray-3.7.1-cp313-cp313-win32.whl", hash = "sha256:da3dfd2776226e15d3288a3a24c7975f9ee160ba198f2efa66bc28c5ba76d792"}, - {file = "bitarray-3.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:33f604bffd06b170637f8a48ddcf42074ed1e1980366ac46058e065ce04bfe2a"}, - {file = "bitarray-3.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f0795e2be2aa8afd013635f30ffe599cc00f1bbaca2d1d19b6187b4d1c58fb44"}, - {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f9f9bb2c5cc1f679605ebbeb72f46fc395d850b93fa7de7addd502a1dc66e99"}, - {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9faa4c6fcb19a31240ad389426699a99df481b6576f7286471e24efbf1b44dfc"}, - {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7998dfb1e9e0255fb8553abb019c3e7f558925de4edc8604243775ff9dd3898d"}, - {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bfdfe2e2af434d3f4e47250f693657334e34a7ec557cd703b129a814422b4b8"}, - {file = "bitarray-3.7.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97c448a20aded59727261468873d9b11dfdcce5a6338a359135667d5e3f1d070"}, - {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:f7c531722e8c3901f6bb303db464cac98ab44ed422c0fd0c762baa4a8d49ffa1"}, - {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:639389b023315596e0293f85999645f47ec3dc28c892e51242dde6176c91486b"}, - {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:4a83d247420b147d4b3cba0335e484365e117dc1cfe5ab35acd6a0817ad9244f"}, - {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_s390x.whl", hash = "sha256:befac6644c6f304a1b6a7948a04095682849c426cebcc44cb2459aa92d3e1735"}, - {file = "bitarray-3.7.1-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:87a29b8a4cc72af6118954592dcd4e49223420470ccc3f8091c255f6c7330bb1"}, - {file = "bitarray-3.7.1-cp36-cp36m-win32.whl", hash = "sha256:7afc740ad45ee0e0cef055765faf64789c2c183eb4aa3ecb8cecdb4b607396b3"}, - {file = "bitarray-3.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:ea60cf85b4e5a78b5a41eed3a65abc3839a50d915c6e0f6966cbcf81b85991bd"}, - {file = "bitarray-3.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a5b89349f05431270d1ccc7321aaab91c42ff33f463868779e502438b7f0e668"}, - {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b6bd81c77d9925809b714980cd30b1831a86bd090316d37cab124d92af1daf"}, - {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98373c273e01a5a7c17103ecb617de7c9980b7608351d58c72198e3525f0002e"}, - {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e4648c09103bc18f488957c1e0863d2397bab6625c0e6771891f151ee0bd96"}, - {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03dc877ec286b7f2813185ea6bc5f1f5527fd859e61038d38768883b134e06b3"}, - {file = "bitarray-3.7.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:101230b8074919970433ef79866570989157ade3421246d4c3afb7a994fdc614"}, - {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:fbe1ef622748d2edb3dd4fef933b934e90e479f9831dfe31bda3fdc16bf5287f"}, - {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:d160173efdad8a57c22e422a034196df3d84753672c497aee2f94bd5b128f8dd"}, - {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:e84cff8e8fe71903a6cf873fb3c8731df8bd7c1dac878e7a0fe19d8e2ef39aa9"}, - {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:03eeab48f376c3cd988add2b75c20d2d084b6fcc9a164adb0dc390ef152255b4"}, - {file = "bitarray-3.7.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:2db04b165a57499fbcfe0eaa2f7752f118552bbcfab2163a43fef8d95f4ae745"}, - {file = "bitarray-3.7.1-cp37-cp37m-win32.whl", hash = "sha256:f8ab90410b2ba5b8276657c66941bcaae556a38be8dd81630a7647e8735f0a20"}, - {file = "bitarray-3.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:bc0880011b86f81c5353ce4abaeb2472d942ba2320985166a2a3dd4f783563a9"}, - {file = "bitarray-3.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c1f4880bcb6fb7a8e2ab89128032b3dcf59e1e877ff4493b11c8bf7c3a5b3df2"}, - {file = "bitarray-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:78103afbd0a94ac4c1f0b4014545fd149b968d5ea423aaa3b1f6e2c3fc19423e"}, - {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec3fd30622180cbe2326d48c14a4ab7f98a504b104bdca7dda88b134adad6e31"}, - {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98e4a17f55f3cbf6fe06cc79234269572f234467c8355b6758eb252073f78e6b"}, - {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c48cf5a92244ef3df4161c8625ee1890bb3d931db9a9f3b699e61a037cd58a"}, - {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8489bff00a1f81ac0754355772e76775878c32a42f16f01d427c3645546761c4"}, - {file = "bitarray-3.7.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e75eb1734046291c554d9addecca9a8785bdf5d53a64f525569f8549da863dde"}, - {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4079857566077f290d35e23ff0e8ba593069c139ae85b0d152b9fa476494f50a"}, - {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7378055c9f456c5bb034ac313d9a9028fc6597619a0b16584099adba5a589fdb"}, - {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:c44cf0059633470c6bb415091def546adbeb5dcfa91cc3fcb1ac16593f14e52a"}, - {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:1fb0a46ae4b8d244a3fb80c3055717baa3dec6be17938e6871042a8d5b4ce670"}, - {file = "bitarray-3.7.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bebb17125373c499beea009cc5bced757bde52bcb3fa1d6335650e6c2d8111d7"}, - {file = "bitarray-3.7.1-cp38-cp38-win32.whl", hash = "sha256:df7cc9584614f495f474a5ded365cf72decbcee4efcdc888d2943f8a794c789e"}, - {file = "bitarray-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:3110b98c5dfb31dc1cf82d8b0c32e3fa6d6d0b268ff9f2a1599165770c1af80f"}, - {file = "bitarray-3.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3bb3cf22c3c03ae698647e6766314149c9cf04aa2018d9f48d5efddc3ced2764"}, - {file = "bitarray-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:30a2fc37698820cbf9b51d5f801219ef4bed828a04f3307072b8f983dc422a0e"}, - {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11fcfdf272549a3d876f10d8422bcd5f675750aa746ce04ff04937ec3bb2329e"}, - {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d4aa56782368269eb9402caf7378b2a5ada6f05eb9c7edc2362be258973fd7e"}, - {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3572889fcb87e5ca94add412d8b365dbb7b59773a4362e52caa556e5fd98643"}, - {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a393b0f881eff94440f72846a6f0f95b983594a0a50af81c41ed18107420d6a7"}, - {file = "bitarray-3.7.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fdf059d4e3acec44f512ebe247718ae511fde632e2b06992022df8e637385a6"}, - {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a569c993942ac26c6c590639ed6712c6c9c3f0c8d287a067bf2a60eb615f3c6b"}, - {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:dbbaa147cf28b3e87738c624d390a3a9e2a5dfef4316f4c38b4ecaf3155a3eab"}, - {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d877759842ff9eb16d9c2b8b497953a7d994d4b231c171515f0bf3a2ae185c0c"}, - {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c3e014f7295b9327fa6f0b3e55a3fd485abac98be145b9597e0cdbb05c44ad07"}, - {file = "bitarray-3.7.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57b9df5d38ab49c13eaa9e0152fdfa8501fc23987f6dcf421b73484bfe573918"}, - {file = "bitarray-3.7.1-cp39-cp39-win32.whl", hash = "sha256:08c114cf02a63e13ce6d70bc5b9e7bdcfa8d5db17cece207cfa085c4bc4a7a0c"}, - {file = "bitarray-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:c427dfcce13a8c814556dfe7c110b8ef61b8fab5fca0d856d4890856807321dc"}, - {file = "bitarray-3.7.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c9bf2bf29854f165a47917b8782b6cf3a7d602971bf454806208d0cbb96f797a"}, - {file = "bitarray-3.7.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:002b73bf4a9f7b3ecb02260bd4dd332a6ee4d7f74ee9779a1ef342a36244d0cf"}, - {file = "bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:481239cd0966f965c2b8fa78b88614be5f12a64e7773bb5feecc567d39bb2dd5"}, - {file = "bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f583a1fb180a123c00064fab1a3bfb9d43e574b6474be1be3f6469e0331e3e2e"}, - {file = "bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3db0648536f3e08afa7ceb928153c39913f98fd50a5c3adf92a4d0d4268f213e"}, - {file = "bitarray-3.7.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3875578748b484638f6ea776f534e9088cfb15eee131aac051036cba40fd5d05"}, - {file = "bitarray-3.7.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ed4a87eda16e2f95d536152c5acccae07841fbdda3b9a752f3dbf43e39f4d6b"}, - {file = "bitarray-3.7.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f7a8fc5085450635a539c47c9fce6d441b4a973686f88fc220aa20e3921fe55"}, - {file = "bitarray-3.7.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be2f40045432e8aa33d9fd5cb43c91b0c61d77d3d8810f88e84e2e46411c27a7"}, - {file = "bitarray-3.7.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f825ebedcad87a2825ddb6cf62f6d7d5b7a56ddaf7c93eef4b974e7ddc16408"}, - {file = "bitarray-3.7.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:59ddb8a9f47ec807009c69e582d0de1c86c005f9f614557f4cebc7b8ac9b7d28"}, - {file = "bitarray-3.7.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a048e41e1cb0c1a37021269d02698e30d2a7cc9a0205dd3390e0807745b76dae"}, - {file = "bitarray-3.7.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:61b9f3cf3a55322baed8f0532b73bce77d688a01446c179392c4056ab74eb551"}, - {file = "bitarray-3.7.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53d2abeabb91a822e9d76420c9b44980edd2d6b21767c7bb9cb2b1b4cf091049"}, - {file = "bitarray-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b524306104c1296f1e91d74ee4ccbeeea621f6a13e44addf0bb630a1839fd72"}, - {file = "bitarray-3.7.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69687ef16d501c9217675af36fa3c68c009c03e184b07d22ba245e5c01d47e6b"}, - {file = "bitarray-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3dc654da62b3a3027b7c922f7e9f4b27feaabd5d38b2a98ea98de5e8107c72f2"}, - {file = "bitarray-3.7.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:eccc6829035c8b7b391a0aa124fade54932bb937dd1079f2740b9f1bde829226"}, - {file = "bitarray-3.7.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:05ee46a734b5110c5ac483815da4379f7622f4316362872ec7c0ed16db4b0148"}, - {file = "bitarray-3.7.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd7f6bfa2a36fb91b7dec9ddf905716f2ed0c3675d2b63c69b7530c9d211e715"}, - {file = "bitarray-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99124e39658b2f72d296819ec03418609dd4f1b275b00289c2f278a19da6f9c0"}, - {file = "bitarray-3.7.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16426a843b1bc9c552a7c97d6d7555e69730c2de1e2f560503d3fc0e7f6d8005"}, - {file = "bitarray-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6f7e1cdf0abb11718e655bb258920453b1e89c2315e9019f60f0775704b12a8c"}, - {file = "bitarray-3.7.1.tar.gz", hash = "sha256:795b1760418ab750826420ae24f06f392c08e21dc234f0a369a69cc00444f8ec"}, + {file = "bitarray-3.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f08342dc8d19214faa7ef99574dea6c37a2790d6d04a9793ef8fa76c188dc08d"}, + {file = "bitarray-3.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:792462abfeeca6cc8c6c1e6d27e14319682f0182f6b0ba37befe911af794db70"}, + {file = "bitarray-3.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0df69d26f21a9d2f1b20266f6737fa43f08aa5015c99900fb69f255fbe4dabb4"}, + {file = "bitarray-3.8.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b4f10d3f304be7183fac79bf2cd997f82e16aa9a9f37343d76c026c6e435a8a8"}, + {file = "bitarray-3.8.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fc98ff43abad61f00515ad9a06213b7716699146e46eabd256cdfe7cb522bd97"}, + {file = "bitarray-3.8.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:81c6b4a6c1af800d52a6fa32389ef8f4281583f4f99dc1a40f2bb47667281541"}, + {file = "bitarray-3.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f3fd8df63c41ff6a676d031956aebf68ebbc687b47c507da25501eb22eec341f"}, + {file = "bitarray-3.8.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f0ce9d9e07c75da8027c62b4c9f45771d1d8aae7dc9ad7fb606c6a5aedbe9741"}, + {file = "bitarray-3.8.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8a9c962c64a4c08def58b9799333e33af94ec53038cf151d36edacdb41f81646"}, + {file = "bitarray-3.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1a54d7e7999735faacdcbe8128e30207abc2caf9f9fd7102d180b32f1b78bfce"}, + {file = "bitarray-3.8.0-cp310-cp310-win32.whl", hash = "sha256:3ea52df96566457735314794422274bd1962066bfb609e7eea9113d70cf04ffe"}, + {file = "bitarray-3.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:82a07de83dce09b4fa1bccbdc8bde8f188b131666af0dc9048ba0a0e448d8a3b"}, + {file = "bitarray-3.8.0-cp310-cp310-win_arm64.whl", hash = "sha256:c5ba07e58fd98c9782201e79eb8dd4225733d212a5a3700f9a84d329bd0463a6"}, + {file = "bitarray-3.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:25b9cff6c9856bc396232e2f609ea0c5ec1a8a24c500cee4cca96ba8a3cd50b6"}, + {file = "bitarray-3.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d9984017314da772f5f7460add7a0301a4ffc06c72c2998bb16c300a6253607"}, + {file = "bitarray-3.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbbbfbb7d039b20d289ce56b1beb46138d65769d04af50c199c6ac4cb6054d52"}, + {file = "bitarray-3.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1f723e260c35e1c7c57a09d3a6ebe681bd56c83e1208ae3ce1869b7c0d10d4f"}, + {file = "bitarray-3.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cbd1660fb48827381ce3a621a4fdc237959e1cd4e98b098952a8f624a0726425"}, + {file = "bitarray-3.8.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df6d7bf3e15b7e6e202a16ff4948a51759354016026deb04ab9b5acbbe35e096"}, + {file = "bitarray-3.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d5c931ec1c03111718cabf85f6012bb2815fa0ce578175567fa8d6f2cc15d3b4"}, + {file = "bitarray-3.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:41b53711f89008ba2de62e4c2d2260a8b357072fd4f18e1351b28955db2719dc"}, + {file = "bitarray-3.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4f298daaaea58d45e245a132d6d2bdfb6f856da50dc03d75ebb761439fb626cf"}, + {file = "bitarray-3.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:30989a2451b693c3f9359d91098a744992b5431a0be4858f1fdf0ec76b457125"}, + {file = "bitarray-3.8.0-cp311-cp311-win32.whl", hash = "sha256:e5aed4754895942ae15ffa48c52d181e1c1463236fda68d2dba29c03aa61786b"}, + {file = "bitarray-3.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:22c540ed20167d3dbb1e2d868ca935180247d620c40eace90efa774504a40e3b"}, + {file = "bitarray-3.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:84b52b2cf77bb7f703d16c4007b021078dbbe6cf8ffb57abe81a7bacfc175ef2"}, + {file = "bitarray-3.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2fcbe9b3a5996b417e030aa33a562e7e20dfc86271e53d7e841fc5df16268b8"}, + {file = "bitarray-3.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cd761d158f67e288fd0ebe00c3b158095ce80a4bc7c32b60c7121224003ba70d"}, + {file = "bitarray-3.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c394a3f055b49f92626f83c1a0b6d6cd2c628f1ccd72481c3e3c6aa4695f3b20"}, + {file = "bitarray-3.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:969fd67de8c42affdb47b38b80f1eaa79ac0ef17d65407cdd931db1675315af1"}, + {file = "bitarray-3.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:99d25aff3745c54e61ab340b98400c52ebec04290a62078155e0d7eb30380220"}, + {file = "bitarray-3.8.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e645b4c365d6f1f9e0799380ad6395268f3c3b898244a650aaeb8d9d27b74c35"}, + {file = "bitarray-3.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2fa23fdb3beab313950bbb49674e8a161e61449332d3997089fe3944953f1b77"}, + {file = "bitarray-3.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:165052a0e61c880f7093808a0c524ce1b3555bfa114c0dfb5c809cd07918a60d"}, + {file = "bitarray-3.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:337c8cd46a4c6568d367ed676cbf2d7de16f890bb31dbb54c44c1d6bb6d4a1de"}, + {file = "bitarray-3.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21ca6a47bf20db9e7ad74ca04b3d479e4d76109b68333eb23535553d2705339e"}, + {file = "bitarray-3.8.0-cp312-cp312-win32.whl", hash = "sha256:178c5a4c7fdfb5cd79e372ae7f675390e670f3732e5bc68d327e01a5b3ff8d55"}, + {file = "bitarray-3.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:75a3b6e9c695a6570ea488db75b84bb592ff70a944957efa1c655867c575018b"}, + {file = "bitarray-3.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:5591daf81313096909d973fb2612fccd87528fdfdd39f6478bdce54543178954"}, + {file = "bitarray-3.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18214bac86341f1cc413772e66447d6cca10981e2880b70ecaf4e826c04f95e9"}, + {file = "bitarray-3.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:01c5f0dc080b0ebb432f7a68ee1e88a76bd34f6d89c9568fcec65fb16ed71f0e"}, + {file = "bitarray-3.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:86685fa04067f7175f9718489ae755f6acde03593a1a9ca89305554af40e14fd"}, + {file = "bitarray-3.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56896ceeffe25946c4010320629e2d858ca763cd8ded273c81672a5edbcb1e0a"}, + {file = "bitarray-3.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9858dcbc23ba7eaadcd319786b982278a1a2b2020720b19db43e309579ff76fb"}, + {file = "bitarray-3.8.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa7dec53c25f1949513457ef8b0ea1fb40e76c672cc4d2daa8ad3c8d6b73491a"}, + {file = "bitarray-3.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15a2eff91f54d2b1f573cca8ca6fb58763ce8fea80e7899ab028f3987ef71cd5"}, + {file = "bitarray-3.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b1572ee0eb1967e71787af636bb7d1eb9c6735d5337762c450650e7f51844594"}, + {file = "bitarray-3.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5bfac7f236ba1a4d402644bdce47fb9db02a7cf3214a1f637d3a88390f9e5428"}, + {file = "bitarray-3.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f0a55cf02d2cdd739b40ce10c09bbdd520e141217696add7a48b56e67bdfdfe6"}, + {file = "bitarray-3.8.0-cp313-cp313-win32.whl", hash = "sha256:a2ba92f59e30ce915e9e79af37649432e3a212ddddf416d4d686b1b4825bcdb2"}, + {file = "bitarray-3.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:1c8f2a5d8006db5a555e06f9437e76bf52537d3dfd130cb8ae2b30866aca32c9"}, + {file = "bitarray-3.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:50ddbe3a7b4b6ab96812f5a4d570f401a2cdb95642fd04c062f98939610bbeee"}, + {file = "bitarray-3.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8cbd4bfc933b33b85c43ef4c1f4d5e3e9d91975ea6368acf5fbac02bac06ea89"}, + {file = "bitarray-3.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9d35d8f8a1c9ed4e2b08187b513f8a3c71958600129db3aa26d85ea3abfd1310"}, + {file = "bitarray-3.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99f55e14e7c56f4fafe1343480c32b110ef03836c21ff7c48bae7add6818f77c"}, + {file = "bitarray-3.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dfbe2aa45b273f49e715c5345d94874cb65a28482bf231af408891c260601b8d"}, + {file = "bitarray-3.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:64af877116edf051375b45f0bda648143176a017b13803ec7b3a3111dc05f4c5"}, + {file = "bitarray-3.8.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cdfbb27f2c46bb5bbdcee147530cbc5ca8ab858d7693924e88e30ada21b2c5e2"}, + {file = "bitarray-3.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4d73d4948dcc5591d880db8933004e01f1dd2296df9de815354d53469beb26fe"}, + {file = "bitarray-3.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:28a85b056c0eb7f5d864c0ceef07034117e8ebfca756f50648c71950a568ba11"}, + {file = "bitarray-3.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:79ec4498a545733ecace48d780d22407411b07403a2e08b9a4d7596c0b97ebd7"}, + {file = "bitarray-3.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:33af25c4ff7723363cb8404dfc2eefeab4110b654f6c98d26aba8a08c745d860"}, + {file = "bitarray-3.8.0-cp314-cp314-win32.whl", hash = "sha256:2c3bb96b6026643ce24677650889b09073f60b9860a71765f843c99f9ab38b25"}, + {file = "bitarray-3.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:847c7f61964225fc489fe1d49eda7e0e0d253e98862c012cecf845f9ad45cdf4"}, + {file = "bitarray-3.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:a2cb35a6efaa0e3623d8272471371a12c7e07b51a33e5efce9b58f655d864b4e"}, + {file = "bitarray-3.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:15e8d0597cc6e8496de6f4dea2a6880c57e1251502a7072f5631108a1aa28521"}, + {file = "bitarray-3.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8ffe660e963ae711cb9e2b8d8461c9b1ad6167823837fc17d59d5e539fb898fa"}, + {file = "bitarray-3.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4779f356083c62e29b4198d290b7b17a39a69702d150678b7efff0fdddf494a8"}, + {file = "bitarray-3.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:025d133bf4ca8cf75f904eeb8ea946228d7c043231866143f31946a6f4dd0bf3"}, + {file = "bitarray-3.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:451f9958850ea98440d542278368c8d1e1ea821e2494b204570ba34a340759df"}, + {file = "bitarray-3.8.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6d79f659965290af60d6acc8e2716341865fe74609a7ede2a33c2f86ad893b8f"}, + {file = "bitarray-3.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fbf05678c2ae0064fb1b8de7e9e8f0fc30621b73c8477786dd0fb3868044a8c8"}, + {file = "bitarray-3.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:c396358023b876cff547ce87f4e8ff8a2280598873a137e8cc69e115262260b8"}, + {file = "bitarray-3.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:ed3493a369fe849cce98542d7405c88030b355e4d2e113887cb7ecc86c205773"}, + {file = "bitarray-3.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c764fb167411d5afaef88138542a4bfa28bd5e5ded5e8e42df87cef965efd6e9"}, + {file = "bitarray-3.8.0-cp314-cp314t-win32.whl", hash = "sha256:e12769d3adcc419e65860de946df8d2ed274932177ac1cdb05186e498aaa9149"}, + {file = "bitarray-3.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0ca70ccf789446a6dfde40b482ec21d28067172cd1f8efd50d5548159fccad9e"}, + {file = "bitarray-3.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2a3d1b05ffdd3e95687942ae7b13c63689f85d3f15c39b33329e3cb9ce6c015f"}, + {file = "bitarray-3.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f8d3417db5e14a6789073b21ae44439a755289477901901bae378a57b905e148"}, + {file = "bitarray-3.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7f65bd5d4cdb396295b6aa07f84ca659ac65c5c68b53956a6d95219e304b0ada"}, + {file = "bitarray-3.8.0-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f14d6b303e55bd7d19b28309ef8014370e84a3806c5e452e078e7df7344d97a"}, + {file = "bitarray-3.8.0-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c5a8a83df95e51f7a7c2b083eaea134cbed39fc42c6aeb2e764ddb7ccccd43e"}, + {file = "bitarray-3.8.0-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6d70fa9c6d2e955bde8cd327ffc11f2cc34bc21944e5571a46ca501e7eadef24"}, + {file = "bitarray-3.8.0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f8069a807a3e6e3c361ce302ece4bf1c3b49962c1726d1d56587e8f48682861"}, + {file = "bitarray-3.8.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a358277122456666a8b2a0b9aa04f1b89d34e8aa41d08a6557d693e6abb6667c"}, + {file = "bitarray-3.8.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:014df8a9430276862392ac5d471697de042367996c49f32d0008585d2c60755a"}, + {file = "bitarray-3.8.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:720963fee259291a88348ae9735d9deb5d334e84a016244f61c89f5a49aa400a"}, + {file = "bitarray-3.8.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:239578587b9c29469ab61149dda40a2fe714a6a4eca0f8ff9ea9439ec4b7bc30"}, + {file = "bitarray-3.8.0-cp38-cp38-win32.whl", hash = "sha256:004d518fa410e6da43386d20e07b576a41eb417ac67abf9f30fa75e125697199"}, + {file = "bitarray-3.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:5338a313f998e1be7267191b7caaae82563b4a2b42b393561055412a34042caa"}, + {file = "bitarray-3.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d2dbe8a3baf2d842e342e8acb06ae3844765d38df67687c144cdeb71f1bcb5d7"}, + {file = "bitarray-3.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff1863f037dad765ef5963efc2e37d399ac023e192a6f2bb394e2377d023cefe"}, + {file = "bitarray-3.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:26714898eb0d847aac8af94c4441c9cb50387847d0fe6b9fc4217c086cd68b80"}, + {file = "bitarray-3.8.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5f2fb10518f6b365f5b720e43a529c3b2324ca02932f609631a44edb347d8d54"}, + {file = "bitarray-3.8.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1a926fa554870642607fd10e66ee25b75fdd9a7ca4bbffa93d424e4ae2bf734a"}, + {file = "bitarray-3.8.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4902f4ecd5fcb6a5f482d7b0ae1c16c21f26fc5279b3b6127363d13ad8e7a9d9"}, + {file = "bitarray-3.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94652da1a4ca7cfb69c15dd6986b205e0bd9c63a05029c3b48b4201085f527bd"}, + {file = "bitarray-3.8.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:31a4ad2b730128e273f1c22300da3e3631f125703e4fee0ac44d385abfb15671"}, + {file = "bitarray-3.8.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:cbba763d99de0255a3e4938f25a8579930ac8aa089233cb2fb2ed7d04d4aff02"}, + {file = "bitarray-3.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:46cf239856b87fe1c86dfbb3d459d840a8b1649e7922b1e0bfb6b6464692644a"}, + {file = "bitarray-3.8.0-cp39-cp39-win32.whl", hash = "sha256:2fe8c54b15a9cd4f93bc2aaceab354ec65af93370aa1496ba2f9c537a4855ee0"}, + {file = "bitarray-3.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:58a01ea34057463f7a98a4d6ff40160f65f945e924fec08a5b39e327e372875d"}, + {file = "bitarray-3.8.0-cp39-cp39-win_arm64.whl", hash = "sha256:a60da2f9efbed355edb35a1fb6829148676786c829fad708bb6bb47211b3593a"}, + {file = "bitarray-3.8.0.tar.gz", hash = "sha256:3eae38daffd77c9621ae80c16932eea3fb3a4af141fb7cc724d4ad93eff9210d"}, ] [[package]] @@ -533,6 +621,58 @@ files = [ [package.dependencies] bitarray = ">=3.0.0,<4.0" +[[package]] +name = "black" +version = "25.11.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "black-25.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ec311e22458eec32a807f029b2646f661e6859c3f61bc6d9ffb67958779f392e"}, + {file = "black-25.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1032639c90208c15711334d681de2e24821af0575573db2810b0763bcd62e0f0"}, + {file = "black-25.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c0f7c461df55cf32929b002335883946a4893d759f2df343389c4396f3b6b37"}, + {file = "black-25.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:f9786c24d8e9bd5f20dc7a7f0cdd742644656987f6ea6947629306f937726c03"}, + {file = "black-25.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:895571922a35434a9d8ca67ef926da6bc9ad464522a5fe0db99b394ef1c0675a"}, + {file = "black-25.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cb4f4b65d717062191bdec8e4a442539a8ea065e6af1c4f4d36f0cdb5f71e170"}, + {file = "black-25.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d81a44cbc7e4f73a9d6ae449ec2317ad81512d1e7dce7d57f6333fd6259737bc"}, + {file = "black-25.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:7eebd4744dfe92ef1ee349dc532defbf012a88b087bb7ddd688ff59a447b080e"}, + {file = "black-25.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:80e7486ad3535636657aa180ad32a7d67d7c273a80e12f1b4bfa0823d54e8fac"}, + {file = "black-25.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6cced12b747c4c76bc09b4db057c319d8545307266f41aaee665540bc0e04e96"}, + {file = "black-25.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cb2d54a39e0ef021d6c5eef442e10fd71fcb491be6413d083a320ee768329dd"}, + {file = "black-25.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae263af2f496940438e5be1a0c1020e13b09154f3af4df0835ea7f9fe7bfa409"}, + {file = "black-25.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0a1d40348b6621cc20d3d7530a5b8d67e9714906dfd7346338249ad9c6cedf2b"}, + {file = "black-25.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:51c65d7d60bb25429ea2bf0731c32b2a2442eb4bd3b2afcb47830f0b13e58bfd"}, + {file = "black-25.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:936c4dd07669269f40b497440159a221ee435e3fddcf668e0c05244a9be71993"}, + {file = "black-25.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:f42c0ea7f59994490f4dccd64e6b2dd49ac57c7c84f38b8faab50f8759db245c"}, + {file = "black-25.11.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:35690a383f22dd3e468c85dc4b915217f87667ad9cce781d7b42678ce63c4170"}, + {file = "black-25.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:dae49ef7369c6caa1a1833fd5efb7c3024bb7e4499bf64833f65ad27791b1545"}, + {file = "black-25.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bd4a22a0b37401c8e492e994bce79e614f91b14d9ea911f44f36e262195fdda"}, + {file = "black-25.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:aa211411e94fdf86519996b7f5f05e71ba34835d8f0c0f03c00a26271da02664"}, + {file = "black-25.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3bb5ce32daa9ff0605d73b6f19da0b0e6c1f8f2d75594db539fdfed722f2b06"}, + {file = "black-25.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9815ccee1e55717fe9a4b924cae1646ef7f54e0f990da39a34fc7b264fcf80a2"}, + {file = "black-25.11.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:92285c37b93a1698dcbc34581867b480f1ba3a7b92acf1fe0467b04d7a4da0dc"}, + {file = "black-25.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:43945853a31099c7c0ff8dface53b4de56c41294fa6783c0441a8b1d9bf668bc"}, + {file = "black-25.11.0-py3-none-any.whl", hash = "sha256:e3f562da087791e96cefcd9dda058380a442ab322a02e222add53736451f604b"}, + {file = "black-25.11.0.tar.gz", hash = "sha256:9a323ac32f5dc75ce7470501b887250be5005a01602e931a15e45593f70f6e08"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +pytokens = ">=0.3.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.10)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + [[package]] name = "bolt11" version = "2.1.1" @@ -554,14 +694,14 @@ coincurve = "*" [[package]] name = "certifi" -version = "2025.8.3" +version = "2025.11.12" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}, - {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}, + {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, + {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, ] [[package]] @@ -661,93 +801,139 @@ files = [ [package.dependencies] pycparser = {version = "*", markers = "implementation_name != \"PyPy\""} +[[package]] +name = "cfgv" +version = "3.5.0" +description = "Validate configuration and produce human readable error messages." +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0"}, + {file = "cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132"}, +] + [[package]] name = "charset-normalizer" -version = "3.4.3" +version = "3.4.4" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-win32.whl", hash = "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca"}, - {file = "charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a"}, - {file = "charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, + {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, + {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, + {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, + {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, + {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, + {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, + {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, + {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, ] [[package]] @@ -756,7 +942,7 @@ version = "8.2.1" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"}, {file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"}, @@ -838,7 +1024,7 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main"] +groups = ["main", "dev"] markers = "platform_system == \"Windows\" or sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, @@ -847,82 +1033,112 @@ files = [ [[package]] name = "cryptography" -version = "45.0.7" +version = "46.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false -python-versions = "!=3.9.0,!=3.9.1,>=3.7" +python-versions = "!=3.9.0,!=3.9.1,>=3.8" groups = ["main"] files = [ - {file = "cryptography-45.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:3be4f21c6245930688bd9e162829480de027f8bf962ede33d4f8ba7d67a00cee"}, - {file = "cryptography-45.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:67285f8a611b0ebc0857ced2081e30302909f571a46bfa7a3cc0ad303fe015c6"}, - {file = "cryptography-45.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:577470e39e60a6cd7780793202e63536026d9b8641de011ed9d8174da9ca5339"}, - {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4bd3e5c4b9682bc112d634f2c6ccc6736ed3635fc3319ac2bb11d768cc5a00d8"}, - {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:465ccac9d70115cd4de7186e60cfe989de73f7bb23e8a7aa45af18f7412e75bf"}, - {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:16ede8a4f7929b4b7ff3642eba2bf79aa1d71f24ab6ee443935c0d269b6bc513"}, - {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8978132287a9d3ad6b54fcd1e08548033cc09dc6aacacb6c004c73c3eb5d3ac3"}, - {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b6a0e535baec27b528cb07a119f321ac024592388c5681a5ced167ae98e9fff3"}, - {file = "cryptography-45.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a24ee598d10befaec178efdff6054bc4d7e883f615bfbcd08126a0f4931c83a6"}, - {file = "cryptography-45.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:fa26fa54c0a9384c27fcdc905a2fb7d60ac6e47d14bc2692145f2b3b1e2cfdbd"}, - {file = "cryptography-45.0.7-cp311-abi3-win32.whl", hash = "sha256:bef32a5e327bd8e5af915d3416ffefdbe65ed975b646b3805be81b23580b57b8"}, - {file = "cryptography-45.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:3808e6b2e5f0b46d981c24d79648e5c25c35e59902ea4391a0dcb3e667bf7443"}, - {file = "cryptography-45.0.7-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bfb4c801f65dd61cedfc61a83732327fafbac55a47282e6f26f073ca7a41c3b2"}, - {file = "cryptography-45.0.7-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:81823935e2f8d476707e85a78a405953a03ef7b7b4f55f93f7c2d9680e5e0691"}, - {file = "cryptography-45.0.7-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3994c809c17fc570c2af12c9b840d7cea85a9fd3e5c0e0491f4fa3c029216d59"}, - {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dad43797959a74103cb59c5dac71409f9c27d34c8a05921341fb64ea8ccb1dd4"}, - {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ce7a453385e4c4693985b4a4a3533e041558851eae061a58a5405363b098fcd3"}, - {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b04f85ac3a90c227b6e5890acb0edbaf3140938dbecf07bff618bf3638578cf1"}, - {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:48c41a44ef8b8c2e80ca4527ee81daa4c527df3ecbc9423c41a420a9559d0e27"}, - {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f3df7b3d0f91b88b2106031fd995802a2e9ae13e02c36c1fc075b43f420f3a17"}, - {file = "cryptography-45.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd342f085542f6eb894ca00ef70236ea46070c8a13824c6bde0dfdcd36065b9b"}, - {file = "cryptography-45.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1993a1bb7e4eccfb922b6cd414f072e08ff5816702a0bdb8941c247a6b1b287c"}, - {file = "cryptography-45.0.7-cp37-abi3-win32.whl", hash = "sha256:18fcf70f243fe07252dcb1b268a687f2358025ce32f9f88028ca5c364b123ef5"}, - {file = "cryptography-45.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:7285a89df4900ed3bfaad5679b1e668cb4b38a8de1ccbfc84b05f34512da0a90"}, - {file = "cryptography-45.0.7-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:de58755d723e86175756f463f2f0bddd45cc36fbd62601228a3f8761c9f58252"}, - {file = "cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a20e442e917889d1a6b3c570c9e3fa2fdc398c20868abcea268ea33c024c4083"}, - {file = "cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:258e0dff86d1d891169b5af222d362468a9570e2532923088658aa866eb11130"}, - {file = "cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d97cf502abe2ab9eff8bd5e4aca274da8d06dd3ef08b759a8d6143f4ad65d4b4"}, - {file = "cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:c987dad82e8c65ebc985f5dae5e74a3beda9d0a2a4daf8a1115f3772b59e5141"}, - {file = "cryptography-45.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c13b1e3afd29a5b3b2656257f14669ca8fa8d7956d509926f0b130b600b50ab7"}, - {file = "cryptography-45.0.7-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a862753b36620af6fc54209264f92c716367f2f0ff4624952276a6bbd18cbde"}, - {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:06ce84dc14df0bf6ea84666f958e6080cdb6fe1231be2a51f3fc1267d9f3fb34"}, - {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d0c5c6bac22b177bf8da7435d9d27a6834ee130309749d162b26c3105c0795a9"}, - {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:2f641b64acc00811da98df63df7d59fd4706c0df449da71cb7ac39a0732b40ae"}, - {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:f5414a788ecc6ee6bc58560e85ca624258a55ca434884445440a810796ea0e0b"}, - {file = "cryptography-45.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:1f3d56f73595376f4244646dd5c5870c14c196949807be39e79e7bd9bac3da63"}, - {file = "cryptography-45.0.7.tar.gz", hash = "sha256:4b1654dfc64ea479c242508eb8c724044f1e964a47d1d1cacc5132292d851971"}, + {file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"}, + {file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"}, + {file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"}, + {file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"}, + {file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"}, + {file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"}, + {file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"}, + {file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"}, + {file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"}, + {file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"}, + {file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"}, + {file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"}, + {file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"}, + {file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"}, + {file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"}, + {file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"}, + {file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"}, + {file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"}, + {file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"}, + {file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"}, ] [package.dependencies] -cffi = {version = ">=1.14", markers = "platform_python_implementation != \"PyPy\""} +cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} +typing-extensions = {version = ">=4.13.2", markers = "python_full_version < \"3.11.0\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs ; python_full_version >= \"3.8.0\"", "sphinx-rtd-theme (>=3.0.0) ; python_full_version >= \"3.8.0\""] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] -nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_full_version >= \"3.8.0\""] -pep8test = ["check-sdist ; python_full_version >= \"3.8.0\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +nox = ["nox[uv] (>=2024.4.15)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi (>=2024)", "cryptography-vectors (==45.0.7)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test-randomorder = ["pytest-randomly"] [[package]] name = "deprecated" -version = "1.2.18" +version = "1.3.1" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" groups = ["main"] files = [ - {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, - {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, + {file = "deprecated-1.3.1-py2.py3-none-any.whl", hash = "sha256:597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f"}, + {file = "deprecated-1.3.1.tar.gz", hash = "sha256:b1b50e0ff0c1fddaa5708a2c6b0a6588bb09b892825ab2b214ac9ea9d92a5223"}, ] [package.dependencies] -wrapt = ">=1.10,<2" +wrapt = ">=1.10,<3" [package.extras] dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"] +[[package]] +name = "distlib" +version = "0.4.0" +description = "Distribution utilities" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"}, + {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"}, +] + [[package]] name = "dnspython" version = "2.8.0" @@ -1017,15 +1233,15 @@ tests = ["backports.strenum ; python_version < \"3.11\"", "environs[django]", "p [[package]] name = "exceptiongroup" -version = "1.3.0" +version = "1.3.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" -groups = ["main"] +groups = ["main", "dev"] markers = "python_version == \"3.10\"" files = [ - {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, - {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, + {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, + {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, ] [package.dependencies] @@ -1036,24 +1252,25 @@ test = ["pytest (>=6)"] [[package]] name = "fastapi" -version = "0.115.13" +version = "0.116.1" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "fastapi-0.115.13-py3-none-any.whl", hash = "sha256:0a0cab59afa7bab22f5eb347f8c9864b681558c278395e94035a741fc10cd865"}, - {file = "fastapi-0.115.13.tar.gz", hash = "sha256:55d1d25c2e1e0a0a50aceb1c8705cd932def273c102bff0b1c1da88b3c6eb307"}, + {file = "fastapi-0.116.1-py3-none-any.whl", hash = "sha256:c46ac7c312df840f0c9e220f7964bada936781bc4e2e6eb71f1c4d7553786565"}, + {file = "fastapi-0.116.1.tar.gz", hash = "sha256:ed52cbf946abfd70c5a0dccb24673f0670deeb517a88b3544d03c2a6bf283143"}, ] [package.dependencies] pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.40.0,<0.47.0" +starlette = ">=0.40.0,<0.48.0" typing-extensions = ">=4.8.0" [package.extras] -all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] -standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"] +all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"] +standard-no-fastapi-cloud-cli = ["email-validator (>=2.0.0)", "fastapi-cli[standard-no-fastapi-cloud-cli] (>=0.0.8)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"] [[package]] name = "fastapi-sso" @@ -1074,6 +1291,18 @@ oauthlib = ">=3.1.0" pydantic = {version = ">=1.8.0", extras = ["email"]} pyjwt = ">=2.10.1,<3.0.0" +[[package]] +name = "filelock" +version = "3.20.0" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2"}, + {file = "filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4"}, +] + [[package]] name = "filetype" version = "1.2.0" @@ -1088,116 +1317,142 @@ files = [ [[package]] name = "frozenlist" -version = "1.7.0" +version = "1.8.0" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "frozenlist-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc4df77d638aa2ed703b878dd093725b72a824c3c546c076e8fdf276f78ee84a"}, - {file = "frozenlist-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:716a9973a2cc963160394f701964fe25012600f3d311f60c790400b00e568b61"}, - {file = "frozenlist-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0fd1bad056a3600047fb9462cff4c5322cebc59ebf5d0a3725e0ee78955001d"}, - {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3789ebc19cb811163e70fe2bd354cea097254ce6e707ae42e56f45e31e96cb8e"}, - {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af369aa35ee34f132fcfad5be45fbfcde0e3a5f6a1ec0712857f286b7d20cca9"}, - {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac64b6478722eeb7a3313d494f8342ef3478dff539d17002f849101b212ef97c"}, - {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f89f65d85774f1797239693cef07ad4c97fdd0639544bad9ac4b869782eb1981"}, - {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1073557c941395fdfcfac13eb2456cb8aad89f9de27bae29fabca8e563b12615"}, - {file = "frozenlist-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed8d2fa095aae4bdc7fdd80351009a48d286635edffee66bf865e37a9125c50"}, - {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:24c34bea555fe42d9f928ba0a740c553088500377448febecaa82cc3e88aa1fa"}, - {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:69cac419ac6a6baad202c85aaf467b65ac860ac2e7f2ac1686dc40dbb52f6577"}, - {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:960d67d0611f4c87da7e2ae2eacf7ea81a5be967861e0c63cf205215afbfac59"}, - {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:41be2964bd4b15bf575e5daee5a5ce7ed3115320fb3c2b71fca05582ffa4dc9e"}, - {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46d84d49e00c9429238a7ce02dc0be8f6d7cd0cd405abd1bebdc991bf27c15bd"}, - {file = "frozenlist-1.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15900082e886edb37480335d9d518cec978afc69ccbc30bd18610b7c1b22a718"}, - {file = "frozenlist-1.7.0-cp310-cp310-win32.whl", hash = "sha256:400ddd24ab4e55014bba442d917203c73b2846391dd42ca5e38ff52bb18c3c5e"}, - {file = "frozenlist-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:6eb93efb8101ef39d32d50bce242c84bcbddb4f7e9febfa7b524532a239b4464"}, - {file = "frozenlist-1.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa51e147a66b2d74de1e6e2cf5921890de6b0f4820b257465101d7f37b49fb5a"}, - {file = "frozenlist-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b35db7ce1cd71d36ba24f80f0c9e7cff73a28d7a74e91fe83e23d27c7828750"}, - {file = "frozenlist-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34a69a85e34ff37791e94542065c8416c1afbf820b68f720452f636d5fb990cd"}, - {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a646531fa8d82c87fe4bb2e596f23173caec9185bfbca5d583b4ccfb95183e2"}, - {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:79b2ffbba483f4ed36a0f236ccb85fbb16e670c9238313709638167670ba235f"}, - {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26f205c9ca5829cbf82bb2a84b5c36f7184c4316617d7ef1b271a56720d6b30"}, - {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcacfad3185a623fa11ea0e0634aac7b691aa925d50a440f39b458e41c561d98"}, - {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72c1b0fe8fe451b34f12dce46445ddf14bd2a5bcad7e324987194dc8e3a74c86"}, - {file = "frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d1a5baeaac6c0798ff6edfaeaa00e0e412d49946c53fae8d4b8e8b3566c4ae"}, - {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7edf5c043c062462f09b6820de9854bf28cc6cc5b6714b383149745e287181a8"}, - {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d50ac7627b3a1bd2dcef6f9da89a772694ec04d9a61b66cf87f7d9446b4a0c31"}, - {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce48b2fece5aeb45265bb7a58259f45027db0abff478e3077e12b05b17fb9da7"}, - {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:fe2365ae915a1fafd982c146754e1de6ab3478def8a59c86e1f7242d794f97d5"}, - {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:45a6f2fdbd10e074e8814eb98b05292f27bad7d1883afbe009d96abdcf3bc898"}, - {file = "frozenlist-1.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:21884e23cffabb157a9dd7e353779077bf5b8f9a58e9b262c6caad2ef5f80a56"}, - {file = "frozenlist-1.7.0-cp311-cp311-win32.whl", hash = "sha256:284d233a8953d7b24f9159b8a3496fc1ddc00f4db99c324bd5fb5f22d8698ea7"}, - {file = "frozenlist-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:387cbfdcde2f2353f19c2f66bbb52406d06ed77519ac7ee21be0232147c2592d"}, - {file = "frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2"}, - {file = "frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb"}, - {file = "frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478"}, - {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8"}, - {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08"}, - {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4"}, - {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b"}, - {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e"}, - {file = "frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca"}, - {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df"}, - {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5"}, - {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025"}, - {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01"}, - {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08"}, - {file = "frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43"}, - {file = "frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3"}, - {file = "frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a"}, - {file = "frozenlist-1.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee80eeda5e2a4e660651370ebffd1286542b67e268aa1ac8d6dbe973120ef7ee"}, - {file = "frozenlist-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1a81c85417b914139e3a9b995d4a1c84559afc839a93cf2cb7f15e6e5f6ed2d"}, - {file = "frozenlist-1.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbb65198a9132ebc334f237d7b0df163e4de83fb4f2bdfe46c1e654bdb0c5d43"}, - {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dab46c723eeb2c255a64f9dc05b8dd601fde66d6b19cdb82b2e09cc6ff8d8b5d"}, - {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6aeac207a759d0dedd2e40745575ae32ab30926ff4fa49b1635def65806fddee"}, - {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd8c4e58ad14b4fa7802b8be49d47993182fdd4023393899632c88fd8cd994eb"}, - {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fb24d104f425da3540ed83cbfc31388a586a7696142004c577fa61c6298c3f"}, - {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a5c505156368e4ea6b53b5ac23c92d7edc864537ff911d2fb24c140bb175e60"}, - {file = "frozenlist-1.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bd7eb96a675f18aa5c553eb7ddc24a43c8c18f22e1f9925528128c052cdbe00"}, - {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:05579bf020096fe05a764f1f84cd104a12f78eaab68842d036772dc6d4870b4b"}, - {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:376b6222d114e97eeec13d46c486facd41d4f43bab626b7c3f6a8b4e81a5192c"}, - {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa7e176ebe115379b5b1c95b4096fb1c17cce0847402e227e712c27bdb5a949"}, - {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3fbba20e662b9c2130dc771e332a99eff5da078b2b2648153a40669a6d0e36ca"}, - {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f4410a0a601d349dd406b5713fec59b4cee7e71678d5b17edda7f4655a940b"}, - {file = "frozenlist-1.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cdfaaec6a2f9327bf43c933c0319a7c429058e8537c508964a133dffee412e"}, - {file = "frozenlist-1.7.0-cp313-cp313-win32.whl", hash = "sha256:5fc4df05a6591c7768459caba1b342d9ec23fa16195e744939ba5914596ae3e1"}, - {file = "frozenlist-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:52109052b9791a3e6b5d1b65f4b909703984b770694d3eb64fad124c835d7cba"}, - {file = "frozenlist-1.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a6f86e4193bb0e235ef6ce3dde5cbabed887e0b11f516ce8a0f4d3b33078ec2d"}, - {file = "frozenlist-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:82d664628865abeb32d90ae497fb93df398a69bb3434463d172b80fc25b0dd7d"}, - {file = "frozenlist-1.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:912a7e8375a1c9a68325a902f3953191b7b292aa3c3fb0d71a216221deca460b"}, - {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9537c2777167488d539bc5de2ad262efc44388230e5118868e172dd4a552b146"}, - {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f34560fb1b4c3e30ba35fa9a13894ba39e5acfc5f60f57d8accde65f46cc5e74"}, - {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acd03d224b0175f5a850edc104ac19040d35419eddad04e7cf2d5986d98427f1"}, - {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2038310bc582f3d6a09b3816ab01737d60bf7b1ec70f5356b09e84fb7408ab1"}, - {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c05e4c8e5f36e5e088caa1bf78a687528f83c043706640a92cb76cd6999384"}, - {file = "frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:765bb588c86e47d0b68f23c1bee323d4b703218037765dcf3f25c838c6fecceb"}, - {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:32dc2e08c67d86d0969714dd484fd60ff08ff81d1a1e40a77dd34a387e6ebc0c"}, - {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:c0303e597eb5a5321b4de9c68e9845ac8f290d2ab3f3e2c864437d3c5a30cd65"}, - {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a47f2abb4e29b3a8d0b530f7c3598badc6b134562b1a5caee867f7c62fee51e3"}, - {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:3d688126c242a6fabbd92e02633414d40f50bb6002fa4cf995a1d18051525657"}, - {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4e7e9652b3d367c7bd449a727dc79d5043f48b88d0cbfd4f9f1060cf2b414104"}, - {file = "frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1a85e345b4c43db8b842cab1feb41be5cc0b10a1830e6295b69d7310f99becaf"}, - {file = "frozenlist-1.7.0-cp313-cp313t-win32.whl", hash = "sha256:3a14027124ddb70dfcee5148979998066897e79f89f64b13328595c4bdf77c81"}, - {file = "frozenlist-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3bf8010d71d4507775f658e9823210b7427be36625b387221642725b515dcf3e"}, - {file = "frozenlist-1.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cea3dbd15aea1341ea2de490574a4a37ca080b2ae24e4b4f4b51b9057b4c3630"}, - {file = "frozenlist-1.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7d536ee086b23fecc36c2073c371572374ff50ef4db515e4e503925361c24f71"}, - {file = "frozenlist-1.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dfcebf56f703cb2e346315431699f00db126d158455e513bd14089d992101e44"}, - {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974c5336e61d6e7eb1ea5b929cb645e882aadab0095c5a6974a111e6479f8878"}, - {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c70db4a0ab5ab20878432c40563573229a7ed9241506181bba12f6b7d0dc41cb"}, - {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1137b78384eebaf70560a36b7b229f752fb64d463d38d1304939984d5cb887b6"}, - {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e793a9f01b3e8b5c0bc646fb59140ce0efcc580d22a3468d70766091beb81b35"}, - {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74739ba8e4e38221d2c5c03d90a7e542cb8ad681915f4ca8f68d04f810ee0a87"}, - {file = "frozenlist-1.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e63344c4e929b1a01e29bc184bbb5fd82954869033765bfe8d65d09e336a677"}, - {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ea2a7369eb76de2217a842f22087913cdf75f63cf1307b9024ab82dfb525938"}, - {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:836b42f472a0e006e02499cef9352ce8097f33df43baaba3e0a28a964c26c7d2"}, - {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e22b9a99741294b2571667c07d9f8cceec07cb92aae5ccda39ea1b6052ed4319"}, - {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:9a19e85cc503d958abe5218953df722748d87172f71b73cf3c9257a91b999890"}, - {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f22dac33bb3ee8fe3e013aa7b91dc12f60d61d05b7fe32191ffa84c3aafe77bd"}, - {file = "frozenlist-1.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9ccec739a99e4ccf664ea0775149f2749b8a6418eb5b8384b4dc0a7d15d304cb"}, - {file = "frozenlist-1.7.0-cp39-cp39-win32.whl", hash = "sha256:b3950f11058310008a87757f3eee16a8e1ca97979833239439586857bc25482e"}, - {file = "frozenlist-1.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:43a82fce6769c70f2f5a06248b614a7d268080a9d20f7457ef10ecee5af82b63"}, - {file = "frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e"}, - {file = "frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f"}, + {file = "frozenlist-1.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011"}, + {file = "frozenlist-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565"}, + {file = "frozenlist-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450"}, + {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f"}, + {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7"}, + {file = "frozenlist-1.8.0-cp310-cp310-win32.whl", hash = "sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a"}, + {file = "frozenlist-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6"}, + {file = "frozenlist-1.8.0-cp310-cp310-win_arm64.whl", hash = "sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e"}, + {file = "frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84"}, + {file = "frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9"}, + {file = "frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967"}, + {file = "frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25"}, + {file = "frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b"}, + {file = "frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a"}, + {file = "frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1"}, + {file = "frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b"}, + {file = "frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa"}, + {file = "frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf"}, + {file = "frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746"}, + {file = "frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd"}, + {file = "frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a"}, + {file = "frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7"}, + {file = "frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5"}, + {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8"}, + {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed"}, + {file = "frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496"}, + {file = "frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231"}, + {file = "frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62"}, + {file = "frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94"}, + {file = "frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c"}, + {file = "frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714"}, + {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0"}, + {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41"}, + {file = "frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b"}, + {file = "frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888"}, + {file = "frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042"}, + {file = "frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0"}, + {file = "frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f"}, + {file = "frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e"}, + {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30"}, + {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7"}, + {file = "frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806"}, + {file = "frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0"}, + {file = "frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b"}, + {file = "frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d"}, + {file = "frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed"}, + {file = "frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a"}, + {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a"}, + {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e"}, + {file = "frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df"}, + {file = "frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd"}, + {file = "frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79"}, + {file = "frozenlist-1.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d8b7138e5cd0647e4523d6685b0eac5d4be9a184ae9634492f25c6eb38c12a47"}, + {file = "frozenlist-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a6483e309ca809f1efd154b4d37dc6d9f61037d6c6a81c2dc7a15cb22c8c5dca"}, + {file = "frozenlist-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b9290cf81e95e93fdf90548ce9d3c1211cf574b8e3f4b3b7cb0537cf2227068"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:59a6a5876ca59d1b63af8cd5e7ffffb024c3dc1e9cf9301b21a2e76286505c95"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6dc4126390929823e2d2d9dc79ab4046ed74680360fc5f38b585c12c66cdf459"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:332db6b2563333c5671fecacd085141b5800cb866be16d5e3eb15a2086476675"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ff15928d62a0b80bb875655c39bf517938c7d589554cbd2669be42d97c2cb61"}, + {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7bf6cdf8e07c8151fba6fe85735441240ec7f619f935a5205953d58009aef8c6"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:48e6d3f4ec5c7273dfe83ff27c91083c6c9065af655dc2684d2c200c94308bb5"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:1a7607e17ad33361677adcd1443edf6f5da0ce5e5377b798fba20fae194825f3"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3a935c3a4e89c733303a2d5a7c257ea44af3a56c8202df486b7f5de40f37e1"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:940d4a017dbfed9daf46a3b086e1d2167e7012ee297fef9e1c545c4d022f5178"}, + {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b9be22a69a014bc47e78072d0ecae716f5eb56c15238acca0f43d6eb8e4a5bda"}, + {file = "frozenlist-1.8.0-cp39-cp39-win32.whl", hash = "sha256:1aa77cb5697069af47472e39612976ed05343ff2e84a3dcf15437b232cbfd087"}, + {file = "frozenlist-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:7398c222d1d405e796970320036b1b563892b65809d9e5261487bb2c7f7b5c6a"}, + {file = "frozenlist-1.8.0-cp39-cp39-win_arm64.whl", hash = "sha256:b4f3b365f31c6cd4af24545ca0a244a53688cad8834e32f56831c4923b50a103"}, + {file = "frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d"}, + {file = "frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad"}, ] [[package]] @@ -1410,21 +1665,48 @@ cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +[[package]] +name = "identify" +version = "2.6.15" +description = "File identification library for Python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757"}, + {file = "identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf"}, +] + +[package.extras] +license = ["ukkonen"] + [[package]] name = "idna" -version = "3.10" +version = "3.11" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" groups = ["main"] files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, + {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, + {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, ] [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] +[[package]] +name = "iniconfig" +version = "2.3.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, + {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, +] + [[package]] name = "itsdangerous" version = "2.2.0" @@ -1471,25 +1753,110 @@ files = [ [package.dependencies] ply = "*" +[[package]] +name = "librt" +version = "0.6.3" +description = "Mypyc runtime library" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "librt-0.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:45660d26569cc22ed30adf583389d8a0d1b468f8b5e518fcf9bfe2cd298f9dd1"}, + {file = "librt-0.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:54f3b2177fb892d47f8016f1087d21654b44f7fc4cf6571c1c6b3ea531ab0fcf"}, + {file = "librt-0.6.3-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c5b31bed2c2f2fa1fcb4815b75f931121ae210dc89a3d607fb1725f5907f1437"}, + {file = "librt-0.6.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f8ed5053ef9fb08d34f1fd80ff093ccbd1f67f147633a84cf4a7d9b09c0f089"}, + {file = "librt-0.6.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3f0e4bd9bcb0ee34fa3dbedb05570da50b285f49e52c07a241da967840432513"}, + {file = "librt-0.6.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d8f89c8d20dfa648a3f0a56861946eb00e5b00d6b00eea14bc5532b2fcfa8ef1"}, + {file = "librt-0.6.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ecc2c526547eacd20cb9fbba19a5268611dbc70c346499656d6cf30fae328977"}, + {file = "librt-0.6.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fbedeb9b48614d662822ee514567d2d49a8012037fc7b4cd63f282642c2f4b7d"}, + {file = "librt-0.6.3-cp310-cp310-win32.whl", hash = "sha256:0765b0fe0927d189ee14b087cd595ae636bef04992e03fe6dfdaa383866c8a46"}, + {file = "librt-0.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:8c659f9fb8a2f16dc4131b803fa0144c1dadcb3ab24bb7914d01a6da58ae2457"}, + {file = "librt-0.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:61348cc488b18d1b1ff9f3e5fcd5ac43ed22d3e13e862489d2267c2337285c08"}, + {file = "librt-0.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64645b757d617ad5f98c08e07620bc488d4bced9ced91c6279cec418f16056fa"}, + {file = "librt-0.6.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:26b8026393920320bb9a811b691d73c5981385d537ffc5b6e22e53f7b65d4122"}, + {file = "librt-0.6.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d998b432ed9ffccc49b820e913c8f327a82026349e9c34fa3690116f6b70770f"}, + {file = "librt-0.6.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e18875e17ef69ba7dfa9623f2f95f3eda6f70b536079ee6d5763ecdfe6cc9040"}, + {file = "librt-0.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a218f85081fc3f70cddaed694323a1ad7db5ca028c379c214e3a7c11c0850523"}, + {file = "librt-0.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1ef42ff4edd369e84433ce9b188a64df0837f4f69e3d34d3b34d4955c599d03f"}, + {file = "librt-0.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0e0f2b79993fec23a685b3e8107ba5f8675eeae286675a216da0b09574fa1e47"}, + {file = "librt-0.6.3-cp311-cp311-win32.whl", hash = "sha256:fd98cacf4e0fabcd4005c452cb8a31750258a85cab9a59fb3559e8078da408d7"}, + {file = "librt-0.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:e17b5b42c8045867ca9d1f54af00cc2275198d38de18545edaa7833d7e9e4ac8"}, + {file = "librt-0.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:87597e3d57ec0120a3e1d857a708f80c02c42ea6b00227c728efbc860f067c45"}, + {file = "librt-0.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74418f718083009108dc9a42c21bf2e4802d49638a1249e13677585fcc9ca176"}, + {file = "librt-0.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:514f3f363d1ebc423357d36222c37e5c8e6674b6eae8d7195ac9a64903722057"}, + {file = "librt-0.6.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cf1115207a5049d1f4b7b4b72de0e52f228d6c696803d94843907111cbf80610"}, + {file = "librt-0.6.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad8ba80cdcea04bea7b78fcd4925bfbf408961e9d8397d2ee5d3ec121e20c08c"}, + {file = "librt-0.6.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4018904c83eab49c814e2494b4e22501a93cdb6c9f9425533fe693c3117126f9"}, + {file = "librt-0.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8983c5c06ac9c990eac5eb97a9f03fe41dc7e9d7993df74d9e8682a1056f596c"}, + {file = "librt-0.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7769c579663a6f8dbf34878969ac71befa42067ce6bf78e6370bf0d1194997c"}, + {file = "librt-0.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d3c9a07eafdc70556f8c220da4a538e715668c0c63cabcc436a026e4e89950bf"}, + {file = "librt-0.6.3-cp312-cp312-win32.whl", hash = "sha256:38320386a48a15033da295df276aea93a92dfa94a862e06893f75ea1d8bbe89d"}, + {file = "librt-0.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:c0ecf4786ad0404b072196b5df774b1bb23c8aacdcacb6c10b4128bc7b00bd01"}, + {file = "librt-0.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:9f2a6623057989ebc469cd9cc8fe436c40117a0147627568d03f84aef7854c55"}, + {file = "librt-0.6.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9e716f9012148a81f02f46a04fc4c663420c6fbfeacfac0b5e128cf43b4413d3"}, + {file = "librt-0.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:669ff2495728009a96339c5ad2612569c6d8be4474e68f3f3ac85d7c3261f5f5"}, + {file = "librt-0.6.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:349b6873ebccfc24c9efd244e49da9f8a5c10f60f07575e248921aae2123fc42"}, + {file = "librt-0.6.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c74c26736008481c9f6d0adf1aedb5a52aff7361fea98276d1f965c0256ee70"}, + {file = "librt-0.6.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:408a36ddc75e91918cb15b03460bdc8a015885025d67e68c6f78f08c3a88f522"}, + {file = "librt-0.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e61ab234624c9ffca0248a707feffe6fac2343758a36725d8eb8a6efef0f8c30"}, + {file = "librt-0.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:324462fe7e3896d592b967196512491ec60ca6e49c446fe59f40743d08c97917"}, + {file = "librt-0.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:36b2ec8c15030002c7f688b4863e7be42820d7c62d9c6eece3db54a2400f0530"}, + {file = "librt-0.6.3-cp313-cp313-win32.whl", hash = "sha256:25b1b60cb059471c0c0c803e07d0dfdc79e41a0a122f288b819219ed162672a3"}, + {file = "librt-0.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:10a95ad074e2a98c9e4abc7f5b7d40e5ecbfa84c04c6ab8a70fabf59bd429b88"}, + {file = "librt-0.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:17000df14f552e86877d67e4ab7966912224efc9368e998c96a6974a8d609bf9"}, + {file = "librt-0.6.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8e695f25d1a425ad7a272902af8ab8c8d66c1998b177e4b5f5e7b4e215d0c88a"}, + {file = "librt-0.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3e84a4121a7ae360ca4da436548a9c1ca8ca134a5ced76c893cc5944426164bd"}, + {file = "librt-0.6.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:05f385a414de3f950886ea0aad8f109650d4b712cf9cc14cc17f5f62a9ab240b"}, + {file = "librt-0.6.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36a8e337461150b05ca2c7bdedb9e591dfc262c5230422cea398e89d0c746cdc"}, + {file = "librt-0.6.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dcbe48f6a03979384f27086484dc2a14959be1613cb173458bd58f714f2c48f3"}, + {file = "librt-0.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4bca9e4c260233fba37b15c4ec2f78aa99c1a79fbf902d19dd4a763c5c3fb751"}, + {file = "librt-0.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:760c25ed6ac968e24803eb5f7deb17ce026902d39865e83036bacbf5cf242aa8"}, + {file = "librt-0.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4aa4a93a353ccff20df6e34fa855ae8fd788832c88f40a9070e3ddd3356a9f0e"}, + {file = "librt-0.6.3-cp314-cp314-win32.whl", hash = "sha256:cb92741c2b4ea63c09609b064b26f7f5d9032b61ae222558c55832ec3ad0bcaf"}, + {file = "librt-0.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:fdcd095b1b812d756fa5452aca93b962cf620694c0cadb192cec2bb77dcca9a2"}, + {file = "librt-0.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:822ca79e28720a76a935c228d37da6579edef048a17cd98d406a2484d10eda78"}, + {file = "librt-0.6.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:078cd77064d1640cb7b0650871a772956066174d92c8aeda188a489b58495179"}, + {file = "librt-0.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5cc22f7f5c0cc50ed69f4b15b9c51d602aabc4500b433aaa2ddd29e578f452f7"}, + {file = "librt-0.6.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:14b345eb7afb61b9fdcdfda6738946bd11b8e0f6be258666b0646af3b9bb5916"}, + {file = "librt-0.6.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d46aa46aa29b067f0b8b84f448fd9719aaf5f4c621cc279164d76a9dc9ab3e8"}, + {file = "librt-0.6.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1b51ba7d9d5d9001494769eca8c0988adce25d0a970c3ba3f2eb9df9d08036fc"}, + {file = "librt-0.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ced0925a18fddcff289ef54386b2fc230c5af3c83b11558571124bfc485b8c07"}, + {file = "librt-0.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:6bac97e51f66da2ca012adddbe9fd656b17f7368d439de30898f24b39512f40f"}, + {file = "librt-0.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b2922a0e8fa97395553c304edc3bd36168d8eeec26b92478e292e5d4445c1ef0"}, + {file = "librt-0.6.3-cp314-cp314t-win32.whl", hash = "sha256:f33462b19503ba68d80dac8a1354402675849259fb3ebf53b67de86421735a3a"}, + {file = "librt-0.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:04f8ce401d4f6380cfc42af0f4e67342bf34c820dae01343f58f472dbac75dcf"}, + {file = "librt-0.6.3-cp314-cp314t-win_arm64.whl", hash = "sha256:afb39550205cc5e5c935762c6bf6a2bb34f7d21a68eadb25e2db7bf3593fecc0"}, + {file = "librt-0.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09262cb2445b6f15d09141af20b95bb7030c6f13b00e876ad8fdd1a9045d6aa5"}, + {file = "librt-0.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:57705e8eec76c5b77130d729c0f70190a9773366c555c5457c51eace80afd873"}, + {file = "librt-0.6.3-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3ac2a7835434b31def8ed5355dd9b895bbf41642d61967522646d1d8b9681106"}, + {file = "librt-0.6.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71f0a5918aebbea1e7db2179a8fe87e8a8732340d9e8b8107401fb407eda446e"}, + {file = "librt-0.6.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa346e202e6e1ebc01fe1c69509cffe486425884b96cb9ce155c99da1ecbe0e9"}, + {file = "librt-0.6.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:92267f865c7bbd12327a0d394666948b9bf4b51308b52947c0cc453bfa812f5d"}, + {file = "librt-0.6.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:86605d5bac340beb030cbc35859325982a79047ebdfba1e553719c7126a2389d"}, + {file = "librt-0.6.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:98e4bbecbef8d2a60ecf731d735602feee5ac0b32117dbbc765e28b054bac912"}, + {file = "librt-0.6.3-cp39-cp39-win32.whl", hash = "sha256:3caa0634c02d5ff0b2ae4a28052e0d8c5f20d497623dc13f629bd4a9e2a6efad"}, + {file = "librt-0.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:b47395091e7e0ece1e6ebac9b98bf0c9084d1e3d3b2739aa566be7e56e3f7bf2"}, + {file = "librt-0.6.3.tar.gz", hash = "sha256:c724a884e642aa2bbad52bb0203ea40406ad742368a5f90da1b220e970384aae"}, +] + [[package]] name = "limits" -version = "5.5.0" +version = "5.6.0" description = "Rate limiting utilities" optional = false python-versions = ">=3.10" groups = ["main"] files = [ - {file = "limits-5.5.0-py3-none-any.whl", hash = "sha256:57217d01ffa5114f7e233d1f5e5bdc6fe60c9b24ade387bf4d5e83c5cf929bae"}, - {file = "limits-5.5.0.tar.gz", hash = "sha256:ee269fedb078a904608b264424d9ef4ab10555acc8d090b6fc1db70e913327ea"}, + {file = "limits-5.6.0-py3-none-any.whl", hash = "sha256:b585c2104274528536a5b68864ec3835602b3c4a802cd6aa0b07419798394021"}, + {file = "limits-5.6.0.tar.gz", hash = "sha256:807fac75755e73912e894fdd61e2838de574c5721876a19f7ab454ae1fffb4b5"}, ] [package.dependencies] deprecated = ">=1.2" packaging = ">=21" -typing_extensions = "*" +typing-extensions = "*" [package.extras] -all = ["coredis (>=3.4.0,<6)", "memcachio (>=0.3)", "motor (>=3,<4)", "pymemcache (>3,<5.0.0)", "pymongo (>4.1,<5)", "redis (>3,!=4.5.2,!=4.5.3,<7.0.0)", "redis (>=4.2.0,!=4.5.2,!=4.5.3)", "valkey (>=6)", "valkey (>=6)"] async-memcached = ["memcachio (>=0.3)"] async-mongodb = ["motor (>=3,<4)"] async-redis = ["coredis (>=3.4.0,<6)"] @@ -1502,53 +1869,54 @@ valkey = ["valkey (>=6)"] [[package]] name = "lnbits" -version = "1.2.1" +version = "1.3.1" description = "LNbits, free and open-source Lightning wallet and accounts system." optional = false python-versions = "<3.13,>=3.10" groups = ["main"] files = [ - {file = "lnbits-1.2.1-py3-none-any.whl", hash = "sha256:64d5b8dc0fe5b72f811e13ada1677b09f55f1070d3da901dc26102f47a07563b"}, - {file = "lnbits-1.2.1.tar.gz", hash = "sha256:7770e90c7072657fb759f4615962a2dd05d064851f58343695a7dd922a6bc20b"}, + {file = "lnbits-1.3.1-py3-none-any.whl", hash = "sha256:4d477e0963ff86adc237ffd2a15642213277772c0c1d51944cd2943f917bb53f"}, + {file = "lnbits-1.3.1.tar.gz", hash = "sha256:3015a3c28d6384cd94a69beed568b21158655f9274bf2081d646f94aeed02c0a"}, ] [package.dependencies] aiosqlite = "0.21.0" asyncpg = "0.30.0" +bcrypt = "4.3.0" bech32 = "1.2.0" bolt11 = "2.1.1" click = "8.2.1" ecdsa = "0.19.1" embit = "0.8.0" environs = "14.2.0" -fastapi = "0.115.13" +fastapi = "0.116.1" fastapi-sso = "0.18.0" -filetype = ">=1.2.0,<2.0.0" +filetype = "1.2.0" grpcio = "1.69.0" httpx = "0.27.0" itsdangerous = "2.2.0" jinja2 = "3.1.6" -jsonpath-ng = ">=1.7.0,<2.0.0" -lnurl = "0.5.3" +jsonpath-ng = "1.7.0" +lnurl = "0.8.3" loguru = "0.7.3" -nostr-sdk = ">=0.42.1,<0.43.0" +nostr-sdk = "0.42.1" packaging = "25.0" -passlib = "1.7.4" -protobuf = "5.29.1" +protobuf = "5.29.5" pycryptodomex = "3.23.0" -pydantic = "1.10.18" +pydantic = "1.10.22" pyjwt = "2.10.1" pyln-client = "25.5" -pynostr = ">=0.6.2,<0.7.0" +pynostr = "0.6.2" pyqrcode = "1.2.1" python-crontab = "3.2.0" -python-multipart = ">=0.0.20,<0.0.21" +python-multipart = "0.0.20" pywebpush = "2.0.3" secp256k1 = "0.14.0" shortuuid = "1.0.13" slowapi = "0.1.9" sqlalchemy = "1.4.54" sse-starlette = "2.3.6" +starlette = "0.47.1" typing-extensions = "4.14.0" uvicorn = "0.34.3" uvloop = "0.21.0" @@ -1556,26 +1924,29 @@ websocket-client = "1.8.0" websockets = "15.0.1" [package.extras] -breez = ["breez-sdk (==0.8.0)"] +breez = ["breez-sdk (==0.8.0)", "breez-sdk-liquid (==0.9.1)"] liquid = ["wallycore (==1.4.0)"] +migration = ["psycopg2-binary (==2.9.10)"] [[package]] name = "lnurl" -version = "0.5.3" +version = "0.8.3" description = "LNURL implementation for Python." optional = false -python-versions = "<4.0,>=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "lnurl-0.5.3-py3-none-any.whl", hash = "sha256:feaf6c60b0b7f104894ef3accbd30d23d52e038c2797c58432baea7f4a8aa952"}, - {file = "lnurl-0.5.3.tar.gz", hash = "sha256:60154bcfdbb98fb143eeca970a16d73a582f28e057a826b5f222259411c497fe"}, + {file = "lnurl-0.8.3-py3-none-any.whl", hash = "sha256:670cdeaef2c55de986dad89126ab58275d5199ba6554a93d9965d1e162080c2a"}, + {file = "lnurl-0.8.3.tar.gz", hash = "sha256:8ca73af84fb9ee36a184d731d165f289ba7bc6260d4dadb2b6cf24f381c3afba"}, ] [package.dependencies] -bech32 = ">=1.2.0,<2.0.0" -bolt11 = ">=2.0.5,<3.0.0" -ecdsa = ">=0.19.0,<0.20.0" -httpx = ">=0.27.0,<0.28.0" +bech32 = "*" +bip32 = ">=4.0,<5.0" +bolt11 = "*" +ecdsa = "*" +httpx = "*" +pycryptodomex = ">=3.21.0,<4.0.0" pydantic = ">=1,<2" [[package]] @@ -1623,85 +1994,113 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "requests"] [[package]] name = "markupsafe" -version = "3.0.2" +version = "3.0.3" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, + {file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"}, + {file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591"}, + {file = "markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6"}, + {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1"}, + {file = "markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa"}, + {file = "markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8"}, + {file = "markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1"}, + {file = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"}, + {file = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"}, + {file = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"}, + {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"}, + {file = "markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"}, + {file = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"}, + {file = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"}, + {file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"}, + {file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"}, + {file = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"}, + {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"}, + {file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"}, + {file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"}, + {file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"}, + {file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"}, + {file = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"}, + {file = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"}, + {file = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"}, + {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"}, + {file = "markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"}, + {file = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"}, + {file = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"}, + {file = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"}, + {file = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"}, + {file = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"}, + {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"}, + {file = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"}, + {file = "markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26"}, + {file = "markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42"}, + {file = "markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2"}, + {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d"}, + {file = "markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7"}, + {file = "markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e"}, + {file = "markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8"}, + {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}, ] [[package]] name = "marshmallow" -version = "4.0.1" +version = "4.1.0" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "marshmallow-4.0.1-py3-none-any.whl", hash = "sha256:72f14ef346f81269dbddee891bac547dda1501e9e08b6a809756ea3dbb7936a1"}, - {file = "marshmallow-4.0.1.tar.gz", hash = "sha256:e1d860bd262737cb2d34e1541b84cb52c32c72c9474e3fe6f30f137ef8b0d97f"}, + {file = "marshmallow-4.1.0-py3-none-any.whl", hash = "sha256:9901660499be3b880dc92d6b5ee0b9a79e94265b7793f71021f92040c07129f1"}, + {file = "marshmallow-4.1.0.tar.gz", hash = "sha256:daa9862f74e2f7864980d25c29b4ea72944cde48aa17537e3bd5797a4ae62d71"}, ] [package.dependencies] @@ -1710,7 +2109,7 @@ typing-extensions = {version = "*", markers = "python_version < \"3.11\""} [package.extras] dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] -docs = ["autodocsumm (==0.2.14)", "furo (==2025.7.19)", "sphinx (==8.2.3)", "sphinx-copybutton (==0.5.2)", "sphinx-issues (==5.0.1)", "sphinxext-opengraph (==0.12.0)"] +docs = ["autodocsumm (==0.2.14)", "furo (==2025.9.25)", "sphinx (==8.2.3)", "sphinx-copybutton (==0.5.2)", "sphinx-issues (==5.0.1)", "sphinxext-opengraph (==0.13.0)"] tests = ["pytest", "simplejson"] [[package]] @@ -1727,127 +2126,249 @@ files = [ [[package]] name = "multidict" -version = "6.6.4" +version = "6.7.0" description = "multidict implementation" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "multidict-6.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b8aa6f0bd8125ddd04a6593437bad6a7e70f300ff4180a531654aa2ab3f6d58f"}, - {file = "multidict-6.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b9e5853bbd7264baca42ffc53391b490d65fe62849bf2c690fa3f6273dbcd0cb"}, - {file = "multidict-6.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0af5f9dee472371e36d6ae38bde009bd8ce65ac7335f55dcc240379d7bed1495"}, - {file = "multidict-6.6.4-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:d24f351e4d759f5054b641c81e8291e5d122af0fca5c72454ff77f7cbe492de8"}, - {file = "multidict-6.6.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db6a3810eec08280a172a6cd541ff4a5f6a97b161d93ec94e6c4018917deb6b7"}, - {file = "multidict-6.6.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a1b20a9d56b2d81e2ff52ecc0670d583eaabaa55f402e8d16dd062373dbbe796"}, - {file = "multidict-6.6.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8c9854df0eaa610a23494c32a6f44a3a550fb398b6b51a56e8c6b9b3689578db"}, - {file = "multidict-6.6.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4bb7627fd7a968f41905a4d6343b0d63244a0623f006e9ed989fa2b78f4438a0"}, - {file = "multidict-6.6.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caebafea30ed049c57c673d0b36238b1748683be2593965614d7b0e99125c877"}, - {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ad887a8250eb47d3ab083d2f98db7f48098d13d42eb7a3b67d8a5c795f224ace"}, - {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:ed8358ae7d94ffb7c397cecb62cbac9578a83ecefc1eba27b9090ee910e2efb6"}, - {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ecab51ad2462197a4c000b6d5701fc8585b80eecb90583635d7e327b7b6923eb"}, - {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c5c97aa666cf70e667dfa5af945424ba1329af5dd988a437efeb3a09430389fb"}, - {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9a950b7cf54099c1209f455ac5970b1ea81410f2af60ed9eb3c3f14f0bfcf987"}, - {file = "multidict-6.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:163c7ea522ea9365a8a57832dea7618e6cbdc3cd75f8c627663587459a4e328f"}, - {file = "multidict-6.6.4-cp310-cp310-win32.whl", hash = "sha256:17d2cbbfa6ff20821396b25890f155f40c986f9cfbce5667759696d83504954f"}, - {file = "multidict-6.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:ce9a40fbe52e57e7edf20113a4eaddfacac0561a0879734e636aa6d4bb5e3fb0"}, - {file = "multidict-6.6.4-cp310-cp310-win_arm64.whl", hash = "sha256:01d0959807a451fe9fdd4da3e139cb5b77f7328baf2140feeaf233e1d777b729"}, - {file = "multidict-6.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c7a0e9b561e6460484318a7612e725df1145d46b0ef57c6b9866441bf6e27e0c"}, - {file = "multidict-6.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6bf2f10f70acc7a2446965ffbc726e5fc0b272c97a90b485857e5c70022213eb"}, - {file = "multidict-6.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66247d72ed62d5dd29752ffc1d3b88f135c6a8de8b5f63b7c14e973ef5bda19e"}, - {file = "multidict-6.6.4-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:105245cc6b76f51e408451a844a54e6823bbd5a490ebfe5bdfc79798511ceded"}, - {file = "multidict-6.6.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cbbc54e58b34c3bae389ef00046be0961f30fef7cb0dd9c7756aee376a4f7683"}, - {file = "multidict-6.6.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:56c6b3652f945c9bc3ac6c8178cd93132b8d82dd581fcbc3a00676c51302bc1a"}, - {file = "multidict-6.6.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b95494daf857602eccf4c18ca33337dd2be705bccdb6dddbfc9d513e6addb9d9"}, - {file = "multidict-6.6.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e5b1413361cef15340ab9dc61523e653d25723e82d488ef7d60a12878227ed50"}, - {file = "multidict-6.6.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e167bf899c3d724f9662ef00b4f7fef87a19c22b2fead198a6f68b263618df52"}, - {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aaea28ba20a9026dfa77f4b80369e51cb767c61e33a2d4043399c67bd95fb7c6"}, - {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8c91cdb30809a96d9ecf442ec9bc45e8cfaa0f7f8bdf534e082c2443a196727e"}, - {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1a0ccbfe93ca114c5d65a2471d52d8829e56d467c97b0e341cf5ee45410033b3"}, - {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:55624b3f321d84c403cb7d8e6e982f41ae233d85f85db54ba6286f7295dc8a9c"}, - {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4a1fb393a2c9d202cb766c76208bd7945bc194eba8ac920ce98c6e458f0b524b"}, - {file = "multidict-6.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:43868297a5759a845fa3a483fb4392973a95fb1de891605a3728130c52b8f40f"}, - {file = "multidict-6.6.4-cp311-cp311-win32.whl", hash = "sha256:ed3b94c5e362a8a84d69642dbeac615452e8af9b8eb825b7bc9f31a53a1051e2"}, - {file = "multidict-6.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:d8c112f7a90d8ca5d20213aa41eac690bb50a76da153e3afb3886418e61cb22e"}, - {file = "multidict-6.6.4-cp311-cp311-win_arm64.whl", hash = "sha256:3bb0eae408fa1996d87247ca0d6a57b7fc1dcf83e8a5c47ab82c558c250d4adf"}, - {file = "multidict-6.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0ffb87be160942d56d7b87b0fdf098e81ed565add09eaa1294268c7f3caac4c8"}, - {file = "multidict-6.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d191de6cbab2aff5de6c5723101705fd044b3e4c7cfd587a1929b5028b9714b3"}, - {file = "multidict-6.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38a0956dd92d918ad5feff3db8fcb4a5eb7dba114da917e1a88475619781b57b"}, - {file = "multidict-6.6.4-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6865f6d3b7900ae020b495d599fcf3765653bc927951c1abb959017f81ae8287"}, - {file = "multidict-6.6.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a2088c126b6f72db6c9212ad827d0ba088c01d951cee25e758c450da732c138"}, - {file = "multidict-6.6.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0f37bed7319b848097085d7d48116f545985db988e2256b2e6f00563a3416ee6"}, - {file = "multidict-6.6.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:01368e3c94032ba6ca0b78e7ccb099643466cf24f8dc8eefcfdc0571d56e58f9"}, - {file = "multidict-6.6.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fe323540c255db0bffee79ad7f048c909f2ab0edb87a597e1c17da6a54e493c"}, - {file = "multidict-6.6.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8eb3025f17b0a4c3cd08cda49acf312a19ad6e8a4edd9dbd591e6506d999402"}, - {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bbc14f0365534d35a06970d6a83478b249752e922d662dc24d489af1aa0d1be7"}, - {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:75aa52fba2d96bf972e85451b99d8e19cc37ce26fd016f6d4aa60da9ab2b005f"}, - {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4fefd4a815e362d4f011919d97d7b4a1e566f1dde83dc4ad8cfb5b41de1df68d"}, - {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:db9801fe021f59a5b375ab778973127ca0ac52429a26e2fd86aa9508f4d26eb7"}, - {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a650629970fa21ac1fb06ba25dabfc5b8a2054fcbf6ae97c758aa956b8dba802"}, - {file = "multidict-6.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:452ff5da78d4720d7516a3a2abd804957532dd69296cb77319c193e3ffb87e24"}, - {file = "multidict-6.6.4-cp312-cp312-win32.whl", hash = "sha256:8c2fcb12136530ed19572bbba61b407f655e3953ba669b96a35036a11a485793"}, - {file = "multidict-6.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:047d9425860a8c9544fed1b9584f0c8bcd31bcde9568b047c5e567a1025ecd6e"}, - {file = "multidict-6.6.4-cp312-cp312-win_arm64.whl", hash = "sha256:14754eb72feaa1e8ae528468f24250dd997b8e2188c3d2f593f9eba259e4b364"}, - {file = "multidict-6.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f46a6e8597f9bd71b31cc708195d42b634c8527fecbcf93febf1052cacc1f16e"}, - {file = "multidict-6.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:22e38b2bc176c5eb9c0a0e379f9d188ae4cd8b28c0f53b52bce7ab0a9e534657"}, - {file = "multidict-6.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5df8afd26f162da59e218ac0eefaa01b01b2e6cd606cffa46608f699539246da"}, - {file = "multidict-6.6.4-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:49517449b58d043023720aa58e62b2f74ce9b28f740a0b5d33971149553d72aa"}, - {file = "multidict-6.6.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae9408439537c5afdca05edd128a63f56a62680f4b3c234301055d7a2000220f"}, - {file = "multidict-6.6.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87a32d20759dc52a9e850fe1061b6e41ab28e2998d44168a8a341b99ded1dba0"}, - {file = "multidict-6.6.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:52e3c8d43cdfff587ceedce9deb25e6ae77daba560b626e97a56ddcad3756879"}, - {file = "multidict-6.6.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ad8850921d3a8d8ff6fbef790e773cecfc260bbfa0566998980d3fa8f520bc4a"}, - {file = "multidict-6.6.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:497a2954adc25c08daff36f795077f63ad33e13f19bfff7736e72c785391534f"}, - {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:024ce601f92d780ca1617ad4be5ac15b501cc2414970ffa2bb2bbc2bd5a68fa5"}, - {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a693fc5ed9bdd1c9e898013e0da4dcc640de7963a371c0bd458e50e046bf6438"}, - {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:190766dac95aab54cae5b152a56520fd99298f32a1266d66d27fdd1b5ac00f4e"}, - {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:34d8f2a5ffdceab9dcd97c7a016deb2308531d5f0fced2bb0c9e1df45b3363d7"}, - {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:59e8d40ab1f5a8597abcef00d04845155a5693b5da00d2c93dbe88f2050f2812"}, - {file = "multidict-6.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:467fe64138cfac771f0e949b938c2e1ada2b5af22f39692aa9258715e9ea613a"}, - {file = "multidict-6.6.4-cp313-cp313-win32.whl", hash = "sha256:14616a30fe6d0a48d0a48d1a633ab3b8bec4cf293aac65f32ed116f620adfd69"}, - {file = "multidict-6.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:40cd05eaeb39e2bc8939451f033e57feaa2ac99e07dbca8afe2be450a4a3b6cf"}, - {file = "multidict-6.6.4-cp313-cp313-win_arm64.whl", hash = "sha256:f6eb37d511bfae9e13e82cb4d1af36b91150466f24d9b2b8a9785816deb16605"}, - {file = "multidict-6.6.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6c84378acd4f37d1b507dfa0d459b449e2321b3ba5f2338f9b085cf7a7ba95eb"}, - {file = "multidict-6.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0e0558693063c75f3d952abf645c78f3c5dfdd825a41d8c4d8156fc0b0da6e7e"}, - {file = "multidict-6.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3f8e2384cb83ebd23fd07e9eada8ba64afc4c759cd94817433ab8c81ee4b403f"}, - {file = "multidict-6.6.4-cp313-cp313t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:f996b87b420995a9174b2a7c1a8daf7db4750be6848b03eb5e639674f7963773"}, - {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc356250cffd6e78416cf5b40dc6a74f1edf3be8e834cf8862d9ed5265cf9b0e"}, - {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:dadf95aa862714ea468a49ad1e09fe00fcc9ec67d122f6596a8d40caf6cec7d0"}, - {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7dd57515bebffd8ebd714d101d4c434063322e4fe24042e90ced41f18b6d3395"}, - {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:967af5f238ebc2eb1da4e77af5492219fbd9b4b812347da39a7b5f5c72c0fa45"}, - {file = "multidict-6.6.4-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a4c6875c37aae9794308ec43e3530e4aa0d36579ce38d89979bbf89582002bb"}, - {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:7f683a551e92bdb7fac545b9c6f9fa2aebdeefa61d607510b3533286fcab67f5"}, - {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:3ba5aaf600edaf2a868a391779f7a85d93bed147854925f34edd24cc70a3e141"}, - {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:580b643b7fd2c295d83cad90d78419081f53fd532d1f1eb67ceb7060f61cff0d"}, - {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:37b7187197da6af3ee0b044dbc9625afd0c885f2800815b228a0e70f9a7f473d"}, - {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e1b93790ed0bc26feb72e2f08299691ceb6da5e9e14a0d13cc74f1869af327a0"}, - {file = "multidict-6.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a506a77ddee1efcca81ecbeae27ade3e09cdf21a8ae854d766c2bb4f14053f92"}, - {file = "multidict-6.6.4-cp313-cp313t-win32.whl", hash = "sha256:f93b2b2279883d1d0a9e1bd01f312d6fc315c5e4c1f09e112e4736e2f650bc4e"}, - {file = "multidict-6.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:6d46a180acdf6e87cc41dc15d8f5c2986e1e8739dc25dbb7dac826731ef381a4"}, - {file = "multidict-6.6.4-cp313-cp313t-win_arm64.whl", hash = "sha256:756989334015e3335d087a27331659820d53ba432befdef6a718398b0a8493ad"}, - {file = "multidict-6.6.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:af7618b591bae552b40dbb6f93f5518328a949dac626ee75927bba1ecdeea9f4"}, - {file = "multidict-6.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b6819f83aef06f560cb15482d619d0e623ce9bf155115150a85ab11b8342a665"}, - {file = "multidict-6.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4d09384e75788861e046330308e7af54dd306aaf20eb760eb1d0de26b2bea2cb"}, - {file = "multidict-6.6.4-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:a59c63061f1a07b861c004e53869eb1211ffd1a4acbca330e3322efa6dd02978"}, - {file = "multidict-6.6.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:350f6b0fe1ced61e778037fdc7613f4051c8baf64b1ee19371b42a3acdb016a0"}, - {file = "multidict-6.6.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0c5cbac6b55ad69cb6aa17ee9343dfbba903118fd530348c330211dc7aa756d1"}, - {file = "multidict-6.6.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:630f70c32b8066ddfd920350bc236225814ad94dfa493fe1910ee17fe4365cbb"}, - {file = "multidict-6.6.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8d4916a81697faec6cb724a273bd5457e4c6c43d82b29f9dc02c5542fd21fc9"}, - {file = "multidict-6.6.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e42332cf8276bb7645d310cdecca93a16920256a5b01bebf747365f86a1675b"}, - {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f3be27440f7644ab9a13a6fc86f09cdd90b347c3c5e30c6d6d860de822d7cb53"}, - {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:21f216669109e02ef3e2415ede07f4f8987f00de8cdfa0cc0b3440d42534f9f0"}, - {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d9890d68c45d1aeac5178ded1d1cccf3bc8d7accf1f976f79bf63099fb16e4bd"}, - {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:edfdcae97cdc5d1a89477c436b61f472c4d40971774ac4729c613b4b133163cb"}, - {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0b2e886624be5773e69cf32bcb8534aecdeb38943520b240fed3d5596a430f2f"}, - {file = "multidict-6.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:be5bf4b3224948032a845d12ab0f69f208293742df96dc14c4ff9b09e508fc17"}, - {file = "multidict-6.6.4-cp39-cp39-win32.whl", hash = "sha256:10a68a9191f284fe9d501fef4efe93226e74df92ce7a24e301371293bd4918ae"}, - {file = "multidict-6.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:ee25f82f53262f9ac93bd7e58e47ea1bdcc3393cef815847e397cba17e284210"}, - {file = "multidict-6.6.4-cp39-cp39-win_arm64.whl", hash = "sha256:f9867e55590e0855bcec60d4f9a092b69476db64573c9fe17e92b0c50614c16a"}, - {file = "multidict-6.6.4-py3-none-any.whl", hash = "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c"}, - {file = "multidict-6.6.4.tar.gz", hash = "sha256:d2d4e4787672911b48350df02ed3fa3fffdc2f2e8ca06dd6afdf34189b76a9dd"}, + {file = "multidict-6.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9f474ad5acda359c8758c8accc22032c6abe6dc87a8be2440d097785e27a9349"}, + {file = "multidict-6.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b7a9db5a870f780220e931d0002bbfd88fb53aceb6293251e2c839415c1b20e"}, + {file = "multidict-6.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:03ca744319864e92721195fa28c7a3b2bc7b686246b35e4078c1e4d0eb5466d3"}, + {file = "multidict-6.7.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f0e77e3c0008bc9316e662624535b88d360c3a5d3f81e15cf12c139a75250046"}, + {file = "multidict-6.7.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08325c9e5367aa379a3496aa9a022fe8837ff22e00b94db256d3a1378c76ab32"}, + {file = "multidict-6.7.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e2862408c99f84aa571ab462d25236ef9cb12a602ea959ba9c9009a54902fc73"}, + {file = "multidict-6.7.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d72a9a2d885f5c208b0cb91ff2ed43636bb7e345ec839ff64708e04f69a13cc"}, + {file = "multidict-6.7.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:478cc36476687bac1514d651cbbaa94b86b0732fb6855c60c673794c7dd2da62"}, + {file = "multidict-6.7.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6843b28b0364dc605f21481c90fadb5f60d9123b442eb8a726bb74feef588a84"}, + {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23bfeee5316266e5ee2d625df2d2c602b829435fc3a235c2ba2131495706e4a0"}, + {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:680878b9f3d45c31e1f730eef731f9b0bc1da456155688c6745ee84eb818e90e"}, + {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:eb866162ef2f45063acc7a53a88ef6fe8bf121d45c30ea3c9cd87ce7e191a8d4"}, + {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:df0e3bf7993bdbeca5ac25aa859cf40d39019e015c9c91809ba7093967f7a648"}, + {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:661709cdcd919a2ece2234f9bae7174e5220c80b034585d7d8a755632d3e2111"}, + {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:096f52730c3fb8ed419db2d44391932b63891b2c5ed14850a7e215c0ba9ade36"}, + {file = "multidict-6.7.0-cp310-cp310-win32.whl", hash = "sha256:afa8a2978ec65d2336305550535c9c4ff50ee527914328c8677b3973ade52b85"}, + {file = "multidict-6.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:b15b3afff74f707b9275d5ba6a91ae8f6429c3ffb29bbfd216b0b375a56f13d7"}, + {file = "multidict-6.7.0-cp310-cp310-win_arm64.whl", hash = "sha256:4b73189894398d59131a66ff157837b1fafea9974be486d036bb3d32331fdbf0"}, + {file = "multidict-6.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc"}, + {file = "multidict-6.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721"}, + {file = "multidict-6.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34"}, + {file = "multidict-6.7.0-cp311-cp311-win32.whl", hash = "sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff"}, + {file = "multidict-6.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81"}, + {file = "multidict-6.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912"}, + {file = "multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184"}, + {file = "multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45"}, + {file = "multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8"}, + {file = "multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4"}, + {file = "multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b"}, + {file = "multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec"}, + {file = "multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6"}, + {file = "multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159"}, + {file = "multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca"}, + {file = "multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8"}, + {file = "multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60"}, + {file = "multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4"}, + {file = "multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f"}, + {file = "multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf"}, + {file = "multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32"}, + {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036"}, + {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec"}, + {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e"}, + {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64"}, + {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd"}, + {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288"}, + {file = "multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17"}, + {file = "multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390"}, + {file = "multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e"}, + {file = "multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00"}, + {file = "multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb"}, + {file = "multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b"}, + {file = "multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c"}, + {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1"}, + {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b"}, + {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5"}, + {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad"}, + {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c"}, + {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5"}, + {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10"}, + {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754"}, + {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c"}, + {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762"}, + {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6"}, + {file = "multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d"}, + {file = "multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6"}, + {file = "multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792"}, + {file = "multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842"}, + {file = "multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b"}, + {file = "multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38"}, + {file = "multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128"}, + {file = "multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34"}, + {file = "multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99"}, + {file = "multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202"}, + {file = "multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1"}, + {file = "multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3"}, + {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d"}, + {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6"}, + {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7"}, + {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb"}, + {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f"}, + {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f"}, + {file = "multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885"}, + {file = "multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c"}, + {file = "multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000"}, + {file = "multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63"}, + {file = "multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718"}, + {file = "multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2"}, + {file = "multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e"}, + {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064"}, + {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e"}, + {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd"}, + {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a"}, + {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96"}, + {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e"}, + {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599"}, + {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394"}, + {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38"}, + {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9"}, + {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0"}, + {file = "multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13"}, + {file = "multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd"}, + {file = "multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827"}, + {file = "multidict-6.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:363eb68a0a59bd2303216d2346e6c441ba10d36d1f9969fcb6f1ba700de7bb5c"}, + {file = "multidict-6.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d874eb056410ca05fed180b6642e680373688efafc7f077b2a2f61811e873a40"}, + {file = "multidict-6.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b55d5497b51afdfde55925e04a022f1de14d4f4f25cdfd4f5d9b0aa96166851"}, + {file = "multidict-6.7.0-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f8e5c0031b90ca9ce555e2e8fd5c3b02a25f14989cbc310701823832c99eb687"}, + {file = "multidict-6.7.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cf41880c991716f3c7cec48e2f19ae4045fc9db5fc9cff27347ada24d710bb5"}, + {file = "multidict-6.7.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8cfc12a8630a29d601f48d47787bd7eb730e475e83edb5d6c5084317463373eb"}, + {file = "multidict-6.7.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3996b50c3237c4aec17459217c1e7bbdead9a22a0fcd3c365564fbd16439dde6"}, + {file = "multidict-6.7.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7f5170993a0dd3ab871c74f45c0a21a4e2c37a2f2b01b5f722a2ad9c6650469e"}, + {file = "multidict-6.7.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ec81878ddf0e98817def1e77d4f50dae5ef5b0e4fe796fae3bd674304172416e"}, + {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9281bf5b34f59afbc6b1e477a372e9526b66ca446f4bf62592839c195a718b32"}, + {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:68af405971779d8b37198726f2b6fe3955db846fee42db7a4286fc542203934c"}, + {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3ba3ef510467abb0667421a286dc906e30eb08569365f5cdb131d7aff7c2dd84"}, + {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b61189b29081a20c7e4e0b49b44d5d44bb0dc92be3c6d06a11cc043f81bf9329"}, + {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fb287618b9c7aa3bf8d825f02d9201b2f13078a5ed3b293c8f4d953917d84d5e"}, + {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:521f33e377ff64b96c4c556b81c55d0cfffb96a11c194fd0c3f1e56f3d8dd5a4"}, + {file = "multidict-6.7.0-cp39-cp39-win32.whl", hash = "sha256:ce8fdc2dca699f8dbf055a61d73eaa10482569ad20ee3c36ef9641f69afa8c91"}, + {file = "multidict-6.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:7e73299c99939f089dd9b2120a04a516b95cdf8c1cd2b18c53ebf0de80b1f18f"}, + {file = "multidict-6.7.0-cp39-cp39-win_arm64.whl", hash = "sha256:6bdce131e14b04fd34a809b6380dbfd826065c3e2fe8a50dbae659fa0c390546"}, + {file = "multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3"}, + {file = "multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5"}, ] [package.dependencies] typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} +[[package]] +name = "mypy" +version = "1.19.0" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "mypy-1.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6148ede033982a8c5ca1143de34c71836a09f105068aaa8b7d5edab2b053e6c8"}, + {file = "mypy-1.19.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a9ac09e52bb0f7fb912f5d2a783345c72441a08ef56ce3e17c1752af36340a39"}, + {file = "mypy-1.19.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11f7254c15ab3f8ed68f8e8f5cbe88757848df793e31c36aaa4d4f9783fd08ab"}, + {file = "mypy-1.19.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318ba74f75899b0e78b847d8c50821e4c9637c79d9a59680fc1259f29338cb3e"}, + {file = "mypy-1.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cf7d84f497f78b682edd407f14a7b6e1a2212b433eedb054e2081380b7395aa3"}, + {file = "mypy-1.19.0-cp310-cp310-win_amd64.whl", hash = "sha256:c3385246593ac2b97f155a0e9639be906e73534630f663747c71908dfbf26134"}, + {file = "mypy-1.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a31e4c28e8ddb042c84c5e977e28a21195d086aaffaf08b016b78e19c9ef8106"}, + {file = "mypy-1.19.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34ec1ac66d31644f194b7c163d7f8b8434f1b49719d403a5d26c87fff7e913f7"}, + {file = "mypy-1.19.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cb64b0ba5980466a0f3f9990d1c582bcab8db12e29815ecb57f1408d99b4bff7"}, + {file = "mypy-1.19.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:120cffe120cca5c23c03c77f84abc0c14c5d2e03736f6c312480020082f1994b"}, + {file = "mypy-1.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7a500ab5c444268a70565e374fc803972bfd1f09545b13418a5174e29883dab7"}, + {file = "mypy-1.19.0-cp311-cp311-win_amd64.whl", hash = "sha256:c14a98bc63fd867530e8ec82f217dae29d0550c86e70debc9667fff1ec83284e"}, + {file = "mypy-1.19.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0fb3115cb8fa7c5f887c8a8d81ccdcb94cff334684980d847e5a62e926910e1d"}, + {file = "mypy-1.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3e19e3b897562276bb331074d64c076dbdd3e79213f36eed4e592272dabd760"}, + {file = "mypy-1.19.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9d491295825182fba01b6ffe2c6fe4e5a49dbf4e2bb4d1217b6ced3b4797bc6"}, + {file = "mypy-1.19.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6016c52ab209919b46169651b362068f632efcd5eb8ef9d1735f6f86da7853b2"}, + {file = "mypy-1.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f188dcf16483b3e59f9278c4ed939ec0254aa8a60e8fc100648d9ab5ee95a431"}, + {file = "mypy-1.19.0-cp312-cp312-win_amd64.whl", hash = "sha256:0e3c3d1e1d62e678c339e7ade72746a9e0325de42cd2cccc51616c7b2ed1a018"}, + {file = "mypy-1.19.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7686ed65dbabd24d20066f3115018d2dce030d8fa9db01aa9f0a59b6813e9f9e"}, + {file = "mypy-1.19.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fd4a985b2e32f23bead72e2fb4bbe5d6aceee176be471243bd831d5b2644672d"}, + {file = "mypy-1.19.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc51a5b864f73a3a182584b1ac75c404396a17eced54341629d8bdcb644a5bba"}, + {file = "mypy-1.19.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37af5166f9475872034b56c5efdcf65ee25394e9e1d172907b84577120714364"}, + {file = "mypy-1.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:510c014b722308c9bd377993bcbf9a07d7e0692e5fa8fc70e639c1eb19fc6bee"}, + {file = "mypy-1.19.0-cp313-cp313-win_amd64.whl", hash = "sha256:cabbee74f29aa9cd3b444ec2f1e4fa5a9d0d746ce7567a6a609e224429781f53"}, + {file = "mypy-1.19.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f2e36bed3c6d9b5f35d28b63ca4b727cb0228e480826ffc8953d1892ddc8999d"}, + {file = "mypy-1.19.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a18d8abdda14035c5718acb748faec09571432811af129bf0d9e7b2d6699bf18"}, + {file = "mypy-1.19.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75e60aca3723a23511948539b0d7ed514dda194bc3755eae0bfc7a6b4887aa7"}, + {file = "mypy-1.19.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f44f2ae3c58421ee05fe609160343c25f70e3967f6e32792b5a78006a9d850f"}, + {file = "mypy-1.19.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:63ea6a00e4bd6822adbfc75b02ab3653a17c02c4347f5bb0cf1d5b9df3a05835"}, + {file = "mypy-1.19.0-cp314-cp314-win_amd64.whl", hash = "sha256:3ad925b14a0bb99821ff6f734553294aa6a3440a8cb082fe1f5b84dfb662afb1"}, + {file = "mypy-1.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0dde5cb375cb94deff0d4b548b993bec52859d1651e073d63a1386d392a95495"}, + {file = "mypy-1.19.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1cf9c59398db1c68a134b0b5354a09a1e124523f00bacd68e553b8bd16ff3299"}, + {file = "mypy-1.19.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3210d87b30e6af9c8faed61be2642fcbe60ef77cec64fa1ef810a630a4cf671c"}, + {file = "mypy-1.19.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2c1101ab41d01303103ab6ef82cbbfedb81c1a060c868fa7cc013d573d37ab5"}, + {file = "mypy-1.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ea4fd21bb48f0da49e6d3b37ef6bd7e8228b9fe41bbf4d80d9364d11adbd43c"}, + {file = "mypy-1.19.0-cp39-cp39-win_amd64.whl", hash = "sha256:16f76ff3f3fd8137aadf593cb4607d82634fca675e8211ad75c43d86033ee6c6"}, + {file = "mypy-1.19.0-py3-none-any.whl", hash = "sha256:0c01c99d626380752e527d5ce8e69ffbba2046eb8a060db0329690849cf9b6f9"}, + {file = "mypy-1.19.0.tar.gz", hash = "sha256:f6b874ca77f733222641e5c46e4711648c4037ea13646fd0cdc814c2eaec2528"}, +] + +[package.dependencies] +librt = ">=0.6.2" +mypy_extensions = ">=1.0.0" +pathspec = ">=0.9.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing_extensions = ">=4.6.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +faster-cache = ["orjson"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +description = "Node.js virtual environment builder" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] +files = [ + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, +] + [[package]] name = "nostr-sdk" version = "0.42.1" @@ -1894,29 +2415,56 @@ version = "25.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, ] [[package]] -name = "passlib" -version = "1.7.4" -description = "comprehensive password hashing framework supporting over 30 schemes" +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." optional = false -python-versions = "*" -groups = ["main"] +python-versions = ">=3.8" +groups = ["dev"] files = [ - {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"}, - {file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"}, + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "platformdirs" +version = "4.5.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3"}, + {file = "platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312"}, ] [package.extras] -argon2 = ["argon2-cffi (>=18.2.0)"] -bcrypt = ["bcrypt (>=3.1.0)"] -build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"] -totp = ["cryptography"] +docs = ["furo (>=2025.9.25)", "proselint (>=0.14)", "sphinx (>=8.2.3)", "sphinx-autodoc-typehints (>=3.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.4.2)", "pytest-cov (>=7)", "pytest-mock (>=3.15.1)"] +type = ["mypy (>=1.18.2)"] + +[[package]] +name = "pluggy" +version = "1.6.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, + {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["coverage", "pytest", "pytest-benchmark"] [[package]] name = "ply" @@ -1930,133 +2478,176 @@ files = [ {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, ] +[[package]] +name = "pre-commit" +version = "4.5.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "pre_commit-4.5.0-py2.py3-none-any.whl", hash = "sha256:25e2ce09595174d9c97860a95609f9f852c0614ba602de3561e267547f2335e1"}, + {file = "pre_commit-4.5.0.tar.gz", hash = "sha256:dc5a065e932b19fc1d4c653c6939068fe54325af8e741e74e88db4d28a4dd66b"}, +] + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + [[package]] name = "propcache" -version = "0.3.2" +version = "0.4.1" description = "Accelerated property cache" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "propcache-0.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:22d9962a358aedbb7a2e36187ff273adeaab9743373a272976d2e348d08c7770"}, - {file = "propcache-0.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d0fda578d1dc3f77b6b5a5dce3b9ad69a8250a891760a548df850a5e8da87f3"}, - {file = "propcache-0.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3def3da3ac3ce41562d85db655d18ebac740cb3fa4367f11a52b3da9d03a5cc3"}, - {file = "propcache-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bec58347a5a6cebf239daba9bda37dffec5b8d2ce004d9fe4edef3d2815137e"}, - {file = "propcache-0.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ffda449a507e9fbd4aca1a7d9aa6753b07d6166140e5a18d2ac9bc49eac220"}, - {file = "propcache-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a67fb39229a8a8491dd42f864e5e263155e729c2e7ff723d6e25f596b1e8cb"}, - {file = "propcache-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da1cf97b92b51253d5b68cf5a2b9e0dafca095e36b7f2da335e27dc6172a614"}, - {file = "propcache-0.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f559e127134b07425134b4065be45b166183fdcb433cb6c24c8e4149056ad50"}, - {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aff2e4e06435d61f11a428360a932138d0ec288b0a31dd9bd78d200bd4a2b339"}, - {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4927842833830942a5d0a56e6f4839bc484785b8e1ce8d287359794818633ba0"}, - {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6107ddd08b02654a30fb8ad7a132021759d750a82578b94cd55ee2772b6ebea2"}, - {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:70bd8b9cd6b519e12859c99f3fc9a93f375ebd22a50296c3a295028bea73b9e7"}, - {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2183111651d710d3097338dd1893fcf09c9f54e27ff1a8795495a16a469cc90b"}, - {file = "propcache-0.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fb075ad271405dcad8e2a7ffc9a750a3bf70e533bd86e89f0603e607b93aa64c"}, - {file = "propcache-0.3.2-cp310-cp310-win32.whl", hash = "sha256:404d70768080d3d3bdb41d0771037da19d8340d50b08e104ca0e7f9ce55fce70"}, - {file = "propcache-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:7435d766f978b4ede777002e6b3b6641dd229cd1da8d3d3106a45770365f9ad9"}, - {file = "propcache-0.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b8d2f607bd8f80ddc04088bc2a037fdd17884a6fcadc47a96e334d72f3717be"}, - {file = "propcache-0.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06766d8f34733416e2e34f46fea488ad5d60726bb9481d3cddf89a6fa2d9603f"}, - {file = "propcache-0.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2dc1f4a1df4fecf4e6f68013575ff4af84ef6f478fe5344317a65d38a8e6dc9"}, - {file = "propcache-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be29c4f4810c5789cf10ddf6af80b041c724e629fa51e308a7a0fb19ed1ef7bf"}, - {file = "propcache-0.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d61f6970ecbd8ff2e9360304d5c8876a6abd4530cb752c06586849ac8a9dc9"}, - {file = "propcache-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62180e0b8dbb6b004baec00a7983e4cc52f5ada9cd11f48c3528d8cfa7b96a66"}, - {file = "propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c144ca294a204c470f18cf4c9d78887810d04a3e2fbb30eea903575a779159df"}, - {file = "propcache-0.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5c2a784234c28854878d68978265617aa6dc0780e53d44b4d67f3651a17a9a2"}, - {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5745bc7acdafa978ca1642891b82c19238eadc78ba2aaa293c6863b304e552d7"}, - {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c0075bf773d66fa8c9d41f66cc132ecc75e5bb9dd7cce3cfd14adc5ca184cb95"}, - {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5f57aa0847730daceff0497f417c9de353c575d8da3579162cc74ac294c5369e"}, - {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:eef914c014bf72d18efb55619447e0aecd5fb7c2e3fa7441e2e5d6099bddff7e"}, - {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a4092e8549031e82facf3decdbc0883755d5bbcc62d3aea9d9e185549936dcf"}, - {file = "propcache-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85871b050f174bc0bfb437efbdb68aaf860611953ed12418e4361bc9c392749e"}, - {file = "propcache-0.3.2-cp311-cp311-win32.whl", hash = "sha256:36c8d9b673ec57900c3554264e630d45980fd302458e4ac801802a7fd2ef7897"}, - {file = "propcache-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53af8cb6a781b02d2ea079b5b853ba9430fcbe18a8e3ce647d5982a3ff69f39"}, - {file = "propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10"}, - {file = "propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154"}, - {file = "propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615"}, - {file = "propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db"}, - {file = "propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1"}, - {file = "propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c"}, - {file = "propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67"}, - {file = "propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b"}, - {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8"}, - {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251"}, - {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474"}, - {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535"}, - {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06"}, - {file = "propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1"}, - {file = "propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1"}, - {file = "propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c"}, - {file = "propcache-0.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ca592ed634a73ca002967458187109265e980422116c0a107cf93d81f95af945"}, - {file = "propcache-0.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ecb0aad4020e275652ba3975740f241bd12a61f1a784df044cf7477a02bc252"}, - {file = "propcache-0.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f08f1cc28bd2eade7a8a3d2954ccc673bb02062e3e7da09bc75d843386b342f"}, - {file = "propcache-0.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1a342c834734edb4be5ecb1e9fb48cb64b1e2320fccbd8c54bf8da8f2a84c33"}, - {file = "propcache-0.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a544caaae1ac73f1fecfae70ded3e93728831affebd017d53449e3ac052ac1e"}, - {file = "propcache-0.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310d11aa44635298397db47a3ebce7db99a4cc4b9bbdfcf6c98a60c8d5261cf1"}, - {file = "propcache-0.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1396592321ac83157ac03a2023aa6cc4a3cc3cfdecb71090054c09e5a7cce3"}, - {file = "propcache-0.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cabf5b5902272565e78197edb682017d21cf3b550ba0460ee473753f28d23c1"}, - {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0a2f2235ac46a7aa25bdeb03a9e7060f6ecbd213b1f9101c43b3090ffb971ef6"}, - {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:92b69e12e34869a6970fd2f3da91669899994b47c98f5d430b781c26f1d9f387"}, - {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:54e02207c79968ebbdffc169591009f4474dde3b4679e16634d34c9363ff56b4"}, - {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4adfb44cb588001f68c5466579d3f1157ca07f7504fc91ec87862e2b8e556b88"}, - {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fd3e6019dc1261cd0291ee8919dd91fbab7b169bb76aeef6c716833a3f65d206"}, - {file = "propcache-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4c181cad81158d71c41a2bce88edce078458e2dd5ffee7eddd6b05da85079f43"}, - {file = "propcache-0.3.2-cp313-cp313-win32.whl", hash = "sha256:8a08154613f2249519e549de2330cf8e2071c2887309a7b07fb56098f5170a02"}, - {file = "propcache-0.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e41671f1594fc4ab0a6dec1351864713cb3a279910ae8b58f884a88a0a632c05"}, - {file = "propcache-0.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:9a3cf035bbaf035f109987d9d55dc90e4b0e36e04bbbb95af3055ef17194057b"}, - {file = "propcache-0.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:156c03d07dc1323d8dacaa221fbe028c5c70d16709cdd63502778e6c3ccca1b0"}, - {file = "propcache-0.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74413c0ba02ba86f55cf60d18daab219f7e531620c15f1e23d95563f505efe7e"}, - {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f066b437bb3fa39c58ff97ab2ca351db465157d68ed0440abecb21715eb24b28"}, - {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1304b085c83067914721e7e9d9917d41ad87696bf70f0bc7dee450e9c71ad0a"}, - {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab50cef01b372763a13333b4e54021bdcb291fc9a8e2ccb9c2df98be51bcde6c"}, - {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad3b2a085ec259ad2c2842666b2a0a49dea8463579c606426128925af1ed725"}, - {file = "propcache-0.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:261fa020c1c14deafd54c76b014956e2f86991af198c51139faf41c4d5e83892"}, - {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:46d7f8aa79c927e5f987ee3a80205c987717d3659f035c85cf0c3680526bdb44"}, - {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:6d8f3f0eebf73e3c0ff0e7853f68be638b4043c65a70517bb575eff54edd8dbe"}, - {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:03c89c1b14a5452cf15403e291c0ccd7751d5b9736ecb2c5bab977ad6c5bcd81"}, - {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0cc17efde71e12bbaad086d679ce575268d70bc123a5a71ea7ad76f70ba30bba"}, - {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:acdf05d00696bc0447e278bb53cb04ca72354e562cf88ea6f9107df8e7fd9770"}, - {file = "propcache-0.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4445542398bd0b5d32df908031cb1b30d43ac848e20470a878b770ec2dcc6330"}, - {file = "propcache-0.3.2-cp313-cp313t-win32.whl", hash = "sha256:f86e5d7cd03afb3a1db8e9f9f6eff15794e79e791350ac48a8c924e6f439f394"}, - {file = "propcache-0.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9704bedf6e7cbe3c65eca4379a9b53ee6a83749f047808cbb5044d40d7d72198"}, - {file = "propcache-0.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a7fad897f14d92086d6b03fdd2eb844777b0c4d7ec5e3bac0fbae2ab0602bbe5"}, - {file = "propcache-0.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1f43837d4ca000243fd7fd6301947d7cb93360d03cd08369969450cc6b2ce3b4"}, - {file = "propcache-0.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:261df2e9474a5949c46e962065d88eb9b96ce0f2bd30e9d3136bcde84befd8f2"}, - {file = "propcache-0.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e514326b79e51f0a177daab1052bc164d9d9e54133797a3a58d24c9c87a3fe6d"}, - {file = "propcache-0.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4a996adb6904f85894570301939afeee65f072b4fd265ed7e569e8d9058e4ec"}, - {file = "propcache-0.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76cace5d6b2a54e55b137669b30f31aa15977eeed390c7cbfb1dafa8dfe9a701"}, - {file = "propcache-0.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31248e44b81d59d6addbb182c4720f90b44e1efdc19f58112a3c3a1615fb47ef"}, - {file = "propcache-0.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abb7fa19dbf88d3857363e0493b999b8011eea856b846305d8c0512dfdf8fbb1"}, - {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d81ac3ae39d38588ad0549e321e6f773a4e7cc68e7751524a22885d5bbadf886"}, - {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:cc2782eb0f7a16462285b6f8394bbbd0e1ee5f928034e941ffc444012224171b"}, - {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:db429c19a6c7e8a1c320e6a13c99799450f411b02251fb1b75e6217cf4a14fcb"}, - {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:21d8759141a9e00a681d35a1f160892a36fb6caa715ba0b832f7747da48fb6ea"}, - {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2ca6d378f09adb13837614ad2754fa8afaee330254f404299611bce41a8438cb"}, - {file = "propcache-0.3.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:34a624af06c048946709f4278b4176470073deda88d91342665d95f7c6270fbe"}, - {file = "propcache-0.3.2-cp39-cp39-win32.whl", hash = "sha256:4ba3fef1c30f306b1c274ce0b8baaa2c3cdd91f645c48f06394068f37d3837a1"}, - {file = "propcache-0.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:7a2368eed65fc69a7a7a40b27f22e85e7627b74216f0846b04ba5c116e191ec9"}, - {file = "propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f"}, - {file = "propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168"}, + {file = "propcache-0.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db"}, + {file = "propcache-0.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8"}, + {file = "propcache-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925"}, + {file = "propcache-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21"}, + {file = "propcache-0.4.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5"}, + {file = "propcache-0.4.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db"}, + {file = "propcache-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7"}, + {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4"}, + {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60"}, + {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f"}, + {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900"}, + {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c"}, + {file = "propcache-0.4.1-cp310-cp310-win32.whl", hash = "sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb"}, + {file = "propcache-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37"}, + {file = "propcache-0.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581"}, + {file = "propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf"}, + {file = "propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5"}, + {file = "propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e"}, + {file = "propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566"}, + {file = "propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165"}, + {file = "propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc"}, + {file = "propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f"}, + {file = "propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1"}, + {file = "propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6"}, + {file = "propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239"}, + {file = "propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2"}, + {file = "propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403"}, + {file = "propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207"}, + {file = "propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72"}, + {file = "propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367"}, + {file = "propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4"}, + {file = "propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75"}, + {file = "propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8"}, + {file = "propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db"}, + {file = "propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1"}, + {file = "propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf"}, + {file = "propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311"}, + {file = "propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74"}, + {file = "propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe"}, + {file = "propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af"}, + {file = "propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c"}, + {file = "propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f"}, + {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1"}, + {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24"}, + {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa"}, + {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61"}, + {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66"}, + {file = "propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81"}, + {file = "propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e"}, + {file = "propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1"}, + {file = "propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b"}, + {file = "propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566"}, + {file = "propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835"}, + {file = "propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e"}, + {file = "propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859"}, + {file = "propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b"}, + {file = "propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0"}, + {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af"}, + {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393"}, + {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874"}, + {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7"}, + {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1"}, + {file = "propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717"}, + {file = "propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37"}, + {file = "propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a"}, + {file = "propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12"}, + {file = "propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c"}, + {file = "propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded"}, + {file = "propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641"}, + {file = "propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4"}, + {file = "propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44"}, + {file = "propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d"}, + {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b"}, + {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e"}, + {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f"}, + {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49"}, + {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144"}, + {file = "propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f"}, + {file = "propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153"}, + {file = "propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992"}, + {file = "propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f"}, + {file = "propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393"}, + {file = "propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0"}, + {file = "propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a"}, + {file = "propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be"}, + {file = "propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc"}, + {file = "propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a"}, + {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89"}, + {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726"}, + {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367"}, + {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36"}, + {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455"}, + {file = "propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85"}, + {file = "propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1"}, + {file = "propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9"}, + {file = "propcache-0.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff"}, + {file = "propcache-0.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb"}, + {file = "propcache-0.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac"}, + {file = "propcache-0.4.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888"}, + {file = "propcache-0.4.1-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc"}, + {file = "propcache-0.4.1-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a"}, + {file = "propcache-0.4.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88"}, + {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00"}, + {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0"}, + {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e"}, + {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781"}, + {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183"}, + {file = "propcache-0.4.1-cp39-cp39-win32.whl", hash = "sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19"}, + {file = "propcache-0.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f"}, + {file = "propcache-0.4.1-cp39-cp39-win_arm64.whl", hash = "sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938"}, + {file = "propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237"}, + {file = "propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d"}, ] [[package]] name = "protobuf" -version = "5.29.1" +version = "5.29.5" description = "" optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "protobuf-5.29.1-cp310-abi3-win32.whl", hash = "sha256:22c1f539024241ee545cbcb00ee160ad1877975690b16656ff87dde107b5f110"}, - {file = "protobuf-5.29.1-cp310-abi3-win_amd64.whl", hash = "sha256:1fc55267f086dd4050d18ef839d7bd69300d0d08c2a53ca7df3920cc271a3c34"}, - {file = "protobuf-5.29.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:d473655e29c0c4bbf8b69e9a8fb54645bc289dead6d753b952e7aa660254ae18"}, - {file = "protobuf-5.29.1-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5ba1d0e4c8a40ae0496d0e2ecfdbb82e1776928a205106d14ad6985a09ec155"}, - {file = "protobuf-5.29.1-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:8ee1461b3af56145aca2800e6a3e2f928108c749ba8feccc6f5dd0062c410c0d"}, - {file = "protobuf-5.29.1-cp38-cp38-win32.whl", hash = "sha256:50879eb0eb1246e3a5eabbbe566b44b10348939b7cc1b267567e8c3d07213853"}, - {file = "protobuf-5.29.1-cp38-cp38-win_amd64.whl", hash = "sha256:027fbcc48cea65a6b17028510fdd054147057fa78f4772eb547b9274e5219331"}, - {file = "protobuf-5.29.1-cp39-cp39-win32.whl", hash = "sha256:5a41deccfa5e745cef5c65a560c76ec0ed8e70908a67cc8f4da5fce588b50d57"}, - {file = "protobuf-5.29.1-cp39-cp39-win_amd64.whl", hash = "sha256:012ce28d862ff417fd629285aca5d9772807f15ceb1a0dbd15b88f58c776c98c"}, - {file = "protobuf-5.29.1-py3-none-any.whl", hash = "sha256:32600ddb9c2a53dedc25b8581ea0f1fd8ea04956373c0c07577ce58d312522e0"}, - {file = "protobuf-5.29.1.tar.gz", hash = "sha256:683be02ca21a6ffe80db6dd02c0b5b2892322c59ca57fd6c872d652cb80549cb"}, + {file = "protobuf-5.29.5-cp310-abi3-win32.whl", hash = "sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079"}, + {file = "protobuf-5.29.5-cp310-abi3-win_amd64.whl", hash = "sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc"}, + {file = "protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671"}, + {file = "protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015"}, + {file = "protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61"}, + {file = "protobuf-5.29.5-cp38-cp38-win32.whl", hash = "sha256:ef91363ad4faba7b25d844ef1ada59ff1604184c0bcd8b39b8a6bef15e1af238"}, + {file = "protobuf-5.29.5-cp38-cp38-win_amd64.whl", hash = "sha256:7318608d56b6402d2ea7704ff1e1e4597bee46d760e7e4dd42a3d45e24b87f2e"}, + {file = "protobuf-5.29.5-cp39-cp39-win32.whl", hash = "sha256:6f642dc9a61782fa72b90878af134c5afe1917c89a568cd3476d758d3c3a0736"}, + {file = "protobuf-5.29.5-cp39-cp39-win_amd64.whl", hash = "sha256:470f3af547ef17847a28e1f47200a1cbf0ba3ff57b7de50d22776607cd2ea353"}, + {file = "protobuf-5.29.5-py3-none-any.whl", hash = "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5"}, + {file = "protobuf-5.29.5.tar.gz", hash = "sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84"}, ] [[package]] @@ -2140,55 +2731,62 @@ files = [ [[package]] name = "pydantic" -version = "1.10.18" +version = "1.10.22" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"}, - {file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"}, - {file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"}, - {file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"}, - {file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"}, - {file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"}, - {file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"}, - {file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"}, - {file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"}, - {file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"}, - {file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"}, - {file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"}, - {file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"}, - {file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"}, - {file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"}, - {file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"}, - {file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"}, - {file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"}, - {file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"}, - {file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"}, - {file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"}, - {file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"}, - {file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"}, - {file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"}, - {file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"}, - {file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"}, - {file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"}, + {file = "pydantic-1.10.22-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:57889565ccc1e5b7b73343329bbe6198ebc472e3ee874af2fa1865cfe7048228"}, + {file = "pydantic-1.10.22-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90729e22426de79bc6a3526b4c45ec4400caf0d4f10d7181ba7f12c01bb3897d"}, + {file = "pydantic-1.10.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8684d347f351554ec94fdcb507983d3116dc4577fb8799fed63c65869a2d10"}, + {file = "pydantic-1.10.22-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8dad498ceff2d9ef1d2e2bc6608f5b59b8e1ba2031759b22dfb8c16608e1802"}, + {file = "pydantic-1.10.22-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fac529cc654d4575cf8de191cce354b12ba705f528a0a5c654de6d01f76cd818"}, + {file = "pydantic-1.10.22-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4148232aded8dd1dd13cf910a01b32a763c34bd79a0ab4d1ee66164fcb0b7b9d"}, + {file = "pydantic-1.10.22-cp310-cp310-win_amd64.whl", hash = "sha256:ece68105d9e436db45d8650dc375c760cc85a6793ae019c08769052902dca7db"}, + {file = "pydantic-1.10.22-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e530a8da353f791ad89e701c35787418605d35085f4bdda51b416946070e938"}, + {file = "pydantic-1.10.22-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:654322b85642e9439d7de4c83cb4084ddd513df7ff8706005dada43b34544946"}, + {file = "pydantic-1.10.22-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8bece75bd1b9fc1c32b57a32831517943b1159ba18b4ba32c0d431d76a120ae"}, + {file = "pydantic-1.10.22-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eccb58767f13c6963dcf96d02cb8723ebb98b16692030803ac075d2439c07b0f"}, + {file = "pydantic-1.10.22-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7778e6200ff8ed5f7052c1516617423d22517ad36cc7a3aedd51428168e3e5e8"}, + {file = "pydantic-1.10.22-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bffe02767d27c39af9ca7dc7cd479c00dda6346bb62ffc89e306f665108317a2"}, + {file = "pydantic-1.10.22-cp311-cp311-win_amd64.whl", hash = "sha256:23bc19c55427091b8e589bc08f635ab90005f2dc99518f1233386f46462c550a"}, + {file = "pydantic-1.10.22-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:92d0f97828a075a71d9efc65cf75db5f149b4d79a38c89648a63d2932894d8c9"}, + {file = "pydantic-1.10.22-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af5a2811b6b95b58b829aeac5996d465a5f0c7ed84bd871d603cf8646edf6ff"}, + {file = "pydantic-1.10.22-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cf06d8d40993e79af0ab2102ef5da77b9ddba51248e4cb27f9f3f591fbb096e"}, + {file = "pydantic-1.10.22-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:184b7865b171a6057ad97f4a17fbac81cec29bd103e996e7add3d16b0d95f609"}, + {file = "pydantic-1.10.22-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:923ad861677ab09d89be35d36111156063a7ebb44322cdb7b49266e1adaba4bb"}, + {file = "pydantic-1.10.22-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:82d9a3da1686443fb854c8d2ab9a473251f8f4cdd11b125522efb4d7c646e7bc"}, + {file = "pydantic-1.10.22-cp312-cp312-win_amd64.whl", hash = "sha256:1612604929af4c602694a7f3338b18039d402eb5ddfbf0db44f1ebfaf07f93e7"}, + {file = "pydantic-1.10.22-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b259dc89c9abcd24bf42f31951fb46c62e904ccf4316393f317abeeecda39978"}, + {file = "pydantic-1.10.22-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9238aa0964d80c0908d2f385e981add58faead4412ca80ef0fa352094c24e46d"}, + {file = "pydantic-1.10.22-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f8029f05b04080e3f1a550575a1bca747c0ea4be48e2d551473d47fd768fc1b"}, + {file = "pydantic-1.10.22-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c06918894f119e0431a36c9393bc7cceeb34d1feeb66670ef9b9ca48c073937"}, + {file = "pydantic-1.10.22-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e205311649622ee8fc1ec9089bd2076823797f5cd2c1e3182dc0e12aab835b35"}, + {file = "pydantic-1.10.22-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:815f0a73d5688d6dd0796a7edb9eca7071bfef961a7b33f91e618822ae7345b7"}, + {file = "pydantic-1.10.22-cp313-cp313-win_amd64.whl", hash = "sha256:9dfce71d42a5cde10e78a469e3d986f656afc245ab1b97c7106036f088dd91f8"}, + {file = "pydantic-1.10.22-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3ecaf8177b06aac5d1f442db1288e3b46d9f05f34fd17fdca3ad34105328b61a"}, + {file = "pydantic-1.10.22-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb36c2de9ea74bd7f66b5481dea8032d399affd1cbfbb9bb7ce539437f1fce62"}, + {file = "pydantic-1.10.22-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6b8d14a256be3b8fff9286d76c532f1a7573fbba5f189305b22471c6679854d"}, + {file = "pydantic-1.10.22-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:1c33269e815db4324e71577174c29c7aa30d1bba51340ce6be976f6f3053a4c6"}, + {file = "pydantic-1.10.22-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:8661b3ab2735b2a9ccca2634738534a795f4a10bae3ab28ec0a10c96baa20182"}, + {file = "pydantic-1.10.22-cp37-cp37m-win_amd64.whl", hash = "sha256:22bdd5fe70d4549995981c55b970f59de5c502d5656b2abdfcd0a25be6f3763e"}, + {file = "pydantic-1.10.22-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e3f33d1358aa4bc2795208cc29ff3118aeaad0ea36f0946788cf7cadeccc166b"}, + {file = "pydantic-1.10.22-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:813f079f9cd136cac621f3f9128a4406eb8abd2ad9fdf916a0731d91c6590017"}, + {file = "pydantic-1.10.22-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab618ab8dca6eac7f0755db25f6aba3c22c40e3463f85a1c08dc93092d917704"}, + {file = "pydantic-1.10.22-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d128e1aaa38db88caca920d5822c98fc06516a09a58b6d3d60fa5ea9099b32cc"}, + {file = "pydantic-1.10.22-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:cc97bbc25def7025e55fc9016080773167cda2aad7294e06a37dda04c7d69ece"}, + {file = "pydantic-1.10.22-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dda5d7157d543b1fa565038cae6e952549d0f90071c839b3740fb77c820fab8"}, + {file = "pydantic-1.10.22-cp38-cp38-win_amd64.whl", hash = "sha256:a093fe44fe518cb445d23119511a71f756f8503139d02fcdd1173f7b76c95ffe"}, + {file = "pydantic-1.10.22-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ec54c89b2568b258bb30d7348ac4d82bec1b58b377fb56a00441e2ac66b24587"}, + {file = "pydantic-1.10.22-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d8f1d1a1532e4f3bcab4e34e8d2197a7def4b67072acd26cfa60e92d75803a48"}, + {file = "pydantic-1.10.22-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ad83ca35508c27eae1005b6b61f369f78aae6d27ead2135ec156a2599910121"}, + {file = "pydantic-1.10.22-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53cdb44b78c420f570ff16b071ea8cd5a477635c6b0efc343c8a91e3029bbf1a"}, + {file = "pydantic-1.10.22-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:16d0a5ae9d98264186ce31acdd7686ec05fd331fab9d68ed777d5cb2d1514e5e"}, + {file = "pydantic-1.10.22-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8aee040e25843f036192b1a1af62117504a209a043aa8db12e190bb86ad7e611"}, + {file = "pydantic-1.10.22-cp39-cp39-win_amd64.whl", hash = "sha256:7f691eec68dbbfca497d3c11b92a3e5987393174cbedf03ec7a4184c35c2def6"}, + {file = "pydantic-1.10.22-py3-none-any.whl", hash = "sha256:343037d608bcbd34df937ac259708bfc83664dadf88afe8516c4f282d7d471a9"}, + {file = "pydantic-1.10.22.tar.gz", hash = "sha256:ee1006cebd43a8e7158fb7190bb8f4e2da9649719bff65d0c287282ec38dec6d"}, ] [package.dependencies] @@ -2205,7 +2803,7 @@ version = "2.19.2" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, @@ -2262,14 +2860,14 @@ pyln-proto = ">=23" [[package]] name = "pyln-proto" -version = "25.9" +version = "25.9.3" description = "This package implements some of the Lightning Network protocol in pure python. It is intended for protocol testing and some minor tooling only. It is not deemed secure enough to handle any amount of real funds (you have been warned!)." optional = false python-versions = "<4.0,>=3.8" groups = ["main"] files = [ - {file = "pyln_proto-25.9-py3-none-any.whl", hash = "sha256:41965d96b7fe62323cb6b2fe8953d82f004a2a06ba1c009f91cd5e899ed5575e"}, - {file = "pyln_proto-25.9.tar.gz", hash = "sha256:df309cf715e92049bb82cc0db994060c7313f545cf62f4ae252a04a810067c57"}, + {file = "pyln_proto-25.9.3-py3-none-any.whl", hash = "sha256:c550bc0ae3abed09c1c9a03c2780e151cde9480afa7875da6526ce936ac71876"}, + {file = "pyln_proto-25.9.3.tar.gz", hash = "sha256:beb56848b569e7a2dba15de18650d9909a5198b05c73bc99aed7d04435f3cbc4"}, ] [package.dependencies] @@ -2331,6 +2929,66 @@ files = [ {file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"}, ] +[[package]] +name = "pytest" +version = "9.0.1" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "pytest-9.0.1-py3-none-any.whl", hash = "sha256:67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad"}, + {file = "pytest-9.0.1.tar.gz", hash = "sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8"}, +] + +[package.dependencies] +colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} +iniconfig = ">=1.0.1" +packaging = ">=22" +pluggy = ">=1.5,<2" +pygments = ">=2.7.2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-asyncio" +version = "1.3.0" +description = "Pytest support for asyncio" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5"}, + {file = "pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5"}, +] + +[package.dependencies] +backports-asyncio-runner = {version = ">=1.1,<2", markers = "python_version < \"3.11\""} +pytest = ">=8.2,<10" +typing-extensions = {version = ">=4.12", markers = "python_version < \"3.13\""} + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] + +[[package]] +name = "pytest-md" +version = "0.2.0" +description = "Plugin for generating Markdown reports for pytest results" +optional = false +python-versions = ">=3.6" +groups = ["dev"] +files = [ + {file = "pytest-md-0.2.0.tar.gz", hash = "sha256:3b248d5b360ea5198e05b4f49c7442234812809a63137ec6cdd3643a40cf0112"}, + {file = "pytest_md-0.2.0-py3-none-any.whl", hash = "sha256:4c4cd16fea6d1485e87ee254558712c804a96d2aa9674b780e7eb8fb6526e1d1"}, +] + +[package.dependencies] +pytest = ">=4.2.1" + [[package]] name = "python-crontab" version = "3.2.0" @@ -2367,14 +3025,14 @@ six = ">=1.5" [[package]] name = "python-dotenv" -version = "1.1.1" +version = "1.2.1" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc"}, - {file = "python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab"}, + {file = "python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61"}, + {file = "python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6"}, ] [package.extras] @@ -2392,6 +3050,21 @@ files = [ {file = "python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13"}, ] +[[package]] +name = "pytokens" +version = "0.3.0" +description = "A Fast, spec compliant Python 3.14+ tokenizer that runs on older Pythons." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pytokens-0.3.0-py3-none-any.whl", hash = "sha256:95b2b5eaf832e469d141a378872480ede3f251a5a5041b8ec6e581d3ac71bbf3"}, + {file = "pytokens-0.3.0.tar.gz", hash = "sha256:2f932b14ed08de5fcf0b391ace2642f858f1394c0857202959000b68ed7a458a"}, +] + +[package.extras] +dev = ["black", "build", "mypy", "pytest", "pytest-cov", "setuptools", "tox", "twine", "wheel"] + [[package]] name = "pywebpush" version = "2.0.3" @@ -2415,6 +3088,89 @@ six = ">=1.15.0" [package.extras] dev = ["black", "mock", "pytest"] +[[package]] +name = "pyyaml" +version = "6.0.3" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"}, + {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"}, + {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"}, + {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"}, + {file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"}, + {file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"}, + {file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"}, + {file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"}, + {file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"}, + {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"}, + {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"}, + {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"}, + {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"}, + {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"}, + {file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"}, + {file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"}, + {file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"}, + {file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"}, + {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"}, + {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"}, + {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"}, + {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"}, + {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"}, + {file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"}, + {file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"}, + {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"}, + {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"}, + {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"}, + {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"}, + {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"}, + {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"}, + {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"}, + {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"}, + {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"}, + {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"}, + {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"}, + {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"}, + {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"}, + {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"}, + {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"}, + {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"}, + {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"}, + {file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"}, + {file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"}, + {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"}, + {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"}, + {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"}, + {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"}, + {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"}, + {file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"}, + {file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"}, + {file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"}, + {file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"}, + {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"}, + {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"}, + {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"}, + {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"}, + {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"}, + {file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"}, + {file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"}, + {file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"}, + {file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"}, + {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"}, + {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"}, + {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"}, + {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"}, + {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"}, + {file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"}, + {file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"}, + {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}, +] + [[package]] name = "requests" version = "2.32.5" @@ -2439,14 +3195,14 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "14.1.0" +version = "14.2.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" groups = ["main"] files = [ - {file = "rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f"}, - {file = "rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8"}, + {file = "rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd"}, + {file = "rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4"}, ] [package.dependencies] @@ -2456,6 +3212,35 @@ pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "ruff" +version = "0.14.7" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "ruff-0.14.7-py3-none-linux_armv6l.whl", hash = "sha256:b9d5cb5a176c7236892ad7224bc1e63902e4842c460a0b5210701b13e3de4fca"}, + {file = "ruff-0.14.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3f64fe375aefaf36ca7d7250292141e39b4cea8250427482ae779a2aa5d90015"}, + {file = "ruff-0.14.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:93e83bd3a9e1a3bda64cb771c0d47cda0e0d148165013ae2d3554d718632d554"}, + {file = "ruff-0.14.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3838948e3facc59a6070795de2ae16e5786861850f78d5914a03f12659e88f94"}, + {file = "ruff-0.14.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24c8487194d38b6d71cd0fd17a5b6715cda29f59baca1defe1e3a03240f851d1"}, + {file = "ruff-0.14.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79c73db6833f058a4be8ffe4a0913b6d4ad41f6324745179bd2aa09275b01d0b"}, + {file = "ruff-0.14.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:12eb7014fccff10fc62d15c79d8a6be4d0c2d60fe3f8e4d169a0d2def75f5dad"}, + {file = "ruff-0.14.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c623bbdc902de7ff715a93fa3bb377a4e42dd696937bf95669118773dbf0c50"}, + {file = "ruff-0.14.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f53accc02ed2d200fa621593cdb3c1ae06aa9b2c3cae70bc96f72f0000ae97a9"}, + {file = "ruff-0.14.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:281f0e61a23fcdcffca210591f0f53aafaa15f9025b5b3f9706879aaa8683bc4"}, + {file = "ruff-0.14.7-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:dbbaa5e14148965b91cb090236931182ee522a5fac9bc5575bafc5c07b9f9682"}, + {file = "ruff-0.14.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1464b6e54880c0fe2f2d6eaefb6db15373331414eddf89d6b903767ae2458143"}, + {file = "ruff-0.14.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f217ed871e4621ea6128460df57b19ce0580606c23aeab50f5de425d05226784"}, + {file = "ruff-0.14.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6be02e849440ed3602d2eb478ff7ff07d53e3758f7948a2a598829660988619e"}, + {file = "ruff-0.14.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19a0f116ee5e2b468dfe80c41c84e2bbd6b74f7b719bee86c2ecde0a34563bcc"}, + {file = "ruff-0.14.7-py3-none-win32.whl", hash = "sha256:e33052c9199b347c8937937163b9b149ef6ab2e4bb37b042e593da2e6f6cccfa"}, + {file = "ruff-0.14.7-py3-none-win_amd64.whl", hash = "sha256:e17a20ad0d3fad47a326d773a042b924d3ac31c6ca6deb6c72e9e6b5f661a7c6"}, + {file = "ruff-0.14.7-py3-none-win_arm64.whl", hash = "sha256:be4d653d3bea1b19742fcc6502354e32f65cd61ff2fbdb365803ef2c2aec6228"}, + {file = "ruff-0.14.7.tar.gz", hash = "sha256:3417deb75d23bd14a722b57b0a1435561db65f0ad97435b4cf9f85ffcef34ae5"}, +] + [[package]] name = "secp256k1" version = "0.14.0" @@ -2659,18 +3444,19 @@ uvicorn = ["uvicorn (>=0.34.0)"] [[package]] name = "starlette" -version = "0.46.2" +version = "0.47.1" description = "The little ASGI library that shines." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35"}, - {file = "starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5"}, + {file = "starlette-0.47.1-py3-none-any.whl", hash = "sha256:5e11c9f5c7c3f24959edbf2dffdc01bba860228acf657129467d8a7468591527"}, + {file = "starlette-0.47.1.tar.gz", hash = "sha256:aef012dd2b6be325ffa16698f9dc533614fb1cebd593a906b90dc1025529a79b"}, ] [package.dependencies] anyio = ">=3.6.2,<5" +typing-extensions = {version = ">=4.10.0", markers = "python_version < \"3.13\""} [package.extras] full = ["httpx (>=0.27.0,<0.29.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.18)", "pyyaml"] @@ -2686,6 +3472,59 @@ files = [ {file = "tlv8-0.10.0.tar.gz", hash = "sha256:7930a590267b809952272ac2a27ee81b99ec5191fa2eba08050e0daee4262684"}, ] +[[package]] +name = "tomli" +version = "2.3.0" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "python_version == \"3.10\"" +files = [ + {file = "tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45"}, + {file = "tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba"}, + {file = "tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf"}, + {file = "tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441"}, + {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845"}, + {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c"}, + {file = "tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456"}, + {file = "tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be"}, + {file = "tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac"}, + {file = "tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22"}, + {file = "tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f"}, + {file = "tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52"}, + {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8"}, + {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6"}, + {file = "tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876"}, + {file = "tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878"}, + {file = "tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b"}, + {file = "tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae"}, + {file = "tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b"}, + {file = "tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf"}, + {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f"}, + {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05"}, + {file = "tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606"}, + {file = "tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999"}, + {file = "tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e"}, + {file = "tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3"}, + {file = "tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc"}, + {file = "tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0"}, + {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879"}, + {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005"}, + {file = "tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463"}, + {file = "tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8"}, + {file = "tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77"}, + {file = "tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf"}, + {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530"}, + {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b"}, + {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67"}, + {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f"}, + {file = "tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0"}, + {file = "tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba"}, + {file = "tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b"}, + {file = "tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549"}, +] + [[package]] name = "tornado" version = "6.5.2" @@ -2710,14 +3549,14 @@ files = [ [[package]] name = "typer" -version = "0.17.4" +version = "0.20.0" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" groups = ["main"] files = [ - {file = "typer-0.17.4-py3-none-any.whl", hash = "sha256:015534a6edaa450e7007eba705d5c18c3349dcea50a6ad79a5ed530967575824"}, - {file = "typer-0.17.4.tar.gz", hash = "sha256:b77dc07d849312fd2bb5e7f20a7af8985c7ec360c45b051ed5412f64d8dc1580"}, + {file = "typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a"}, + {file = "typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37"}, ] [package.dependencies] @@ -2732,7 +3571,7 @@ version = "4.14.0" description = "Backported and Experimental Type Hints for Python 3.9+" optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af"}, {file = "typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4"}, @@ -2828,6 +3667,28 @@ dev = ["Cython (>=3.0,<4.0)", "setuptools (>=60)"] docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] test = ["aiohttp (>=3.10.5)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] +[[package]] +name = "virtualenv" +version = "20.35.4" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "virtualenv-20.35.4-py3-none-any.whl", hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b"}, + {file = "virtualenv-20.35.4.tar.gz", hash = "sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" +typing-extensions = {version = ">=4.13.2", markers = "python_version < \"3.11\""} + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""] + [[package]] name = "websocket-client" version = "1.8.0" @@ -2942,207 +3803,262 @@ dev = ["black (>=19.3b0) ; python_version >= \"3.6\"", "pytest (>=4.6.2)"] [[package]] name = "wrapt" -version = "1.17.3" +version = "2.0.1" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.8" groups = ["main"] files = [ - {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04"}, - {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2"}, - {file = "wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c"}, - {file = "wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775"}, - {file = "wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd"}, - {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05"}, - {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418"}, - {file = "wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390"}, - {file = "wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6"}, - {file = "wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18"}, - {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7"}, - {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85"}, - {file = "wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f"}, - {file = "wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311"}, - {file = "wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1"}, - {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5"}, - {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2"}, - {file = "wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89"}, - {file = "wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77"}, - {file = "wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a"}, - {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0"}, - {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba"}, - {file = "wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd"}, - {file = "wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828"}, - {file = "wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9"}, - {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396"}, - {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc"}, - {file = "wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe"}, - {file = "wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c"}, - {file = "wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6"}, - {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0"}, - {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77"}, - {file = "wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7"}, - {file = "wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277"}, - {file = "wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d"}, - {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa"}, - {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050"}, - {file = "wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8"}, - {file = "wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb"}, - {file = "wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16"}, - {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39"}, - {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235"}, - {file = "wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c"}, - {file = "wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b"}, - {file = "wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa"}, - {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7"}, - {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4"}, - {file = "wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10"}, - {file = "wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6"}, - {file = "wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58"}, - {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a"}, - {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067"}, - {file = "wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454"}, - {file = "wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e"}, - {file = "wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f"}, - {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056"}, - {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804"}, - {file = "wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977"}, - {file = "wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116"}, - {file = "wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6"}, - {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225"}, - {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a"}, - {file = "wrapt-1.17.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f"}, - {file = "wrapt-1.17.3-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00"}, - {file = "wrapt-1.17.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56"}, - {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5"}, - {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22"}, - {file = "wrapt-1.17.3-cp38-cp38-win32.whl", hash = "sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c"}, - {file = "wrapt-1.17.3-cp38-cp38-win_amd64.whl", hash = "sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2"}, - {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc"}, - {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9"}, - {file = "wrapt-1.17.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d"}, - {file = "wrapt-1.17.3-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a"}, - {file = "wrapt-1.17.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139"}, - {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df"}, - {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b"}, - {file = "wrapt-1.17.3-cp39-cp39-win32.whl", hash = "sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81"}, - {file = "wrapt-1.17.3-cp39-cp39-win_amd64.whl", hash = "sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f"}, - {file = "wrapt-1.17.3-cp39-cp39-win_arm64.whl", hash = "sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f"}, - {file = "wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22"}, - {file = "wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0"}, + {file = "wrapt-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:64b103acdaa53b7caf409e8d45d39a8442fe6dcfec6ba3f3d141e0cc2b5b4dbd"}, + {file = "wrapt-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:91bcc576260a274b169c3098e9a3519fb01f2989f6d3d386ef9cbf8653de1374"}, + {file = "wrapt-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab594f346517010050126fcd822697b25a7031d815bb4fbc238ccbe568216489"}, + {file = "wrapt-2.0.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:36982b26f190f4d737f04a492a68accbfc6fa042c3f42326fdfbb6c5b7a20a31"}, + {file = "wrapt-2.0.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23097ed8bc4c93b7bf36fa2113c6c733c976316ce0ee2c816f64ca06102034ef"}, + {file = "wrapt-2.0.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8bacfe6e001749a3b64db47bcf0341da757c95959f592823a93931a422395013"}, + {file = "wrapt-2.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8ec3303e8a81932171f455f792f8df500fc1a09f20069e5c16bd7049ab4e8e38"}, + {file = "wrapt-2.0.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:3f373a4ab5dbc528a94334f9fe444395b23c2f5332adab9ff4ea82f5a9e33bc1"}, + {file = "wrapt-2.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f49027b0b9503bf6c8cdc297ca55006b80c2f5dd36cecc72c6835ab6e10e8a25"}, + {file = "wrapt-2.0.1-cp310-cp310-win32.whl", hash = "sha256:8330b42d769965e96e01fa14034b28a2a7600fbf7e8f0cc90ebb36d492c993e4"}, + {file = "wrapt-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:1218573502a8235bb8a7ecaed12736213b22dcde9feab115fa2989d42b5ded45"}, + {file = "wrapt-2.0.1-cp310-cp310-win_arm64.whl", hash = "sha256:eda8e4ecd662d48c28bb86be9e837c13e45c58b8300e43ba3c9b4fa9900302f7"}, + {file = "wrapt-2.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0e17283f533a0d24d6e5429a7d11f250a58d28b4ae5186f8f47853e3e70d2590"}, + {file = "wrapt-2.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85df8d92158cb8f3965aecc27cf821461bb5f40b450b03facc5d9f0d4d6ddec6"}, + {file = "wrapt-2.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1be685ac7700c966b8610ccc63c3187a72e33cab53526a27b2a285a662cd4f7"}, + {file = "wrapt-2.0.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:df0b6d3b95932809c5b3fecc18fda0f1e07452d05e2662a0b35548985f256e28"}, + {file = "wrapt-2.0.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4da7384b0e5d4cae05c97cd6f94faaf78cc8b0f791fc63af43436d98c4ab37bb"}, + {file = "wrapt-2.0.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ec65a78fbd9d6f083a15d7613b2800d5663dbb6bb96003899c834beaa68b242c"}, + {file = "wrapt-2.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7de3cc939be0e1174969f943f3b44e0d79b6f9a82198133a5b7fc6cc92882f16"}, + {file = "wrapt-2.0.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:fb1a5b72cbd751813adc02ef01ada0b0d05d3dcbc32976ce189a1279d80ad4a2"}, + {file = "wrapt-2.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3fa272ca34332581e00bf7773e993d4f632594eb2d1b0b162a9038df0fd971dd"}, + {file = "wrapt-2.0.1-cp311-cp311-win32.whl", hash = "sha256:fc007fdf480c77301ab1afdbb6ab22a5deee8885f3b1ed7afcb7e5e84a0e27be"}, + {file = "wrapt-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:47434236c396d04875180171ee1f3815ca1eada05e24a1ee99546320d54d1d1b"}, + {file = "wrapt-2.0.1-cp311-cp311-win_arm64.whl", hash = "sha256:837e31620e06b16030b1d126ed78e9383815cbac914693f54926d816d35d8edf"}, + {file = "wrapt-2.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1fdbb34da15450f2b1d735a0e969c24bdb8d8924892380126e2a293d9902078c"}, + {file = "wrapt-2.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3d32794fe940b7000f0519904e247f902f0149edbe6316c710a8562fb6738841"}, + {file = "wrapt-2.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:386fb54d9cd903ee0012c09291336469eb7b244f7183d40dc3e86a16a4bace62"}, + {file = "wrapt-2.0.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7b219cb2182f230676308cdcacd428fa837987b89e4b7c5c9025088b8a6c9faf"}, + {file = "wrapt-2.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:641e94e789b5f6b4822bb8d8ebbdfc10f4e4eae7756d648b717d980f657a9eb9"}, + {file = "wrapt-2.0.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fe21b118b9f58859b5ebaa4b130dee18669df4bd111daad082b7beb8799ad16b"}, + {file = "wrapt-2.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:17fb85fa4abc26a5184d93b3efd2dcc14deb4b09edcdb3535a536ad34f0b4dba"}, + {file = "wrapt-2.0.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:b89ef9223d665ab255ae42cc282d27d69704d94be0deffc8b9d919179a609684"}, + {file = "wrapt-2.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a453257f19c31b31ba593c30d997d6e5be39e3b5ad9148c2af5a7314061c63eb"}, + {file = "wrapt-2.0.1-cp312-cp312-win32.whl", hash = "sha256:3e271346f01e9c8b1130a6a3b0e11908049fe5be2d365a5f402778049147e7e9"}, + {file = "wrapt-2.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:2da620b31a90cdefa9cd0c2b661882329e2e19d1d7b9b920189956b76c564d75"}, + {file = "wrapt-2.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:aea9c7224c302bc8bfc892b908537f56c430802560e827b75ecbde81b604598b"}, + {file = "wrapt-2.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:47b0f8bafe90f7736151f61482c583c86b0693d80f075a58701dd1549b0010a9"}, + {file = "wrapt-2.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cbeb0971e13b4bd81d34169ed57a6dda017328d1a22b62fda45e1d21dd06148f"}, + {file = "wrapt-2.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb7cffe572ad0a141a7886a1d2efa5bef0bf7fe021deeea76b3ab334d2c38218"}, + {file = "wrapt-2.0.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c8d60527d1ecfc131426b10d93ab5d53e08a09c5fa0175f6b21b3252080c70a9"}, + {file = "wrapt-2.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c654eafb01afac55246053d67a4b9a984a3567c3808bb7df2f8de1c1caba2e1c"}, + {file = "wrapt-2.0.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:98d873ed6c8b4ee2418f7afce666751854d6d03e3c0ec2a399bb039cd2ae89db"}, + {file = "wrapt-2.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9e850f5b7fc67af856ff054c71690d54fa940c3ef74209ad9f935b4f66a0233"}, + {file = "wrapt-2.0.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e505629359cb5f751e16e30cf3f91a1d3ddb4552480c205947da415d597f7ac2"}, + {file = "wrapt-2.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2879af909312d0baf35f08edeea918ee3af7ab57c37fe47cb6a373c9f2749c7b"}, + {file = "wrapt-2.0.1-cp313-cp313-win32.whl", hash = "sha256:d67956c676be5a24102c7407a71f4126d30de2a569a1c7871c9f3cabc94225d7"}, + {file = "wrapt-2.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:9ca66b38dd642bf90c59b6738af8070747b610115a39af2498535f62b5cdc1c3"}, + {file = "wrapt-2.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:5a4939eae35db6b6cec8e7aa0e833dcca0acad8231672c26c2a9ab7a0f8ac9c8"}, + {file = "wrapt-2.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a52f93d95c8d38fed0669da2ebdb0b0376e895d84596a976c15a9eb45e3eccb3"}, + {file = "wrapt-2.0.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4e54bbf554ee29fcceee24fa41c4d091398b911da6e7f5d7bffda963c9aed2e1"}, + {file = "wrapt-2.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:908f8c6c71557f4deaa280f55d0728c3bca0960e8c3dd5ceeeafb3c19942719d"}, + {file = "wrapt-2.0.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e2f84e9af2060e3904a32cea9bb6db23ce3f91cfd90c6b426757cf7cc01c45c7"}, + {file = "wrapt-2.0.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3612dc06b436968dfb9142c62e5dfa9eb5924f91120b3c8ff501ad878f90eb3"}, + {file = "wrapt-2.0.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6d2d947d266d99a1477cd005b23cbd09465276e302515e122df56bb9511aca1b"}, + {file = "wrapt-2.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:7d539241e87b650cbc4c3ac9f32c8d1ac8a54e510f6dca3f6ab60dcfd48c9b10"}, + {file = "wrapt-2.0.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:4811e15d88ee62dbf5c77f2c3ff3932b1e3ac92323ba3912f51fc4016ce81ecf"}, + {file = "wrapt-2.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c1c91405fcf1d501fa5d55df21e58ea49e6b879ae829f1039faaf7e5e509b41e"}, + {file = "wrapt-2.0.1-cp313-cp313t-win32.whl", hash = "sha256:e76e3f91f864e89db8b8d2a8311d57df93f01ad6bb1e9b9976d1f2e83e18315c"}, + {file = "wrapt-2.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:83ce30937f0ba0d28818807b303a412440c4b63e39d3d8fc036a94764b728c92"}, + {file = "wrapt-2.0.1-cp313-cp313t-win_arm64.whl", hash = "sha256:4b55cacc57e1dc2d0991dbe74c6419ffd415fb66474a02335cb10efd1aa3f84f"}, + {file = "wrapt-2.0.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:5e53b428f65ece6d9dad23cb87e64506392b720a0b45076c05354d27a13351a1"}, + {file = "wrapt-2.0.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ad3ee9d0f254851c71780966eb417ef8e72117155cff04821ab9b60549694a55"}, + {file = "wrapt-2.0.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7b822c61ed04ee6ad64bc90d13368ad6eb094db54883b5dde2182f67a7f22c0"}, + {file = "wrapt-2.0.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7164a55f5e83a9a0b031d3ffab4d4e36bbec42e7025db560f225489fa929e509"}, + {file = "wrapt-2.0.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e60690ba71a57424c8d9ff28f8d006b7ad7772c22a4af432188572cd7fa004a1"}, + {file = "wrapt-2.0.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3cd1a4bd9a7a619922a8557e1318232e7269b5fb69d4ba97b04d20450a6bf970"}, + {file = "wrapt-2.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b4c2e3d777e38e913b8ce3a6257af72fb608f86a1df471cb1d4339755d0a807c"}, + {file = "wrapt-2.0.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3d366aa598d69416b5afedf1faa539fac40c1d80a42f6b236c88c73a3c8f2d41"}, + {file = "wrapt-2.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c235095d6d090aa903f1db61f892fffb779c1eaeb2a50e566b52001f7a0f66ed"}, + {file = "wrapt-2.0.1-cp314-cp314-win32.whl", hash = "sha256:bfb5539005259f8127ea9c885bdc231978c06b7a980e63a8a61c8c4c979719d0"}, + {file = "wrapt-2.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:4ae879acc449caa9ed43fc36ba08392b9412ee67941748d31d94e3cedb36628c"}, + {file = "wrapt-2.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:8639b843c9efd84675f1e100ed9e99538ebea7297b62c4b45a7042edb84db03e"}, + {file = "wrapt-2.0.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:9219a1d946a9b32bb23ccae66bdb61e35c62773ce7ca6509ceea70f344656b7b"}, + {file = "wrapt-2.0.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:fa4184e74197af3adad3c889a1af95b53bb0466bced92ea99a0c014e48323eec"}, + {file = "wrapt-2.0.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c5ef2f2b8a53b7caee2f797ef166a390fef73979b15778a4a153e4b5fedce8fa"}, + {file = "wrapt-2.0.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e042d653a4745be832d5aa190ff80ee4f02c34b21f4b785745eceacd0907b815"}, + {file = "wrapt-2.0.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2afa23318136709c4b23d87d543b425c399887b4057936cd20386d5b1422b6fa"}, + {file = "wrapt-2.0.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c72328f668cf4c503ffcf9434c2b71fdd624345ced7941bc6693e61bbe36bef"}, + {file = "wrapt-2.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3793ac154afb0e5b45d1233cb94d354ef7a983708cc3bb12563853b1d8d53747"}, + {file = "wrapt-2.0.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:fec0d993ecba3991645b4857837277469c8cc4c554a7e24d064d1ca291cfb81f"}, + {file = "wrapt-2.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:949520bccc1fa227274da7d03bf238be15389cd94e32e4297b92337df9b7a349"}, + {file = "wrapt-2.0.1-cp314-cp314t-win32.whl", hash = "sha256:be9e84e91d6497ba62594158d3d31ec0486c60055c49179edc51ee43d095f79c"}, + {file = "wrapt-2.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:61c4956171c7434634401db448371277d07032a81cc21c599c22953374781395"}, + {file = "wrapt-2.0.1-cp314-cp314t-win_arm64.whl", hash = "sha256:35cdbd478607036fee40273be8ed54a451f5f23121bd9d4be515158f9498f7ad"}, + {file = "wrapt-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:90897ea1cf0679763b62e79657958cd54eae5659f6360fc7d2ccc6f906342183"}, + {file = "wrapt-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:50844efc8cdf63b2d90cd3d62d4947a28311e6266ce5235a219d21b195b4ec2c"}, + {file = "wrapt-2.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49989061a9977a8cbd6d20f2efa813f24bf657c6990a42967019ce779a878dbf"}, + {file = "wrapt-2.0.1-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:09c7476ab884b74dce081ad9bfd07fe5822d8600abade571cb1f66d5fc915af6"}, + {file = "wrapt-2.0.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1a8a09a004ef100e614beec82862d11fc17d601092c3599afd22b1f36e4137e"}, + {file = "wrapt-2.0.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:89a82053b193837bf93c0f8a57ded6e4b6d88033a499dadff5067e912c2a41e9"}, + {file = "wrapt-2.0.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f26f8e2ca19564e2e1fdbb6a0e47f36e0efbab1acc31e15471fad88f828c75f6"}, + {file = "wrapt-2.0.1-cp38-cp38-win32.whl", hash = "sha256:115cae4beed3542e37866469a8a1f2b9ec549b4463572b000611e9946b86e6f6"}, + {file = "wrapt-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c4012a2bd37059d04f8209916aa771dfb564cccb86079072bdcd48a308b6a5c5"}, + {file = "wrapt-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:68424221a2dc00d634b54f92441914929c5ffb1c30b3b837343978343a3512a3"}, + {file = "wrapt-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6bd1a18f5a797fe740cb3d7a0e853a8ce6461cc62023b630caec80171a6b8097"}, + {file = "wrapt-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fb3a86e703868561c5cad155a15c36c716e1ab513b7065bd2ac8ed353c503333"}, + {file = "wrapt-2.0.1-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5dc1b852337c6792aa111ca8becff5bacf576bf4a0255b0f05eb749da6a1643e"}, + {file = "wrapt-2.0.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c046781d422f0830de6329fa4b16796096f28a92c8aef3850674442cdcb87b7f"}, + {file = "wrapt-2.0.1-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f73f9f7a0ebd0db139253d27e5fc8d2866ceaeef19c30ab5d69dcbe35e1a6981"}, + {file = "wrapt-2.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b667189cf8efe008f55bbda321890bef628a67ab4147ebf90d182f2dadc78790"}, + {file = "wrapt-2.0.1-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:a9a83618c4f0757557c077ef71d708ddd9847ed66b7cc63416632af70d3e2308"}, + {file = "wrapt-2.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e9b121e9aeb15df416c2c960b8255a49d44b4038016ee17af03975992d03931"}, + {file = "wrapt-2.0.1-cp39-cp39-win32.whl", hash = "sha256:1f186e26ea0a55f809f232e92cc8556a0977e00183c3ebda039a807a42be1494"}, + {file = "wrapt-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:bf4cb76f36be5de950ce13e22e7fdf462b35b04665a12b64f3ac5c1bbbcf3728"}, + {file = "wrapt-2.0.1-cp39-cp39-win_arm64.whl", hash = "sha256:d6cc985b9c8b235bd933990cdbf0f891f8e010b65a3911f7a55179cd7b0fc57b"}, + {file = "wrapt-2.0.1-py3-none-any.whl", hash = "sha256:4d2ce1bf1a48c5277d7969259232b57645aae5686dba1eaeade39442277afbca"}, + {file = "wrapt-2.0.1.tar.gz", hash = "sha256:9c9c635e78497cacb81e84f8b11b23e0aacac7a136e73b8e5b2109a1d9fc468f"}, ] +[package.extras] +dev = ["pytest", "setuptools"] + [[package]] name = "yarl" -version = "1.20.1" +version = "1.22.0" description = "Yet another URL library" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4"}, - {file = "yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a"}, - {file = "yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed"}, - {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e"}, - {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73"}, - {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e"}, - {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8"}, - {file = "yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23"}, - {file = "yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70"}, - {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb"}, - {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2"}, - {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30"}, - {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309"}, - {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24"}, - {file = "yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13"}, - {file = "yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8"}, - {file = "yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16"}, - {file = "yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e"}, - {file = "yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b"}, - {file = "yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b"}, - {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4"}, - {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1"}, - {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833"}, - {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d"}, - {file = "yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8"}, - {file = "yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf"}, - {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e"}, - {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389"}, - {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f"}, - {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845"}, - {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1"}, - {file = "yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e"}, - {file = "yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773"}, - {file = "yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e"}, - {file = "yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9"}, - {file = "yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a"}, - {file = "yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2"}, - {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee"}, - {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819"}, - {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16"}, - {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6"}, - {file = "yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd"}, - {file = "yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a"}, - {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38"}, - {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef"}, - {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f"}, - {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8"}, - {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a"}, - {file = "yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004"}, - {file = "yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5"}, - {file = "yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698"}, - {file = "yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a"}, - {file = "yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3"}, - {file = "yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7"}, - {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691"}, - {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31"}, - {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28"}, - {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653"}, - {file = "yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5"}, - {file = "yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02"}, - {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53"}, - {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc"}, - {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04"}, - {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4"}, - {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b"}, - {file = "yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1"}, - {file = "yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7"}, - {file = "yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c"}, - {file = "yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d"}, - {file = "yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf"}, - {file = "yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3"}, - {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d"}, - {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c"}, - {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1"}, - {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce"}, - {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3"}, - {file = "yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be"}, - {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16"}, - {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513"}, - {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f"}, - {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390"}, - {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458"}, - {file = "yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e"}, - {file = "yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d"}, - {file = "yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f"}, - {file = "yarl-1.20.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e42ba79e2efb6845ebab49c7bf20306c4edf74a0b20fc6b2ccdd1a219d12fad3"}, - {file = "yarl-1.20.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:41493b9b7c312ac448b7f0a42a089dffe1d6e6e981a2d76205801a023ed26a2b"}, - {file = "yarl-1.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f5a5928ff5eb13408c62a968ac90d43f8322fd56d87008b8f9dabf3c0f6ee983"}, - {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30c41ad5d717b3961b2dd785593b67d386b73feca30522048d37298fee981805"}, - {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:59febc3969b0781682b469d4aca1a5cab7505a4f7b85acf6db01fa500fa3f6ba"}, - {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2b6fb3622b7e5bf7a6e5b679a69326b4279e805ed1699d749739a61d242449e"}, - {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:749d73611db8d26a6281086f859ea7ec08f9c4c56cec864e52028c8b328db723"}, - {file = "yarl-1.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9427925776096e664c39e131447aa20ec738bdd77c049c48ea5200db2237e000"}, - {file = "yarl-1.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff70f32aa316393eaf8222d518ce9118148eddb8a53073c2403863b41033eed5"}, - {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c7ddf7a09f38667aea38801da8b8d6bfe81df767d9dfc8c88eb45827b195cd1c"}, - {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:57edc88517d7fc62b174fcfb2e939fbc486a68315d648d7e74d07fac42cec240"}, - {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:dab096ce479d5894d62c26ff4f699ec9072269d514b4edd630a393223f45a0ee"}, - {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14a85f3bd2d7bb255be7183e5d7d6e70add151a98edf56a770d6140f5d5f4010"}, - {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c89b5c792685dd9cd3fa9761c1b9f46fc240c2a3265483acc1565769996a3f8"}, - {file = "yarl-1.20.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:69e9b141de5511021942a6866990aea6d111c9042235de90e08f94cf972ca03d"}, - {file = "yarl-1.20.1-cp39-cp39-win32.whl", hash = "sha256:b5f307337819cdfdbb40193cad84978a029f847b0a357fbe49f712063cfc4f06"}, - {file = "yarl-1.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:eae7bfe2069f9c1c5b05fc7fe5d612e5bbc089a39309904ee8b829e322dcad00"}, - {file = "yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77"}, - {file = "yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac"}, + {file = "yarl-1.22.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c7bd6683587567e5a49ee6e336e0612bec8329be1b7d4c8af5687dcdeb67ee1e"}, + {file = "yarl-1.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5cdac20da754f3a723cceea5b3448e1a2074866406adeb4ef35b469d089adb8f"}, + {file = "yarl-1.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07a524d84df0c10f41e3ee918846e1974aba4ec017f990dc735aad487a0bdfdf"}, + {file = "yarl-1.22.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1b329cb8146d7b736677a2440e422eadd775d1806a81db2d4cded80a48efc1a"}, + {file = "yarl-1.22.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:75976c6945d85dbb9ee6308cd7ff7b1fb9409380c82d6119bd778d8fcfe2931c"}, + {file = "yarl-1.22.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:80ddf7a5f8c86cb3eb4bc9028b07bbbf1f08a96c5c0bc1244be5e8fefcb94147"}, + {file = "yarl-1.22.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d332fc2e3c94dad927f2112395772a4e4fedbcf8f80efc21ed7cdfae4d574fdb"}, + {file = "yarl-1.22.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cf71bf877efeac18b38d3930594c0948c82b64547c1cf420ba48722fe5509f6"}, + {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:663e1cadaddae26be034a6ab6072449a8426ddb03d500f43daf952b74553bba0"}, + {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6dcbb0829c671f305be48a7227918cfcd11276c2d637a8033a99a02b67bf9eda"}, + {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f0d97c18dfd9a9af4490631905a3f131a8e4c9e80a39353919e2cfed8f00aedc"}, + {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:437840083abe022c978470b942ff832c3940b2ad3734d424b7eaffcd07f76737"}, + {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a899cbd98dce6f5d8de1aad31cb712ec0a530abc0a86bd6edaa47c1090138467"}, + {file = "yarl-1.22.0-cp310-cp310-win32.whl", hash = "sha256:595697f68bd1f0c1c159fcb97b661fc9c3f5db46498043555d04805430e79bea"}, + {file = "yarl-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:cb95a9b1adaa48e41815a55ae740cfda005758104049a640a398120bf02515ca"}, + {file = "yarl-1.22.0-cp310-cp310-win_arm64.whl", hash = "sha256:b85b982afde6df99ecc996990d4ad7ccbdbb70e2a4ba4de0aecde5922ba98a0b"}, + {file = "yarl-1.22.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511"}, + {file = "yarl-1.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6"}, + {file = "yarl-1.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e"}, + {file = "yarl-1.22.0-cp311-cp311-win32.whl", hash = "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca"}, + {file = "yarl-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b"}, + {file = "yarl-1.22.0-cp311-cp311-win_arm64.whl", hash = "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376"}, + {file = "yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f"}, + {file = "yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2"}, + {file = "yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520"}, + {file = "yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8"}, + {file = "yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c"}, + {file = "yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74"}, + {file = "yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53"}, + {file = "yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a"}, + {file = "yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c"}, + {file = "yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601"}, + {file = "yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a"}, + {file = "yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df"}, + {file = "yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2"}, + {file = "yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b"}, + {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273"}, + {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a"}, + {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d"}, + {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02"}, + {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67"}, + {file = "yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95"}, + {file = "yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d"}, + {file = "yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b"}, + {file = "yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10"}, + {file = "yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3"}, + {file = "yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9"}, + {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f"}, + {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0"}, + {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e"}, + {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708"}, + {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f"}, + {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d"}, + {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8"}, + {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5"}, + {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f"}, + {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62"}, + {file = "yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03"}, + {file = "yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249"}, + {file = "yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b"}, + {file = "yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4"}, + {file = "yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683"}, + {file = "yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b"}, + {file = "yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e"}, + {file = "yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590"}, + {file = "yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2"}, + {file = "yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da"}, + {file = "yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784"}, + {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b"}, + {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694"}, + {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d"}, + {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd"}, + {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da"}, + {file = "yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2"}, + {file = "yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79"}, + {file = "yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33"}, + {file = "yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1"}, + {file = "yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca"}, + {file = "yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53"}, + {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c"}, + {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf"}, + {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face"}, + {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b"}, + {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486"}, + {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138"}, + {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a"}, + {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529"}, + {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093"}, + {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c"}, + {file = "yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e"}, + {file = "yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27"}, + {file = "yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1"}, + {file = "yarl-1.22.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3aa27acb6de7a23785d81557577491f6c38a5209a254d1191519d07d8fe51748"}, + {file = "yarl-1.22.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:af74f05666a5e531289cb1cc9c883d1de2088b8e5b4de48004e5ca8a830ac859"}, + {file = "yarl-1.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:62441e55958977b8167b2709c164c91a6363e25da322d87ae6dd9c6019ceecf9"}, + {file = "yarl-1.22.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b580e71cac3f8113d3135888770903eaf2f507e9421e5697d6ee6d8cd1c7f054"}, + {file = "yarl-1.22.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e81fda2fb4a07eda1a2252b216aa0df23ebcd4d584894e9612e80999a78fd95b"}, + {file = "yarl-1.22.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:99b6fc1d55782461b78221e95fc357b47ad98b041e8e20f47c1411d0aacddc60"}, + {file = "yarl-1.22.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:088e4e08f033db4be2ccd1f34cf29fe994772fb54cfe004bbf54db320af56890"}, + {file = "yarl-1.22.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e4e1f6f0b4da23e61188676e3ed027ef0baa833a2e633c29ff8530800edccba"}, + {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:84fc3ec96fce86ce5aa305eb4aa9358279d1aa644b71fab7b8ed33fe3ba1a7ca"}, + {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5dbeefd6ca588b33576a01b0ad58aa934bc1b41ef89dee505bf2932b22ddffba"}, + {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14291620375b1060613f4aab9ebf21850058b6b1b438f386cc814813d901c60b"}, + {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:a4fcfc8eb2c34148c118dfa02e6427ca278bfd0f3df7c5f99e33d2c0e81eae3e"}, + {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:029866bde8d7b0878b9c160e72305bbf0a7342bcd20b9999381704ae03308dc8"}, + {file = "yarl-1.22.0-cp39-cp39-win32.whl", hash = "sha256:4dcc74149ccc8bba31ce1944acee24813e93cfdee2acda3c172df844948ddf7b"}, + {file = "yarl-1.22.0-cp39-cp39-win_amd64.whl", hash = "sha256:10619d9fdee46d20edc49d3479e2f8269d0779f1b031e6f7c2aa1c76be04b7ed"}, + {file = "yarl-1.22.0-cp39-cp39-win_arm64.whl", hash = "sha256:dd7afd3f8b0bfb4e0d9fc3c31bfe8a4ec7debe124cfd90619305def3c8ca8cd2"}, + {file = "yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff"}, + {file = "yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71"}, ] [package.dependencies] diff --git a/pyproject.toml b/pyproject.toml index 76f6851..42556ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,11 +7,8 @@ authors = [{ name = "Riccardo Balbo", email = "oc@rblb.it" }] urls = { Homepage = "https://lnbits.com", Repository = "https://github.com/lnbits/nwcprovider" } dependencies = [ "lnbits>1" ] -[tool.poetry] -package-mode = false - -[tool.uv] -dev-dependencies = [ +[dependency-groups] +dev = [ "black", "pytest-asyncio", "pytest", @@ -21,12 +18,15 @@ dev-dependencies = [ "pytest-md", ] +[tool.poetry] +package-mode = false + [tool.mypy] plugins = ["pydantic.mypy"] [[tool.mypy.overrides]] module = [ - "secp256k1.*", + "pynostr.*", ] ignore_missing_imports = "True" diff --git a/tests/integration/start.sh b/tests/integration/start.sh index 140f26a..825b90e 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -19,8 +19,8 @@ fi docker run --name=lnbits_nwcprovider_ext_nostr_test \ -d \ --rm \ --v $PWD/strfry.conf:/etc/strfry.conf \ --v $PWD/strfry-data:/app/strfry-db \ +-v $PWD/strfry.conf:/etc/strfry.conf:Z \ +-v $PWD/strfry-data:/app/strfry-db:Z \ -p 7777:7777 \ ghcr.io/hoytech/strfry:latest diff --git a/tests/integration/strfry.conf b/tests/integration/strfry.conf index 150bcc3..e6cf792 100644 --- a/tests/integration/strfry.conf +++ b/tests/integration/strfry.conf @@ -47,7 +47,7 @@ relay { port = 7777 # Set OS-limit on maximum number of open files/sockets (if 0, don't attempt to set) (restart required) - nofiles = 1000000 + nofiles = 0 # HTTP header that contains the client's real IP, before reverse proxying (ie x-real-ip) (MUST be all lower-case) realIpHeader = "" diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index 2273126..56d9717 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -1,5 +1,4 @@ import asyncio -import base64 import hashlib import json import random @@ -9,11 +8,8 @@ from typing import Union import bolt11 import httpx import pytest -import secp256k1 -from Cryptodome import Random -from Cryptodome.Cipher import AES -from Cryptodome.Util.Padding import pad, unpad from loguru import logger +from pynostr.key import PrivateKey from websockets.legacy.client import connect wallets = { @@ -95,12 +91,12 @@ async def refresh_wallet_balances(): def gen_keypair(): - private_key_hex = bytes.hex(secp256k1._gen_private_key()) - private_key = secp256k1.PrivateKey(bytes.fromhex(private_key_hex)) - public_key = private_key.pubkey + private_key = PrivateKey() + private_key_hex = private_key.hex() + public_key = private_key.public_key if not public_key: raise Exception("Error generating pubkey") - public_key_hex = public_key.serialize().hex()[2:] + public_key_hex = public_key.hex() return {"priv": private_key_hex, "pub": public_key_hex} @@ -164,12 +160,12 @@ class NWCWallet: self.event_queue = [] self.subscriptions_count = 0 self.sub_id = "" - self.private_key = secp256k1.PrivateKey(bytes.fromhex(self.secret)) + self.private_key = PrivateKey.from_hex(self.secret) self.private_key_hex = self.secret - self.public_key = self.private_key.pubkey + self.public_key = self.private_key.public_key if not self.public_key: raise Exception("Error generating pubkey") - self.public_key_hex = self.public_key.serialize().hex()[2:] + self.public_key_hex = self.public_key.hex() self.task = None async def close(self): @@ -243,43 +239,13 @@ class NWCWallet: else: break - def _encrypt_content( - self, content: str, pubkey_hex: str, iv_seed: int | None = None - ) -> str: - pubkey = secp256k1.PublicKey(bytes.fromhex("02" + pubkey_hex), True) - shared = pubkey.tweak_mul(bytes.fromhex(self.private_key_hex)).serialize()[1:] - if not iv_seed: - iv = Random.new().read(AES.block_size) - else: - iv = hashlib.sha256(iv_seed.to_bytes(32, byteorder="big")).digest() - iv = iv[: AES.block_size] - aes = AES.new(shared, AES.MODE_CBC, iv) - content_bytes = content.encode("utf-8") - content_bytes = pad(content_bytes, AES.block_size) - encrypted_b64 = base64.b64encode(aes.encrypt(content_bytes)).decode("ascii") - iv_b64 = base64.b64encode(iv).decode("ascii") - encrypted_content = encrypted_b64 + "?iv=" + iv_b64 - return encrypted_content - - def _decrypt_content(self, content: str, pubkey_hex: str) -> str: - pubkey = secp256k1.PublicKey(bytes.fromhex("02" + pubkey_hex), True) - shared = pubkey.tweak_mul(bytes.fromhex(self.private_key_hex)).serialize()[1:] - (encrypted_content_b64, iv_b64) = content.split("?iv=") - encrypted_content = base64.b64decode(encrypted_content_b64.encode("ascii")) - iv = base64.b64decode(iv_b64.encode("ascii")) - aes = AES.new(shared, AES.MODE_CBC, iv) - decrypted_bytes = aes.decrypt(encrypted_content) - decrypted_bytes = unpad(decrypted_bytes, AES.block_size) - decrypted = decrypted_bytes.decode("utf-8") - return decrypted - async def _on_message(self, _, message: str): logger.debug("Received message: " + message) msg = json.loads(message) if msg[0] == "EVENT": # Event message event = msg[2] nwc_pubkey = event["pubkey"] - content = self._decrypt_content(event["content"], nwc_pubkey) + content = self.private_key.decrypt_message(event["content"], nwc_pubkey) content = json.loads(content) self.event_queue.append( { @@ -312,10 +278,9 @@ class NWCWallet: event_id = hashlib.sha256(signature_data.encode()).hexdigest() event["id"] = event_id event["pubkey"] = self.public_key_hex - signature = ( - self.private_key.schnorr_sign(bytes.fromhex(event_id), None, raw=True) - ).hex() - event["sig"] = signature + signature = self.private_key.sign(bytes.fromhex(event_id)) + # type error? returns str but is bytes + event["sig"] = signature.hex() # type: ignore return event async def send_event(self, method, params): @@ -331,7 +296,7 @@ class NWCWallet: "content": json.dumps({"method": method, "params": params}), } logger.debug("Sending event: " + str(event)) - event["content"] = self._encrypt_content( + event["content"] = self.private_key.encrypt_message( event["content"], self.provider_pub_hex ) self._sign_event(event) @@ -888,7 +853,7 @@ async def test_idor_vulnerability(): f"http://localhost:5002/nwcprovider/api/v1/nwc/{nwc_wallet1['pubkey']}", headers={"X-Api-Key": wallets["wallet2"]["admin_key"]}, ) - assert resp.status_code == 500 + assert resp.status_code == 400 assert "Pubkey has no associated wallet" in resp.text diff --git a/tests/unit/test_nwcp.py b/tests/unit/test_nwcp.py index ebc3d75..3e23eb6 100644 --- a/tests/unit/test_nwcp.py +++ b/tests/unit/test_nwcp.py @@ -33,25 +33,22 @@ def test_supported_methods(nwc_service_provider): def test_encrytdecrypt(nwc_service_provider, nwc_service_provider2): content = "Hello World" - expected_enc = "qVurNVISSl/9CfREIhk5Lg==?iv=QpCo5dI9gUcoLsSMLA7o7Q==" - enc_a = nwc_service_provider._encrypt_content( - content, nwc_service_provider2.public_key_hex, 21 + enc_a = nwc_service_provider.private_key.encrypt_message( + content, nwc_service_provider2.public_key_hex ) - enc_b = nwc_service_provider2._encrypt_content( - content, nwc_service_provider.public_key_hex, 21 + enc_b = nwc_service_provider2.private_key.encrypt_message( + content, nwc_service_provider.public_key_hex ) - dec_a = nwc_service_provider2._decrypt_content( + dec_a = nwc_service_provider2.private_key.decrypt_message( enc_a, nwc_service_provider.public_key_hex ) - dec_b = nwc_service_provider._decrypt_content( + dec_b = nwc_service_provider.private_key.decrypt_message( enc_b, nwc_service_provider2.public_key_hex ) assert dec_a == content assert dec_b == content - assert enc_a == expected_enc - assert enc_b == expected_enc def test_signverify(nwc_service_provider, nwc_service_provider2): @@ -82,8 +79,8 @@ async def test_handle(nwc_service_provider, nwc_service_provider2): content = nwc_service_provider._json_dumps( {"method": "pay_invoice", "params": {"invoice": "abc"}} ) - content = nwc_service_provider._encrypt_content( - content, nwc_service_provider2.public_key_hex, 21 + content = nwc_service_provider.private_key.encrypt_message( + content, nwc_service_provider2.public_key_hex ) event = { "kind": 23194, @@ -108,7 +105,7 @@ async def test_handle(nwc_service_provider, nwc_service_provider2): assert len(sent_events) == 1 for revent in sent_events: assert nwc_service_provider2._verify_event(revent) - content = nwc_service_provider2._decrypt_content( + content = nwc_service_provider2.private_key.decrypt_message( revent["content"], nwc_service_provider.public_key_hex ) logger.debug(event) diff --git a/views_api.py b/views_api.py index 810f8ca..cd85962 100644 --- a/views_api.py +++ b/views_api.py @@ -1,10 +1,10 @@ from http import HTTPStatus -import secp256k1 from fastapi import APIRouter, Depends, Request from fastapi.responses import JSONResponse from lnbits.core.models import WalletTypeInfo from lnbits.decorators import check_admin, require_admin_key +from pynostr.key import PrivateKey from .crud import ( create_nwc, @@ -88,11 +88,13 @@ async def api_get_nwc( nwc = await get_nwc( GetNWC(pubkey=pubkey, wallet=wallet_id, include_expired=include_expired) ) + if not nwc: - raise Exception("Pubkey has no associated wallet") + raise ValueError("Pubkey has no associated wallet") res = NWCGetResponse( data=nwc, budgets=await get_budgets_nwc(GetBudgetsNWC(pubkey=pubkey)) ) + return res @@ -123,11 +125,11 @@ async def api_get_pairing_url(req: Request, secret: str) -> str: scheme = "wss" netloc += "/nostrclient/api/v1/relay" relay = f"{scheme}://{netloc}" - psk = secp256k1.PrivateKey(bytes.fromhex(pprivkey)) - ppk = psk.pubkey + psk = PrivateKey.from_hex(pprivkey) + ppk = psk.public_key if not ppk: raise Exception("Error generating pubkey") - ppubkey = ppk.serialize().hex()[2:] + ppubkey = ppk.hex() url = "nostr+walletconnect://" url += ppubkey url += "?relay=" + relay From 53d1e0d5df01b65f0f34209c9e7603283c9bb433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Tue, 2 Dec 2025 21:06:06 +0100 Subject: [PATCH 62/90] chore: update to v1.1.0 (#19) --- config.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index f853b33..035ccbc 100644 --- a/config.json +++ b/config.json @@ -2,7 +2,8 @@ "name": "NWC Service Provider", "short_description": "A NWC service provider for LNbits", "tile": "/nwcprovider/static/image/nwcprovider.png", - "min_lnbits_version": "1.0.0", + "version": "1.1.0", + "min_lnbits_version": "1.4.0", "contributors": [ { "name": "Riccardo Balbo", From 8c14c6fac8ec5e0fe8ebf79e919a2f6865f694c0 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 23 Dec 2025 10:15:30 +0100 Subject: [PATCH 63/90] relax printable checks (#21) * relax printable checks * format --- paranoia.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/paranoia.py b/paranoia.py index 5ebca7c..205debe 100644 --- a/paranoia.py +++ b/paranoia.py @@ -2,6 +2,12 @@ from loguru import logger ENABLE_HARDENING = True +WHITELISTED_NON_PRINTABLE_CHARS = { + "\n", # newline + "\r", # carriage return + "\t", # tab + "\xa0", # non-breaking space ( ) +} def panic(reason: str): @@ -17,8 +23,17 @@ def assert_printable(v: str): return if not isinstance(v, str): panic("not a string " + str(v)) - if not v.isprintable(): - panic("string contains non-printable characters") + for ch in v: + # check if printable + if ch.isprintable(): + continue + + # check if whitelisted non-printable + if ch in WHITELISTED_NON_PRINTABLE_CHARS: + continue + + # Anything else is rejected + panic(f"string contains non-printable character: (0x{ord(ch):04X})") # Check if number is valid int and not NaN From 65da39e0b46a79a752648472b229a9a2a1de211f Mon Sep 17 00:00:00 2001 From: Arc <33088785+arcbtc@users.noreply.github.com> Date: Mon, 12 Jan 2026 11:16:37 +0000 Subject: [PATCH 64/90] Revert "Revert "Improve configuration form for readability and UX"" (#11) Co-authored-by: blackcoffeexbt <87530449+blackcoffeexbt@users.noreply.github.com> --- static/js/admin.js | 18 ++++-------- templates/nwcprovider/admin.html | 47 ++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/static/js/admin.js b/static/js/admin.js index 2e18b9b..38acf69 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -4,7 +4,7 @@ window.app = Vue.createApp({ delimiters: ['${', '}'], data: function () { return { - entries: [], + config: {}, columns: [ { name: 'key', @@ -36,15 +36,8 @@ window.app = Vue.createApp({ this.g.user.wallets[0].adminkey ) .then(response => { - const newEntries = [] - for (const [key, value] of Object.entries(response.data)) { - newEntries.push({ - key: key, - value: value - }) - } - this.entries.length = 0 - this.entries.push(...newEntries) + this.config = response.data + console.log('Config fetched:', this.config) }) .catch(function (error) { console.error('Error fetching config:', error) @@ -52,9 +45,10 @@ window.app = Vue.createApp({ }, async saveConfig() { const data = {} - for (const entry of this.entries) { - data[entry.key] = entry.value + for (const [key, value] of Object.entries(this.config)) { + data[key] = value } + console.log('Saving config:', data) try { const response = await LNbits.api.request( 'POST', diff --git a/templates/nwcprovider/admin.html b/templates/nwcprovider/admin.html index 171a6d0..81576b4 100644 --- a/templates/nwcprovider/admin.html +++ b/templates/nwcprovider/admin.html @@ -6,21 +6,56 @@
-
+
- NWC Service Provider - Config + NWC Service Provider Configuration
- + - + - ${entry.key} + + + + - + + + + + + + + + + + From 2b322863ca7f545dd21ba419f5f62f92ef1c112e Mon Sep 17 00:00:00 2001 From: blackcoffeexbt <87530449+blackcoffeexbt@users.noreply.github.com> Date: Mon, 12 Jan 2026 11:35:43 +0000 Subject: [PATCH 65/90] Fix configuration page errors (#24) --- static/js/admin.js | 8 ++------ static/routes.json | 0 2 files changed, 2 insertions(+), 6 deletions(-) create mode 100644 static/routes.json diff --git a/static/js/admin.js b/static/js/admin.js index 38acf69..e9a405c 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -30,11 +30,7 @@ window.app = Vue.createApp({ fetchConfig() { this.entries = [] LNbits.api - .request( - 'GET', - '/nwcprovider/api/v1/config', - this.g.user.wallets[0].adminkey - ) + .request('GET', '/nwcprovider/api/v1/config') .then(response => { this.config = response.data console.log('Config fetched:', this.config) @@ -53,7 +49,7 @@ window.app = Vue.createApp({ const response = await LNbits.api.request( 'POST', '/nwcprovider/api/v1/config', - this.g.user.wallets[0].adminkey, + null, data ) Quasar.Notify.create({ diff --git a/static/routes.json b/static/routes.json new file mode 100644 index 0000000..e69de29 From ace75fdd3d354f96686f13e731e8721854607365 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 25 Mar 2026 17:04:57 +0100 Subject: [PATCH 66/90] update dev env and delete stale yarnpkg repo (#33) --- .devcontainer/pre-setup.sh | 5 +++++ .devcontainer/setup.sh | 6 ++++++ package-lock.json | 16 ++++++++-------- package.json | 4 ++-- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/.devcontainer/pre-setup.sh b/.devcontainer/pre-setup.sh index 6a2b99e..a6e490a 100644 --- a/.devcontainer/pre-setup.sh +++ b/.devcontainer/pre-setup.sh @@ -1,6 +1,11 @@ #!/bin/bash set -e +# workaround for devimage +sudo find /etc/apt/sources.list.d -maxdepth 1 -type f -exec \ + sh -c 'grep -q "dl.yarnpkg.com/debian" "$1" && rm -f "$1" || true' _ {} \; +sudo sed -i '/dl.yarnpkg.com\/debian/d' /etc/apt/sources.list || true + sudo apt update -y sudo apt install -y curl sudo apt-get install -y docker.io diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index 261f66b..04053c0 100644 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -3,6 +3,11 @@ echo $PYTHONPATH CONTAINER_WORKSPACE_FOLDER=$1 cd $CONTAINER_WORKSPACE_FOLDER +# workaround for devimage +sudo find /etc/apt/sources.list.d -maxdepth 1 -type f -exec \ + sh -c 'grep -q "dl.yarnpkg.com/debian" "$1" && rm -f "$1" || true' _ {} \; +sudo sed -i '/dl.yarnpkg.com\/debian/d' /etc/apt/sources.list || true + cd $HOME echo $PWD if [ ! -d ./lnbits ] ; then @@ -25,3 +30,4 @@ cd $CONTAINER_WORKSPACE_FOLDER poetry install --no-interaction npm i prettier npm i pyright +pip install uv diff --git a/package-lock.json b/package-lock.json index 06a81d1..11f3af5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "prettier": "^3.2.5", - "pyright": "^1.1.358" + "prettier": "^3.8.1", + "pyright": "^1.1.408" } }, "node_modules/fsevents": { @@ -28,9 +28,9 @@ } }, "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" @@ -43,9 +43,9 @@ } }, "node_modules/pyright": { - "version": "1.1.405", - "resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.405.tgz", - "integrity": "sha512-hgy12kLZ1oAMtl9LTsByHftg3AD6Pouwu5rBsQlqYQqCCdGBgaQm9XDAPDap7ayWe9W+NWrUwO7Zy1K7uXoE2A==", + "version": "1.1.408", + "resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.408.tgz", + "integrity": "sha512-N61pxaLLCsPcUuPPHMNIrGoZgGBgrbjBX5UqkaT5UV8NVZdL7ExsO6N3ectv1DzAUsLOzdlyqoYtX76u8eF4YA==", "license": "MIT", "bin": { "pyright": "index.js", diff --git a/package.json b/package.json index 97f219d..1ff8b61 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "author": "", "license": "ISC", "dependencies": { - "prettier": "^3.2.5", - "pyright": "^1.1.358" + "prettier": "^3.8.1", + "pyright": "^1.1.408" } } From 60e18c88f0f13b5fb49d16c59b3afddc8920b021 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 25 Mar 2026 17:29:47 +0100 Subject: [PATCH 67/90] make sure gc never iterate over a mutating dict --- nwcp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nwcp.py b/nwcp.py index 26eeab3..61f8661 100644 --- a/nwcp.py +++ b/nwcp.py @@ -53,7 +53,7 @@ class MainSubscription: expire = expire or 1 * 60 * 60 now = int(time.time()) deleted_ids = [] - for [event_id, event] in self.events.items(): + for event_id, event in list(self.events.items()): if event_id in self.responses: if now - event["created_at"] > expire: del self.events[event_id] From 75107ff04da294bad17d346be846c4595ab77763 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 25 Mar 2026 17:33:53 +0100 Subject: [PATCH 68/90] default with empty tag list for listeners that return None --- nwcp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nwcp.py b/nwcp.py index 61f8661..6e254d5 100644 --- a/nwcp.py +++ b/nwcp.py @@ -338,7 +338,7 @@ class NWCServiceProvider: for result in results: r = result[0] e = result[1] - t = result[2] if len(result) > 2 else None + t = result[2] if len(result) > 2 else [] out = {"result": r, "error": e, "tags": t} outs.append(out) except Exception as e: From 3c52d5d49df0d8a0ac8568807cbc38708d2e749a Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 25 Mar 2026 17:37:38 +0100 Subject: [PATCH 69/90] copy tags returned by listeners instead of mutating them in place --- nwcp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nwcp.py b/nwcp.py index 6e254d5..cfa7f82 100644 --- a/nwcp.py +++ b/nwcp.py @@ -356,7 +356,7 @@ class NWCServiceProvider: res: dict = { "kind": 23195, "created_at": int(time.time()), - "tags": out.get("tags", []), + "tags": list(out.get("tags", [])), "content": self._json_dumps(content), } # Reference request From 08070257f84a80db6af84a117d1e3798b6fb9348 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 25 Mar 2026 17:38:03 +0100 Subject: [PATCH 70/90] fix expiration handling (#32) --- nwcp.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/nwcp.py b/nwcp.py index cfa7f82..9e45622 100644 --- a/nwcp.py +++ b/nwcp.py @@ -378,6 +378,17 @@ class NWCServiceProvider: sent_events.append(res) return sent_events + def _extract_expiration_from_tags(self, tags: list) -> int: + expiration = -1 + for tag in tags: + try: + if tag[0] == "expiration" and len(tag) > 1: + expiration = int(tag[1]) + break + except Exception: + pass + return expiration + async def _on_event_message(self, msg): if not self.sub: return @@ -387,7 +398,7 @@ class NWCServiceProvider: if not self._verify_event(event): raise Exception("Invalid event signature") tags = event["tags"] - expiration = int(next((tag for tag in tags if tag[0] == "expiration"), -1)) + expiration = self._extract_expiration_from_tags(tags) # Handle event expiration if the relay doesn't support nip 40 if expiration > 0 and expiration < int(time.time()): logger.debug("Event expired") From 5d70b9f42778d806747690c2e1be5525e0a8e111 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 25 Mar 2026 17:41:45 +0100 Subject: [PATCH 71/90] Strengthen types for linter --- nwcp.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nwcp.py b/nwcp.py index 9e45622..3f26647 100644 --- a/nwcp.py +++ b/nwcp.py @@ -352,11 +352,13 @@ class NWCServiceProvider: content["result"] = out["result"] if "error" in out: content["error"] = out["error"] + raw_tags = out.get("tags") + tags = list(raw_tags) if isinstance(raw_tags, list) else [] # Prepare response event res: dict = { "kind": 23195, "created_at": int(time.time()), - "tags": list(out.get("tags", [])), + "tags": tags, "content": self._json_dumps(content), } # Reference request From 936768880290dd60a6fb167cb75ef64b34e12c7f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 18:16:46 +0100 Subject: [PATCH 72/90] Periodically resend NWC service info event (kind 13194) (#34) --- nwcp.py | 33 +++++++++++++++-- tests/unit/test_nwcp.py | 80 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/nwcp.py b/nwcp.py index 3f26647..efa5279 100644 --- a/nwcp.py +++ b/nwcp.py @@ -121,6 +121,9 @@ class NWCServiceProvider: # Garbage collection loop self.gc_task = None + # Periodic info event resend loop + self.info_event_task = None + # Subscription self.sub = None self.rate_limit: dict[str, RateLimit] = {} @@ -185,6 +188,7 @@ class NWCServiceProvider: """ self.reconnect_task = asyncio.create_task(self._connect_to_relay()) self.gc_task = asyncio.create_task(self._gc_loop()) + self.info_event_task = asyncio.create_task(self._info_event_loop()) def _json_dumps(self, data: Union[dict, list]) -> str: """ @@ -296,6 +300,14 @@ class NWCServiceProvider: methods and subscribe to nip67 events. """ # Send info event + await self._send_info_event() + # Resubscribe to nwc events + await self._subscribe() + + async def _send_info_event(self): + """ + Build and publish the NWC service info event (kind 13194). + """ event = { "kind": 13194, "content": " ".join(self.supported_methods), @@ -304,8 +316,20 @@ class NWCServiceProvider: } self._sign_event(event) await self._send(["EVENT", event]) - # Resubscribe to nwc events - await self._subscribe() + + async def _info_event_loop(self): + """ + Periodically resend the service info event (kind 13194) so that the + provider can recover if the relay silently dropped the event without + closing the WebSocket connection. + """ + while not self._is_shutting_down(): + await asyncio.sleep(60) + if self.connected and not self._is_shutting_down(): + try: + await self._send_info_event() + except Exception as e: + logger.warning("Error resending info event: " + str(e)) async def _handle_request(self, event: dict) -> list[dict]: """ @@ -600,6 +624,11 @@ class NWCServiceProvider: self.gc_task.cancel() except Exception as e: logger.warning("Error closing gc loop: " + str(e)) + try: + if self.info_event_task: + self.info_event_task.cancel() + except Exception as e: + logger.warning("Error closing info event loop: " + str(e)) # close the websocket try: if self.ws: diff --git a/tests/unit/test_nwcp.py b/tests/unit/test_nwcp.py index 3e23eb6..800e853 100644 --- a/tests/unit/test_nwcp.py +++ b/tests/unit/test_nwcp.py @@ -1,3 +1,4 @@ +import asyncio import json import random import string @@ -125,3 +126,82 @@ async def test_handle(nwc_service_provider, nwc_service_provider2): p_tag = [tag for tag in tags if tag[0] == "p"] assert len(p_tag) == 1 assert p_tag[0][1] == nwc_service_provider.public_key_hex + + +@pytest.mark.asyncio +async def test_send_info_event(nwc_service_provider): + """_send_info_event should publish a signed kind-13194 event.""" + nwc_service_provider.add_request_listener( + "pay_invoice", lambda *args, **kwargs: None # type: ignore[arg-type] + ) + + sent: list[list] = [] + + async def _send_capture(obj): + sent.append(obj) + + nwc_service_provider._send = _send_capture + nwc_service_provider.connected = True + + await nwc_service_provider._send_info_event() + + assert len(sent) == 1 + msg = sent[0] + assert msg[0] == "EVENT" + event = msg[1] + assert event["kind"] == 13194 + assert "pay_invoice" in event["content"] + assert nwc_service_provider._verify_event(event) + + +@pytest.mark.asyncio +async def test_info_event_loop_resends(nwc_service_provider): + """_info_event_loop should resend the info event while connected.""" + sent: list[list] = [] + + async def _send_capture(obj): + sent.append(obj) + + nwc_service_provider._send = _send_capture + nwc_service_provider.connected = True + + loop_task = asyncio.create_task(nwc_service_provider._info_event_loop()) + # Allow the loop to run through one sleep cycle (patched to near-zero). + # We drive it by cancelling right after the first send opportunity. + await asyncio.sleep(0) # yield to let the task start + # Manually trigger a resend call to verify the helper works correctly. + await nwc_service_provider._send_info_event() + loop_task.cancel() + try: + await loop_task + except asyncio.CancelledError: + pass + + # At least the manual call went through. + assert len(sent) >= 1 + for msg in sent: + assert msg[0] == "EVENT" + assert msg[1]["kind"] == 13194 + + +@pytest.mark.asyncio +async def test_info_event_loop_skips_when_disconnected(nwc_service_provider): + """_info_event_loop should not send the info event while disconnected.""" + sent: list[list] = [] + + async def _send_capture(obj): + sent.append(obj) + + nwc_service_provider._send = _send_capture + nwc_service_provider.connected = False # not connected + + loop_task = asyncio.create_task(nwc_service_provider._info_event_loop()) + await asyncio.sleep(0) + loop_task.cancel() + try: + await loop_task + except asyncio.CancelledError: + pass + + # Nothing should have been sent because connected=False. + assert len(sent) == 0 From 1d001d6e1051d48130841f36313895ba0e150419 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 19 May 2026 15:22:45 +0200 Subject: [PATCH 73/90] fix budget refresh logic for "Never" --- models.py | 2 +- tests/integration/test_all.py | 73 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/models.py b/models.py index a84c46f..fa52baa 100644 --- a/models.py +++ b/models.py @@ -39,7 +39,7 @@ class NWCBudget(BaseModel): c = int(time.time()) if self.refresh_window <= 0: # never refresh # return a timestamp in the future - return c, c + 21000000 + return self.created_at, c + 21000000 # calculate the next refresh timestamp elapsed = c - self.created_at passed_cycles = elapsed // self.refresh_window diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index 56d9717..2eeb059 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -822,6 +822,79 @@ async def test_budget_refresh(): await wallet1.close() +@pytest.mark.asyncio +async def test_never_refresh_budget_counts_previous_spend(): + await check_services() + nwc1 = await create_nwc( + "wallet1", + "test_never_refresh_budget_counts_previous_spend", + ["invoice"], + [], + 0, + ) + nwc3 = await create_nwc( + "wallet3", + "test_never_refresh_budget_counts_previous_spend", + ["pay"], + [ + { + "budget_msats": 100000, + "refresh_window": 0, + "created_at": int(time.time()), + } + ], + 0, + ) + wallet1 = NWCWallet(nwc1["pairing"]) + wallet3 = NWCWallet(nwc3["pairing"]) + + try: + await wallet1.start() + await wallet3.start() + + await wallet1.send_event( + "make_invoice", {"amount": 60000, "description": "Within lifetime budget"} + ) + result, _, error = await wallet1.wait_for("make_invoice") + assert not error + + await wallet3.send_event("pay_invoice", {"invoice": result["invoice"]}) + _, _, error = await wallet3.wait_for("pay_invoice") + assert not error + + await asyncio.sleep(2) + + async with httpx.AsyncClient() as client: + resp = await client.get( + "http://localhost:5002/nwcprovider/api/v1/nwc" + "?calculate_spent_budget=true", + headers={"X-Api-Key": wallets["wallet3"]["admin_key"]}, + ) + assert resp.status_code == 200 + payer_nwc = next( + item + for item in resp.json() + if item["data"]["pubkey"] == nwc3["pubkey"] + ) + assert payer_nwc["budgets"][0]["used_budget_msats"] == 60000 + + await wallet1.send_event( + "make_invoice", {"amount": 50000, "description": "Exceeds lifetime budget"} + ) + result, _, error = await wallet1.wait_for("make_invoice") + assert not error + + await wallet3.send_event("pay_invoice", {"invoice": result["invoice"]}) + _, _, error = await wallet3.wait_for("pay_invoice") + assert error + assert error["code"] == "QUOTA_EXCEEDED" + finally: + if wallet3.ws: + await wallet3.close() + if wallet1.ws: + await wallet1.close() + + # Mostly AI generated pentests From 16dd9015c4b6bf0662d6988cd743d8f18a7e7006 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 19 May 2026 13:35:03 +0000 Subject: [PATCH 74/90] format --- tests/integration/test_all.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index 2eeb059..fb33c1f 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -872,9 +872,7 @@ async def test_never_refresh_budget_counts_previous_spend(): ) assert resp.status_code == 200 payer_nwc = next( - item - for item in resp.json() - if item["data"]["pubkey"] == nwc3["pubkey"] + item for item in resp.json() if item["data"]["pubkey"] == nwc3["pubkey"] ) assert payer_nwc["budgets"][0]["used_budget_msats"] == 60000 From bb94f38c2f5cf460820c4c035682c92668a4debe Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 19 May 2026 14:16:04 +0000 Subject: [PATCH 75/90] break wait loop when payment fails --- tasks.py | 8 ++++++++ tests/unit/test_tasks.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/unit/test_tasks.py diff --git a/tasks.py b/tasks.py index a19a0d8..70f3205 100644 --- a/tasks.py +++ b/tasks.py @@ -114,6 +114,14 @@ async def _process_invoice( payment_status = await check_transaction_status(wallet_id, payment_hash) if payment_status.success: break + if payment_status.failed: + return { + "error": { + "code": "PAYMENT_FAILED", + "message": "Payment failed.", + }, + "in_budget": in_budget, + } await asyncio.sleep(0.05) if not payment_status: raise Exception("Payment status not found") diff --git a/tests/unit/test_tasks.py b/tests/unit/test_tasks.py new file mode 100644 index 0000000..cca51bb --- /dev/null +++ b/tests/unit/test_tasks.py @@ -0,0 +1,31 @@ +from types import SimpleNamespace + +import pytest + +from ... import tasks + + +@pytest.mark.asyncio +async def test_process_invoice_returns_payment_failed_on_failed_status(monkeypatch): + async def fake_tracked_spend_nwc(*args, **kwargs): + return True, "a" * 64 + + async def fake_check_transaction_status(wallet_id: str, payment_hash: str): + return SimpleNamespace(success=False, failed=True) + + monkeypatch.setattr(tasks, "tracked_spend_nwc", fake_tracked_spend_nwc) + monkeypatch.setattr( + tasks, "check_transaction_status", fake_check_transaction_status + ) + + result = await tasks._process_invoice( + wallet_id="wallet123", + pubkey="a" * 64, + invoice="lnbc1example", + amount_msats=1000, + description="test", + ) + + assert result["error"]["code"] == "PAYMENT_FAILED" + assert result["error"]["message"] == "Payment failed." + assert result["in_budget"] is True From 5fecaca2689e097832aa228d32c3a6b37912e5a3 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 19 May 2026 14:36:13 +0000 Subject: [PATCH 76/90] make linter happy --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 42556ae..dc659bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,8 +83,8 @@ classmethod-decorators = [ # [tool.ruff.lint.extend-per-file-ignores] # "views_api.py" = ["F401"] -# [tool.ruff.lint.mccabe] -# max-complexity = 10 +[tool.ruff.lint.mccabe] +max-complexity = 11 [tool.ruff.lint.flake8-bugbear] # Allow default arguments like, e.g., `data: List[str] = fastapi.Query(None)`. From 16a0ec8ab260e5787b12e7c09f76cae66f487a06 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Tue, 19 May 2026 15:00:35 +0000 Subject: [PATCH 77/90] bump version to 1.1.2 --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 035ccbc..e74cc86 100644 --- a/config.json +++ b/config.json @@ -2,7 +2,7 @@ "name": "NWC Service Provider", "short_description": "A NWC service provider for LNbits", "tile": "/nwcprovider/static/image/nwcprovider.png", - "version": "1.1.0", + "version": "1.1.2", "min_lnbits_version": "1.4.0", "contributors": [ { From 0204f8ff85ed9a4125671171d5bf394d84d6812e Mon Sep 17 00:00:00 2001 From: Richard <115934595+bitcoin3us@users.noreply.github.com> Date: Tue, 2 Jun 2026 10:36:40 +0100 Subject: [PATCH 78/90] list_transactions: fall back to extra.comment / memo when BOLT11 description is empty (#43) --- tasks.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tasks.py b/tasks.py index 70f3205..412f2b5 100644 --- a/tasks.py +++ b/tasks.py @@ -425,7 +425,13 @@ async def _on_list_transactions( { "type": "outgoing" if p.is_out else "incoming", "invoice": p.bolt11, - "description": invoice_data.description, + # Fallback chain so a human-readable description reaches + # the NWC client. Mirror of `_on_lookup_invoice` + "description": ( + (p.extra or {}).get("comment") + or invoice_data.description + or p.memo + ), "description_hash": invoice_data.description_hash, "preimage": p.preimage if is_settled or p.is_in else None, "payment_hash": p.payment_hash, From 14a96271ad44d01333231c84843ea2dd881220df Mon Sep 17 00:00:00 2001 From: DoktorShift <106493492+DoktorShift@users.noreply.github.com> Date: Wed, 3 Jun 2026 11:47:38 +0200 Subject: [PATCH 79/90] Changes to more pages (#29) * Changes to more pages * fix: correct thumbnail URL in config.json Changed image URI from lnbits/tpos to lnbits/nwcprovider. * Fix lint after main merge (tasks.py) - remove trailing whitespace (ruff W291) - collapse description chain (black) --- README.md | 17 +++++++++++++++++ config.json | 14 +++++++++++++- description.md | 11 +++++++++-- static/image/nwc_thumbnail.png | Bin 0 -> 509736 bytes tasks.py | 6 ++---- 5 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 static/image/nwc_thumbnail.png diff --git a/README.md b/README.md index b222469..84ba938 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ + + + + LNbits + + + +[![License: MIT](https://img.shields.io/badge/License-MIT-success?logo=open-source-initiative&logoColor=white)](./LICENSE) +[![Built for LNbits](https://img.shields.io/badge/Built%20for-LNbits-4D4DFF?logo=lightning&logoColor=white)](https://github.com/lnbits/lnbits) + # NWC Service Provider Extension for [LNbits](https://github.com/lnbits/lnbits) Easily connect your LNbits wallets via [NWC](https://nwc.dev/). @@ -68,3 +78,10 @@ The "Configuration" page of the NWC Service Provider extension can be accessed b > For example, in shared or community lnbits instances, where users are unaware of this functionality, they might assume a payment has failed and attempt to pay a new invoice with a different wallet, only for the instance to come back online and process the original payment request, potentially leading to duplicate payments. > > For this reason, unless you are trying to tackle this specific issue, it is recommended to leave this setting at `0`. + +## Powered by LNbits + +[LNbits](https://lnbits.com) is a free and open-source lightning accounts system. + +[![Visit LNbits Shop](https://img.shields.io/badge/Visit-LNbits%20Shop-7C3AED?logo=shopping-cart&logoColor=white&labelColor=5B21B6)](https://shop.lnbits.com/) +[![Try myLNbits SaaS](https://img.shields.io/badge/Try-myLNbits%20SaaS-2563EB?logo=lightning&logoColor=white&labelColor=1E40AF)](https://my.lnbits.com/login) diff --git a/config.json b/config.json index e74cc86..9fbe5ce 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,10 @@ { + "id": "nwcprovider", + "version": "1.1.0", "name": "NWC Service Provider", + "repo": "https://github.com/lnbits/nwcprovider", "short_description": "A NWC service provider for LNbits", + "description": "", "tile": "/nwcprovider/static/image/nwcprovider.png", "version": "1.1.2", "min_lnbits_version": "1.4.0", @@ -22,6 +26,10 @@ } ], "images": [ + { + "uri": "https://raw.githubusercontent.com/lnbits/nwcprovider/main/static/image/nwc_thumbnail.png", + "link": "https://www.youtube.com/watch?v=0c77d2q-_PQ" + }, { "uri": "https://raw.githubusercontent.com/lnbits/nwcprovider/main/static/image/1.png" }, @@ -34,5 +42,9 @@ ], "description_md": "https://raw.githubusercontent.com/lnbits/nwcprovider/main/description.md", "terms_and_conditions_md": "https://raw.githubusercontent.com/lnbits/nwcprovider/main/toc.md", - "license": "MIT" + "license": "MIT", + "paid_features": "", + "tags": ["Nostr", "Wallet"], + "donate": "", + "hidden": false } diff --git a/description.md b/description.md index bc65726..edb14d1 100644 --- a/description.md +++ b/description.md @@ -1,3 +1,10 @@ -NWC Service Provider Extension for https://github.com/lnbits/lnbits +Connect your LNbits wallet to apps using the Nostr Wallet Connect protocol. -Easily connect your LNbits wallets via https://nwc.dev/ +Its functions include: + +- Exposing your wallet via the NWC protocol +- Connecting to NWC-compatible applications +- Managing wallet connection permissions +- Supporting the nwc.dev standard + +Enables seamless integration with NWC-compatible apps like Alby, Amethyst, Jumble, Buho and other Nostr clients that support wallet connections. diff --git a/static/image/nwc_thumbnail.png b/static/image/nwc_thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..31b1c7d9b83cc47bb65a6753e83dc4f167e203e0 GIT binary patch literal 509736 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�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
B!fN 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
uSKKWjp-11Hl4+5KDrD;NSg zI*Z%5u5LK`pvOR}!0(miN4HmIcLax<}Pqa#J zf9vVF`n7JL%-Zi!UE8ksaENxsY;*}$yc5xU*lZq?M3=OR^@~l*zgr!(%`fJNdu()x zEqJ~Vg8*A-$1btNpL?cUah}QY?1fO}m!mqVe;BqbFu7@d(Rq6J+QQsA(^+c_t1tdj z;ggQsR_A@afU{LA^LnX`xs#CM*At7Ud{^{bAFRH4W0b1~Q=G!D6YKig_*M%rwew~9 zbw3g4Z(hrIFyO-EMcloj9NlJL)H^Tfvz|y!zEN;EU?O98+|eZyZiQ{SJNe3lD0Zt~ zJ>oxNyRJ#R3JZ9oFmEqM2G@r6_6{kPGcs=kgPKVzguX?>$&+>VxF@WXr-Kd zaJ6WDXXbtmhnZ6sq&;@?`yd#9Yc>DstJ{{Tgm<(vx*hkEkrHEAF-_!>n{t7VYEZ~V z4z)blXXQ#oev$u;R}|}*M!W0&v5A?SEw;?DrEOO41^F#cC&}!dz1Q&Fg1dn(I$=7b|e{jZCw@EsLbJ14ri)$awn$?`HxA&M2b4hThP;S1gr;+70#*Gsn`^}XR z+d$A$?E0V z8&=IVnH;KkpgrJOaA@c6$NyJWE?*)g718G`w`@tDm6TQ2acA4!?`=Ze-==-@WY#bC zOjB|>^0NHST&qpbo|oN7@nQtOa;sD=8##A{=rs$=pZj!6@m$oIm$c5*&vJ2`U6OsOQ%IyiE#q|bvflVJ zktO%9WJPa2nWEhByQ1UQPp8Gji_<1voa^^Ta*ySw-PYGlz1xpP_k33pj1F!VGNEJRa$&|C!ViM|NVGkL(Uv;opoma?)F`X z&gG3-qG#PN-0XRx#=XLe_tzJnpeNt?Zz-5b{BNJYeuF7$jimgR zg5AYy)SDgD&E}SGt7TR0I<>E7dBcj?Q&~AvGi7$XZT_3)Z?){u9r$ zc9o2G-;-Syd_J{tx)mwe+h5DAT3c9m_sH)x{kxo<-ha%webs^S<#RLM%~p9O66?+ITKNv=Wj&W?yR9@_*WR4=bmjNF)5i9p8;(EVv&pbI{rB$` z#*|#1VCQbDrDr##c5H9o+Qp%h;(s}1%gN)mxi?t2tTr~ydbVt(WKjD>4v|+|mME|m zUluy-eSA@t`P+M;I zmLylRyM0Gzak)`@pGycQ|#GHRfl3GUa`jF&X%dk ziYgDSVvki{z0Pr{?!xqbo;RD{l{|91cGyklTE5C^C$?s91{0syLs!lzJ?ii0yd-nX z{mhkct~Cpv&#|05X_t0p_j~8W-(phvKF%$t^IVor{_9%J({(H7N!C2gnYR0{ocvzL zrEa{sa_*hWYqL_d?zHh*Mzi|3yxX=|z@w-B0DDsR1e;Zro98JvO?Vzy5Gm<~i#dQ=>ayn=gMeHwk=l z-ggh2IO$}iLkQi6Sty*~f^v8kei%Tt!CPOVj} zbqo9T)Y+6S$8Y<-ReNthLmHQfQ1#=M-I`r$X)_inXznrJt6a#t`>3cR@AJhI3~C$P z1sI*SzCNR-V{)d(?5gXtoj;!6y~@C#R#as!XYwm>B3F;Lu2SK?+(ibfxHoBPq!-P+ za_|znqoI}gwK^?n)s#QW-257v+kA72OAVd81P>V>-SRt&8BUcIjgC9SR?UoE9lpWw!v*8D(UNS3 zdJZ1CS`@;Rv2=ldxu5siR3E8~ZpB-|+=?q@D=%?#&E4~nZ`SwgA>9`z^}IG*@wQph zUev`{ZI-L8Re_vTiswH2OM!YdqJm~q&qTwZ%bM!qHPIrB|} zM+K97U6#GpWc6f9UTQM?Y3Z?);GS}}{$y-}vji&o&JZYvT^lyov zijBM^qfeiJ}PmbON@lvQ|=EjQkzUb+$1J8}k5o4Hjr##B<4zt5<*7hB#pLXZIP0YDCS8(Z$wC!IvDKwip zncWH&Grn3D^@(NSLiGTd6>VHI1Nbzaq<=c{(5h}F=P%VYhc-7aEcV-ddL93AzlpVT ze$-9&Zg*KYw}M;f$jR?Nb^qR2CUkB7&&7@*ozJ(dD*3>9@$`jLQx`vW z;LS4sc*K3NZ_4jENWvV7F5D5}|l@#$PU{-SRgig-IOa4ZD`TR8f_uu}7pB7FwQdcclU{I3J zIn_GUZ2bvZ0so+gZO_?_R&CwrBmNd$-pgW2t#0zMMJKp0`gdOaD~%8u1E` zaAw~>Rr2hMR&O?KtvNJz`Oz6mCbA#BP<32#;SM$41{;|PS?&9Gbx&rVWvJC_;pXBg zylEnj>g~1D?;Tp#=yP}StZh7o0VgwrL_WloNY-gQR&syb*>w2_Z=o!oN=a0O`QjeakJDvKz^I0cK0e1h3-1lN$WRVxtSDnyk^Z}^Z7QtS4}f}WxWf0Vyh%f753f^ z=XmmNnk>KLt?vsN{khf#70>!*=Xc`Hv}qZ>$`cc$&$>C8I5?F4y%u|5*TX4%|2h~R z&OGbIJU!oSt>GujZN16wgID~0-v4~g_t$M!zqU9$UM2PLSnl1*4%Jc#jS1ISLTc@V zK0PZ7jV@PH{Virtw?;JU^`Yps0p;hG9ua&~*ZoX*!y%5a)4Jw%6$@S%9%=ZudE3Qz zlh>R*{=f<2z8Q<1S1_^8`_Fgx?9t*aUneOF^d*GN zR88bKcwF#W%d3Wqk6vW>J4bz}$$d5PpAB=SO3C)}uBsX7Tv^|5^5&c?@7wZLD%bI@ z$FV1R=b0E{nHto}-!nAa@|jcOd_4JC?u>g&yh9A@W*nREm-ld*xZJ6QH3Hmkw=Uy* z8c?@x>FxMvOVN5;(W%cFpJmF;+SluL|8MkZ#anj|%e^)fdOGW-lic6ZrlT6cp{soK zf`!>1T)KBV<G<pp6LFEtyRMN>CNw}B1g@nZRcLjIP?2IbHR73 z?94;CmgmmCII~vHWYK?xX&d#*SDOk~>dk$8%eUbATntdMdxt8voKmDj; zX_@i$v&T#B^}4e&-?ELZ&~5%aDPwNer1sLQrLq#W`N_F&`4dc{y8|NL7Oz_Wa?-Po zy^lBKzNuD|UTvCT?G&7#JT`pA>UB?4d+fF7^FtRk zOKC&Ck9~si*D@~d>G>vHz3McpnbPie3p5&M7ce^o34P7c^_(@kSM`sur(# zcbg+jVte%^k1h9vrGEHIO<3K}X}Z9XdBT~(W#1YfS+uZZZoZb#QB!Gt%SvhPQ>W-# zc0X-ar4~MWw!Uzg{cgK^J-3Q^yu=N@&iwk?^7Kv>L1Q0Sx(l zwbxvFrm^H;-D97|RHjEhQ)kaywAG@c(tAg>$;$27{;Qljt_6H=>O5yW>5AJm=_^+I z40KGas^u9A0z;#mOVmGHns01gsFf7dGykfe`lT182kQQERO{B&ozr;Smg;>X-C)(r z73(bZm-Ho?B+p#=Z1Th}m%CriGtRcT9xGXEe41~%Px7rxx~|dkqID%J7kzHN?`AbC zNRMH~<RxYl%7se_YL~yPQT_MGVUGH4#iwg@wrpRmV!`JA z-sHRZjI#;*`?rSO*!B8n#PNrp>U`zwvU;Rvln5`Ww7;O^WBvT#g52xDEP4CE- z-tBo?d+zd;&;K(ed@SMhn8h5%(|bfS##cd?qC!-=ThfCiK%Jzmio2Z zHjz#4DbWQO^e@`#&k)Ql^Ms}u& zy)ySon|E9{byn;;l&qT?#2USMm0+7CZ;hKQ_m@4*F4zBG3j_Y=tjc2Dv*MM{uC)BZxxrgQ%|x9) zGk?`TwL0<4#h0dCHy8Md%-d;W)BW1;cG}9RcgSywzG$)>A*X!Rh>r&UuC(gp}-`KCSCey4!zw(zZV( zi>H5WKiOd+Vi=O#kz(SqxBo=a#kw`k2@j(7RjIp~Tv*BNBKJ&rp<7n(`>!=!o?kT1 zN*v$*DyQjIRmu0o>(+L1EL@p*GnY?F#&g!n*?J5PEqOI+%qG8%%~Q?XRcE#6?x&RO z$@QK^oliY(I?3Ljzj(QWTC+TFR@ZUkllR&S9jmu)T=Xw5Yn4vZ`5!ly-M!h->ted^ z)^g@cw~QBQM}Kn3)jTS!{LQ4Hgx3cBSTe=MSc$>%Uc+c`{0+ zBd;p(cz#Z9_O*axiyztMx-i9Yl$a#fJn6a+V|m-#OhN5-^|6&=la4N)8L`!5_c;>| zBc=H(w*C|=+kU}Scg@45oBm2h<@WcplVyrTXMJDH9LLAd+q7)PN&ce=3qLAFpA`(; zce~8(;LE?y?#@bleC=QPu30O~E#KQ~h&(u#Wx=+uc~_F#olEL>gnsW`#NKdBdyVe0 zi+}H?&AMGvz2vdX$?8 zrmni)C#`1Q|NWZZ$r;X^vCLOoPkfua%fl)tCjF6vu;3QcWwNE^W!lA&XZpf^rx;3H zH?B1HY0q>sb9u`--S+sWg3FGXLCNdq-U|2h?&h0xBKi5p$c+1buK({<{$*K^s&vxu zB|~55WCg~~PXWR5yMIi-GC^+X2GiLcA>C!XW=jj}&G*MH7VdjJx8Yg(Z(oV4AxVEF zZq5^Qk<;t?7_QL7C~T^k`zGdzmBytTOK$3HdAW!)=Zc2ey{RI`v(`^6GTm%JAL@Bev8dL#S)DP=R}?i2Zzv{(M& z4E5!@=Q;oJ=Eh{ySRPBc^L?Y&410+mOW*!Akvbeacd!34{cB${dcS1rHhkJ+$?x(*xVze^{|Nw@#Ex>ZVDi`K3z{?3!DY=FXk9Gw{s}F0KnqlG)*h z;||Y$YO`&vX72;F*w@RN&84nznsNDFcXDHSD3`qNNnT7r5X>!{en)+Qk|18|8Vp_CfX{6Y*&y%i; zN?3P)WeD(}|2ErRtUGtgyqEhn8_AVei5B{tO1Y@#_h0kmd(Z~o1s61D-d!kjihXIo zzs>K@E?@h{Y+m$=cDHJq71kHL6&up|la`n+6qj|{v#ov0bd_&;>!KM}z6xQVEpy(j z=FY}}eP3U8lpre%mXbrLgIcN&U8R!xKwXy#0GqrwGiSwxHK@cDmCev!`2* zMr<{HvhtOv*Occ`O-{$xN!F#f_5GnDUd)t&$9*0sMzuM@*(>%M$Za=CwdsddNCCq|Di^Log(t_{t| zf8BE6P{YR`&n-+Ox~qK4_jIo~o4>q^srzB+qWzp^zE`gc?(=jB32iC5r+}5E8pT4OE1{0+eUV!~)7f&$_azseyytv+MR2Zv|ad>7--gvv*F&y53j#>qbRORmcPY>qQ+-j<*mF;;7?YP zfFV<&Rg_fi(TX#>@5iQ3%k&YGvb}!djC%C$goB%Z-%eMWwWj-;rG;&JKT~5i&vxbS zo#Fxa8q4h6N|iZR^tww=Iw^E=s(I}4Tt%(4YIo+VEAHAny4tejXN{ip^~CpQS$Jco z?#tR0?lW`w_M5ZplO&@v;u)`esgTysd+T)L*>0^P499sMO}^?MlFD#)f6lLS4`N%U zY4^Kr&$+2{>po}e&f+;`jxXHJH$>|OecE_Yx+sogfu7m?wwq$9u{T-1+Lb*qj{jnn zd7|ZR>5>~~jTwrSx!Q!6sC+iucuPcULQL@Ew@R4>E_*l6+Gg_q$?Q*AudjTXYs_|~ z-cxK#h~-(o;A7tVbd}{-b9}wgll`oAoAuVS-P__BczHDDzb)=h;}&{!CG+gQ1XU%& z$Uh5ap4ny*w7V;5-@^TuFTFQ@Uv_u$cNvBS&OeuG!4lZ2o|3J5^Y-4W;nFy`Cm@jSXHr-(=gxn2+za08EvYjXEc1;$~r97E%^FezwKN5tw6o` znS$=6PhroSQa$&c-OwW@KGE;seKXm2+b^;Iio7uC*v9O?-vyU$b+?*Yw8Svg`eN%BcfN%%AasuJWp5a&5K_h`tuXwEXfg1+>9#><+uCQe@FLwIaf|H*MGBmv0%}G8mmv1 zk8G8tivNDxG=Jm4j;;52?><^~ExxdM@y8<>yEIoO9y(iAy06qvV$GpDFK#(JS)j9V zdgSXe{bfIw?F~5=?NNSv+NtJ4zk91+&z9^ko^f<;Rn^2v=6?5gUJ**a``6lZe+l#J z_m|#H+{`C_Q)c5(#x@qb9wO_QoJ;L+cvceocAuZt-Q3bvUW?hd8_W(XunJKZd~`C z?A!RrF#JdGy)4Il)=M{bo(}e%#4)cq?ccd;dRdMKZ&$}k%FW&$!Sh(I@$|PXw{(_t z&XvRm2d6FIlU z%Ty@;`G#|8Vd)24&KGYhnPt$u$}De!nrur|t&;yY^VdDXhdA@xtKCcsl~(bd$xVDP zd2#AlS?zg&US_KwyY|WU_y#lFcl*Vi*)9Hh(S7r?MT$Gma1^|kO8b7h&Z^aJsqVkd zo3GEMTvng*LF22P@3(GOl?)amHXf5~r}K83S8py`rc?Oa)??GfkN4(%UJ)Q=ssH@Z z3yGxcIZjI!ZeRQVw)s=lbsH9c2`!s%rQ~sL(buMO=(;$Zfs-{sA=C?_w?#}yT59WR({x3!Z6#)J^S#T|7$oye|M;GJH>@ReBtBYhRx``8Ve}v*qjMd(S^yzWwr# zo1K1F?UydL{+0ROYkCsT!iQzeJJw%$I@i};nAPL=!r6!P{@(vNz4fP5=BCdVecmRB z3+nGZvF`20iu7aAYi%X{mUsU6mTe`z?3=Z8K>d>~mvZ}DLX0GD%kl^PHc@ zFSD$7TO`+N1-^WDv1Z~T%Z#rd7MPU>zRKLVUf$TguV9O0V#|RO58EF74W9Jk%RXDR z+K~S<1a~eoZ?m6vEzxGjjXC>fe}4Tpy3-~v%;?&a^@)}iX&mahakF@P^j0pLe9Y&U z`Of{u#UA^tf@*)CDhe#wf2>sM?=0qus=x(nCrZ}19FXvk{OB|L=44Cfum!Q)=@ni+ zH_wQzzaOq9`s_Jp<(YYJ-%i;Yxnk>iZ=dC7FK*(zx8(7|%iDXa{B@$=N0}_SJ750Y zf(WJ+vmdVOUu^iYr*-ckKaHq0cT*ZZmdl@+7_#i`{hE}*d7rz)KZ-2P^ejJA@y3|- zy(+_&bm4m^S3k3P0&3*$xKO<(4Kx>bc$4@1sC}Ph_r1Py)rX~fjY{HzbGw#wZdP2U z%T=G-|972@S_KB*F+Hc{$YWgeZSMS>k0}p2W^=h?#%;kFC zxA%;VQS_1fo|(x)(~`K~zrAG~6wJ9e`twazokz0bQ9o`3Uvs%Tf7cA3EsI%~u8Q~O zdTXUP?^@M6vFBIszWe!XisqaXs@1V8_WqlaKWD`m%f(jFosNQwuP^b-&U|JdbzbnT zM6H2@zJ~${<^fiVA=O?lO1;Er-i>c#8Tt`^~STDnELShFJEj8-G8=D zoYnCUtblgTD9@Q(T{DjxBFjPu(rHsz5ek#kyWMfGFx9(Pdt13 zaMXs#iRxc2Z*qPY{_M*|(|55qoPQgwdpG4t!K-l7X+;|CpS%NJ*v1)y#(WYL6D*b9 zUYh&XPtT9S}^gsVQpEyZMWC^X=c%7L36p)KBrf4&;9sb*!9H! zX_gFAf)?)gkG;Eu$N9kAKU+edr6J=7n_RWjG&S`qQ?0%CvH|JL%IxJDgJ2P0th8Ha+s|T)Enc zTAOu$B{S91oR+M;yPDfUWmZ&`!jx@hr;9I7Dto?zd98Zn*H5dWa&BB&lvBE+{kYlL zg4u2+Sx5WC)O#zva_$<=d&$2uJ#v%#Ec1-;m-09N-a2VC<8IBPsQjy6w!Cn@V(aVK zzwN@~-X%9IU;m7F^>L+ckHu|I=gt4cF7FKMm7BwJsi~_^b2@Wc@XF2eH5Xhe@sgUY z8?Y^N{-)bi<$_0V2Yr7rSJ-1kb=5@Ql|C~Wj&3&km$)#!T3Vspcb4mkxK)?Ur^g6+ zuaA`BpTu#^+G?_-`BL^^wX);Uw`*q!9a(SqM%_N)PUp0D%Oz#s*L{^+d%LW3OVBpK z+tXHwSp*+%a9?aKsxMXkV*8zT^{Gu}yK~oT#Tv|wvp8|A#5Ci5r`zV=&-D^+N6q-2QGRdgztr8{Jy#d)u&Z@f zf4ofg|E5nfzDG|8KlEbXy?;q+GlH~SU)6T)`X(SyrIF~Uf6+BCnQ_X=Nu9~1MbkVc zCs%~KtIw(n{%~um;18k2=WCU#Vw2KeuH2jNo#<@>&yFy${l^JDR5 z(cLD;mOomv(ZcW2vWvW*I_mq?Gmad|_>z#NSa*iu^g(6`#?l5Fa^$=h>|DTh{muNFP~NqgVc z@~<{OLzKVwmQGwNPLQAY}j^taARh9mj&)%R(%EN$t{m z8FVeq<-;e>r@uK~6!xng%nUrEUb~Z5H?`(JXX27y-_nlPMPPGncoP0X&h~4fBJy*rvTZC$-nU}pTIKAS{_9MG*tMAXt z{~8p#F(Tjm(YtrYi)^3%E(yh|-g!hNn{_jX=$9lNb}CjHQyak9mD zF?YPtTHW{a-x+@Hw|@RGqSxU}Rpj~nC^EP!{+!M_ZaHTqm zA!7}rM%wcAFE%wiHBDLl`-lGI*gdz;DeruvDP<~C^A~$ zdDYv{Yg?z9?Sc)-r+ytz`?$^j-c$ccmSv2}%3rl#T?i1&+daWN^UJ-;IV*L~e=}^D zHrr5Y>9jrB;gg?>GzHwqnE9@1Yx?@g8CUi#{xWINb@|uEXH3%y=lZOl#pV~g!dhs; z_evRQqZr=c91vuFPqcJ-_m%~86hAD-}CKD1mn!0q}4!|SuJ@7Q5~E^7PV8ojV-C5#H%;_8FF9|+lHOo9V_}OvY?)%$x=1mr^o7-0AKJjb0{S1|x zzBA`}*uDDy>d&J`L3_`(Za<-rVZ#}1aoOkwL-%CUS9hO?ZnoOCt#-fPS;hsoHKHv( zzVZDmn|0l*H+$CSN~h&&B6ePX?ebr*dGlhImd^6q?{51Ae!F?$yUtD(w>d9ubwHkJp>$qPPWP8J z44>}>x&(E1u-rB-tk*fUOHIyxPLZ_P#**1FDUNZ%;xq1TSaM>e-T}AE?EZ@df6iaW zsJ{BfZLg}(%-_45UrPO*rEHVG=9TmeU3TDVFZpLxE?%jo5AzOVVmwYMEGQNFt9 z=c%m~H!rtZWtv}pB2#*89c%L()veu8%GMJ!UVeV!=dWJ0M$JzzquP6YXs=ywMrz36 zqWWKI=fbQd*O=w|n}4mI`g3=hy`KFxhiLAJ#?xx_{j)Bvt4&#U<897=&eZdUSrZ?- z`v)~AH7)n!lXIJD^3ULR;)E=8<#K2D zzggn5u*l+KtH-(*UvwsKOdN)7wcFEh&jpu&vy3?&%Rur_m z?BAx=_PGJy_U?VY_n?s2J=e|scmG}bzx(gbrQ6}Ls%5ANa#_D8?C6^T}T)UBR5Q+KOQ=z86Y z>A$;+Q;YmntKtu3U-WTnxKgzGbDQo~ea*j@rN14tRXaFg+t*eTrL-RLDEr*rMi-N7 zdrwXK@KoJw@5O-Yt*usnuG{iWQU7Z{@kP+ZThG==ef7C|+VGpH?D@(Gk8Mx!e3-wt zdiS$kuSHL1C!Be_`eV32R)k?h1SgfeXb-BtH$sn)%nCi_mGeK|k2CgppzpQ^-HwLYoYAD3iXEj%L2 z+j-QSu|bXLLfN|A;kT#f&AL)6{ZrQeV+-@6TL%`%=APMl<)aD1-07b@-`}!(WNo(m zU-IOg4y%;=Ht?&z^D6lfa(JtIrcbpS`}?_ex1Egk?w)Ho#rbC?_=ed1caFMFnJ>;@ zqG{75?s4N4t8w+iOR9HE?}yF3xg;v?8@uE|?XunTp2%ITJ;|YenwMK}vHkWq6a8CZ z-$d{DZ@ZhX`)StpmUEVj`GyBp%X`kgP_7a1PJMTBp@Yx8TTi1+ei~hh44Qf0NQ%Wr z_2|vH@8{KQS$=KH=T6qp3tWj4L$>>V32QlV?`Ed0@LlWBD;zFsXFg2-w$Ap86z`lg zPR)5?8Ig_0WFrIAwy%z`&btv>rWLDhXAIpH zppxU;zf~P-Dal;e>R7T^<&ITtqfiE)V*iEdN5x7v?_!NN$vGu27`~-US%UY`O!i+F zkM>`_rt|ODyeXWK`g$LOO;h*1**s}(ZTUV0?uQ~jT(q|th&J8#@Z4pQJ^=%K|{Le8d*kki` zOT*)Lw>CN?fJ!XB)cfFFoB1v`FWY9#|Kw+&(4`Xj*YU!)u5XpDPG-S#>z`|0;M2`; zEV_T2>BW}EZ=7u2R#|+g{NqB)ZrR*(@73o% z>+R#+y=wbnIV)wSQ&bzV9Id5(K?0qJDuP=w1 zTwkmd6p(MQ{`B|v84s4ob=_7k)85VCa>&H$`?PO6zIHhr>w4~F{Cw97rQ#Wnb#8kF zJQllU!5JF6=%=iR$=lfTty15_>?bAPkB+Kk%GxZxtoSy=meQ$Efxm$0i)?Ryj?b3?b8U4<)kNJGd*wEkDx2QWe zcY4w;h2ww9lvewc_3oS36+GFooZnYBkoU;JmkbL6pIU~gNBw^r8f#Xf_3Fvj?<>HA zs;SzbnE2;5rCgBVkoAEEqkF~cAM2`wcHUZ^^n0D!Tg~Yee{YvP%Jn*7*B4tg>q*jP z_iviTbz8r>F2A#6`qe|OJQ}8p13bjG-Z5k|S)W{O9Q-)p?uEz6La7F-PIi&%L9rszC5?p zR<2&bQ@KypPx|lK*IdguLd{SA+`9Y8ZkN>g5*EcycQ>y5vax9U^pCe{`%kZ_jy{=n z+RwoCemdClUyK9`mJK5yBI_m8bl+2!B+ zddbfvq|@X>)_5|`6qU_?&eP4SpBQ!D=0`Ur_`PXH*cCrn_Sng zKd1fvYeZDmZKeHEcWZW68^85cRQ@SXbjXV!bSEMJx1r}#cD=XiM(6WiR&AHGPpGR&Ez_x4R`3(u!Y`Q#dh#qEFgOf{d; zIwe)}R-K*|>z!TUy&IaBYFJt#J;R=~_gSuP-dV?^>dv?RJ9$p_@xHff9?bPWwd8v7hYu~A zlx=^`2-Ip*!K)1^9=-tt)tQ~dl+&)+1pL-#5s$g057Kvj!+|9P{|7%k9{afkv z>-KMt9+{mZ#IozK?DMUGZb_KmB6; znmy;9_@!pEs(o+X^1ZigcPoeNI5+=BY3lE4F$=Y6J72Reeq*~~xl@H7+nHU~p}+F0 zZA*Tqw#OJb{t{C!s`~vq)@`kUvaCr?lKztnHYVNs`GGg`n7>+_%*(hksn4?Q#|F{N z+t~+p|J=HTdAqNfvbez=J%%f9=XB=ie(L(}H{TZ2+0u`W{JTfGK%@QBJ8|BO&wC$V zdG9j)p03bY6Jy!eEDK&z9ec z#UZ+1w&&MRxAu46=JEgkw|BXxLq)k6R$Te{-~XMjeTZJif&>%8D{~hAeiO2&ql3%) zN@R$c%{A57_S>^`rxnGQ99O$1n|i}<>#U-vExLPOZ!mS;wc}RHc_F>@rI)KRHgB5H zyC>Cg>9TdXs>!qW9{-vDdUx^JV`1y&XxraWer*+1HfQPNiu9_uHTr9wfBm+;vztHG zIB(kZQ$Kg*etOwz7Ipbyo}6>MpZs>M&#Rp_^%P`>9htgZ^Vsv6rR%l3Z_M2u`Re=I z;<$=uxi0k*ZWb?Zu*gr@QuTOmec3h3if`{Pc7ETYz5COL%k!U4%e$J(5}>wMap{zI zX?}9Wf6YTb&5hwXHM=(VwPm)o-K1Up-y$L(Z28IZ`jqk(^GzSC>jOUb=z4B%-?%I8 z?6#Rvp%FhvUdocK&Wl9?z%en8MpT75|($oOSfd_qSnJcYWXWPge2k zL_N=qr}sK9lv<|}QQv=~J5KZPJ?Za{9)7Kxwd}aTH2>0o*|*rcUy9GJR&Km?emzU# z<=tzg7v;o0`cm;L?z7FqeWu?2{CA@6c$IAUxVu_TPJX&_gPh{OsT^+}_sHb$?D{@^ z^E=I3Pa6K66m(c*-*bdR!Ohey#aKk@$X0<9f7Y+z{}NTWrzG_E#lD-j-^^WmYX2#h zo39h(jIT}q@kiC?vi}dy=lj`tKbxI?V-$5}nzjFzc|j3*2Ui*RZvXvMesRdMt>ulO zlRV6Ry*>O^?N6}I`oQN?^_Il@^}8#^p)rJiOcF7>_hJgjcr z`Nx&E{U**vf7kFz)#V?bu|Dr%-MlMoprbHL+u=uY4`ol ze_V3j?AY#Ai)Qe=5m|Sct!eR++~@c0ZhI;>TuPPO*IL2=3{v9lLrgZ{(PEMX~?sY z!`JMYx}WaX>W`&s&uw`tA9?*<$BLJ7H`8n$1njx9S^ApV{3rjuO#80kHYI-h*5_AM zrz%fVPR!r3b@}mIAqy3+l)hT^mG9C@HDlxKpGy|Yb$>qNA2XHxTd2~_m*P`TeEijO zT4dho-?EG)_j4)_WE%drc`NWsL9*KbdLF3b6k)6`IcQGspBws-eM8BR^F z_Q;Cu=l{dGx!X;4$k+jS=m z`)sw@%dDzzW!;MknRP=u>3nYX_Q+)>{^@UXr+(`G-WPeeXg=fRUzfYnzJ9oNujljq z`TtYSKD}w4Xm?oY!p_Cfo5TKxEx&(fzg+&V`R;q8#HKHo^>S~Vx+hoVzK#e}Y~+=+ zI=vUYOTy+I|Kinpf7Vt-gH6j{*j@OrdM?|g_sNwV=_kr|t;}cL#q@yP``pgUD{uZN zf8@N0+r2NqffUVB?_*V$XqKlSvk>+$yJuaCb|6yjO5T6g2~ z#>=N&F6A7Xv5z&!dW*=VV-6K->U5d5trcOI<#jvp@1Jjr4wbd6S7SJmvFXC$+e{9} z-RjF!z6gIZbF#hj>BdKX{b`RT`={kjb>;qd(de9=PVmjo26K;f9<~Vz_Ah?Dy7lSm zNAK^8UwZjcRY!mR`CXp5ckdLPI_p|{-nn9FV|mY)T=&;?x0hdiZoT&0^=nHb%cjX~ zoH|`<;_K>ff0lmQ9ew!djsbNi-={OzihLh^zZK9_ams863g-`-v=q{DG^<+HCV ztN;JK|8^_q+G#T*IFGkX-G8bpRMr1yT<{~4_=h`I1blTBDHXrFuh~g$?T_w`v%8KT zZLZ$&WTM}sm2F#AHGZ!@*<2%)6mecYsbTSw{I9pBEOXg{S~#sD^W6Q=j*r(EYNmaBR&6|O5?6>c;}qYBlOdN=o>sCp zNc6Nj7;jVNzxj6W=|@{)ugmhix%4#N&fRX#_4hMMUq8y7c{S-|+RCMouOGdS>ix3z z^>+0Dv+X&{eyQn|N#&n?bT2#f^t0l51>aWg-li{nE=i`A)7D9=_1T}!+B+XOCU4Q& z(sDU=(T3`lJ&V@qzmH_-{(5d#)5d*soj;v_ua$Opo({iZWK4Xa`ssD+!dK3E+v)JP z>`$Km%eXhinH}1%t<1|CH@!8xTmE+1y30N$Q{Ir#?qP5hy{cGm(eJ=W&tK)mwgnv@Y(??yE@jEZ=TwOR}UexSW z^*gt%UGu>^YvYw;FK3&~uX=F0<$O#{Q?X9g=f%t$0?)_a=e<AJc+pL^|^GTnvg zzqf1^{_CS}Cl;V{*Tl;B_r9I^+kO{(iutnWcz}*PmoHvGSxncw+G^m1RcVfVS;^7_|r zzq-G2Rr}}q%m3^4&tcE_)bYXSi>2-IcuT$Gr=IsmuZ($UzN?U*OFgmw_v)oibNaY= zLLWU|zbrP(&URmC_Dg;LdE3h?j~p$_=RBo1ZU49Hd{=+`IHa5<^7#GZ`G-HJep=td z@GCsB+hF#qim5+LYYZ6`+Jd+l)|QlaYwdk^E463F+~e}Xshismg|xcbFMDyS_-)k{ zqrbO;GdEqCv_x+G&zS7jZ!T_bQ+)UG?p~pwmqBl*_}TN$Ug~+vFe0|<{-J4SAI?wb z&3v=j_vos^xbBsgrsM~{D4fb=s%NJgo^|oo`zcQ!bGTo7_q&_*J1hILl&8;5-aBl& zFlxqT-A~qkZ5h7wR8E~1XK_wlb&hUQok0G*wSHSSeGD_+yzQ>{@m^*A#?wu{|1EY1 z@4A1=Z=20E(bdQP8N7b~=6_Y#{)&Q?#~J0*kLSNyc1-h#<{!8Ed5L{nuN%wFYuyrh zZOP}3zxplrvNq?d9ya-FSMWTzcGm}sWB-oTJpLlhFzcQFqx=6g+Nu`+(%j~^qy6`O ziGBtF=SWV5y;IK2x)$BO?DoHF20z!mOGq}$V_fj>@4khim&jY??$q;nx*MPEs&m-+E$m$8>hQT!-`1paoV=YnEmY(D z>GQ?Eo*%h?U+er~)wh=ngRQ5PHaRWHKgGXGyK>*viANQ;$!OHn%)GKXwU%SGw~k-T zZ_V}RO*0RCyeHgu^TyS^U(0g$72LKycUS!y|Bkt*|H=OT{Cj`(lAXo!FQ&PEd&M0y zPyCjCr%Lzl>%s|9@lMkwzO?)J`Mkt$IhK8=fB6M;M1PZCS){uKr z&C(#@tMTWng}YdFe7nxZms2iEF<6C!vFv4Ba8@*0Pv43vkutUV;rK5+i1&oql;Z2lDxw+B9n$lBlWcu$rme(}e}9$#U9$YM$a44c zU%gT9tQ$<$WzKnYUU%PrIrf~U>KD%|qch4GH26>3f7%w{zs=&_3d6XF^Outs)t}6o zD>v)s3yuY=rd|HHi<#Ns^M}xEX})8R6)$|)#4lQB9G}?oi3}4UAMt%cKC*FXEVQBY2P0{I{kWe|MG+*nvxOoV%zIu zzMU_+r*UV!y*~T$GwRhmCMVP~-_8gXs@c<)U;px0jqqE}+go|EBK-a|nIufV`X%+# z%VV6E|D@dx+_Uz4*{LQk%{1<=ZvN9IkCM*E$?Z0~d^5TB`+J|oRtpx`n_R9geR9Nh zv4mo#1lN{n^C$4XnWev`v^wRz;F|N-if62TZf$qYF}rfsUzvH$v*j2MJhjX>J-VHx z|K0=ZzB|hEk`_2HbZpEud;9FMLz&*A4R_|ey*IV@GyCO|h?4!?+?MKj7w#X8|Cw56 zT6S}51ovW_sFK8)L7S(leafDyGR^M%?IpK0TT-L`{>gq3EsxPCAH$XqaN=^owJ9W|G#r?JeIXg z{M+T6=xgaWH?Eo5b#rfY>dzg|x6Ru7bNzYaqh1|Po)~=jyuZ3%GgE5)^QT{bp4V9Q zYHLd>>yH2CK2uKx)clQ{_v_g)jh1WDI;-v#1x7kl6)sJG?JKg`E%l|z4xQasb+<|S z?p}3xR@3_&%lc%;!+cB*e@qiEvRD`#eCxS>p|1H`)xysX z&bG+^Vk@=o^Lj7dLl&i18_c#|iCbZRROPzcULCeQCEVRbK1P$@w%xs&RQ~Kzf^)94 zezp3-FNs>U>r&Q>O{`Sq_pE8m8 zZ@pVHyS_5UbaPeud`XYX|NQ=Xu;$VYK5us}m785O@2kbxdy#fe9x9q-OUfOWIX=eSQi0S+Z z(;pZdOwbaw>W!7DY2vXpSNl_QQ%-!jK$ZN}ny|QK^Dq41Suky7(m(eb^9(ax*Dv3$ z?wl{Ws{XFj^VQOSEm@M6-nUyTa_wnqVylI3Z2pJHWx+pQ&-_z&bVac9_ne(~Udgcc z?LV>Zk2rJa=lzer*u>d0Z|h%i;rtij=lpEHuW^M3-rnDJYh8{^rOvMRvQK41*%?|c znY?A}+r4Y`7|8e>!RN-`}Nu zUF9v+_n%$)yLZNqFk6jvF{V26O5U5#KDG6s#nYT)ubl5DS3U7euk@MUr|*5tdGA8c z`=XO?&iq#^dGu^V-0?5{XA@Gzv}+0-E}nXGdVZJb;#&Eevu}sD@4fTZKjrBm$H#SB zw?2BP`_(@BLf0+NRh5dbPm1~9T)Kax0q6zAK%zBa9{AUDQR z?c0)#)o~Inf(|{)5?L;M^yXQ*I`HT-r%BDP8vak)cC}kd{A2YxUPYhZ(fjn*xmR6% z`+Vz?I?-E~5_hdnnI7?H$DBu2$8WrqxK*od{`6;V?K|#{o2Mev#UY9?M+59ol@aqhD?}tyopieH?yA)99KmyzP2Jv*Ush#b#KHeF`oJccvr{%rcUvBwK5yB| zPY<@{91V|V+Pv&uTE*rcXD4pcd-A8sIl9R8qoIfX$+FG&?Ze#|o{E2(CjaogAydc2 zIkhKiUv57v^UB#pi+8on^7EPZt_r=*(to3Sb(`r*v&Zw|r^{X6p?oOlg#VmJBFRR5 z3A#s*RUA()IlTAsR->O@|JUu+D)}0pc6x^DMPmlFFuQ&YlYPh4cdjUsE}3An`_*dnjz>!2}Dsv_H@46`!mQj=T^>3;$%(n}FU-&zr@ZS zJ8j#4;Pfjq-^*nVTfZGYCUkkGl(ku;dE#QBZLN1^9n!R3Rek1P?B?S9EY9vLNjGwx z!>x|EHk!B0kK$f#$RM)p<^3<~Q-9rR>U&+cEOJF}x*( zZkBocoxQcMm<*j{Du?yZYO<%hB&sg%uV4 z?Z|%Dw?kT_Y`O<1XYrop3Yh;8OW-Z-RqkSfKk|DFh?`tb= z^!I+Y@8(|p=hvTK-|P0T*M5Gv)HN&X@4Y?mrItw~=bu^{aOumTbr+>GZqNC5@#A^s zzQkFN9;cnYzKef;#-8uf3ZmUh|6ToN7Zc%Domdh+$(fHOQlx%gpT3^ru{~$5oj=OU zxa0oCy6oQtQfo8Lz343cR{q@Ua({4L+=^G4>zmJW7tVUOz2WFlj{BGO8UE-QuCeXR zd3kZt8`+Ygp6SdE-7~Fbui3kKPSpZGf8*GP=X>KH@c%f*Cz|uah2h1*uS<&Zx3s;q zd{QCEUimln&R5s>pASBEol&>%ZN=4yOMCCW7Z;vs|9C;o+kM}!<{v(N$Ygflwr_k% zf6V_@FWjs|Ka~CU%qrRc@!!OMQORmEUwq@cvO(h0r#bbH>%KT`O1J*I z>dx84vj5hqzkJs8O84B;(!1_oGkvn+mdk~{{aJ4DB=fd&^xg=$M^nUJgo)PWwnyzh zSAXx_W%E}mmFKc~w%@k7zwwQ*Of|=u$y$B$qE344@B1UaW!3DPb9f(S_O+`m7CUY3 z^Imh_{XoUS*KaOQIDEbRS?;XV^{G53ifSU$CFgF{n{Rvec+H8YO1+ri!*fBPTI3tczONhFY$+qxHH$LyyM@o{`KdD=YtRLSa?_U z%MHQ(OMB+qPLN0zV&>{Dy%DikcDtU;s{^Xyeaoi5T9mrFD(%>#qQb2?caHbj{IkgF zK611^`|{Jq&t2JX=PmrSb47sZ`cQLz;|E$(ZMD9+NAu_p+?kR2N?xHD97Org+OWAsw3?D;DOPhjFhlIh6M7qu0u(Rq{bXM)la zX7}=EnTMUOGxoY+lzcqqy!6Miv-ekCQ|7KT{ZlLUAxo?9+tKIQj(d9TXW8D?I9FGn z9@iJLQaWGa<`>PQ&hJ#iHa|7FFz2EU&kn;IZ-0edtKI0jzryrk#6u-_a|^GfPWf#y z_Y%s^7F6Fkvib6qx?1bSPkX1_n|Nn!{?<6(C11)Ful{2d<$f+bk5NQhe1YGovN&!j zG2zK>feUYz|F8V4w&D1usHk~Yr8Y#F?&4l67j`?sA!dt+_`#k&j_e9H=SN%agcsNH zH|m|aKWpQ&OzSnGUzILRc9#ox?u}l0ZNg4{5w7`KN#EW-ntnXE^!B&*oMPEEmRBUq z`vQ*6oDs_(wOKh~&&Q+OkKWe*?Z09dv}b$FxfMT;uZg^!x>@@j$NQ7PJM5V=Hi}+9 zCVD77jYXjT2z$HU^0}vEA0O+s#vB_(;~SRn}y|D^KABfeqZFc_|$2eg#0U4uE{#@6VJDqb8}hZj8BWYPdZFZ zS{GJzdZ9sN)#Tv#>@9``mm~7nLyo50&SjCgd{FA)wd=c&DogPl-R^d z=xe3)uiYt&bF%d#{yts2i%r~g&9iOKqPXg3F$m0Ad%?T^^XrGU$>qsE`{#x5eU>OJ zymWKhXQvNKW9;^yeswA6LiYY+XEn9B^L*;JyZb9ge(4sRe1DS`&-x#Cch@hQV59n^ z-2Nx8@z-?^${N*wR?dFTuzcE5HCMss?%h#S5^a5Uemb1qF0|&vw>9@?1xpuPoAoHU z*7@Gsn}%!FggvXgcg=a;dYw0MqIuP)Yp(A5AoHQjnk(b;ri+V|WCg0WDrWEUdbafN z@vkZ2e&52mJM&f%R{b=$7A zY^yIEgq`I&mJY7zM>`+qF!{&RjKbNGG+nPop`@4xiy^i$*i+S2uN+3%ITvETUb z;iPLyn*S%cKmYe_YuGhao4T5^KmGZu+au5Gs(GJ0)Zc${x$AeuzblW{>Rhh*C%3U= z`8~Icbz7Kq4@bw|wERC2fi|4V;=-rDZD^?dcEnI`uauB%`(khj@fkRi!r>f{4Q{duf6hrd5? z_7VSQ&i?H1=~Y=@x9`}a5@*%3Y1UeC_PuZ3J^Z#)J$C=QvMU=F=!;AWtoCIUcwc-s z*-hK`4zu~ID(78g6StcGecrQM%UP^_)z`~m`?UJjz1BUp_F}^M%tMRbuga7jHhY$7zfBwQIMg2UlgP zd%pXVCAB@`=UUB#E19;fJAPc4TC`&N*L_uAeSXFruhY)DGyQ06-Sn+I#X9HDjf)fLUzsAqevJ*E1tS^V3Y zOB1f=TgK~~-$~X8-t~V^YV4seca)|o9{leA{dV=^Ywtua)qa#=e}6mN(l16;K3<9U z?HV(W%a@ys+WxXMNL<)%A{Rfg|8hrgCQCr#r>%!Fcckqwi%h)K%W4<3`edRjVk6zxUZIidIxSvl1H7!yd6#X|n=0zfpS@k8=#iCr zW71qrziTs|-z?kjX1?Mpr`>Dz$!mnFc+W|{IqQ#XUi{nm zugr|OuKz1HfBD2Y>7(h@%vp0Ut@CTX@`&_XmG9 zm&^L)YyINRjhAR<5U81d)b#(<)lXZmolrd6T0MEG#gBz^>K@9>>oKjkpIyhluVqiw z-O|7Fwmte{{C#G$^)}h_5BRqBe}8>FG5_}e9j}jOnk4OPnX0J#)_caX%z4+dp5E!WW@2i)}N-nm|2p>^n<=|``x&&*|C z{nx}d*h*ycm#QOYkH#*2Flm|02UeDbAIfc3+F!q){>*XFt?^*A)bl@2wq;u1*;Ri|eOfEN>uUA9zn3J6UT|%1wYh0= zU&Na?aK%;2!#VE?_TPP(eoHpEl7%x*{`>nX!}Uft|0`2|n3w|zbQ=64kTu81Yp)BZcYkEpVmrW2i2@oq-p$K+*(t6!_POm+Eob?sG# zvQMwm-pP0WzbVf!Pj%Y-8I$b3UE6d1ae?ZLJJt(~?(T5j8h0vAD!pXt;=)4JTlZym zmd~93J>qcfPRl$7*$Z9_9Q)2|U!0#gE9v{{Tgl(v|9QN5<)3QZeB&pEubq#-tSc>f zoO-ig`-Fu29*9!DRPTk7?YyH(H)7?%7-%-!b@4GYms;7Ka$hd*tJtH-9wh<*vw`;C

RpwE#*48`Kj>;Xe}#wihQIy=x>N4ih=@+|l-_;vr*(XnckgDkbN;htFG;)? zuCO|}V^@xjxnD4cZL93=>r1umRgXIAx!XP3zGs53?qP1fEE&DFZ7o06TO=O7vzgD~ zlgo-V8|C67mqv8=opZC4DPr*19PalauKE*0fY}edGhJ%ZeTB0Vw(8hj*4ArPb~cjB znxoCDe&fcH|F@Womn!L|cD; z;OOy+)i-vW$k;E8~WAqf9CoB zZguFXI>nmccPU}|cjPLjWOwa65`8#nss0@McdIL=XtZxWbwBpGLEY9rHIprJj~MXr zEBjB~wcVomEuVqyR3?Ykl=t4b{x&}9>)yYnZJUu4c=phijlGXgRv+~2 zT)uoB^CJ88xyyfVTv;>WrO%67W#)VN&L8&jTNmH+VJ}O=4{NFF3GZKfzxnp*7+` zb4r$MSS~%OUw_pXhU6QCGfp+}E$1nVj?VK)~R$F21cxadySeRLirIrJ2{Blot`5yX^Y58)=*BA8D{%S711D;-0Wq z#pcDcME<^%xj!S)to^=B-D-0St5@e(*9GUMEZiPazqszBozniVn@a1C@y&g`LuLNP zCAMD;x7nUrWN`o3`t>Y@Nl%McZTx?Eoz0u~lJ6p7J3sX7(rptuSG;BB74ALWb4;A1-0wH<9H*bIh<2Y|KJD^jS>u2unU=?+ z?%bO_HAHUvI@UdplRn*Fd}W_<=)Z*<&V2UIch^bWdo4dLq1fP5&8KH3@u$L8JAHbd zyCwYEQgw^h&-5*(GYHhQrmsk;H96b;FE^ZtnJTEcr-|MTWG*{3bu zKif2I>D+%2XHP9NIRD+NA^BTs&Z~VP-n;i0hcc^uFXiu^wS#BI^Z0xJPjGG6aqs2) zmj-KXE?(NEA>zL2MUa-1)uFjeExayjc-Eqxh7G2(RYj4WTe;3*K^=Y}< zHp6_~ZJ&Q^&W}v|`D9tTOUBMM$5te*k(YkeocQU=?ccZ7hi|)9``YZ{=gj!85~m+O zzfgGO-Oc0MR~OazZQ0~1w{q{3ng7qv<-B*(#U?lMeRQYsv@MbXtbM8sEcaI!Jo|st zB}&KtkG>h}w9VU>idkEwtdES-h_AahJx3^NRb-q^e(bZ-B-`-lFM5TuR`IWi^!ZV7 zr{=uH+#k{=r>f7-G)9~&Me z`JeV~&(G#NAaH2;_nL~y^Sbi(&*0oF=CY9gOA^lt%ZUcQ_VG7jPRO61uyyVIYwzAH z{Ffi`cFEECk>Pp1bC%U_FBkFakGpKWy5fGu(j!UJ3jW)*X|{ZjQ5KTlf9BadukgS8 zHe23=^L>`t657RjZ^pO4#P`dRf7mSU_mUJd-qM$_y5qeJLs?hNQ}2n_ByPEVd9zi> zxpQ;9mFRuO{l6C&`dj>KV|$#-65w%3FDkNmUfGdD`|maU4O5en75sK;`cEg>*Qd`3 zuHErHY~_!v)4y+ir9bXg3$CzRW=c= z`Q4qzD*o@1SnB=Aar=d1zXF=i#>k4^sakwB!qw+^ZtLYReVg)QUnV|$E|%(J_vUWk z~`|z^Zy=ljf4G~A5R?JPeJeql`t$fY&^QQv06rQSGweqUlCes?rZUNon6?-SG zUcDmqgWyA5p9yaAlf<1;WB*P6EPBYcqw4>nDQ{M)>EIGKyPzcgdW0{1Mepx$bWA z+V|DtQ_@GV@ALeBN9f2^@G~kb@Vt|??OjIM-=))zPK_#`qq@wo_ie9SeRbRQTl{e^ zCLBp!pt5t*-X3<_JfZ0LFtg_c<@sU2(i#exC#mY8s zbvOEv?#1?hjsDlf+WHypPP4zXFh1Y?*1W&rbF-oGeAek>IZf|NhwP@WEec#>p|4dqwI_KYAwTizt*Q;x}&6SHkyY15X+ux@jm({yD^;dOV zzOpu7r|z}mC3~t@9F5&%dueq;c%mvO97OC3BNM)yxQ;ll$bmZvE@kR_iO;yDwaP>MzWYWm5mG z=&Q)T4Bqz^C%4~ybnnN8i`lvRoR9zAzr>RNy4Hd0?$1TMkqODG--pil_AB?vREYqe zKIY3cn|@z0ToyZ{JL;YG_WWs)b@dD{jNG~z-@aIox3<10?9A&c6Q8&2=vc0of9_WH z&fUkqwEszVE;9U|9IvajKDfrszF+IMcf^#7znLAL_H4dw-dcAURj!iN)qn-MYil8%+eB zuW;NNsjIFSp{U1FLUm|ON?VHl#^6aC(zU_G`srl~V(VGq3 z0t}DVYtIXwyxdIed~V^#hoY~qzg?G9XKTN|?fZ{^AGB>g=cRlrTAFp`g;i?!E4Fy2 zrKU6a=IxJC*X@E3MhD8=xg+|;w-rw_Y@EqgU_d0_t5Te5|k-+x)P|J4_+soAr< zer0WP|1rM{iQZ9l_vZX~ST_H{$JV%*zu)vvU#{JdB_kNaefi$6yW18oeK>F3tL=9a z^<_<+3h(W>v2pfhfjq?peeDO##nMVQ$^L%z?B>&c%`0c8zFKwRLDr$8x4wUn?7sWp zMp}Bs+LIqEdm}BkN{63zp7FhHd9?ErE%xp8YyUp=-ZJsg+cg{JJ^U{6<{i_`Ifd!} zrsscKsdBG``^J`zjbGjBr!_WgzxpGIH`6}j*vtESlWThSZi&>LCp1s~{5gjr=DXbY zqTf7K)VjLg`{^C&LwBS<-LVwQzx%GQ@O)ZU<&(>&!cJ&~M)9q0J7>Q6Q&m>vsjZJ6 zM(O5w|J;0uTcKa{Z@{{5SG)Sf6%Bmd7#xpErmwv9;%@E3h1+*s^0dysA-=x-c&69y zhvFyxvu+Cb=q3NsWO-lK%UMfRUj+N^DQv6#_-sN+>7^xhOA|#u`IaqpzUN&Ye&o&l z=1&2VvQ-Wn=Wgd;?tZuW=(%ZPn>GJmEpI%VT(S1tbn(dTzcVf^s%Uy|H)~CnT;CN7 z2P577W9papi-^>1z8CwVDf{Eg7eALz=ilSNz_IM*7X}}nf6>27r5?3Z&HWZPC(pb) zc43HqkXq_ey=zO2YrfC(d1q<%<=&zV`M&#-l$SpG?D6ActkLJ7x}^Fa3pVZfQ}yq9 z?xW1`f2X&Lem(PBw2b%r?a4o0h0HDXxoqOQu&Vfb6qooN6Y(=b2Yz!h9K6i>OZDbi zpFQh#t3UQdek`;&1`??MV&nIJ>c z%+>e1kE+M)xBMOc_Qj<)TNd-}S$?kN)N}I}_0O))KAaRgYgb776T2;6=d6qLdAo02 zc|}>{^6BMz8wzi~PWX9m-O6vbUwyxRF~VMd!_swcUVke}n8nhtz(eB2p8c7xAKH%RxEn;>&^SumNn;nmrR#syz**7O@7$5)A`54URveZaQyni6LVa0 zr`FY(XP=scZqdINtG%zJ)KAv&TT>!m_=k252FK9vy6^Wm@7VwU(Kml*?-jcnH|-IA zf5pA!)26OU=kK;SdUf_8C!@$u-~SYw)z_~}dKjGP_`dL_a`fkj zC6A|9yIIB8K8dV!yBc`(>(!^1SO2tIFzxsLWo^9yHs79gcbtEpUL7a(%v$T#rL8;r zS4&Hk9I#+%cu-O;%@|x?cH;$r{wG2&c8XK|IyyKw&~IT{`L!VF1;1nd-%vv ziv^RSo@YHi*8Ax4bp357k8OGLd*8wv`lc+4PtX2#<}!DBDo^}(Exp4k?P>eWH%@gA zOua9{?AE_<$9awNvR^A&_n-e(w6g9o-*?UH*+vYjo92q$TT?mx_ochW^R7tk;9qki z!{Gb&TYYD<>a;IJ9{p(feC=sV-*1OM?Ut*VQ$M+W`|F#$t@qNzepP-BeR=jw{hoR2 zpM3bbXYUW2sgtKwr=EIJu$A4_^d9eApKIF-A3d@O>+X`ZzL!4#T=Z9SwfH}OK0dy) zzGCU$1si?VO-}rAxrd>t+<4LtRz=CIf3K&0J0cmqpx|xs2Hx6#N5Ac3ZGCfp`;_m$ zjKq{nrX`nsi~aFlZ_fV3AN!`STweEP_su6Cp5LljpE|STuE3U}$(Po3WG#MVF#nkJ zGQaI{c}F)k?iV{a>)xblJu^MKGoJ(ge*N$$T7LhP;t9P=PiFs=eKU*i!}FS#0?ZOe zUcLLibocWL=Qz1(w$pDp{M)i|E`MiwX!!OgYoGpl_I8J4K*ZjE|NAZ+T<&(H=7RLE zExnZ%|MxA=jZVC9_M_U*f^CzNisiRQtiP~fm##9OwbCK|uq)NSvQKWga&j~Kqpw_- zMV8mEHr!frtL9$jtVhTBN~cRPepzj}g1hF%^lt`Aitq1vcCPvr=f3Qz=l3eE zn9Fcs)phMN_jT{4L^$0N?Frr*FfD%jwEEK}-4`RO#X@|)R!-fwOKk4qW2^4PYaV|q zv6aQ(f8Sj8)j2#tZ?#;$o%QaHxmwwOwRqay?+bEMAAeu4ePWtsgLLxW(nU)PXDj|K zp5JyO&hqVy|D|W=YMibqED`dPLx%BUcn+3mei&ZYi7%cg4P`Ku!Bg^c|pXKsb zi$2f0w)zgEk@)=o>sV@od>I#rZ;zaz`(gr@fY;wUHh;z0`(>>+rNxIzu9;ktqcCBe z?4REDHQ!^iJO4ia-5!<86CBev&40zx+u!ZJ#Xs0&%vjCAaIp2wUFqBU@wvCIPqKde zQ9Qq(EHB@8@4Dl0G51WP=PaL|UG}p!DrT~M{=!`0F#RO`Dfx;wx89k0#k?xW{SEi# zh_m0Xoz8wXCtHheT}6%Fxx!}$3zvS9E49C0#1Z&$$L#xl6{&6PO!HM4SgwDXCR_AB zSK;%`^&cF1{4@7&`zxCo^nOBp_~YXG%=E`svhQ|J&Fs5cXCC~9n?ZKli$(V)9QSH3 zTUGM4>t#*rRy*xCTa9ww-iTf&q|dk0cKbW?d+V!OWeZYQ$0$}Gn84ETplDy^d>{8+ zd+H-DJbb&bWs+=rvFN&db2S9q#Gk7?S(<(~s{J#p}*zFusdx ztvPmme(Ue9bFa5e&+uNq{f+o{nYTXm+s*T*pSsh^(zlD9`A6LGqYc;kgr`f1a~|Mg zRQO@E_{~Oj-X#{hYj-HG-W+-FLY?h9p%)X&MN9Q}r#~|AEquRNFHV28|J_K#`73Si zSKa%v?16rTCEFE|UpFVd^X6tt5NA~Qk#zX&-qY!-+ij9RHTxdxNzT+}zG|9|7x8t=4c`nTqi;i|v9{Hx=)>gCO5 z7CCT}r6GZ(>@m0XgG!U*OQOC0bD1vxU%Kt#NB{f1+ez%A+1B0?415-rtF~y+obqR8{Tnq{JfDBrGO&G2x!?hs+FiJU^JLUg9)uwFu+N|{<4VuTy{{S#V>^gxeaqnj1^B? zhDXQmvdFRvKa_qH6y@#nTYDvo^=ine)tXzfEqp)7JbM3#hyIVJ@vEU@1p9p?FpA&CjVWo_r1jFhrMdXp_-m& RU$2AQ`wCz#{+v literal 0 HcmV?d00001 diff --git a/tasks.py b/tasks.py index 412f2b5..d7e9015 100644 --- a/tasks.py +++ b/tasks.py @@ -426,11 +426,9 @@ async def _on_list_transactions( "type": "outgoing" if p.is_out else "incoming", "invoice": p.bolt11, # Fallback chain so a human-readable description reaches - # the NWC client. Mirror of `_on_lookup_invoice` + # the NWC client. Mirror of `_on_lookup_invoice` "description": ( - (p.extra or {}).get("comment") - or invoice_data.description - or p.memo + (p.extra or {}).get("comment") or invoice_data.description or p.memo ), "description_hash": invoice_data.description_hash, "preimage": p.preimage if is_settled or p.is_in else None, From 11cfbe877269484a16796c3f89a08a03f8395ae4 Mon Sep 17 00:00:00 2001 From: Richard <115934595+bitcoin3us@users.noreply.github.com> Date: Wed, 17 Jun 2026 14:56:32 +0200 Subject: [PATCH 80/90] fix(docs): correct NWC configuration page location (#36) * fix(docs): correct NWC configuration page location The README referenced a "gear icon in the top-right corner" for accessing relay settings. This UI element does not exist in LNbits 1.5.x. The configuration page is actually at /nwcprovider/admin and requires LNbits admin privileges. Co-Authored-By: Claude Opus 4.6 (1M context) * revert example relay URL to original Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: Richard Taylor Co-authored-by: Claude Opus 4.6 (1M context) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 84ba938..1265fed 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Before you can start using the extension, you need to configure a Nostr relay. This is the easiest option for most users. It allows you to run LNbits on a private network while connecting to NWC apps through a public Nostr relay. 1. Choose a Nostr relay that supports NWC connections. -2. Open the **NWC Service Provider settings** (gear icon in the top-right corner). +2. Navigate to the **NWC Service Provider admin page** at `/nwcprovider/admin` (requires LNbits admin privileges). 1. Enter your chosen relay URL in the **Nostr Relay URL** field (e.g. `wss://relay.nostrconnect.com`). 2. Click **Save**. @@ -60,7 +60,7 @@ This is the easiest option for most users. It allows you to run LNbits on a priv # Extension Configuration -The "Configuration" page of the NWC Service Provider extension can be accessed by clicking the gear icon in the top-right corner of the extension page. +The configuration page of the NWC Service Provider extension is available at `/nwcprovider/admin` and requires LNbits admin privileges. ### Configuration Options: From 9674110d042180e35bf2900e02bd11b7e294d719 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Fri, 19 Jun 2026 01:31:56 +0200 Subject: [PATCH 81/90] yield event loop when processing multiple invoices (#46) --- tasks.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasks.py b/tasks.py index d7e9015..8dffedb 100644 --- a/tasks.py +++ b/tasks.py @@ -231,6 +231,7 @@ async def _on_multi_pay_invoice( results.append(r) except Exception as e: results.append((None, {"code": "INTERNAL", "message": str(e)}, [])) + await asyncio.sleep(0) # await log_nwc(pubkey, payload) return results @@ -440,6 +441,7 @@ async def _on_list_transactions( "metadata": {}, } ) + await asyncio.sleep(0) # await log_nwc(pubkey, payload) return [({"transactions": transactions}, None, [])] From 8f7aa33d4f38537b54ce247a1d6fb1b9e14a4487 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Fri, 26 Jun 2026 13:28:12 +0200 Subject: [PATCH 82/90] feat: track seen events until they expire (#47) * yield event loop when processing multiple invoices * track seen events until they expire --- nwcp.py | 39 ++++++++++++++++++++++++----- tests/unit/test_nwcp.py | 55 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/nwcp.py b/nwcp.py index efa5279..20c3195 100644 --- a/nwcp.py +++ b/nwcp.py @@ -27,6 +27,7 @@ class MainSubscription: self.responses_eose = False self.events: dict[str, dict] = {} self.responses: list[str] = [] + self.seen_requests: dict[str, int] = {} def get_stale(self) -> list[dict]: """ @@ -49,6 +50,7 @@ class MainSubscription: """ Garbage collection, remove all the events that have a response older than expire seconds (defaults to 1 hour if 0 or None) + and all seen requests that are expired """ expire = expire or 1 * 60 * 60 now = int(time.time()) @@ -65,6 +67,11 @@ class MainSubscription: if len(deleted_ids) > 0: logger.debug("Garbage collected " + str(len(deleted_ids)) + " events") + # Clean seen requests + for event_id, expiry in list(self.seen_requests.items()): + if expiry < now: + del self.seen_requests[event_id] + class Config: arbitrary_types_allowed = True @@ -125,7 +132,7 @@ class NWCServiceProvider: self.info_event_task = None # Subscription - self.sub = None + self.sub: MainSubscription | None = None self.rate_limit: dict[str, RateLimit] = {} # websocket connection @@ -142,6 +149,8 @@ class NWCServiceProvider: # (handles reboots) self.handle_missed_events = handle_missed_events + self.event_max_age = self.handle_missed_events or 5 * 60 + logger.info( "NWC Service is ready. relay: " + str(self.relay) @@ -270,11 +279,16 @@ class NWCServiceProvider: await asyncio.sleep(limit.backoff) limit.last_attempt_time = int(time.time()) + def _create_subscription(self) -> MainSubscription: + sub = MainSubscription() + self.sub = sub + return sub + async def _subscribe(self): """ [Re]Subscribe to receive nip 47 requests and responses from the relay """ - self.sub = MainSubscription() + sub = self._create_subscription() # Create requests subscription req_filter = { "kinds": [23194], @@ -282,17 +296,17 @@ class NWCServiceProvider: # Since the last handle_missed_events seconds (handles reboots) "since": int(time.time()) - self.handle_missed_events, } - self.sub.requests_sub_id = self._get_new_subid() + sub.requests_sub_id = self._get_new_subid() # Create responses subscription (needed to track previosly responded requests) res_filter = { "kinds": [23195], "authors": [self.public_key_hex], "since": int(time.time()) - self.handle_missed_events, } - self.sub.responses_sub_id = self._get_new_subid() + sub.responses_sub_id = self._get_new_subid() # Subscribe - await self._send(["REQ", self.sub.requests_sub_id, req_filter]) - await self._send(["REQ", self.sub.responses_sub_id, res_filter]) + await self._send(["REQ", sub.requests_sub_id, req_filter]) + await self._send(["REQ", sub.responses_sub_id, res_filter]) async def _on_connection(self, _): """ @@ -335,6 +349,19 @@ class NWCServiceProvider: """ Handle a nwc request """ + if not self.sub: + raise Exception("Subscription is not established") + sub = self.sub + + expire = sub.seen_requests.get(event["id"]) + if expire or event["created_at"] < int(time.time() - self.event_max_age): + raise Exception("Event is too old or already handled") + + expiration = self._extract_expiration_from_tags(event["tags"]) + if expiration <= 0: + expiration = int(time.time() + self.event_max_age) + sub.seen_requests[event["id"]] = expiration + nwc_pubkey = event["pubkey"] content = event["content"] # Decrypt the content diff --git a/tests/unit/test_nwcp.py b/tests/unit/test_nwcp.py index 800e853..6cd4d13 100644 --- a/tests/unit/test_nwcp.py +++ b/tests/unit/test_nwcp.py @@ -2,6 +2,7 @@ import asyncio import json import random import string +import time import pytest from loguru import logger @@ -75,6 +76,18 @@ def test_signverify(nwc_service_provider, nwc_service_provider2): assert nwc_service_provider2._verify_event(signed) +def test_default_event_max_age(nwc_service_provider): + assert nwc_service_provider.event_max_age == 5 * 60 + assert ( + NWCServiceProvider( + "d7b5232fba0e02e32cfe26f20cdf2c803b27ecd81052c2dd5d17e5e1a333fe58", + "", + handle_missed_events=123, + ).event_max_age + == 123 + ) + + @pytest.mark.asyncio async def test_handle(nwc_service_provider, nwc_service_provider2): content = nwc_service_provider._json_dumps( @@ -87,7 +100,7 @@ async def test_handle(nwc_service_provider, nwc_service_provider2): "kind": 23194, "content": content, "tags": [["p", nwc_service_provider2.public_key_hex]], - "created_at": 1234567890, + "created_at": int(time.time()), } signed = nwc_service_provider._sign_event(event) @@ -101,6 +114,7 @@ async def test_handle(nwc_service_provider, nwc_service_provider2): pass nwc_service_provider2._send = _send_pass + nwc_service_provider2._create_subscription() nwc_service_provider2.add_request_listener("pay_invoice", _handle_pay_invoice) sent_events = await nwc_service_provider2._handle_request(signed) assert len(sent_events) == 1 @@ -128,6 +142,45 @@ async def test_handle(nwc_service_provider, nwc_service_provider2): assert p_tag[0][1] == nwc_service_provider.public_key_hex +@pytest.mark.asyncio +async def test_handle_rejects_same_event_replay( + nwc_service_provider, nwc_service_provider2 +): + content = nwc_service_provider._json_dumps( + {"method": "pay_invoice", "params": {"invoice": "abc"}} + ) + content = nwc_service_provider.private_key.encrypt_message( + content, nwc_service_provider2.public_key_hex + ) + event = { + "kind": 23194, + "content": content, + "tags": [["p", nwc_service_provider2.public_key_hex]], + "created_at": int(time.time()), + } + signed = nwc_service_provider._sign_event(event) + calls = 0 + + async def _handle_pay_invoice(provider, pubkey, content): + nonlocal calls + calls += 1 + return [({"preimage": "00000"}, None, [])] + + async def _send_pass(obj): + pass + + nwc_service_provider2._send = _send_pass + nwc_service_provider2._create_subscription() + nwc_service_provider2.add_request_listener("pay_invoice", _handle_pay_invoice) + + await nwc_service_provider2._handle_request(signed) + + with pytest.raises(Exception, match="already handled"): + await nwc_service_provider2._handle_request(signed) + + assert calls == 1 + + @pytest.mark.asyncio async def test_send_info_event(nwc_service_provider): """_send_info_event should publish a signed kind-13194 event.""" From d432d74c886853f2185967324c6e7f72f49c7c34 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 26 Aug 2026 08:31:52 +0000 Subject: [PATCH 83/90] fix: dispatch NWC requests concurrently --- nwcp.py | 26 ++++++++++++++-- tests/unit/test_nwcp.py | 66 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/nwcp.py b/nwcp.py index 20c3195..bb3afa6 100644 --- a/nwcp.py +++ b/nwcp.py @@ -131,6 +131,9 @@ class NWCServiceProvider: # Periodic info event resend loop self.info_event_task = None + # Requests are handled independently from the relay receive loop. + self.request_tasks: set[asyncio.Task[list[dict]]] = set() + # Subscription self.sub: MainSubscription | None = None self.rate_limit: dict[str, RateLimit] = {} @@ -431,6 +434,19 @@ class NWCServiceProvider: sent_events.append(res) return sent_events + def _log_request_task_exception(self, task: asyncio.Future[list[dict]]) -> None: + if task.cancelled(): + return + exception = task.exception() + if exception: + logger.error("Error handling request: " + str(exception)) + + def _dispatch_request(self, event: dict) -> None: + task = asyncio.create_task(self._handle_request(event)) + self.request_tasks.add(task) + task.add_done_callback(self.request_tasks.discard) + task.add_done_callback(self._log_request_task_exception) + def _extract_expiration_from_tags(self, tags: list) -> int: expiration = -1 for tag in tags: @@ -470,7 +486,7 @@ class NWCServiceProvider: # already handled or stale, all stale requests will be handled # later when eose is received if self.sub.requests_eose and self.sub.responses_eose: - await self._handle_request(event) + self._dispatch_request(event) elif event["kind"] == 23195 and sub_id == self.sub.responses_sub_id: # Ensure the response is from this service provider if event["pubkey"] != self.public_key_hex: @@ -498,7 +514,7 @@ class NWCServiceProvider: if self.sub.requests_eose and self.sub.responses_eose: stales = self.sub.get_stale() for stale in stales: - await self._handle_request(stale) + self._dispatch_request(stale) async def _on_closed_message(self, msg): if not self.sub: @@ -656,6 +672,12 @@ class NWCServiceProvider: self.info_event_task.cancel() except Exception as e: logger.warning("Error closing info event loop: " + str(e)) + request_tasks = list(self.request_tasks) + for task in request_tasks: + task.cancel() + if request_tasks: + await asyncio.gather(*request_tasks, return_exceptions=True) + self.request_tasks.clear() # close the websocket try: if self.ws: diff --git a/tests/unit/test_nwcp.py b/tests/unit/test_nwcp.py index 6cd4d13..a631037 100644 --- a/tests/unit/test_nwcp.py +++ b/tests/unit/test_nwcp.py @@ -181,6 +181,72 @@ async def test_handle_rejects_same_event_replay( assert calls == 1 +@pytest.mark.asyncio +async def test_relay_dispatches_requests_without_waiting_for_previous_request( + nwc_service_provider, monkeypatch +): + sub = nwc_service_provider._create_subscription() + sub.requests_sub_id = "requests" + sub.requests_eose = True + sub.responses_eose = True + monkeypatch.setattr(nwc_service_provider, "_verify_event", lambda event: True) + + first_request_finished = asyncio.Event() + second_request_finished = asyncio.Event() + + async def _handle_request(event): + if event["id"] == "first": + await first_request_finished.wait() + else: + second_request_finished.set() + return [] + + monkeypatch.setattr(nwc_service_provider, "_handle_request", _handle_request) + + def request(event_id): + return json.dumps( + [ + "EVENT", + sub.requests_sub_id, + { + "id": event_id, + "kind": 23194, + "pubkey": "a" * 64, + "content": "", + "tags": [["p", nwc_service_provider.public_key_hex]], + "created_at": int(time.time()), + }, + ] + ) + + await nwc_service_provider._on_message(None, request("first")) + await nwc_service_provider._on_message(None, request("second")) + + await asyncio.wait_for(second_request_finished.wait(), timeout=1) + assert not first_request_finished.is_set() + + first_request_finished.set() + await asyncio.gather(*list(nwc_service_provider.request_tasks)) + + +@pytest.mark.asyncio +async def test_cleanup_cancels_pending_request_tasks(nwc_service_provider, monkeypatch): + request_started = asyncio.Event() + + async def _handle_request(event): + request_started.set() + await asyncio.Event().wait() + return [] + + monkeypatch.setattr(nwc_service_provider, "_handle_request", _handle_request) + nwc_service_provider._dispatch_request({"id": "pending"}) + await request_started.wait() + + await nwc_service_provider.cleanup() + + assert not nwc_service_provider.request_tasks + + @pytest.mark.asyncio async def test_send_info_event(nwc_service_provider): """_send_info_event should publish a signed kind-13194 event.""" From f4b96107fa9b6f2c001b0c4faccd7b19084dda9c Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 26 Aug 2026 08:32:35 +0000 Subject: [PATCH 84/90] fix: reduce pending payment polling rate --- tasks.py | 4 +++- tests/unit/test_tasks.py | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/tasks.py b/tasks.py index 8dffedb..5ea3ffc 100644 --- a/tasks.py +++ b/tasks.py @@ -34,6 +34,8 @@ from .paranoia import ( ) from .permission import nwc_permissions +PAYMENT_STATUS_POLL_INTERVAL_SECONDS = 1.0 + async def _check(nwc: NWCKey | None, method: str) -> dict | None: # check @@ -122,7 +124,7 @@ async def _process_invoice( }, "in_budget": in_budget, } - await asyncio.sleep(0.05) + await asyncio.sleep(PAYMENT_STATUS_POLL_INTERVAL_SECONDS) if not payment_status: raise Exception("Payment status not found") return { diff --git a/tests/unit/test_tasks.py b/tests/unit/test_tasks.py index cca51bb..9758954 100644 --- a/tests/unit/test_tasks.py +++ b/tests/unit/test_tasks.py @@ -29,3 +29,51 @@ async def test_process_invoice_returns_payment_failed_on_failed_status(monkeypat assert result["error"]["code"] == "PAYMENT_FAILED" assert result["error"]["message"] == "Payment failed." assert result["in_budget"] is True + + +@pytest.mark.asyncio +async def test_process_invoice_polls_pending_payment_at_sustainable_interval( + monkeypatch, +): + async def fake_tracked_spend_nwc(*args, **kwargs): + return True, "a" * 64 + + statuses = iter( + [ + SimpleNamespace(success=False, failed=False), + SimpleNamespace( + success=True, + failed=False, + preimage="b" * 64, + fee_msat=10, + paid=True, + ), + ] + ) + + async def fake_check_transaction_status(wallet_id: str, payment_hash: str): + return next(statuses) + + sleep_calls = [] + + async def fake_sleep(delay: float): + sleep_calls.append(delay) + + monkeypatch.setattr(tasks, "tracked_spend_nwc", fake_tracked_spend_nwc) + monkeypatch.setattr( + tasks, "check_transaction_status", fake_check_transaction_status + ) + monkeypatch.setattr(tasks.asyncio, "sleep", fake_sleep) + + result = await tasks._process_invoice( + wallet_id="wallet123", + pubkey="a" * 64, + invoice="lnbc1example", + amount_msats=1000, + description="test", + ) + + assert sleep_calls == [tasks.PAYMENT_STATUS_POLL_INTERVAL_SECONDS] + assert result["preimage"] == "b" * 64 + assert result["fee_msats"] == 10 + assert result["paid"] is True From e9d3c48aec8797391a14107ae79a4f249ca5b5b5 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 26 Aug 2026 16:15:51 +0200 Subject: [PATCH 85/90] feat: back off pending payment polling --- tasks.py | 11 +++++++++-- tests/unit/test_tasks.py | 13 +++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tasks.py b/tasks.py index 5ea3ffc..5540a31 100644 --- a/tasks.py +++ b/tasks.py @@ -34,7 +34,9 @@ from .paranoia import ( ) from .permission import nwc_permissions -PAYMENT_STATUS_POLL_INTERVAL_SECONDS = 1.0 +PAYMENT_STATUS_POLL_INITIAL_INTERVAL_SECONDS = 1.0 +PAYMENT_STATUS_POLL_MAX_INTERVAL_SECONDS = 60.0 +PAYMENT_STATUS_POLL_BACKOFF_MULTIPLIER = 2.0 async def _check(nwc: NWCKey | None, method: str) -> dict | None: @@ -112,6 +114,7 @@ async def _process_invoice( True # currently required by nip 47 specs, might change in future ) payment_status: PaymentStatus | None = None + poll_interval = PAYMENT_STATUS_POLL_INITIAL_INTERVAL_SECONDS while wait_for_preimage: payment_status = await check_transaction_status(wallet_id, payment_hash) if payment_status.success: @@ -124,7 +127,11 @@ async def _process_invoice( }, "in_budget": in_budget, } - await asyncio.sleep(PAYMENT_STATUS_POLL_INTERVAL_SECONDS) + await asyncio.sleep(poll_interval) + poll_interval = min( + poll_interval * PAYMENT_STATUS_POLL_BACKOFF_MULTIPLIER, + PAYMENT_STATUS_POLL_MAX_INTERVAL_SECONDS, + ) if not payment_status: raise Exception("Payment status not found") return { diff --git a/tests/unit/test_tasks.py b/tests/unit/test_tasks.py index 9758954..370daf4 100644 --- a/tests/unit/test_tasks.py +++ b/tests/unit/test_tasks.py @@ -32,29 +32,30 @@ async def test_process_invoice_returns_payment_failed_on_failed_status(monkeypat @pytest.mark.asyncio -async def test_process_invoice_polls_pending_payment_at_sustainable_interval( +async def test_process_invoice_backs_off_pending_payment_polling_to_configured_max( monkeypatch, ): async def fake_tracked_spend_nwc(*args, **kwargs): return True, "a" * 64 + pending = SimpleNamespace(success=False, failed=False) statuses = iter( - [ - SimpleNamespace(success=False, failed=False), + [pending] * 8 + + [ SimpleNamespace( success=True, failed=False, preimage="b" * 64, fee_msat=10, paid=True, - ), + ) ] ) async def fake_check_transaction_status(wallet_id: str, payment_hash: str): return next(statuses) - sleep_calls = [] + sleep_calls: list[float] = [] async def fake_sleep(delay: float): sleep_calls.append(delay) @@ -73,7 +74,7 @@ async def test_process_invoice_polls_pending_payment_at_sustainable_interval( description="test", ) - assert sleep_calls == [tasks.PAYMENT_STATUS_POLL_INTERVAL_SECONDS] + assert sleep_calls == [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 60.0, 60.0] assert result["preimage"] == "b" * 64 assert result["fee_msats"] == 10 assert result["paid"] is True From 5af8335fdd345743e9a33fce41726e1f5b5b6745 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 26 Aug 2026 17:20:37 +0000 Subject: [PATCH 86/90] fix: make integration services fail fast --- .github/workflows/test.yml | 14 +++++++ tests/integration/.env | 6 ++- tests/integration/start.sh | 57 ++++++++++++++++++++++----- tests/integration/test_all.py | 74 +++++++++++++++++++---------------- 4 files changed, 107 insertions(+), 44 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7fa81f8..054d6ec 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,7 @@ on: jobs: test: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout code @@ -50,3 +51,16 @@ jobs: pip install pytest-asyncio cd $cdir pytest tests/integration/*.py -s + + - name: Show integration service logs + if: failure() + run: | + docker ps -a + docker logs --tail 200 lnbits_nwcprovider_ext_nostr_test || true + docker exec lnbits_nwcprovider_ext_lnbits_test tail -n 200 /tmp/lnbits.log || true + + - name: Stop integration services + if: always() + run: | + docker rm -f lnbits_nwcprovider_ext_lnbits_test lnbits_nwcprovider_ext_nostr_test || true + docker network rm lnbits_nwcprovider_ext_test_network || true diff --git a/tests/integration/.env b/tests/integration/.env index 05905b6..1fe75bd 100644 --- a/tests/integration/.env +++ b/tests/integration/.env @@ -199,7 +199,9 @@ LNBITS_HIDE_API=false # Extensions to be installed by default. If an extension from this list is uninstalled then it will be re-installed on the next restart. # The extension must be removed from this list in order to not be re-installed. -LNBITS_EXTENSIONS_DEFAULT_INSTALL="tpos" +# The tpos extension is no longer shipped with the LNbits dev tree. Keep the +# integration fixture focused on the extension under test. +LNBITS_EXTENSIONS_DEFAULT_INSTALL="" # Database: to use SQLite, specify LNBITS_DATA_FOLDER # to use PostgreSQL, specify LNBITS_DATABASE_URL=postgres://... @@ -249,4 +251,4 @@ LOG_ROTATION="100 MB" LOG_RETENTION="3 months" # for database cleanup commands -# CLEANUP_WALLETS_DAYS=90 \ No newline at end of file +# CLEANUP_WALLETS_DAYS=90 diff --git a/tests/integration/start.sh b/tests/integration/start.sh index 825b90e..a7babd1 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -28,6 +28,19 @@ ghcr.io/hoytech/strfry:latest rm -Rf lnbits_itest_data unzip data.zip +# The fixture was created with the standalone tpos extension installed. tpos +# is no longer part of the LNbits dev tree, so leaving its database metadata in +# the fixture makes current LNbits attempt to import a module that is absent. +# The integration suite only exercises nwcprovider. +python3 - <<'PY' +import sqlite3 + +with sqlite3.connect("lnbits_itest_data/database.sqlite3") as conn: + conn.execute("DELETE FROM installed_extensions WHERE id = 'tpos'") + conn.execute("DELETE FROM dbversions WHERE db = 'tpos'") +PY +rm -f lnbits_itest_data/ext_tpos.sqlite3 lnbits_itest_data/zips/tpos.zip + id=$(id -u) gid=$(id -g) @@ -45,24 +58,50 @@ docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -v ${PWD}/../../.devcontainer/pre-setup.sh:/pre-setup.sh:ro \ mcr.microsoft.com/devcontainers/python:1-3.12 bash -c "while true; do sleep 1000; done" -docker network create lnbits_nwcprovider_ext_test_network || true -docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_nostr_test --alias nostr|| true -docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_lnbits_test --alias lnbits|| true +if ! docker network inspect lnbits_nwcprovider_ext_test_network >/dev/null 2>&1; then + docker network create lnbits_nwcprovider_ext_test_network +fi +docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_nostr_test --alias nostr +docker network connect lnbits_nwcprovider_ext_test_network lnbits_nwcprovider_ext_lnbits_test --alias lnbits docker exec -u root lnbits_nwcprovider_ext_lnbits_test bash -c "id -u $id &>/dev/null || useradd -m -u $id tester" docker exec -u root lnbits_nwcprovider_ext_lnbits_test bash -c "bash /pre-setup.sh" docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "curl -sSL https://install.python-poetry.org | python3 -" -set +e docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"\$HOME/.local/bin:\$PATH\" && bash /setup.sh /nwcprovider" docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "ln -s /app/.env \$HOME/lnbits/.env" -ARGS="" if [ "$HEADLESS" != "" ]; then - ARGS="-d" -fi + # Keep the server log inside the container so a failed health check can + # show the actual startup error instead of silently swallowing it. + docker exec --user $id:$gid -d lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"\$HOME/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits > /tmp/lnbits.log 2>&1" -docker exec --user $id:$gid $ARGS lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"\$HOME/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" - + wait_for_http() { + local service="$1" + local url="$2" + local timeout_seconds="$3" + local deadline=$((SECONDS + timeout_seconds)) + + until curl --fail --silent --show-error --max-time 2 "$url" >/dev/null 2>&1; do + if [ "$SECONDS" -ge "$deadline" ]; then + echo "Timed out waiting for $service at $url" >&2 + docker ps -a >&2 + if [ "$service" = "LNbits" ]; then + docker exec lnbits_nwcprovider_ext_lnbits_test tail -n 100 /tmp/lnbits.log >&2 || true + else + docker logs --tail 100 lnbits_nwcprovider_ext_nostr_test >&2 || true + fi + return 1 + fi + sleep 1 + done + } + + # LNbits may need a few minutes for a fresh database migration. + wait_for_http "nostr relay" "http://localhost:7777" 180 + wait_for_http "LNbits" "http://localhost:5002" 180 +else + docker exec --user $id:$gid lnbits_nwcprovider_ext_lnbits_test bash -c "export PATH=\"\$HOME/.local/bin:\$PATH\" && cd \$HOME/lnbits && poetry run lnbits" +fi diff --git a/tests/integration/test_all.py b/tests/integration/test_all.py index fb33c1f..2752e01 100644 --- a/tests/integration/test_all.py +++ b/tests/integration/test_all.py @@ -12,6 +12,10 @@ from loguru import logger from pynostr.key import PrivateKey from websockets.legacy.client import connect +SERVICE_STARTUP_TIMEOUT_SECONDS = 180 +NWC_CONNECTION_TIMEOUT_SECONDS = 60 +NWC_RESPONSE_TIMEOUT_SECONDS = 60 + wallets = { "wallet1": { "name": "wallet1", @@ -41,35 +45,29 @@ wallets = { async def check_services(): - # wait for http server in localhost:7777 - while True: + async def wait_for_service(name: str, url: str): + deadline = time.monotonic() + SERVICE_STARTUP_TIMEOUT_SECONDS try: async with httpx.AsyncClient() as client: - resp = await client.get("http://localhost:7777") - assert resp.status_code == 200 - break - except Exception: - logger.info("Waiting for nostr relay @ http://localhost:7777") - logger.info( - """Please start the required services by running\ - `bash start.sh` if you haven't already""" - ) - await asyncio.sleep(1) + while True: + try: + resp = await client.get(url) + if resp.status_code == 200: + return + except httpx.HTTPError: + pass + if time.monotonic() >= deadline: + raise RuntimeError( + f"Timed out waiting for {name} at {url}. " + "Start the integration services with `bash start.sh`." + ) + logger.info(f"Waiting for {name} @ {url}") + await asyncio.sleep(1) + except httpx.HTTPError as exc: + raise RuntimeError(f"Unable to check {name} at {url}: {exc}") from exc - # wait lnbits @ localhost:5000 - while True: - try: - async with httpx.AsyncClient() as client: - resp = await client.get("http://localhost:5002") - assert resp.status_code == 200 - break - except Exception: - logger.info("Waiting for lnbits @ http://localhost:5002") - logger.info( - """Please start the required services by running\ - `bash start.sh` if you haven't already""" - ) - await asyncio.sleep(1) + await wait_for_service("nostr relay", "http://localhost:7777") + await wait_for_service("LNbits", "http://localhost:5002") async def get_wallet_balance(w: str): @@ -179,15 +177,21 @@ class NWCWallet: async def _wait_for_connection(self): while not self.connected: - try: - await asyncio.sleep(0.2) - except asyncio.CancelledError: - logger.debug("Connection wait cancelled") - return + await asyncio.sleep(0.2) async def start(self): self.task = asyncio.create_task(self._run()) - await self._wait_for_connection() + try: + await asyncio.wait_for( + self._wait_for_connection(), timeout=NWC_CONNECTION_TIMEOUT_SECONDS + ) + except asyncio.TimeoutError as exc: + self.task.cancel() + await asyncio.gather(self.task, return_exceptions=True) + self.task = None + raise RuntimeError( + f"Timed out connecting to NWC relay {self.relay}" + ) from exc def _is_shutting_down(self): return self.shutdown @@ -304,7 +308,11 @@ class NWCWallet: await self.ws.send(self._json_dumps(["EVENT", event])) async def wait_for( - self, result_type, callback=None, on_error_callback=None, timeout=60000 + self, + result_type, + callback=None, + on_error_callback=None, + timeout=NWC_RESPONSE_TIMEOUT_SECONDS, ): now = time.time() while True: From 9362bf53aecc40a0f51784d6f8a4dabddb189a7f Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 26 Aug 2026 21:54:44 +0200 Subject: [PATCH 87/90] fix: run integration relay as runner user --- tests/integration/start.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/integration/start.sh b/tests/integration/start.sh index a7babd1..2a669c1 100644 --- a/tests/integration/start.sh +++ b/tests/integration/start.sh @@ -15,10 +15,16 @@ if [ "`cat .v039fk_lnbits_integration_test_folder`" != "yes v039fk_lnbits_integr exit 1 fi -# Start nostr Relay +# Start nostr Relay. The image defaults to the `strfry` user (UID 1000), +# which is not necessarily the user running the CI job. Create the bind mount +# first and run the relay as the current user so LMDB can initialize its files. +id=$(id -u) +gid=$(id -g) +mkdir -p strfry-data docker run --name=lnbits_nwcprovider_ext_nostr_test \ -d \ --rm \ +--user $id:$gid \ -v $PWD/strfry.conf:/etc/strfry.conf:Z \ -v $PWD/strfry-data:/app/strfry-db:Z \ -p 7777:7777 \ @@ -41,10 +47,6 @@ with sqlite3.connect("lnbits_itest_data/database.sqlite3") as conn: PY rm -f lnbits_itest_data/ext_tpos.sqlite3 lnbits_itest_data/zips/tpos.zip -id=$(id -u) -gid=$(id -g) - - docker run --name=lnbits_nwcprovider_ext_lnbits_test \ -d \ --rm \ From b3500f63d9cf5c6f1652388b4cca96d92269d7a1 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Thu, 27 Aug 2026 18:29:46 +0200 Subject: [PATCH 88/90] Update version number to 1.1.3 in config.json --- config.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config.json b/config.json index 9fbe5ce..9999c93 100644 --- a/config.json +++ b/config.json @@ -1,12 +1,11 @@ { "id": "nwcprovider", - "version": "1.1.0", "name": "NWC Service Provider", "repo": "https://github.com/lnbits/nwcprovider", "short_description": "A NWC service provider for LNbits", "description": "", "tile": "/nwcprovider/static/image/nwcprovider.png", - "version": "1.1.2", + "version": "1.1.3", "min_lnbits_version": "1.4.0", "contributors": [ { From bf55b46f769baea28245139ff4704286ad640ac7 Mon Sep 17 00:00:00 2001 From: Patrick Mulligan <43773168+PatMulligan@users.noreply.github.com> Date: Mon, 14 Sep 2026 22:22:07 +0200 Subject: [PATCH 89/90] fix: accept null optional params in make_invoice and list_transactions Clients may send optional params as an explicit JSON null rather than omitting them; Amethyst does for description, description_hash and expiry. dict.get only applies its default for a missing key, so description arrived as None and make_invoice failed with "'NoneType' object has no attribute 'encode'". Coerce with `or` instead, pass no unhashed_description when the description is blank, and apply the same to list_transactions' paging params, which had the same exposure. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_013Tbyw6FwjhEJg3gHfPHxWt --- tasks.py | 22 ++++++------ tests/unit/test_tasks.py | 74 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 10 deletions(-) diff --git a/tasks.py b/tasks.py index 5540a31..76aab58 100644 --- a/tasks.py +++ b/tasks.py @@ -264,9 +264,11 @@ async def _on_make_invoice( # Ensures amount is provided if not amount_msats: raise Exception("Missing amount") - description = params.get("description", "") - description_hash = params.get("description_hash", None) - expiry = params.get("expiry", None) + # Optional params may arrive as explicit JSON null, which dict.get does + # not default, so coerce here rather than trusting the fallback. + description = params.get("description") or "" + description_hash = params.get("description_hash") or None + expiry = params.get("expiry") or None # hardening # assert_valid_msats(amount_msats) @@ -284,7 +286,7 @@ async def _on_make_invoice( currency="sat", memo=description, description_hash=bytes.fromhex(description_hash) if description_hash else None, - unhashed_description=description.encode("utf-8"), + unhashed_description=description.encode("utf-8") if description else None, expiry=expiry, ) payment_hash = payment.payment_hash @@ -394,12 +396,12 @@ async def _on_list_transactions( if not nwc: raise Exception("Pubkey has no associated wallet") params = payload.get("params", 0) - tfrom = params.get("from", 0) - tuntil = params.get("until", int(time.time())) - limit = params.get("limit", 10) - offset = params.get("offset", 0) - unpaid = params.get("unpaid", False) - tx_type = params.get("type", "") + tfrom = params.get("from") or 0 + tuntil = params.get("until") or int(time.time()) + limit = params.get("limit") or 10 + offset = params.get("offset") or 0 + unpaid = params.get("unpaid") or False + tx_type = params.get("type") or "" # hardening # assert_valid_positive_int(tfrom) diff --git a/tests/unit/test_tasks.py b/tests/unit/test_tasks.py index 370daf4..6dfeb55 100644 --- a/tests/unit/test_tasks.py +++ b/tests/unit/test_tasks.py @@ -78,3 +78,77 @@ async def test_process_invoice_backs_off_pending_payment_polling_to_configured_m assert result["preimage"] == "b" * 64 assert result["fee_msats"] == 10 assert result["paid"] is True + + +def _stub_make_invoice(monkeypatch, captured: dict): + async def fake_get_nwc(*args, **kwargs): + return SimpleNamespace(wallet="wallet123") + + async def fake_check(nwc, method): + return None + + async def fake_create_invoice(**kwargs): + captured.update(kwargs) + return SimpleNamespace(payment_hash="b" * 64, bolt11="lnbc1example") + + async def fake_check_transaction_status(wallet_id: str, payment_hash: str): + return SimpleNamespace(preimage=None) + + monkeypatch.setattr(tasks, "get_nwc", fake_get_nwc) + monkeypatch.setattr(tasks, "_check", fake_check) + monkeypatch.setattr(tasks, "create_invoice", fake_create_invoice) + monkeypatch.setattr( + tasks, "check_transaction_status", fake_check_transaction_status + ) + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "params", + [ + # rust-nostr, Alby JS SDK: unused optional fields are omitted + {"amount": 21000}, + # Amethyst: unused optional fields are sent as explicit null + { + "amount": 21000, + "description": None, + "description_hash": None, + "expiry": None, + }, + ], +) +async def test_make_invoice_accepts_absent_or_null_optional_params(monkeypatch, params): + captured: dict = {} + _stub_make_invoice(monkeypatch, captured) + + [(result, error, _)] = await tasks._on_make_invoice( + SimpleNamespace(), "a" * 64, {"params": params} + ) + + assert error is None + assert result["invoice"] == "lnbc1example" + assert result["description"] == "" + assert "expires_at" not in result + assert captured["memo"] == "" + assert captured["description_hash"] is None + assert captured["unhashed_description"] is None + assert captured["expiry"] is None + + +@pytest.mark.asyncio +async def test_make_invoice_passes_description_and_expiry_through(monkeypatch): + captured: dict = {} + _stub_make_invoice(monkeypatch, captured) + + [(result, error, _)] = await tasks._on_make_invoice( + SimpleNamespace(), + "a" * 64, + {"params": {"amount": 21000, "description": "coffee", "expiry": 600}}, + ) + + assert error is None + assert captured["memo"] == "coffee" + assert captured["unhashed_description"] == b"coffee" + assert captured["expiry"] == 600 + assert result["description"] == "coffee" + assert "expires_at" in result From 5f4dde6b53cf14c5cecdb45d023a09ed98679a54 Mon Sep 17 00:00:00 2001 From: Padreug Date: Mon, 14 Sep 2026 22:34:27 +0200 Subject: [PATCH 90/90] chore: bump version to 1.1.3-aio.1 Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_013Tbyw6FwjhEJg3gHfPHxWt --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 9999c93..187cb5d 100644 --- a/config.json +++ b/config.json @@ -5,7 +5,7 @@ "short_description": "A NWC service provider for LNbits", "description": "", "tile": "/nwcprovider/static/image/nwcprovider.png", - "version": "1.1.3", + "version": "1.1.3-aio.1", "min_lnbits_version": "1.4.0", "contributors": [ {