Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-maxminddb for 
openSUSE:Factory checked in at 2026-09-12 21:15:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-maxminddb (Old)
 and      /work/SRC/openSUSE:Factory/.python-maxminddb.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-maxminddb"

Sat Sep 12 21:15:10 2026 rev:19 rq:1376983 version:3.1.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-maxminddb/python-maxminddb.changes        
2026-02-02 14:56:02.336660272 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-maxminddb.new.1265/python-maxminddb.changes  
    2026-09-12 21:15:19.548413667 +0200
@@ -1,0 +2,24 @@
+Thu Sep  3 17:15:11 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to 3.1.1:
+  * Vendored libmaxminddb bumped to 1.13.3: no longer rejects
+    databases whose metadata ends in a 0-element map or array
+- Changes from 3.1.0:
+  * Vendored libmaxminddb bumped to 1.13.1: hardening for corrupt
+    or malicious databases (integer overflow, bounds checking,
+    use-after-free)
+- Build against the system libmaxminddb instead of the vendored copy,
+  which was statically linked in until now - the two fixes above come
+  from whatever libmaxminddb the target ships (1.13.3 on Tumbleweed,
+  still 1.12.2 on Leap 16.x), not from a private copy
+  * MAXMINDDB_USE_SYSTEM_LIBMAXMINDDB=1, plus
+    MAXMINDDB_REQUIRE_EXTENSION=1 so a failed extension build errors
+    out instead of silently falling back to pure Python
+- Set MM_FORCE_EXT_TESTS=1 so the extension tests fail loudly instead
+  of skipping should the .so ever go missing
+- Replace libmaxminddb-devel with pkgconfig(libmaxminddb) + pkgconfig,
+  add gcc
+- BuildRequire setuptools >= 77.0.3, as upstream requires
+- Drop the Leap 15.6 setuptools compatibility sed, 15.6 is EOL
+
+-------------------------------------------------------------------

Old:
----
  maxminddb-3.0.0.tar.gz

New:
----
  maxminddb-3.1.1.tar.gz

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

Other differences:
------------------
++++++ python-maxminddb.spec ++++++
--- /var/tmp/diff_new_pack.nB6sYn/_old  2026-09-12 21:15:20.069435336 +0200
+++ /var/tmp/diff_new_pack.nB6sYn/_new  2026-09-12 21:15:20.070435377 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-maxminddb
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2026 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-maxminddb
-Version:        3.0.0
+Version:        3.1.1
 Release:        0
 Summary:        Reader for the MaxMind DB format
 License:        Apache-2.0
@@ -26,11 +26,13 @@
 Source:         
https://files.pythonhosted.org/packages/source/m/maxminddb/maxminddb-%{version}.tar.gz
 BuildRequires:  %{python_module devel >= 3.10}
 BuildRequires:  %{python_module pip}
-BuildRequires:  %{python_module setuptools}
+BuildRequires:  %{python_module setuptools >= 77.0.3}
 BuildRequires:  %{python_module wheel}
 BuildRequires:  fdupes
-BuildRequires:  libmaxminddb-devel
+BuildRequires:  gcc
+BuildRequires:  pkgconfig
 BuildRequires:  python-rpm-macros
+BuildRequires:  pkgconfig(libmaxminddb)
 # SECTION test requirements
 BuildRequires:  %{python_module pytest}
 # /SECTION
@@ -45,14 +47,14 @@
 
 %prep
 %autosetup -n maxminddb-%{version}
-
-# hack to restore compatibility with older setuptools
-%if 0%{?suse_version} <= 1500
-sed -i 's/^from setuptools.command.bdist_wheel/from wheel.bdist_wheel/' 
setup.py
-%endif
+# no bundled libmaxminddb, see MAXMINDDB_USE_SYSTEM_LIBMAXMINDDB below
+rm -r extension/libmaxminddb
 
 %build
 export CFLAGS="%{optflags}"
+export MAXMINDDB_USE_SYSTEM_LIBMAXMINDDB=1
+# without this setup.py silently falls back to the pure Python reader
+export MAXMINDDB_REQUIRE_EXTENSION=1
 %pyproject_wheel
 
 %install
@@ -60,6 +62,8 @@
 %python_expand %fdupes %{buildroot}%{$python_sitearch}
 
 %check
+# else the extension tests skip themselves when the .so is missing
+export MM_FORCE_EXT_TESTS=1
 %pytest_arch
 
 %files %{python_files}

++++++ maxminddb-3.0.0.tar.gz -> maxminddb-3.1.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/maxminddb-3.0.0/HISTORY.rst 
new/maxminddb-3.1.1/HISTORY.rst
--- old/maxminddb-3.0.0/HISTORY.rst     2025-10-15 21:46:00.000000000 +0200
+++ new/maxminddb-3.1.1/HISTORY.rst     2026-03-05 19:03:12.000000000 +0100
@@ -3,6 +3,23 @@
 History
 -------
 
+3.1.1 (2026-03-05)
+++++++++++++++++++
+
+* The vendored ``libmaxminddb`` has been updated to 1.13.3. This includes
+  a fix for the validation of empty maps and arrays at the end of the
+  metadata section. Previously, the extension would incorrectly reject
+  databases where a 0-element map or array was the last field in metadata.
+  Reported in vimt/MaxMind-DB-Writer-python#16.
+
+3.1.0 (2026-02-24)
+++++++++++++++++++
+
+* The vendored ``libmaxminddb`` has been updated to 1.13.1. This includes
+  several security hardening improvements when reading corrupt or malicious
+  database files, including fixes for integer overflows, bounds checking, and
+  use-after-free prevention.
+
 3.0.0 (2025-10-15)
 ++++++++++++++++++
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/maxminddb-3.0.0/PKG-INFO new/maxminddb-3.1.1/PKG-INFO
--- old/maxminddb-3.0.0/PKG-INFO        2025-10-15 21:46:06.075603500 +0200
+++ new/maxminddb-3.1.1/PKG-INFO        2026-03-05 19:03:17.954726700 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: maxminddb
-Version: 3.0.0
+Version: 3.1.1
 Summary: Reader for the MaxMind DB format
 Author-email: Gregory Oschwald <[email protected]>
 License-Expression: Apache-2.0
@@ -132,12 +132,6 @@
 protection. Calling ``close()`` while reads are in progress may cause
 exceptions in those threads.
 
-Requirements
-------------
-
-This code requires Python 3.10+. Older versions are not supported. The C
-extension requires CPython.
-
 Versioning
 ----------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/maxminddb-3.0.0/README.rst 
new/maxminddb-3.1.1/README.rst
--- old/maxminddb-3.0.0/README.rst      2025-10-15 21:46:00.000000000 +0200
+++ new/maxminddb-3.1.1/README.rst      2026-03-05 19:03:12.000000000 +0100
@@ -104,12 +104,6 @@
 protection. Calling ``close()`` while reads are in progress may cause
 exceptions in those threads.
 
-Requirements
-------------
-
-This code requires Python 3.10+. Older versions are not supported. The C
-extension requires CPython.
-
 Versioning
 ----------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/maxminddb-3.0.0/extension/libmaxminddb/include/maxminddb.h 
new/maxminddb-3.1.1/extension/libmaxminddb/include/maxminddb.h
--- old/maxminddb-3.0.0/extension/libmaxminddb/include/maxminddb.h      
2025-10-15 21:46:02.000000000 +0200
+++ new/maxminddb-3.1.1/extension/libmaxminddb/include/maxminddb.h      
2026-03-05 19:03:13.000000000 +0100
@@ -3,80 +3,97 @@
 #endif
 
 #ifndef MAXMINDDB_H
-#define MAXMINDDB_H
+    #define MAXMINDDB_H
 
-#include "maxminddb_config.h"
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-/* libmaxminddb package version from configure */
-
-#if defined(_MSC_VER)
-/* MSVC doesn't define signed size_t, copy it from configure */
-#define ssize_t SSIZE_T
+    #include "maxminddb_config.h"
+    #include <stdarg.h>
+    #include <stdbool.h>
+    #include <stdint.h>
+    #include <stdio.h>
+    #include <sys/types.h>
+
+    #ifdef __has_include
+        #if __has_include(<endian.h>)
+            #include <endian.h>
+        #elif __has_include(<sys/endian.h>)
+            #include <sys/endian.h>
+        #endif
+    #endif
+
+    #ifdef _WIN32
+        #include <winsock2.h>
+        #include <ws2tcpip.h>
+    /* libmaxminddb package version from configure */
+
+        #if defined(_MSC_VER)
+            /* MSVC doesn't define signed size_t, copy it from configure */
+            #define ssize_t SSIZE_T
+
+        #endif
+    #else
+        #include <netdb.h>
+        #include <netinet/in.h>
+        #include <sys/socket.h>
+    #endif
+
+    #if !defined(MMDB_LITTLE_ENDIAN)
+        #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
+            #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+                #define MMDB_LITTLE_ENDIAN 1
+            #endif
+        #elif defined(_WIN32) || defined(_WIN64)
+            // We assume modern Windows targets are little endian
+            #define MMDB_LITTLE_ENDIAN 1
+        #endif
+    #endif
+
+    #define MMDB_DATA_TYPE_EXTENDED (0)
+    #define MMDB_DATA_TYPE_POINTER (1)
+    #define MMDB_DATA_TYPE_UTF8_STRING (2)
+    #define MMDB_DATA_TYPE_DOUBLE (3)
+    #define MMDB_DATA_TYPE_BYTES (4)
+    #define MMDB_DATA_TYPE_UINT16 (5)
+    #define MMDB_DATA_TYPE_UINT32 (6)
+    #define MMDB_DATA_TYPE_MAP (7)
+    #define MMDB_DATA_TYPE_INT32 (8)
+    #define MMDB_DATA_TYPE_UINT64 (9)
+    #define MMDB_DATA_TYPE_UINT128 (10)
+    #define MMDB_DATA_TYPE_ARRAY (11)
+    #define MMDB_DATA_TYPE_CONTAINER (12)
+    #define MMDB_DATA_TYPE_END_MARKER (13)
+    #define MMDB_DATA_TYPE_BOOLEAN (14)
+    #define MMDB_DATA_TYPE_FLOAT (15)
+
+    #define MMDB_RECORD_TYPE_SEARCH_NODE (0)
+    #define MMDB_RECORD_TYPE_EMPTY (1)
+    #define MMDB_RECORD_TYPE_DATA (2)
+    #define MMDB_RECORD_TYPE_INVALID (3)
+
+    /* flags for open */
+    #define MMDB_MODE_MMAP (1)
+    #define MMDB_MODE_MASK (7)
+
+    /* error codes */
+    #define MMDB_SUCCESS (0)
+    #define MMDB_FILE_OPEN_ERROR (1)
+    #define MMDB_CORRUPT_SEARCH_TREE_ERROR (2)
+    #define MMDB_INVALID_METADATA_ERROR (3)
+    #define MMDB_IO_ERROR (4)
+    #define MMDB_OUT_OF_MEMORY_ERROR (5)
+    #define MMDB_UNKNOWN_DATABASE_FORMAT_ERROR (6)
+    #define MMDB_INVALID_DATA_ERROR (7)
+    #define MMDB_INVALID_LOOKUP_PATH_ERROR (8)
+    #define MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR (9)
+    #define MMDB_INVALID_NODE_NUMBER_ERROR (10)
+    #define MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR (11)
 
-/* MSVC doesn't support restricted pointers */
-#define restrict
-#endif
-#else
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#endif
-
-#define MMDB_DATA_TYPE_EXTENDED (0)
-#define MMDB_DATA_TYPE_POINTER (1)
-#define MMDB_DATA_TYPE_UTF8_STRING (2)
-#define MMDB_DATA_TYPE_DOUBLE (3)
-#define MMDB_DATA_TYPE_BYTES (4)
-#define MMDB_DATA_TYPE_UINT16 (5)
-#define MMDB_DATA_TYPE_UINT32 (6)
-#define MMDB_DATA_TYPE_MAP (7)
-#define MMDB_DATA_TYPE_INT32 (8)
-#define MMDB_DATA_TYPE_UINT64 (9)
-#define MMDB_DATA_TYPE_UINT128 (10)
-#define MMDB_DATA_TYPE_ARRAY (11)
-#define MMDB_DATA_TYPE_CONTAINER (12)
-#define MMDB_DATA_TYPE_END_MARKER (13)
-#define MMDB_DATA_TYPE_BOOLEAN (14)
-#define MMDB_DATA_TYPE_FLOAT (15)
-
-#define MMDB_RECORD_TYPE_SEARCH_NODE (0)
-#define MMDB_RECORD_TYPE_EMPTY (1)
-#define MMDB_RECORD_TYPE_DATA (2)
-#define MMDB_RECORD_TYPE_INVALID (3)
-
-/* flags for open */
-#define MMDB_MODE_MMAP (1)
-#define MMDB_MODE_MASK (7)
-
-/* error codes */
-#define MMDB_SUCCESS (0)
-#define MMDB_FILE_OPEN_ERROR (1)
-#define MMDB_CORRUPT_SEARCH_TREE_ERROR (2)
-#define MMDB_INVALID_METADATA_ERROR (3)
-#define MMDB_IO_ERROR (4)
-#define MMDB_OUT_OF_MEMORY_ERROR (5)
-#define MMDB_UNKNOWN_DATABASE_FORMAT_ERROR (6)
-#define MMDB_INVALID_DATA_ERROR (7)
-#define MMDB_INVALID_LOOKUP_PATH_ERROR (8)
-#define MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR (9)
-#define MMDB_INVALID_NODE_NUMBER_ERROR (10)
-#define MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR (11)
-
-#if !(MMDB_UINT128_IS_BYTE_ARRAY)
-#if MMDB_UINT128_USING_MODE
+    #if !(MMDB_UINT128_IS_BYTE_ARRAY)
+        #if MMDB_UINT128_USING_MODE
 typedef unsigned int mmdb_uint128_t __attribute__((__mode__(TI)));
-#else
+        #else
 typedef unsigned __int128 mmdb_uint128_t;
-#endif
-#endif
+        #endif
+    #endif
 
 /* This is a pointer into the data section for a given IP address lookup */
 typedef struct MMDB_entry_s {
@@ -101,11 +118,11 @@
         uint32_t uint32;
         int32_t int32;
         uint64_t uint64;
-#if MMDB_UINT128_IS_BYTE_ARRAY
+    #if MMDB_UINT128_IS_BYTE_ARRAY
         uint8_t uint128[16];
-#else
+    #else
         mmdb_uint128_t uint128;
-#endif
+    #endif
         bool boolean;
         float float_value;
     };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/maxminddb-3.0.0/extension/libmaxminddb/src/data-pool.c 
new/maxminddb-3.1.1/extension/libmaxminddb/src/data-pool.c
--- old/maxminddb-3.0.0/extension/libmaxminddb/src/data-pool.c  2025-10-15 
21:46:02.000000000 +0200
+++ new/maxminddb-3.1.1/extension/libmaxminddb/src/data-pool.c  2026-03-05 
19:03:13.000000000 +0100
@@ -1,5 +1,5 @@
 #ifndef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 200809L
+    #define _POSIX_C_SOURCE 200809L
 #endif
 
 #include "data-pool.h"
@@ -146,8 +146,8 @@
 
 #ifdef TEST_DATA_POOL
 
-#include <libtap/tap.h>
-#include <maxminddb_test_helper.h>
+    #include <libtap/tap.h>
+    #include <maxminddb_test_helper.h>
 
 static void test_can_multiply(void);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/maxminddb-3.0.0/extension/libmaxminddb/src/maxminddb.c 
new/maxminddb-3.1.1/extension/libmaxminddb/src/maxminddb.c
--- old/maxminddb-3.0.0/extension/libmaxminddb/src/maxminddb.c  2025-10-15 
21:46:02.000000000 +0200
+++ new/maxminddb-3.1.1/extension/libmaxminddb/src/maxminddb.c  2026-03-05 
19:03:13.000000000 +0100
@@ -1,9 +1,9 @@
 #ifndef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 200809L
+    #define _POSIX_C_SOURCE 200809L
 #endif
 
 #if HAVE_CONFIG_H
-#include <config.h>
+    #include <config.h>
 #endif
 #include "data-pool.h"
 #include "maxminddb-compat-util.h"
@@ -18,43 +18,43 @@
 #include <sys/stat.h>
 
 #ifdef _WIN32
-#ifndef UNICODE
-#define UNICODE
-#endif
-#include <windows.h>
-#include <ws2ipdef.h>
-#ifndef SSIZE_MAX
-#define SSIZE_MAX INTPTR_MAX
-#endif
+    #ifndef UNICODE
+        #define UNICODE
+    #endif
+    #include <windows.h>
+    #include <ws2ipdef.h>
+    #ifndef SSIZE_MAX
+        #define SSIZE_MAX INTPTR_MAX
+    #endif
 typedef ADDRESS_FAMILY sa_family_t;
 #else
-#include <arpa/inet.h>
-#include <sys/mman.h>
-#include <unistd.h>
+    #include <arpa/inet.h>
+    #include <sys/mman.h>
+    #include <unistd.h>
 #endif
 
 #define MMDB_DATA_SECTION_SEPARATOR (16)
 #define MAXIMUM_DATA_STRUCTURE_DEPTH (512)
 
 #ifdef MMDB_DEBUG
-#define DEBUG_MSG(msg) fprintf(stderr, msg "\n")
-#define DEBUG_MSGF(fmt, ...) fprintf(stderr, fmt "\n", __VA_ARGS__)
-#define DEBUG_BINARY(fmt, byte)                                                
\
-    do {                                                                       
\
-        char *binary = byte_to_binary(byte);                                   
\
-        if (NULL == binary) {                                                  
\
-            fprintf(stderr, "Calloc failed in DEBUG_BINARY\n");                
\
-            abort();                                                           
\
-        }                                                                      
\
-        fprintf(stderr, fmt "\n", binary);                                     
\
-        free(binary);                                                          
\
-    } while (0)
-#define DEBUG_NL fprintf(stderr, "\n")
+    #define DEBUG_MSG(msg) fprintf(stderr, msg "\n")
+    #define DEBUG_MSGF(fmt, ...) fprintf(stderr, fmt "\n", __VA_ARGS__)
+    #define DEBUG_BINARY(fmt, byte)                                            
\
+        do {                                                                   
\
+            char *binary = byte_to_binary(byte);                               
\
+            if (NULL == binary) {                                              
\
+                fprintf(stderr, "Calloc failed in DEBUG_BINARY\n");            
\
+                abort();                                                       
\
+            }                                                                  
\
+            fprintf(stderr, fmt "\n", binary);                                 
\
+            free(binary);                                                      
\
+        } while (0)
+    #define DEBUG_NL fprintf(stderr, "\n")
 #else
-#define DEBUG_MSG(...)
-#define DEBUG_MSGF(...)
-#define DEBUG_BINARY(...)
-#define DEBUG_NL
+    #define DEBUG_MSG(...)
+    #define DEBUG_MSGF(...)
+    #define DEBUG_BINARY(...)
+    #define DEBUG_NL
 #endif
 
 #ifdef MMDB_DEBUG
@@ -116,12 +116,12 @@
  * platforms where SIZE_MAX is a 64-bit integer, this would be a no-op, and it
  * makes the compiler complain if we do the check anyway. */
 #if SIZE_MAX == UINT32_MAX
-#define MAYBE_CHECK_SIZE_OVERFLOW(lhs, rhs, error)                             
\
-    if ((lhs) > (rhs)) {                                                       
\
-        return error;                                                          
\
-    }
+    #define MAYBE_CHECK_SIZE_OVERFLOW(lhs, rhs, error)                         
\
+        if ((lhs) > (rhs)) {                                                   
\
+            return error;                                                      
\
+        }
 #else
-#define MAYBE_CHECK_SIZE_OVERFLOW(...)
+    #define MAYBE_CHECK_SIZE_OVERFLOW(...)
 #endif
 
 typedef struct record_info_s {
@@ -178,7 +178,8 @@
                               const MMDB_s *const mmdb,
                               MMDB_entry_data_s *entry_data);
 static int skip_map_or_array(const MMDB_s *const mmdb,
-                             MMDB_entry_data_s *entry_data);
+                             MMDB_entry_data_s *entry_data,
+                             int depth);
 static int decode_one_follow(const MMDB_s *const mmdb,
                              uint32_t offset,
                              MMDB_entry_data_s *entry_data);
@@ -366,7 +367,7 @@
 }
 
 static int map_file(MMDB_s *const mmdb) {
-    DWORD size;
+    ssize_t size;
     int status = MMDB_SUCCESS;
     HANDLE mmh = NULL;
     HANDLE fd = INVALID_HANDLE_VALUE;
@@ -386,12 +387,17 @@
         status = MMDB_FILE_OPEN_ERROR;
         goto cleanup;
     }
-    size = GetFileSize(fd, NULL);
-    if (size == INVALID_FILE_SIZE) {
-        status = MMDB_FILE_OPEN_ERROR;
+    LARGE_INTEGER file_size;
+    if (!GetFileSizeEx(fd, &file_size)) {
+        status = MMDB_IO_ERROR;
         goto cleanup;
     }
-    mmh = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, size, NULL);
+    if (file_size.QuadPart < 0 || file_size.QuadPart > SSIZE_MAX) {
+        status = MMDB_IO_ERROR;
+        goto cleanup;
+    }
+    size = (ssize_t)file_size.QuadPart;
+    mmh = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL);
     /* Microsoft documentation for CreateFileMapping indicates this returns
         NULL not INVALID_HANDLE_VALUE on error */
     if (NULL == mmh) {
@@ -428,21 +434,21 @@
     int status = MMDB_SUCCESS;
 
     int o_flags = O_RDONLY;
-#ifdef O_CLOEXEC
+    #ifdef O_CLOEXEC
     o_flags |= O_CLOEXEC;
-#endif
+    #endif
     int fd = open(mmdb->filename, o_flags);
     if (fd < 0) {
         status = MMDB_FILE_OPEN_ERROR;
         goto cleanup;
     }
 
-#if defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
+    #if defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
     int fd_flags = fcntl(fd, F_GETFD);
     if (fd_flags >= 0) {
         fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC);
     }
-#endif
+    #endif
 
     struct stat s;
     if (fstat(fd, &s)) {
@@ -882,6 +888,11 @@
 
     if (!*gai_error) {
         result = MMDB_lookup_sockaddr(mmdb, addresses->ai_addr, mmdb_error);
+    } else {
+        /* No MMDB error occurred; the GAI failure is reported via
+         * *gai_error. Set *mmdb_error to a defined value so callers
+         * don't read indeterminate memory. */
+        *mmdb_error = MMDB_SUCCESS;
     }
 
     if (NULL != addresses) {
@@ -979,7 +990,7 @@
 
     result->netmask = current_bit;
 
-    if (value >= node_count + mmdb->data_section_size) {
+    if (value >= (uint64_t)node_count + mmdb->data_section_size) {
         // The pointer points off the end of the database.
         return MMDB_CORRUPT_SEARCH_TREE_ERROR;
     }
@@ -1039,7 +1050,8 @@
     uint32_t node_count = mmdb->metadata.node_count;
 
     for (netmask = 0; netmask < 96 && node_value < node_count; netmask++) {
-        record_pointer = &search_tree[node_value * record_info.record_length];
+        record_pointer =
+            &search_tree[(uint64_t)node_value * record_info.record_length];
         if (record_pointer + record_info.record_length > mmdb->data_section) {
             return MMDB_CORRUPT_SEARCH_TREE_ERROR;
         }
@@ -1097,13 +1109,16 @@
         return MMDB_UNKNOWN_DATABASE_FORMAT_ERROR;
     }
 
-    if (node_number > mmdb->metadata.node_count) {
+    if (node_number >= mmdb->metadata.node_count) {
         return MMDB_INVALID_NODE_NUMBER_ERROR;
     }
 
     const uint8_t *search_tree = mmdb->file_content;
     const uint8_t *record_pointer =
-        &search_tree[node_number * record_info.record_length];
+        &search_tree[(uint64_t)node_number * record_info.record_length];
+    if (record_pointer + record_info.record_length > mmdb->data_section) {
+        return MMDB_CORRUPT_SEARCH_TREE_ERROR;
+    }
     node->left_record = record_info.left_record_getter(record_pointer);
     record_pointer += record_info.right_record_offset;
     node->right_record = record_info.right_record_getter(record_pointer);
@@ -1272,7 +1287,7 @@
         /* We don't want to follow a pointer here. If the next element is a
          * pointer we simply skip it and keep going */
         CHECKED_DECODE_ONE(mmdb, entry_data->offset_to_next, entry_data);
-        int status = skip_map_or_array(mmdb, entry_data);
+        int status = skip_map_or_array(mmdb, entry_data, 0);
         if (MMDB_SUCCESS != status) {
             return status;
         }
@@ -1314,7 +1329,7 @@
             /* We don't want to follow a pointer here. If the next element is
              * a pointer we simply skip it and keep going */
             CHECKED_DECODE_ONE(mmdb, offset_to_value, &value);
-            int status = skip_map_or_array(mmdb, &value);
+            int status = skip_map_or_array(mmdb, &value, 0);
             if (MMDB_SUCCESS != status) {
                 return status;
             }
@@ -1327,7 +1342,13 @@
 }
 
 static int skip_map_or_array(const MMDB_s *const mmdb,
-                             MMDB_entry_data_s *entry_data) {
+                             MMDB_entry_data_s *entry_data,
+                             int depth) {
+    if (depth >= MAXIMUM_DATA_STRUCTURE_DEPTH) {
+        DEBUG_MSG("reached the maximum data structure depth");
+        return MMDB_INVALID_DATA_ERROR;
+    }
+
     if (entry_data->type == MMDB_DATA_TYPE_MAP) {
         uint32_t size = entry_data->data_size;
         while (size-- > 0) {
@@ -1335,7 +1356,7 @@
                 mmdb, entry_data->offset_to_next, entry_data); // key
             CHECKED_DECODE_ONE(
                 mmdb, entry_data->offset_to_next, entry_data); // value
-            int status = skip_map_or_array(mmdb, entry_data);
+            int status = skip_map_or_array(mmdb, entry_data, depth + 1);
             if (MMDB_SUCCESS != status) {
                 return status;
             }
@@ -1345,7 +1366,7 @@
         while (size-- > 0) {
             CHECKED_DECODE_ONE(
                 mmdb, entry_data->offset_to_next, entry_data); // value
-            int status = skip_map_or_array(mmdb, entry_data);
+            int status = skip_map_or_array(mmdb, entry_data, depth + 1);
             if (MMDB_SUCCESS != status) {
                 return status;
             }
@@ -1707,6 +1728,12 @@
         case MMDB_DATA_TYPE_ARRAY: {
             uint32_t array_size = entry_data_list->entry_data.data_size;
             uint32_t array_offset = entry_data_list->entry_data.offset_to_next;
+            /* Each array element needs at least 1 byte. */
+            if (array_offset > mmdb->data_section_size ||
+                array_size > mmdb->data_section_size - array_offset) {
+                DEBUG_MSG("array size exceeds remaining data section");
+                return MMDB_INVALID_DATA_ERROR;
+            }
             while (array_size-- > 0) {
                 MMDB_entry_data_list_s *entry_data_list_to =
                     data_pool_alloc(pool);
@@ -1730,6 +1757,12 @@
             uint32_t size = entry_data_list->entry_data.data_size;
 
             offset = entry_data_list->entry_data.offset_to_next;
+            /* Each map entry needs at least a key and a value (1 byte each). 
*/
+            if (offset > mmdb->data_section_size ||
+                size > (mmdb->data_section_size - offset) / 2) {
+                DEBUG_MSG("map size exceeds remaining data section");
+                return MMDB_INVALID_DATA_ERROR;
+            }
             while (size-- > 0) {
                 MMDB_entry_data_list_s *list_key = data_pool_alloc(pool);
                 if (!list_key) {
@@ -1767,38 +1800,63 @@
     return MMDB_SUCCESS;
 }
 
-static float get_ieee754_float(const uint8_t *restrict p) {
-    volatile float f;
-    volatile uint8_t *q = (volatile void *)&f;
-/* Windows builds don't use autoconf but we can assume they're all
- * little-endian. */
-#if MMDB_LITTLE_ENDIAN || _WIN32
-    q[3] = p[0];
-    q[2] = p[1];
-    q[1] = p[2];
-    q[0] = p[3];
+#ifndef __has_builtin
+    #define __has_builtin(x) 0
+#endif
+
+static inline uint32_t mmdb_bswap32(uint32_t x) {
+#if defined(_MSC_VER)
+    return _byteswap_ulong(x);
+#elif __has_builtin(__builtin_bswap32)
+    return __builtin_bswap32(x);
+#else
+    x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF);
+    return (x << 16) | (x >> 16);
+#endif
+}
+
+static inline uint64_t mmdb_bswap64(uint64_t x) {
+#if defined(_MSC_VER)
+    return _byteswap_uint64(x);
+#elif __has_builtin(__builtin_bswap64)
+    return __builtin_bswap64(x);
 #else
-    memcpy(q, p, 4);
+    x = ((x & 0x00000000FFFFFFFFULL) << 32) |
+        ((x & 0xFFFFFFFF00000000ULL) >> 32);
+    x = ((x & 0x0000FFFF0000FFFFULL) << 16) |
+        ((x & 0xFFFF0000FFFF0000ULL) >> 16);
+    return ((x & 0x00FF00FF00FF00FFULL) << 8) |
+           ((x & 0xFF00FF00FF00FF00ULL) >> 8);
+#endif
+}
+
+static float get_ieee754_float(const uint8_t *restrict p) {
+    float f;
+    uint32_t i;
+
+    memcpy(&i, p, sizeof(uint32_t));
+
+#if MMDB_LITTLE_ENDIAN
+    i = mmdb_bswap32(i);
 #endif
+
+    memcpy(&f, &i, sizeof(float));
+
     return f;
 }
 
 static double get_ieee754_double(const uint8_t *restrict p) {
-    volatile double d;
-    volatile uint8_t *q = (volatile void *)&d;
-#if MMDB_LITTLE_ENDIAN || _WIN32
-    q[7] = p[0];
-    q[6] = p[1];
-    q[5] = p[2];
-    q[4] = p[3];
-    q[3] = p[4];
-    q[2] = p[5];
-    q[1] = p[6];
-    q[0] = p[7];
-#else
-    memcpy(q, p, 8);
+    double d;
+    uint64_t i;
+
+    memcpy(&i, p, sizeof(uint64_t));
+
+#if MMDB_LITTLE_ENDIAN
+    i = mmdb_bswap64(i);
 #endif
 
+    memcpy(&d, &i, sizeof(double));
+
     return d;
 }
 
@@ -1841,14 +1899,14 @@
 
     if (NULL != mmdb->filename) {
 #if defined(__clang__)
-// This is a const char * that we need to free, which isn't valid. However it
-// would mean changing the public API to fix this.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wcast-qual"
+    // This is a const char * that we need to free, which isn't valid. However
+    // it would mean changing the public API to fix this.
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wcast-qual"
 #endif
         FREE_AND_SET_NULL(mmdb->filename);
 #if defined(__clang__)
-#pragma clang diagnostic pop
+    #pragma clang diagnostic pop
 #endif
     }
     if (NULL != mmdb->file_content) {
@@ -1858,29 +1916,35 @@
          * to cleanup then. */
         WSACleanup();
 #else
-#if defined(__clang__)
-// This is a const char * that we need to free, which isn't valid. However it
-// would mean changing the public API to fix this.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wcast-qual"
-#endif
+    #if defined(__clang__)
+        // This is a const char * that we need to free, which isn't valid.
+        // However it would mean changing the public API to fix this.
+        #pragma clang diagnostic push
+        #pragma clang diagnostic ignored "-Wcast-qual"
+    #endif
         munmap((void *)mmdb->file_content, (size_t)mmdb->file_size);
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-#endif
+    #if defined(__clang__)
+        #pragma clang diagnostic pop
+    #endif
+#endif
+        mmdb->file_content = NULL;
+        mmdb->file_size = 0;
+        mmdb->data_section = NULL;
+        mmdb->data_section_size = 0;
+        mmdb->metadata_section = NULL;
+        mmdb->metadata_section_size = 0;
     }
 
     if (NULL != mmdb->metadata.database_type) {
 #if defined(__clang__)
-// This is a const char * that we need to free, which isn't valid. However it
-// would mean changing the public API to fix this.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wcast-qual"
+    // This is a const char * that we need to free, which isn't valid. However
+    // it would mean changing the public API to fix this.
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wcast-qual"
 #endif
         FREE_AND_SET_NULL(mmdb->metadata.database_type);
 #if defined(__clang__)
-#pragma clang diagnostic pop
+    #pragma clang diagnostic pop
 #endif
     }
 
@@ -1895,17 +1959,18 @@
 
     for (size_t i = 0; i < mmdb->metadata.languages.count; i++) {
 #if defined(__clang__)
-// This is a const char * that we need to free, which isn't valid. However it
-// would mean changing the public API to fix this.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wcast-qual"
+    // This is a const char * that we need to free, which isn't valid. However
+    // it would mean changing the public API to fix this.
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wcast-qual"
 #endif
         FREE_AND_SET_NULL(mmdb->metadata.languages.names[i]);
 #if defined(__clang__)
-#pragma clang diagnostic pop
+    #pragma clang diagnostic pop
 #endif
     }
     FREE_AND_SET_NULL(mmdb->metadata.languages.names);
+    mmdb->metadata.languages.count = 0;
 }
 
 static void free_descriptions_metadata(MMDB_s *mmdb) {
@@ -1917,30 +1982,30 @@
         if (NULL != mmdb->metadata.description.descriptions[i]) {
             if (NULL != mmdb->metadata.description.descriptions[i]->language) {
 #if defined(__clang__)
-// This is a const char * that we need to free, which isn't valid. However it
-// would mean changing the public API to fix this.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wcast-qual"
+    // This is a const char * that we need to free, which isn't valid. However
+    // it would mean changing the public API to fix this.
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wcast-qual"
 #endif
                 FREE_AND_SET_NULL(
                     mmdb->metadata.description.descriptions[i]->language);
 #if defined(__clang__)
-#pragma clang diagnostic pop
+    #pragma clang diagnostic pop
 #endif
             }
 
             if (NULL !=
                 mmdb->metadata.description.descriptions[i]->description) {
 #if defined(__clang__)
-// This is a const char * that we need to free, which isn't valid. However it
-// would mean changing the public API to fix this.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wcast-qual"
+    // This is a const char * that we need to free, which isn't valid. However
+    // it would mean changing the public API to fix this.
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wcast-qual"
 #endif
                 FREE_AND_SET_NULL(
                     mmdb->metadata.description.descriptions[i]->description);
 #if defined(__clang__)
-#pragma clang diagnostic pop
+    #pragma clang diagnostic pop
 #endif
             }
             FREE_AND_SET_NULL(mmdb->metadata.description.descriptions[i]);
@@ -1948,6 +2013,7 @@
     }
 
     FREE_AND_SET_NULL(mmdb->metadata.description.descriptions);
+    mmdb->metadata.description.count = 0;
 }
 
 const char *MMDB_lib_version(void) { return PACKAGE_VERSION; }
@@ -2133,7 +2199,7 @@
 
 static void print_indentation(FILE *stream, int i) {
     char buffer[1024];
-    int size = i >= 1024 ? 1023 : i;
+    int size = i < 0 ? 0 : (i >= 1024 ? 1023 : i);
     memset(buffer, 32, (size_t)size);
     buffer[size] = '\0';
     fputs(buffer, stream);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/maxminddb-3.0.0/maxminddb.egg-info/PKG-INFO 
new/maxminddb-3.1.1/maxminddb.egg-info/PKG-INFO
--- old/maxminddb-3.0.0/maxminddb.egg-info/PKG-INFO     2025-10-15 
21:46:06.000000000 +0200
+++ new/maxminddb-3.1.1/maxminddb.egg-info/PKG-INFO     2026-03-05 
19:03:17.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: maxminddb
-Version: 3.0.0
+Version: 3.1.1
 Summary: Reader for the MaxMind DB format
 Author-email: Gregory Oschwald <[email protected]>
 License-Expression: Apache-2.0
@@ -132,12 +132,6 @@
 protection. Calling ``close()`` while reads are in progress may cause
 exceptions in those threads.
 
-Requirements
-------------
-
-This code requires Python 3.10+. Older versions are not supported. The C
-extension requires CPython.
-
 Versioning
 ----------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/maxminddb-3.0.0/pyproject.toml 
new/maxminddb-3.1.1/pyproject.toml
--- old/maxminddb-3.0.0/pyproject.toml  2025-10-15 21:46:00.000000000 +0200
+++ new/maxminddb-3.1.1/pyproject.toml  2026-03-05 19:03:12.000000000 +0100
@@ -1,6 +1,6 @@
 [project]
 name = "maxminddb"
-version = "3.0.0"
+version = "3.1.1"
 description = "Reader for the MaxMind DB format"
 authors = [
     {name = "Gregory Oschwald", email = "[email protected]"},
@@ -33,6 +33,7 @@
 [dependency-groups]
 dev = [
     "pytest>=8.3.5",
+    "tox-uv>=1.29.0",
 ]
 lint = [
     "mypy>=1.15.0",
@@ -109,6 +110,8 @@
 skip_missing_interpreters = false
 
 [tool.tox.env_run_base]
+runner = "uv-venv-lock-runner"
+uv_python_preference = "managed"
 dependency_groups = [
   "dev",
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/maxminddb-3.0.0/uv.lock new/maxminddb-3.1.1/uv.lock
--- old/maxminddb-3.0.0/uv.lock 2025-10-15 21:46:00.000000000 +0200
+++ new/maxminddb-3.1.1/uv.lock 2026-03-05 19:03:12.000000000 +0100
@@ -3,6 +3,15 @@
 requires-python = ">=3.10"
 
 [[package]]
+name = "cachetools"
+version = "7.0.1"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/d4/07/56595285564e90777d758ebd383d6b0b971b87729bbe2184a849932a3736/cachetools-7.0.1.tar.gz";,
 hash = 
"sha256:e31e579d2c5b6e2944177a0397150d312888ddf4e16e12f1016068f0c03b8341", size 
= 36126, upload-time = "2026-02-10T22:24:05.03Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/ed/9e/5faefbf9db1db466d633735faceda1f94aa99ce506ac450d232536266b32/cachetools-7.0.1-py3-none-any.whl";,
 hash = 
"sha256:8f086515c254d5664ae2146d14fc7f65c9a4bce75152eb247e5a9c5e6d7b2ecf", size 
= 13484, upload-time = "2026-02-10T22:24:03.741Z" },
+]
+
+[[package]]
 name = "colorama"
 version = "0.4.6"
 source = { registry = "https://pypi.org/simple"; }
@@ -12,6 +21,15 @@
 ]
 
 [[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 = "exceptiongroup"
 version = "1.3.0"
 source = { registry = "https://pypi.org/simple"; }
@@ -24,6 +42,15 @@
 ]
 
 [[package]]
+name = "filelock"
+version = "3.24.3"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/73/92/a8e2479937ff39185d20dd6a851c1a63e55849e447a55e798cc2e1f49c65/filelock-3.24.3.tar.gz";,
 hash = 
"sha256:011a5644dc937c22699943ebbfc46e969cdde3e171470a6e40b9533e5a72affa", size 
= 37935, upload-time = "2026-02-19T00:48:20.543Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/9c/0f/5d0c71a1aefeb08efff26272149e07ab922b64f46c63363756224bd6872e/filelock-3.24.3-py3-none-any.whl";,
 hash = 
"sha256:426e9a4660391f7f8a810d71b0555bce9008b0a1cc342ab1f6947d37639e002d", size 
= 24331, upload-time = "2026-02-19T00:48:18.465Z" },
+]
+
+[[package]]
 name = "iniconfig"
 version = "2.1.0"
 source = { registry = "https://pypi.org/simple"; }
@@ -33,13 +60,87 @@
 ]
 
 [[package]]
+name = "librt"
+version = "0.6.3"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/37/c3/cdff3c10e2e608490dc0a310ccf11ba777b3943ad4fcead2a2ade98c21e1/librt-0.6.3.tar.gz";,
 hash = 
"sha256:c724a884e642aa2bbad52bb0203ea40406ad742368a5f90da1b220e970384aae", size 
= 54209, upload-time = "2025-11-29T14:01:56.058Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/a6/84/859df8db21dedab2538ddfbe1d486dda3eb66a98c6ad7ba754a99e25e45e/librt-0.6.3-cp310-cp310-macosx_10_9_x86_64.whl";,
 hash = 
"sha256:45660d26569cc22ed30adf583389d8a0d1b468f8b5e518fcf9bfe2cd298f9dd1", size 
= 27294, upload-time = "2025-11-29T14:00:35.053Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f7/01/ec3971cf9c4f827f17de6729bdfdbf01a67493147334f4ef8fac68936e3a/librt-0.6.3-cp310-cp310-macosx_11_0_arm64.whl";,
 hash = 
"sha256:54f3b2177fb892d47f8016f1087d21654b44f7fc4cf6571c1c6b3ea531ab0fcf", size 
= 27635, upload-time = "2025-11-29T14:00:36.496Z" },
+    { url = 
"https://files.pythonhosted.org/packages/b4/f9/3efe201df84dd26388d2e0afa4c4dc668c8e406a3da7b7319152faf835a1/librt-0.6.3-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl";,
 hash = 
"sha256:c5b31bed2c2f2fa1fcb4815b75f931121ae210dc89a3d607fb1725f5907f1437", size 
= 81768, upload-time = "2025-11-29T14:00:37.451Z" },
+    { url = 
"https://files.pythonhosted.org/packages/0a/13/f63e60bc219b17f3d8f3d13423cd4972e597b0321c51cac7bfbdd5e1f7b9/librt-0.6.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:8f8ed5053ef9fb08d34f1fd80ff093ccbd1f67f147633a84cf4a7d9b09c0f089", size 
= 85884, upload-time = "2025-11-29T14:00:38.433Z" },
+    { url = 
"https://files.pythonhosted.org/packages/c2/42/0068f14f39a79d1ce8a19d4988dd07371df1d0a7d3395fbdc8a25b1c9437/librt-0.6.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:3f0e4bd9bcb0ee34fa3dbedb05570da50b285f49e52c07a241da967840432513", size 
= 85830, upload-time = "2025-11-29T14:00:39.418Z" },
+    { url = 
"https://files.pythonhosted.org/packages/14/1c/87f5af3a9e6564f09e50c72f82fc3057fd42d1facc8b510a707d0438c4ad/librt-0.6.3-cp310-cp310-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:d8f89c8d20dfa648a3f0a56861946eb00e5b00d6b00eea14bc5532b2fcfa8ef1", size 
= 88086, upload-time = "2025-11-29T14:00:40.555Z" },
+    { url = 
"https://files.pythonhosted.org/packages/05/e5/22153b98b88a913b5b3f266f12e57df50a2a6960b3f8fcb825b1a0cfe40a/librt-0.6.3-cp310-cp310-musllinux_1_2_i686.whl";,
 hash = 
"sha256:ecc2c526547eacd20cb9fbba19a5268611dbc70c346499656d6cf30fae328977", size 
= 86470, upload-time = "2025-11-29T14:00:41.827Z" },
+    { url = 
"https://files.pythonhosted.org/packages/18/3c/ea1edb587799b1edcc22444e0630fa422e32d7aaa5bfb5115b948acc2d1c/librt-0.6.3-cp310-cp310-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:fbedeb9b48614d662822ee514567d2d49a8012037fc7b4cd63f282642c2f4b7d", size 
= 89079, upload-time = "2025-11-29T14:00:42.882Z" },
+    { url = 
"https://files.pythonhosted.org/packages/73/ad/50bb4ae6b07c9f3ab19653e0830a210533b30eb9a18d515efb5a2b9d0c7c/librt-0.6.3-cp310-cp310-win32.whl";,
 hash = 
"sha256:0765b0fe0927d189ee14b087cd595ae636bef04992e03fe6dfdaa383866c8a46", size 
= 19820, upload-time = "2025-11-29T14:00:44.211Z" },
+    { url = 
"https://files.pythonhosted.org/packages/7a/12/7426ee78f3b1dbe11a90619d54cb241ca924ca3c0ff9ade3992178e9b440/librt-0.6.3-cp310-cp310-win_amd64.whl";,
 hash = 
"sha256:8c659f9fb8a2f16dc4131b803fa0144c1dadcb3ab24bb7914d01a6da58ae2457", size 
= 21332, upload-time = "2025-11-29T14:00:45.427Z" },
+    { url = 
"https://files.pythonhosted.org/packages/8b/80/bc60fd16fe24910bf5974fb914778a2e8540cef55385ab2cb04a0dfe42c4/librt-0.6.3-cp311-cp311-macosx_10_9_x86_64.whl";,
 hash = 
"sha256:61348cc488b18d1b1ff9f3e5fcd5ac43ed22d3e13e862489d2267c2337285c08", size 
= 27285, upload-time = "2025-11-29T14:00:46.626Z" },
+    { url = 
"https://files.pythonhosted.org/packages/88/3c/26335536ed9ba097c79cffcee148393592e55758fe76d99015af3e47a6d0/librt-0.6.3-cp311-cp311-macosx_11_0_arm64.whl";,
 hash = 
"sha256:64645b757d617ad5f98c08e07620bc488d4bced9ced91c6279cec418f16056fa", size 
= 27629, upload-time = "2025-11-29T14:00:47.863Z" },
+    { url = 
"https://files.pythonhosted.org/packages/af/fd/2dcedeacfedee5d2eda23e7a49c1c12ce6221b5d58a13555f053203faafc/librt-0.6.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl";,
 hash = 
"sha256:26b8026393920320bb9a811b691d73c5981385d537ffc5b6e22e53f7b65d4122", size 
= 82039, upload-time = "2025-11-29T14:00:49.131Z" },
+    { url = 
"https://files.pythonhosted.org/packages/48/ff/6aa11914b83b0dc2d489f7636942a8e3322650d0dba840db9a1b455f3caa/librt-0.6.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:d998b432ed9ffccc49b820e913c8f327a82026349e9c34fa3690116f6b70770f", size 
= 86560, upload-time = "2025-11-29T14:00:50.403Z" },
+    { url = 
"https://files.pythonhosted.org/packages/76/a1/d25af61958c2c7eb978164aeba0350719f615179ba3f428b682b9a5fdace/librt-0.6.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:e18875e17ef69ba7dfa9623f2f95f3eda6f70b536079ee6d5763ecdfe6cc9040", size 
= 86494, upload-time = "2025-11-29T14:00:51.383Z" },
+    { url = 
"https://files.pythonhosted.org/packages/7d/4b/40e75d3b258c801908e64b39788f9491635f9554f8717430a491385bd6f2/librt-0.6.3-cp311-cp311-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:a218f85081fc3f70cddaed694323a1ad7db5ca028c379c214e3a7c11c0850523", size 
= 88914, upload-time = "2025-11-29T14:00:52.688Z" },
+    { url = 
"https://files.pythonhosted.org/packages/97/6d/0070c81aba8a169224301c75fb5fb6c3c25ca67e6ced086584fc130d5a67/librt-0.6.3-cp311-cp311-musllinux_1_2_i686.whl";,
 hash = 
"sha256:1ef42ff4edd369e84433ce9b188a64df0837f4f69e3d34d3b34d4955c599d03f", size 
= 86944, upload-time = "2025-11-29T14:00:53.768Z" },
+    { url = 
"https://files.pythonhosted.org/packages/a6/94/809f38887941b7726692e0b5a083dbdc87dbb8cf893e3b286550c5f0b129/librt-0.6.3-cp311-cp311-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:0e0f2b79993fec23a685b3e8107ba5f8675eeae286675a216da0b09574fa1e47", size 
= 89852, upload-time = "2025-11-29T14:00:54.71Z" },
+    { url = 
"https://files.pythonhosted.org/packages/58/a3/b0e5b1cda675b91f1111d8ba941da455d8bfaa22f4d2d8963ba96ccb5b12/librt-0.6.3-cp311-cp311-win32.whl";,
 hash = 
"sha256:fd98cacf4e0fabcd4005c452cb8a31750258a85cab9a59fb3559e8078da408d7", size 
= 19948, upload-time = "2025-11-29T14:00:55.989Z" },
+    { url = 
"https://files.pythonhosted.org/packages/cc/73/70011c2b37e3be3ece3affd3abc8ebe5cda482b03fd6b3397906321a901e/librt-0.6.3-cp311-cp311-win_amd64.whl";,
 hash = 
"sha256:e17b5b42c8045867ca9d1f54af00cc2275198d38de18545edaa7833d7e9e4ac8", size 
= 21406, upload-time = "2025-11-29T14:00:56.874Z" },
+    { url = 
"https://files.pythonhosted.org/packages/91/ee/119aa759290af6ca0729edf513ca390c1afbeae60f3ecae9b9d56f25a8a9/librt-0.6.3-cp311-cp311-win_arm64.whl";,
 hash = 
"sha256:87597e3d57ec0120a3e1d857a708f80c02c42ea6b00227c728efbc860f067c45", size 
= 20875, upload-time = "2025-11-29T14:00:57.752Z" },
+    { url = 
"https://files.pythonhosted.org/packages/b4/2c/b59249c566f98fe90e178baf59e83f628d6c38fb8bc78319301fccda0b5e/librt-0.6.3-cp312-cp312-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:74418f718083009108dc9a42c21bf2e4802d49638a1249e13677585fcc9ca176", size 
= 27841, upload-time = "2025-11-29T14:00:58.925Z" },
+    { url = 
"https://files.pythonhosted.org/packages/40/e8/9db01cafcd1a2872b76114c858f81cc29ce7ad606bc102020d6dabf470fb/librt-0.6.3-cp312-cp312-macosx_11_0_arm64.whl";,
 hash = 
"sha256:514f3f363d1ebc423357d36222c37e5c8e6674b6eae8d7195ac9a64903722057", size 
= 27844, upload-time = "2025-11-29T14:01:00.2Z" },
+    { url = 
"https://files.pythonhosted.org/packages/59/4d/da449d3a7d83cc853af539dee42adc37b755d7eea4ad3880bacfd84b651d/librt-0.6.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl";,
 hash = 
"sha256:cf1115207a5049d1f4b7b4b72de0e52f228d6c696803d94843907111cbf80610", size 
= 84091, upload-time = "2025-11-29T14:01:01.118Z" },
+    { url = 
"https://files.pythonhosted.org/packages/ea/6c/f90306906fb6cc6eaf4725870f0347115de05431e1f96d35114392d31fda/librt-0.6.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:ad8ba80cdcea04bea7b78fcd4925bfbf408961e9d8397d2ee5d3ec121e20c08c", size 
= 88239, upload-time = "2025-11-29T14:01:02.11Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e7/ae/473ce7b423cfac2cb503851a89d9d2195bf615f534d5912bf86feeebbee7/librt-0.6.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:4018904c83eab49c814e2494b4e22501a93cdb6c9f9425533fe693c3117126f9", size 
= 88815, upload-time = "2025-11-29T14:01:03.114Z" },
+    { url = 
"https://files.pythonhosted.org/packages/c4/6d/934df738c87fb9617cabefe4891eece585a06abe6def25b4bca3b174429d/librt-0.6.3-cp312-cp312-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:8983c5c06ac9c990eac5eb97a9f03fe41dc7e9d7993df74d9e8682a1056f596c", size 
= 90598, upload-time = "2025-11-29T14:01:04.071Z" },
+    { url = 
"https://files.pythonhosted.org/packages/72/89/eeaa124f5e0f431c2b39119550378ae817a4b1a3c93fd7122f0639336fff/librt-0.6.3-cp312-cp312-musllinux_1_2_i686.whl";,
 hash = 
"sha256:d7769c579663a6f8dbf34878969ac71befa42067ce6bf78e6370bf0d1194997c", size 
= 88603, upload-time = "2025-11-29T14:01:05.02Z" },
+    { url = 
"https://files.pythonhosted.org/packages/4d/ed/c60b3c1cfc27d709bc0288af428ce58543fcb5053cf3eadbc773c24257f5/librt-0.6.3-cp312-cp312-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:d3c9a07eafdc70556f8c220da4a538e715668c0c63cabcc436a026e4e89950bf", size 
= 92112, upload-time = "2025-11-29T14:01:06.304Z" },
+    { url = 
"https://files.pythonhosted.org/packages/c1/ab/f56169be5f716ef4ab0277be70bcb1874b4effc262e655d85b505af4884d/librt-0.6.3-cp312-cp312-win32.whl";,
 hash = 
"sha256:38320386a48a15033da295df276aea93a92dfa94a862e06893f75ea1d8bbe89d", size 
= 20127, upload-time = "2025-11-29T14:01:07.283Z" },
+    { url = 
"https://files.pythonhosted.org/packages/ff/8d/222750ce82bf95125529eaab585ac7e2829df252f3cfc05d68792fb1dd2c/librt-0.6.3-cp312-cp312-win_amd64.whl";,
 hash = 
"sha256:c0ecf4786ad0404b072196b5df774b1bb23c8aacdcacb6c10b4128bc7b00bd01", size 
= 21545, upload-time = "2025-11-29T14:01:08.184Z" },
+    { url = 
"https://files.pythonhosted.org/packages/72/c9/f731ddcfb72f446a92a8674c6b8e1e2242773cce43a04f41549bd8b958ff/librt-0.6.3-cp312-cp312-win_arm64.whl";,
 hash = 
"sha256:9f2a6623057989ebc469cd9cc8fe436c40117a0147627568d03f84aef7854c55", size 
= 20946, upload-time = "2025-11-29T14:01:09.384Z" },
+    { url = 
"https://files.pythonhosted.org/packages/dd/aa/3055dd440f8b8b3b7e8624539a0749dd8e1913e978993bcca9ce7e306231/librt-0.6.3-cp313-cp313-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:9e716f9012148a81f02f46a04fc4c663420c6fbfeacfac0b5e128cf43b4413d3", size 
= 27874, upload-time = "2025-11-29T14:01:10.615Z" },
+    { url = 
"https://files.pythonhosted.org/packages/ef/93/226d7dd455eaa4c26712b5ccb2dfcca12831baa7f898c8ffd3a831e29fda/librt-0.6.3-cp313-cp313-macosx_11_0_arm64.whl";,
 hash = 
"sha256:669ff2495728009a96339c5ad2612569c6d8be4474e68f3f3ac85d7c3261f5f5", size 
= 27852, upload-time = "2025-11-29T14:01:11.535Z" },
+    { url = 
"https://files.pythonhosted.org/packages/4e/8b/db9d51191aef4e4cc06285250affe0bb0ad8b2ed815f7ca77951655e6f02/librt-0.6.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl";,
 hash = 
"sha256:349b6873ebccfc24c9efd244e49da9f8a5c10f60f07575e248921aae2123fc42", size 
= 84264, upload-time = "2025-11-29T14:01:12.461Z" },
+    { url = 
"https://files.pythonhosted.org/packages/8d/53/297c96bda3b5a73bdaf748f1e3ae757edd29a0a41a956b9c10379f193417/librt-0.6.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:0c74c26736008481c9f6d0adf1aedb5a52aff7361fea98276d1f965c0256ee70", size 
= 88432, upload-time = "2025-11-29T14:01:13.405Z" },
+    { url = 
"https://files.pythonhosted.org/packages/54/3a/c005516071123278e340f22de72fa53d51e259d49215295c212da16c4dc2/librt-0.6.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:408a36ddc75e91918cb15b03460bdc8a015885025d67e68c6f78f08c3a88f522", size 
= 89014, upload-time = "2025-11-29T14:01:14.373Z" },
+    { url = 
"https://files.pythonhosted.org/packages/8e/9b/ea715f818d926d17b94c80a12d81a79e95c44f52848e61e8ca1ff29bb9a9/librt-0.6.3-cp313-cp313-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:e61ab234624c9ffca0248a707feffe6fac2343758a36725d8eb8a6efef0f8c30", size 
= 90807, upload-time = "2025-11-29T14:01:15.377Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f0/fc/4e2e4c87e002fa60917a8e474fd13c4bac9a759df82be3778573bb1ab954/librt-0.6.3-cp313-cp313-musllinux_1_2_i686.whl";,
 hash = 
"sha256:324462fe7e3896d592b967196512491ec60ca6e49c446fe59f40743d08c97917", size 
= 88890, upload-time = "2025-11-29T14:01:16.633Z" },
+    { url = 
"https://files.pythonhosted.org/packages/70/7f/c7428734fbdfd4db3d5b9237fc3a857880b2ace66492836f6529fef25d92/librt-0.6.3-cp313-cp313-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:36b2ec8c15030002c7f688b4863e7be42820d7c62d9c6eece3db54a2400f0530", size 
= 92300, upload-time = "2025-11-29T14:01:17.658Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f9/0c/738c4824fdfe74dc0f95d5e90ef9e759d4ecf7fd5ba964d54a7703322251/librt-0.6.3-cp313-cp313-win32.whl";,
 hash = 
"sha256:25b1b60cb059471c0c0c803e07d0dfdc79e41a0a122f288b819219ed162672a3", size 
= 20159, upload-time = "2025-11-29T14:01:18.61Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f2/95/93d0e61bc617306ecf4c54636b5cbde4947d872563565c4abdd9d07a39d3/librt-0.6.3-cp313-cp313-win_amd64.whl";,
 hash = 
"sha256:10a95ad074e2a98c9e4abc7f5b7d40e5ecbfa84c04c6ab8a70fabf59bd429b88", size 
= 21484, upload-time = "2025-11-29T14:01:19.506Z" },
+    { url = 
"https://files.pythonhosted.org/packages/10/23/abd7ace79ab54d1dbee265f13529266f686a7ce2d21ab59a992f989009b6/librt-0.6.3-cp313-cp313-win_arm64.whl";,
 hash = 
"sha256:17000df14f552e86877d67e4ab7966912224efc9368e998c96a6974a8d609bf9", size 
= 20935, upload-time = "2025-11-29T14:01:20.415Z" },
+    { url = 
"https://files.pythonhosted.org/packages/83/14/c06cb31152182798ed98be73f54932ab984894f5a8fccf9b73130897a938/librt-0.6.3-cp314-cp314-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:8e695f25d1a425ad7a272902af8ab8c8d66c1998b177e4b5f5e7b4e215d0c88a", size 
= 27566, upload-time = "2025-11-29T14:01:21.609Z" },
+    { url = 
"https://files.pythonhosted.org/packages/0c/b1/ce83ca7b057b06150519152f53a0b302d7c33c8692ce2f01f669b5a819d9/librt-0.6.3-cp314-cp314-macosx_11_0_arm64.whl";,
 hash = 
"sha256:3e84a4121a7ae360ca4da436548a9c1ca8ca134a5ced76c893cc5944426164bd", size 
= 27753, upload-time = "2025-11-29T14:01:22.558Z" },
+    { url = 
"https://files.pythonhosted.org/packages/3b/ec/739a885ef0a2839b6c25f1b01c99149d2cb6a34e933ffc8c051fcd22012e/librt-0.6.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl";,
 hash = 
"sha256:05f385a414de3f950886ea0aad8f109650d4b712cf9cc14cc17f5f62a9ab240b", size 
= 83178, upload-time = "2025-11-29T14:01:23.555Z" },
+    { url = 
"https://files.pythonhosted.org/packages/db/bd/dc18bb1489d48c0911b9f4d72eae2d304ea264e215ba80f1e6ba4a9fc41d/librt-0.6.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:36a8e337461150b05ca2c7bdedb9e591dfc262c5230422cea398e89d0c746cdc", size 
= 87266, upload-time = "2025-11-29T14:01:24.532Z" },
+    { url = 
"https://files.pythonhosted.org/packages/94/f3/d0c5431b39eef15e48088b2d739ad84b17c2f1a22c0345c6d4c4a42b135e/librt-0.6.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:dcbe48f6a03979384f27086484dc2a14959be1613cb173458bd58f714f2c48f3", size 
= 87623, upload-time = "2025-11-29T14:01:25.798Z" },
+    { url = 
"https://files.pythonhosted.org/packages/3b/15/9a52e90834e4bd6ee16cdbaf551cb32227cbaad27398391a189c489318bc/librt-0.6.3-cp314-cp314-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:4bca9e4c260233fba37b15c4ec2f78aa99c1a79fbf902d19dd4a763c5c3fb751", size 
= 89436, upload-time = "2025-11-29T14:01:26.769Z" },
+    { url = 
"https://files.pythonhosted.org/packages/c3/8a/a7e78e46e8486e023c50f21758930ef4793999115229afd65de69e94c9cc/librt-0.6.3-cp314-cp314-musllinux_1_2_i686.whl";,
 hash = 
"sha256:760c25ed6ac968e24803eb5f7deb17ce026902d39865e83036bacbf5cf242aa8", size 
= 87540, upload-time = "2025-11-29T14:01:27.756Z" },
+    { url = 
"https://files.pythonhosted.org/packages/49/01/93799044a1cccac31f1074b07c583e181829d240539657e7f305ae63ae2a/librt-0.6.3-cp314-cp314-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:4aa4a93a353ccff20df6e34fa855ae8fd788832c88f40a9070e3ddd3356a9f0e", size 
= 90597, upload-time = "2025-11-29T14:01:29.35Z" },
+    { url = 
"https://files.pythonhosted.org/packages/a7/29/00c7f58b8f8eb1bad6529ffb6c9cdcc0890a27dac59ecda04f817ead5277/librt-0.6.3-cp314-cp314-win32.whl";,
 hash = 
"sha256:cb92741c2b4ea63c09609b064b26f7f5d9032b61ae222558c55832ec3ad0bcaf", size 
= 18955, upload-time = "2025-11-29T14:01:30.325Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d7/13/2739e6e197a9f751375a37908a6a5b0bff637b81338497a1bcb5817394da/librt-0.6.3-cp314-cp314-win_amd64.whl";,
 hash = 
"sha256:fdcd095b1b812d756fa5452aca93b962cf620694c0cadb192cec2bb77dcca9a2", size 
= 20263, upload-time = "2025-11-29T14:01:31.287Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e1/73/393868fc2158705ea003114a24e73bb10b03bda31e9ad7b5c5ec6575338b/librt-0.6.3-cp314-cp314-win_arm64.whl";,
 hash = 
"sha256:822ca79e28720a76a935c228d37da6579edef048a17cd98d406a2484d10eda78", size 
= 19575, upload-time = "2025-11-29T14:01:32.229Z" },
+    { url = 
"https://files.pythonhosted.org/packages/48/6d/3c8ff3dec21bf804a205286dd63fd28dcdbe00b8dd7eb7ccf2e21a40a0b0/librt-0.6.3-cp314-cp314t-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:078cd77064d1640cb7b0650871a772956066174d92c8aeda188a489b58495179", size 
= 28732, upload-time = "2025-11-29T14:01:33.165Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f4/90/e214b8b4aa34ed3d3f1040719c06c4d22472c40c5ef81a922d5af7876eb4/librt-0.6.3-cp314-cp314t-macosx_11_0_arm64.whl";,
 hash = 
"sha256:5cc22f7f5c0cc50ed69f4b15b9c51d602aabc4500b433aaa2ddd29e578f452f7", size 
= 29065, upload-time = "2025-11-29T14:01:34.088Z" },
+    { url = 
"https://files.pythonhosted.org/packages/ab/90/ef61ed51f0a7770cc703422d907a757bbd8811ce820c333d3db2fd13542a/librt-0.6.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl";,
 hash = 
"sha256:14b345eb7afb61b9fdcdfda6738946bd11b8e0f6be258666b0646af3b9bb5916", size 
= 93703, upload-time = "2025-11-29T14:01:35.057Z" },
+    { url = 
"https://files.pythonhosted.org/packages/a8/ae/c30bb119c35962cbe9a908a71da99c168056fc3f6e9bbcbc157d0b724d89/librt-0.6.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:6d46aa46aa29b067f0b8b84f448fd9719aaf5f4c621cc279164d76a9dc9ab3e8", size 
= 98890, upload-time = "2025-11-29T14:01:36.031Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d1/96/47a4a78d252d36f072b79d592df10600d379a895c3880c8cbd2ac699f0ad/librt-0.6.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:1b51ba7d9d5d9001494769eca8c0988adce25d0a970c3ba3f2eb9df9d08036fc", size 
= 98255, upload-time = "2025-11-29T14:01:37.058Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e5/28/779b5cc3cd9987683884eb5f5672e3251676bebaaae6b7da1cf366eb1da1/librt-0.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:ced0925a18fddcff289ef54386b2fc230c5af3c83b11558571124bfc485b8c07", size 
= 100769, upload-time = "2025-11-29T14:01:38.413Z" },
+    { url = 
"https://files.pythonhosted.org/packages/28/d7/771755e57c375cb9d25a4e106f570607fd856e2cb91b02418db1db954796/librt-0.6.3-cp314-cp314t-musllinux_1_2_i686.whl";,
 hash = 
"sha256:6bac97e51f66da2ca012adddbe9fd656b17f7368d439de30898f24b39512f40f", size 
= 98580, upload-time = "2025-11-29T14:01:39.459Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d0/ec/8b157eb8fbc066339a2f34b0aceb2028097d0ed6150a52e23284a311eafe/librt-0.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:b2922a0e8fa97395553c304edc3bd36168d8eeec26b92478e292e5d4445c1ef0", size 
= 101706, upload-time = "2025-11-29T14:01:40.474Z" },
+    { url = 
"https://files.pythonhosted.org/packages/82/a8/4aaead9a06c795a318282aebf7d3e3e578fa889ff396e1b640c3be4c7806/librt-0.6.3-cp314-cp314t-win32.whl";,
 hash = 
"sha256:f33462b19503ba68d80dac8a1354402675849259fb3ebf53b67de86421735a3a", size 
= 19465, upload-time = "2025-11-29T14:01:41.77Z" },
+    { url = 
"https://files.pythonhosted.org/packages/3a/61/b7e6a02746c1731670c19ba07d86da90b1ae45d29e405c0b5615abf97cde/librt-0.6.3-cp314-cp314t-win_amd64.whl";,
 hash = 
"sha256:04f8ce401d4f6380cfc42af0f4e67342bf34c820dae01343f58f472dbac75dcf", size 
= 21042, upload-time = "2025-11-29T14:01:42.865Z" },
+    { url = 
"https://files.pythonhosted.org/packages/0e/3d/72cc9ec90bb80b5b1a65f0bb74a0f540195837baaf3b98c7fa4a7aa9718e/librt-0.6.3-cp314-cp314t-win_arm64.whl";,
 hash = 
"sha256:afb39550205cc5e5c935762c6bf6a2bb34f7d21a68eadb25e2db7bf3593fecc0", size 
= 20246, upload-time = "2025-11-29T14:01:44.13Z" },
+]
+
+[[package]]
 name = "maxminddb"
-version = "2.8.2"
+version = "3.1.1"
 source = { editable = "." }
 
 [package.dev-dependencies]
 dev = [
     { name = "pytest" },
+    { name = "tox-uv" },
 ]
 lint = [
     { name = "mypy" },
@@ -49,7 +150,10 @@
 [package.metadata]
 
 [package.metadata.requires-dev]
-dev = [{ name = "pytest", specifier = ">=8.3.5" }]
+dev = [
+    { name = "pytest", specifier = ">=8.3.5" },
+    { name = "tox-uv", specifier = ">=1.29.0" },
+]
 lint = [
     { name = "mypy", specifier = ">=1.15.0" },
     { name = "ruff", specifier = ">=0.11.6" },
@@ -57,47 +161,48 @@
 
 [[package]]
 name = "mypy"
-version = "1.18.2"
+version = "1.19.1"
 source = { registry = "https://pypi.org/simple"; }
 dependencies = [
+    { name = "librt", marker = "platform_python_implementation != 'PyPy'" },
     { name = "mypy-extensions" },
     { name = "pathspec" },
     { name = "tomli", marker = "python_full_version < '3.11'" },
     { name = "typing-extensions" },
 ]
-sdist = { url = 
"https://files.pythonhosted.org/packages/c0/77/8f0d0001ffad290cef2f7f216f96c814866248a0b92a722365ed54648e7e/mypy-1.18.2.tar.gz";,
 hash = 
"sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b", size 
= 3448846, upload-time = "2025-09-19T00:11:10.519Z" }
+sdist = { url = 
"https://files.pythonhosted.org/packages/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz";,
 hash = 
"sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size 
= 3582404, upload-time = "2025-12-15T05:03:48.42Z" }
 wheels = [
-    { url = 
"https://files.pythonhosted.org/packages/03/6f/657961a0743cff32e6c0611b63ff1c1970a0b482ace35b069203bf705187/mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl";,
 hash = 
"sha256:c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c", size 
= 12807973, upload-time = "2025-09-19T00:10:35.282Z" },
-    { url = 
"https://files.pythonhosted.org/packages/10/e9/420822d4f661f13ca8900f5fa239b40ee3be8b62b32f3357df9a3045a08b/mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl";,
 hash = 
"sha256:7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e", size 
= 11896527, upload-time = "2025-09-19T00:10:55.791Z" },
-    { url = 
"https://files.pythonhosted.org/packages/aa/73/a05b2bbaa7005f4642fcfe40fb73f2b4fb6bb44229bd585b5878e9a87ef8/mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b", size 
= 12507004, upload-time = "2025-09-19T00:11:05.411Z" },
-    { url = 
"https://files.pythonhosted.org/packages/4f/01/f6e4b9f0d031c11ccbd6f17da26564f3a0f3c4155af344006434b0a05a9d/mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66", size 
= 13245947, upload-time = "2025-09-19T00:10:46.923Z" },
-    { url = 
"https://files.pythonhosted.org/packages/d7/97/19727e7499bfa1ae0773d06afd30ac66a58ed7437d940c70548634b24185/mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428", size 
= 13499217, upload-time = "2025-09-19T00:09:39.472Z" },
-    { url = 
"https://files.pythonhosted.org/packages/9f/4f/90dc8c15c1441bf31cf0f9918bb077e452618708199e530f4cbd5cede6ff/mypy-1.18.2-cp310-cp310-win_amd64.whl";,
 hash = 
"sha256:7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed", size 
= 9766753, upload-time = "2025-09-19T00:10:49.161Z" },
-    { url = 
"https://files.pythonhosted.org/packages/88/87/cafd3ae563f88f94eec33f35ff722d043e09832ea8530ef149ec1efbaf08/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl";,
 hash = 
"sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f", size 
= 12731198, upload-time = "2025-09-19T00:09:44.857Z" },
-    { url = 
"https://files.pythonhosted.org/packages/0f/e0/1e96c3d4266a06d4b0197ace5356d67d937d8358e2ee3ffac71faa843724/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl";,
 hash = 
"sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341", size 
= 11817879, upload-time = "2025-09-19T00:09:47.131Z" },
-    { url = 
"https://files.pythonhosted.org/packages/72/ef/0c9ba89eb03453e76bdac5a78b08260a848c7bfc5d6603634774d9cd9525/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d", size 
= 12427292, upload-time = "2025-09-19T00:10:22.472Z" },
-    { url = 
"https://files.pythonhosted.org/packages/1a/52/ec4a061dd599eb8179d5411d99775bec2a20542505988f40fc2fee781068/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86", size 
= 13163750, upload-time = "2025-09-19T00:09:51.472Z" },
-    { url = 
"https://files.pythonhosted.org/packages/c4/5f/2cf2ceb3b36372d51568f2208c021870fe7834cf3186b653ac6446511839/mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37", size 
= 13351827, upload-time = "2025-09-19T00:09:58.311Z" },
-    { url = 
"https://files.pythonhosted.org/packages/c8/7d/2697b930179e7277529eaaec1513f8de622818696857f689e4a5432e5e27/mypy-1.18.2-cp311-cp311-win_amd64.whl";,
 hash = 
"sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8", size 
= 9757983, upload-time = "2025-09-19T00:10:09.071Z" },
-    { url = 
"https://files.pythonhosted.org/packages/07/06/dfdd2bc60c66611dd8335f463818514733bc763e4760dee289dcc33df709/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34", size 
= 12908273, upload-time = "2025-09-19T00:10:58.321Z" },
-    { url = 
"https://files.pythonhosted.org/packages/81/14/6a9de6d13a122d5608e1a04130724caf9170333ac5a924e10f670687d3eb/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl";,
 hash = 
"sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764", size 
= 11920910, upload-time = "2025-09-19T00:10:20.043Z" },
-    { url = 
"https://files.pythonhosted.org/packages/5f/a9/b29de53e42f18e8cc547e38daa9dfa132ffdc64f7250e353f5c8cdd44bee/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893", size 
= 12465585, upload-time = "2025-09-19T00:10:33.005Z" },
-    { url = 
"https://files.pythonhosted.org/packages/77/ae/6c3d2c7c61ff21f2bee938c917616c92ebf852f015fb55917fd6e2811db2/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914", size 
= 13348562, upload-time = "2025-09-19T00:10:11.51Z" },
-    { url = 
"https://files.pythonhosted.org/packages/4d/31/aec68ab3b4aebdf8f36d191b0685d99faa899ab990753ca0fee60fb99511/mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8", size 
= 13533296, upload-time = "2025-09-19T00:10:06.568Z" },
-    { url = 
"https://files.pythonhosted.org/packages/9f/83/abcb3ad9478fca3ebeb6a5358bb0b22c95ea42b43b7789c7fb1297ca44f4/mypy-1.18.2-cp312-cp312-win_amd64.whl";,
 hash = 
"sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074", size 
= 9828828, upload-time = "2025-09-19T00:10:28.203Z" },
-    { url = 
"https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc", size 
= 12898728, upload-time = "2025-09-19T00:10:01.33Z" },
-    { url = 
"https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl";,
 hash = 
"sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e", size 
= 11910758, upload-time = "2025-09-19T00:10:42.607Z" },
-    { url = 
"https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986", size 
= 12475342, upload-time = "2025-09-19T00:11:00.371Z" },
-    { url = 
"https://files.pythonhosted.org/packages/83/45/4798f4d00df13eae3bfdf726c9244bcb495ab5bd588c0eed93a2f2dd67f3/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d", size 
= 13338709, upload-time = "2025-09-19T00:11:03.358Z" },
-    { url = 
"https://files.pythonhosted.org/packages/d7/09/479f7358d9625172521a87a9271ddd2441e1dab16a09708f056e97007207/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba", size 
= 13529806, upload-time = "2025-09-19T00:10:26.073Z" },
-    { url = 
"https://files.pythonhosted.org/packages/71/cf/ac0f2c7e9d0ea3c75cd99dff7aec1c9df4a1376537cb90e4c882267ee7e9/mypy-1.18.2-cp313-cp313-win_amd64.whl";,
 hash = 
"sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544", size 
= 9833262, upload-time = "2025-09-19T00:10:40.035Z" },
-    { url = 
"https://files.pythonhosted.org/packages/5a/0c/7d5300883da16f0063ae53996358758b2a2df2a09c72a5061fa79a1f5006/mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce", size 
= 12893775, upload-time = "2025-09-19T00:10:03.814Z" },
-    { url = 
"https://files.pythonhosted.org/packages/50/df/2cffbf25737bdb236f60c973edf62e3e7b4ee1c25b6878629e88e2cde967/mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl";,
 hash = 
"sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d", size 
= 11936852, upload-time = "2025-09-19T00:10:51.631Z" },
-    { url = 
"https://files.pythonhosted.org/packages/be/50/34059de13dd269227fb4a03be1faee6e2a4b04a2051c82ac0a0b5a773c9a/mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c", size 
= 12480242, upload-time = "2025-09-19T00:11:07.955Z" },
-    { url = 
"https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb", size 
= 13326683, upload-time = "2025-09-19T00:09:55.572Z" },
-    { url = 
"https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075", size 
= 13514749, upload-time = "2025-09-19T00:10:44.827Z" },
-    { url = 
"https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl";,
 hash = 
"sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf", size 
= 9982959, upload-time = "2025-09-19T00:10:37.344Z" },
-    { url = 
"https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl";,
 hash = 
"sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e", size 
= 2352367, upload-time = "2025-09-19T00:10:15.489Z" },
+    { url = 
"https://files.pythonhosted.org/packages/2f/63/e499890d8e39b1ff2df4c0c6ce5d371b6844ee22b8250687a99fd2f657a8/mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl";,
 hash = 
"sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec", size 
= 13101333, upload-time = "2025-12-15T05:03:03.28Z" },
+    { url = 
"https://files.pythonhosted.org/packages/72/4b/095626fc136fba96effc4fd4a82b41d688ab92124f8c4f7564bffe5cf1b0/mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl";,
 hash = 
"sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b", size 
= 12164102, upload-time = "2025-12-15T05:02:33.611Z" },
+    { url = 
"https://files.pythonhosted.org/packages/0c/5b/952928dd081bf88a83a5ccd49aaecfcd18fd0d2710c7ff07b8fb6f7032b9/mypy-1.19.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6", size 
= 12765799, upload-time = "2025-12-15T05:03:28.44Z" },
+    { url = 
"https://files.pythonhosted.org/packages/2a/0d/93c2e4a287f74ef11a66fb6d49c7a9f05e47b0a4399040e6719b57f500d2/mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74", size 
= 13522149, upload-time = "2025-12-15T05:02:36.011Z" },
+    { url = 
"https://files.pythonhosted.org/packages/7b/0e/33a294b56aaad2b338d203e3a1d8b453637ac36cb278b45005e0901cf148/mypy-1.19.1-cp310-cp310-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1", size 
= 13810105, upload-time = "2025-12-15T05:02:40.327Z" },
+    { url = 
"https://files.pythonhosted.org/packages/0e/fd/3e82603a0cb66b67c5e7abababce6bf1a929ddf67bf445e652684af5c5a0/mypy-1.19.1-cp310-cp310-win_amd64.whl";,
 hash = 
"sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac", size 
= 10057200, upload-time = "2025-12-15T05:02:51.012Z" },
+    { url = 
"https://files.pythonhosted.org/packages/ef/47/6b3ebabd5474d9cdc170d1342fbf9dddc1b0ec13ec90bf9004ee6f391c31/mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl";,
 hash = 
"sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288", size 
= 13028539, upload-time = "2025-12-15T05:03:44.129Z" },
+    { url = 
"https://files.pythonhosted.org/packages/5c/a6/ac7c7a88a3c9c54334f53a941b765e6ec6c4ebd65d3fe8cdcfbe0d0fd7db/mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl";,
 hash = 
"sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab", size 
= 12083163, upload-time = "2025-12-15T05:03:37.679Z" },
+    { url = 
"https://files.pythonhosted.org/packages/67/af/3afa9cf880aa4a2c803798ac24f1d11ef72a0c8079689fac5cfd815e2830/mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6", size 
= 12687629, upload-time = "2025-12-15T05:02:31.526Z" },
+    { url = 
"https://files.pythonhosted.org/packages/2d/46/20f8a7114a56484ab268b0ab372461cb3a8f7deed31ea96b83a4e4cfcfca/mypy-1.19.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331", size 
= 13436933, upload-time = "2025-12-15T05:03:15.606Z" },
+    { url = 
"https://files.pythonhosted.org/packages/5b/f8/33b291ea85050a21f15da910002460f1f445f8007adb29230f0adea279cb/mypy-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925", size 
= 13661754, upload-time = "2025-12-15T05:02:26.731Z" },
+    { url = 
"https://files.pythonhosted.org/packages/fd/a3/47cbd4e85bec4335a9cd80cf67dbc02be21b5d4c9c23ad6b95d6c5196bac/mypy-1.19.1-cp311-cp311-win_amd64.whl";,
 hash = 
"sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042", size 
= 10055772, upload-time = "2025-12-15T05:03:26.179Z" },
+    { url = 
"https://files.pythonhosted.org/packages/06/8a/19bfae96f6615aa8a0604915512e0289b1fad33d5909bf7244f02935d33a/mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1", size 
= 13206053, upload-time = "2025-12-15T05:03:46.622Z" },
+    { url = 
"https://files.pythonhosted.org/packages/a5/34/3e63879ab041602154ba2a9f99817bb0c85c4df19a23a1443c8986e4d565/mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl";,
 hash = 
"sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e", size 
= 12219134, upload-time = "2025-12-15T05:03:24.367Z" },
+    { url = 
"https://files.pythonhosted.org/packages/89/cc/2db6f0e95366b630364e09845672dbee0cbf0bbe753a204b29a944967cd9/mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2", size 
= 12731616, upload-time = "2025-12-15T05:02:44.725Z" },
+    { url = 
"https://files.pythonhosted.org/packages/00/be/dd56c1fd4807bc1eba1cf18b2a850d0de7bacb55e158755eb79f77c41f8e/mypy-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8", size 
= 13620847, upload-time = "2025-12-15T05:03:39.633Z" },
+    { url = 
"https://files.pythonhosted.org/packages/6d/42/332951aae42b79329f743bf1da088cd75d8d4d9acc18fbcbd84f26c1af4e/mypy-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a", size 
= 13834976, upload-time = "2025-12-15T05:03:08.786Z" },
+    { url = 
"https://files.pythonhosted.org/packages/6f/63/e7493e5f90e1e085c562bb06e2eb32cae27c5057b9653348d38b47daaecc/mypy-1.19.1-cp312-cp312-win_amd64.whl";,
 hash = 
"sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13", size 
= 10118104, upload-time = "2025-12-15T05:03:10.834Z" },
+    { url = 
"https://files.pythonhosted.org/packages/de/9f/a6abae693f7a0c697dbb435aac52e958dc8da44e92e08ba88d2e42326176/mypy-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250", size 
= 13201927, upload-time = "2025-12-15T05:02:29.138Z" },
+    { url = 
"https://files.pythonhosted.org/packages/9a/a4/45c35ccf6e1c65afc23a069f50e2c66f46bd3798cbe0d680c12d12935caa/mypy-1.19.1-cp313-cp313-macosx_11_0_arm64.whl";,
 hash = 
"sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b", size 
= 12206730, upload-time = "2025-12-15T05:03:01.325Z" },
+    { url = 
"https://files.pythonhosted.org/packages/05/bb/cdcf89678e26b187650512620eec8368fded4cfd99cfcb431e4cdfd19dec/mypy-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e", size 
= 12724581, upload-time = "2025-12-15T05:03:20.087Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d1/32/dd260d52babf67bad8e6770f8e1102021877ce0edea106e72df5626bb0ec/mypy-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef", size 
= 13616252, upload-time = "2025-12-15T05:02:49.036Z" },
+    { url = 
"https://files.pythonhosted.org/packages/71/d0/5e60a9d2e3bd48432ae2b454b7ef2b62a960ab51292b1eda2a95edd78198/mypy-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75", size 
= 13840848, upload-time = "2025-12-15T05:02:55.95Z" },
+    { url = 
"https://files.pythonhosted.org/packages/98/76/d32051fa65ecf6cc8c6610956473abdc9b4c43301107476ac03559507843/mypy-1.19.1-cp313-cp313-win_amd64.whl";,
 hash = 
"sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd", size 
= 10135510, upload-time = "2025-12-15T05:02:58.438Z" },
+    { url = 
"https://files.pythonhosted.org/packages/de/eb/b83e75f4c820c4247a58580ef86fcd35165028f191e7e1ba57128c52782d/mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl";,
 hash = 
"sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1", size 
= 13199744, upload-time = "2025-12-15T05:03:30.823Z" },
+    { url = 
"https://files.pythonhosted.org/packages/94/28/52785ab7bfa165f87fcbb61547a93f98bb20e7f82f90f165a1f69bce7b3d/mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl";,
 hash = 
"sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718", size 
= 12215815, upload-time = "2025-12-15T05:02:42.323Z" },
+    { url = 
"https://files.pythonhosted.org/packages/0a/c6/bdd60774a0dbfb05122e3e925f2e9e846c009e479dcec4821dad881f5b52/mypy-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b", size 
= 12740047, upload-time = "2025-12-15T05:03:33.168Z" },
+    { url = 
"https://files.pythonhosted.org/packages/32/2a/66ba933fe6c76bd40d1fe916a83f04fed253152f451a877520b3c4a5e41e/mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045", size 
= 13601998, upload-time = "2025-12-15T05:03:13.056Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e3/da/5055c63e377c5c2418760411fd6a63ee2b96cf95397259038756c042574f/mypy-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957", size 
= 13807476, upload-time = "2025-12-15T05:03:17.977Z" },
+    { url = 
"https://files.pythonhosted.org/packages/cd/09/4ebd873390a063176f06b0dbf1f7783dd87bd120eae7727fa4ae4179b685/mypy-1.19.1-cp314-cp314-win_amd64.whl";,
 hash = 
"sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f", size 
= 10281872, upload-time = "2025-12-15T05:03:05.549Z" },
+    { url = 
"https://files.pythonhosted.org/packages/8d/f4/4ce9a05ce5ded1de3ec1c1d96cf9f9504a04e54ce0ed55cfa38619a32b8d/mypy-1.19.1-py3-none-any.whl";,
 hash = 
"sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247", size 
= 2471239, upload-time = "2025-12-15T05:03:07.248Z" },
 ]
 
 [[package]]
@@ -111,11 +216,11 @@
 
 [[package]]
 name = "packaging"
-version = "25.0"
+version = "26.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" }
+sdist = { url = 
"https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz";,
 hash = 
"sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size 
= 143416, upload-time = "2026-01-21T20:50:39.064Z" }
 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" },
+    { url = 
"https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl";,
 hash = 
"sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size 
= 74366, upload-time = "2026-01-21T20:50:37.788Z" },
 ]
 
 [[package]]
@@ -128,6 +233,15 @@
 ]
 
 [[package]]
+name = "platformdirs"
+version = "4.9.2"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/1b/04/fea538adf7dbbd6d186f551d595961e564a3b6715bdf276b477460858672/platformdirs-4.9.2.tar.gz";,
 hash = 
"sha256:9a33809944b9db043ad67ca0db94b14bf452cc6aeaac46a88ea55b26e2e9d291", size 
= 28394, upload-time = "2026-02-16T03:56:10.574Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl";,
 hash = 
"sha256:9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd", size 
= 21168, upload-time = "2026-02-16T03:56:08.891Z" },
+]
+
+[[package]]
 name = "pluggy"
 version = "1.6.0"
 source = { registry = "https://pypi.org/simple"; }
@@ -146,8 +260,21 @@
 ]
 
 [[package]]
+name = "pyproject-api"
+version = "1.10.0"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "packaging" },
+    { name = "tomli", marker = "python_full_version < '3.11'" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/45/7b/c0e1333b61d41c69e59e5366e727b18c4992688caf0de1be10b3e5265f6b/pyproject_api-1.10.0.tar.gz";,
 hash = 
"sha256:40c6f2d82eebdc4afee61c773ed208c04c19db4c4a60d97f8d7be3ebc0bbb330", size 
= 22785, upload-time = "2025-10-09T19:12:27.21Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/54/cc/cecf97be298bee2b2a37dd360618c819a2a7fd95251d8e480c1f0eb88f3b/pyproject_api-1.10.0-py3-none-any.whl";,
 hash = 
"sha256:8757c41a79c0f4ab71b99abed52b97ecf66bd20b04fa59da43b5840bac105a09", size 
= 13218, upload-time = "2025-10-09T19:12:24.428Z" },
+]
+
+[[package]]
 name = "pytest"
-version = "8.4.2"
+version = "9.0.2"
 source = { registry = "https://pypi.org/simple"; }
 dependencies = [
     { name = "colorama", marker = "sys_platform == 'win32'" },
@@ -158,81 +285,182 @@
     { 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" }
+sdist = { url = 
"https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz";,
 hash = 
"sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size 
= 1568901, upload-time = "2025-12-06T21:30:51.014Z" }
 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" },
+    { url = 
"https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl";,
 hash = 
"sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size 
= 374801, upload-time = "2025-12-06T21:30:49.154Z" },
 ]
 
 [[package]]
 name = "ruff"
-version = "0.14.0"
+version = "0.15.2"
 source = { registry = "https://pypi.org/simple"; }
-sdist = { url = 
"https://files.pythonhosted.org/packages/41/b9/9bd84453ed6dd04688de9b3f3a4146a1698e8faae2ceeccce4e14c67ae17/ruff-0.14.0.tar.gz";,
 hash = 
"sha256:62ec8969b7510f77945df916de15da55311fade8d6050995ff7f680afe582c57", size 
= 5452071, upload-time = "2025-10-07T18:21:55.763Z" }
+sdist = { url = 
"https://files.pythonhosted.org/packages/06/04/eab13a954e763b0606f460443fcbf6bb5a0faf06890ea3754ff16523dce5/ruff-0.15.2.tar.gz";,
 hash = 
"sha256:14b965afee0969e68bb871eba625343b8673375f457af4abe98553e8bbb98342", size 
= 4558148, upload-time = "2026-02-19T22:32:20.271Z" }
 wheels = [
-    { url = 
"https://files.pythonhosted.org/packages/3a/4e/79d463a5f80654e93fa653ebfb98e0becc3f0e7cf6219c9ddedf1e197072/ruff-0.14.0-py3-none-linux_armv6l.whl";,
 hash = 
"sha256:58e15bffa7054299becf4bab8a1187062c6f8cafbe9f6e39e0d5aface455d6b3", size 
= 12494532, upload-time = "2025-10-07T18:21:00.373Z" },
-    { url = 
"https://files.pythonhosted.org/packages/ee/40/e2392f445ed8e02aa6105d49db4bfff01957379064c30f4811c3bf38aece/ruff-0.14.0-py3-none-macosx_10_12_x86_64.whl";,
 hash = 
"sha256:838d1b065f4df676b7c9957992f2304e41ead7a50a568185efd404297d5701e8", size 
= 13160768, upload-time = "2025-10-07T18:21:04.73Z" },
-    { url = 
"https://files.pythonhosted.org/packages/75/da/2a656ea7c6b9bd14c7209918268dd40e1e6cea65f4bb9880eaaa43b055cd/ruff-0.14.0-py3-none-macosx_11_0_arm64.whl";,
 hash = 
"sha256:703799d059ba50f745605b04638fa7e9682cc3da084b2092feee63500ff3d9b8", size 
= 12363376, upload-time = "2025-10-07T18:21:07.833Z" },
-    { url = 
"https://files.pythonhosted.org/packages/42/e2/1ffef5a1875add82416ff388fcb7ea8b22a53be67a638487937aea81af27/ruff-0.14.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl";,
 hash = 
"sha256:3ba9a8925e90f861502f7d974cc60e18ca29c72bb0ee8bfeabb6ade35a3abde7", size 
= 12608055, upload-time = "2025-10-07T18:21:10.72Z" },
-    { url = 
"https://files.pythonhosted.org/packages/4a/32/986725199d7cee510d9f1dfdf95bf1efc5fa9dd714d0d85c1fb1f6be3bc3/ruff-0.14.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl";,
 hash = 
"sha256:e41f785498bd200ffc276eb9e1570c019c1d907b07cfb081092c8ad51975bbe7", size 
= 12318544, upload-time = "2025-10-07T18:21:13.741Z" },
-    { url = 
"https://files.pythonhosted.org/packages/9a/ed/4969cefd53315164c94eaf4da7cfba1f267dc275b0abdd593d11c90829a3/ruff-0.14.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl";,
 hash = 
"sha256:30a58c087aef4584c193aebf2700f0fbcfc1e77b89c7385e3139956fa90434e2", size 
= 14001280, upload-time = "2025-10-07T18:21:16.411Z" },
-    { url = 
"https://files.pythonhosted.org/packages/ab/ad/96c1fc9f8854c37681c9613d825925c7f24ca1acfc62a4eb3896b50bacd2/ruff-0.14.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl";,
 hash = 
"sha256:f8d07350bc7af0a5ce8812b7d5c1a7293cf02476752f23fdfc500d24b79b783c", size 
= 15027286, upload-time = "2025-10-07T18:21:19.577Z" },
-    { url = 
"https://files.pythonhosted.org/packages/b3/00/1426978f97df4fe331074baf69615f579dc4e7c37bb4c6f57c2aad80c87f/ruff-0.14.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl";,
 hash = 
"sha256:eec3bbbf3a7d5482b5c1f42d5fc972774d71d107d447919fca620b0be3e3b75e", size 
= 14451506, upload-time = "2025-10-07T18:21:22.779Z" },
-    { url = 
"https://files.pythonhosted.org/packages/58/d5/9c1cea6e493c0cf0647674cca26b579ea9d2a213b74b5c195fbeb9678e15/ruff-0.14.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl";,
 hash = 
"sha256:16b68e183a0e28e5c176d51004aaa40559e8f90065a10a559176713fcf435206", size 
= 13437384, upload-time = "2025-10-07T18:21:25.758Z" },
-    { url = 
"https://files.pythonhosted.org/packages/29/b4/4cd6a4331e999fc05d9d77729c95503f99eae3ba1160469f2b64866964e3/ruff-0.14.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl";,
 hash = 
"sha256:eb732d17db2e945cfcbbc52af0143eda1da36ca8ae25083dd4f66f1542fdf82e", size 
= 13447976, upload-time = "2025-10-07T18:21:28.83Z" },
-    { url = 
"https://files.pythonhosted.org/packages/3b/c0/ac42f546d07e4f49f62332576cb845d45c67cf5610d1851254e341d563b6/ruff-0.14.0-py3-none-manylinux_2_31_riscv64.whl";,
 hash = 
"sha256:c958f66ab884b7873e72df38dcabee03d556a8f2ee1b8538ee1c2bbd619883dd", size 
= 13682850, upload-time = "2025-10-07T18:21:31.842Z" },
-    { url = 
"https://files.pythonhosted.org/packages/5f/c4/4b0c9bcadd45b4c29fe1af9c5d1dc0ca87b4021665dfbe1c4688d407aa20/ruff-0.14.0-py3-none-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:7eb0499a2e01f6e0c285afc5bac43ab380cbfc17cd43a2e1dd10ec97d6f2c42d", size 
= 12449825, upload-time = "2025-10-07T18:21:35.074Z" },
-    { url = 
"https://files.pythonhosted.org/packages/4b/a8/e2e76288e6c16540fa820d148d83e55f15e994d852485f221b9524514730/ruff-0.14.0-py3-none-musllinux_1_2_armv7l.whl";,
 hash = 
"sha256:4c63b2d99fafa05efca0ab198fd48fa6030d57e4423df3f18e03aa62518c565f", size 
= 12272599, upload-time = "2025-10-07T18:21:38.08Z" },
-    { url = 
"https://files.pythonhosted.org/packages/18/14/e2815d8eff847391af632b22422b8207704222ff575dec8d044f9ab779b2/ruff-0.14.0-py3-none-musllinux_1_2_i686.whl";,
 hash = 
"sha256:668fce701b7a222f3f5327f86909db2bbe99c30877c8001ff934c5413812ac02", size 
= 13193828, upload-time = "2025-10-07T18:21:41.216Z" },
-    { url = 
"https://files.pythonhosted.org/packages/44/c6/61ccc2987cf0aecc588ff8f3212dea64840770e60d78f5606cd7dc34de32/ruff-0.14.0-py3-none-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:a86bf575e05cb68dcb34e4c7dfe1064d44d3f0c04bbc0491949092192b515296", size 
= 13628617, upload-time = "2025-10-07T18:21:44.04Z" },
-    { url = 
"https://files.pythonhosted.org/packages/73/e6/03b882225a1b0627e75339b420883dc3c90707a8917d2284abef7a58d317/ruff-0.14.0-py3-none-win32.whl";,
 hash = 
"sha256:7450a243d7125d1c032cb4b93d9625dea46c8c42b4f06c6b709baac168e10543", size 
= 12367872, upload-time = "2025-10-07T18:21:46.67Z" },
-    { url = 
"https://files.pythonhosted.org/packages/41/77/56cf9cf01ea0bfcc662de72540812e5ba8e9563f33ef3d37ab2174892c47/ruff-0.14.0-py3-none-win_amd64.whl";,
 hash = 
"sha256:ea95da28cd874c4d9c922b39381cbd69cb7e7b49c21b8152b014bd4f52acddc2", size 
= 13464628, upload-time = "2025-10-07T18:21:50.318Z" },
-    { url = 
"https://files.pythonhosted.org/packages/c6/2a/65880dfd0e13f7f13a775998f34703674a4554906167dce02daf7865b954/ruff-0.14.0-py3-none-win_arm64.whl";,
 hash = 
"sha256:f42c9495f5c13ff841b1da4cb3c2a42075409592825dada7c5885c2c844ac730", size 
= 12565142, upload-time = "2025-10-07T18:21:53.577Z" },
+    { url = 
"https://files.pythonhosted.org/packages/2f/70/3a4dc6d09b13cb3e695f28307e5d889b2e1a66b7af9c5e257e796695b0e6/ruff-0.15.2-py3-none-linux_armv6l.whl";,
 hash = 
"sha256:120691a6fdae2f16d65435648160f5b81a9625288f75544dc40637436b5d3c0d", size 
= 10430565, upload-time = "2026-02-19T22:32:41.824Z" },
+    { url = 
"https://files.pythonhosted.org/packages/71/0b/bb8457b56185ece1305c666dc895832946d24055be90692381c31d57466d/ruff-0.15.2-py3-none-macosx_10_12_x86_64.whl";,
 hash = 
"sha256:a89056d831256099658b6bba4037ac6dd06f49d194199215befe2bb10457ea5e", size 
= 10820354, upload-time = "2026-02-19T22:32:07.366Z" },
+    { url = 
"https://files.pythonhosted.org/packages/2d/c1/e0532d7f9c9e0b14c46f61b14afd563298b8b83f337b6789ddd987e46121/ruff-0.15.2-py3-none-macosx_11_0_arm64.whl";,
 hash = 
"sha256:e36dee3a64be0ebd23c86ffa3aa3fd3ac9a712ff295e192243f814a830b6bd87", size 
= 10170767, upload-time = "2026-02-19T22:32:13.188Z" },
+    { url = 
"https://files.pythonhosted.org/packages/47/e8/da1aa341d3af017a21c7a62fb5ec31d4e7ad0a93ab80e3a508316efbcb23/ruff-0.15.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl";,
 hash = 
"sha256:a9fb47b6d9764677f8c0a193c0943ce9a05d6763523f132325af8a858eadc2b9", size 
= 10529591, upload-time = "2026-02-19T22:32:02.547Z" },
+    { url = 
"https://files.pythonhosted.org/packages/93/74/184fbf38e9f3510231fbc5e437e808f0b48c42d1df9434b208821efcd8d6/ruff-0.15.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl";,
 hash = 
"sha256:f376990f9d0d6442ea9014b19621d8f2aaf2b8e39fdbfc79220b7f0c596c9b80", size 
= 10260771, upload-time = "2026-02-19T22:32:36.938Z" },
+    { url = 
"https://files.pythonhosted.org/packages/05/ac/605c20b8e059a0bc4b42360414baa4892ff278cec1c91fff4be0dceedefd/ruff-0.15.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl";,
 hash = 
"sha256:2dcc987551952d73cbf5c88d9fdee815618d497e4df86cd4c4824cc59d5dd75f", size 
= 11045791, upload-time = "2026-02-19T22:32:31.642Z" },
+    { url = 
"https://files.pythonhosted.org/packages/fd/52/db6e419908f45a894924d410ac77d64bdd98ff86901d833364251bd08e22/ruff-0.15.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl";,
 hash = 
"sha256:42a47fd785cbe8c01b9ff45031af875d101b040ad8f4de7bbb716487c74c9a77", size 
= 11879271, upload-time = "2026-02-19T22:32:29.305Z" },
+    { url = 
"https://files.pythonhosted.org/packages/3e/d8/7992b18f2008bdc9231d0f10b16df7dda964dbf639e2b8b4c1b4e91b83af/ruff-0.15.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl";,
 hash = 
"sha256:cbe9f49354866e575b4c6943856989f966421870e85cd2ac94dccb0a9dcb2fea", size 
= 11303707, upload-time = "2026-02-19T22:32:22.492Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d7/02/849b46184bcfdd4b64cde61752cc9a146c54759ed036edd11857e9b8443b/ruff-0.15.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl";,
 hash = 
"sha256:b7a672c82b5f9887576087d97be5ce439f04bbaf548ee987b92d3a7dede41d3a", size 
= 11149151, upload-time = "2026-02-19T22:32:44.234Z" },
+    { url = 
"https://files.pythonhosted.org/packages/70/04/f5284e388bab60d1d3b99614a5a9aeb03e0f333847e2429bebd2aaa1feec/ruff-0.15.2-py3-none-manylinux_2_31_riscv64.whl";,
 hash = 
"sha256:72ecc64f46f7019e2bcc3cdc05d4a7da958b629a5ab7033195e11a438403d956", size 
= 11091132, upload-time = "2026-02-19T22:32:24.691Z" },
+    { url = 
"https://files.pythonhosted.org/packages/fa/ae/88d844a21110e14d92cf73d57363fab59b727ebeabe78009b9ccb23500af/ruff-0.15.2-py3-none-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:8dcf243b15b561c655c1ef2f2b0050e5d50db37fe90115507f6ff37d865dc8b4", size 
= 10504717, upload-time = "2026-02-19T22:32:26.75Z" },
+    { url = 
"https://files.pythonhosted.org/packages/64/27/867076a6ada7f2b9c8292884ab44d08fd2ba71bd2b5364d4136f3cd537e1/ruff-0.15.2-py3-none-musllinux_1_2_armv7l.whl";,
 hash = 
"sha256:dab6941c862c05739774677c6273166d2510d254dac0695c0e3f5efa1b5585de", size 
= 10263122, upload-time = "2026-02-19T22:32:10.036Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e7/ef/faf9321d550f8ebf0c6373696e70d1758e20ccdc3951ad7af00c0956be7c/ruff-0.15.2-py3-none-musllinux_1_2_i686.whl";,
 hash = 
"sha256:1b9164f57fc36058e9a6806eb92af185b0697c9fe4c7c52caa431c6554521e5c", size 
= 10735295, upload-time = "2026-02-19T22:32:39.227Z" },
+    { url = 
"https://files.pythonhosted.org/packages/2f/55/e8089fec62e050ba84d71b70e7834b97709ca9b7aba10c1a0b196e493f97/ruff-0.15.2-py3-none-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:80d24fcae24d42659db7e335b9e1531697a7102c19185b8dc4a028b952865fd8", size 
= 11241641, upload-time = "2026-02-19T22:32:34.617Z" },
+    { url = 
"https://files.pythonhosted.org/packages/23/01/1c30526460f4d23222d0fabd5888868262fd0e2b71a00570ca26483cd993/ruff-0.15.2-py3-none-win32.whl";,
 hash = 
"sha256:fd5ff9e5f519a7e1bd99cbe8daa324010a74f5e2ebc97c6242c08f26f3714f6f", size 
= 10507885, upload-time = "2026-02-19T22:32:15.635Z" },
+    { url = 
"https://files.pythonhosted.org/packages/5c/10/3d18e3bbdf8fc50bbb4ac3cc45970aa5a9753c5cb51bf9ed9a3cd8b79fa3/ruff-0.15.2-py3-none-win_amd64.whl";,
 hash = 
"sha256:d20014e3dfa400f3ff84830dfb5755ece2de45ab62ecea4af6b7262d0fb4f7c5", size 
= 11623725, upload-time = "2026-02-19T22:32:04.947Z" },
+    { url = 
"https://files.pythonhosted.org/packages/6d/78/097c0798b1dab9f8affe73da9642bb4500e098cb27fd8dc9724816ac747b/ruff-0.15.2-py3-none-win_arm64.whl";,
 hash = 
"sha256:cabddc5822acdc8f7b5527b36ceac55cc51eec7b1946e60181de8fe83ca8876e", size 
= 10941649, upload-time = "2026-02-19T22:32:18.108Z" },
 ]
 
 [[package]]
 name = "tomli"
-version = "2.2.1"
+version = "2.4.0"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz";,
 hash = 
"sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size 
= 17477, upload-time = "2026-01-11T11:22:38.165Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl";,
 hash = 
"sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size 
= 153663, upload-time = "2026-01-11T11:21:45.27Z" },
+    { url = 
"https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl";,
 hash = 
"sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size 
= 148469, upload-time = "2026-01-11T11:21:46.873Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size 
= 236039, upload-time = "2026-01-11T11:21:48.503Z" },
+    { url = 
"https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size 
= 243007, upload-time = "2026-01-11T11:21:49.456Z" },
+    { url = 
"https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size 
= 240875, upload-time = "2026-01-11T11:21:50.755Z" },
+    { url = 
"https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size 
= 246271, upload-time = "2026-01-11T11:21:51.81Z" },
+    { url = 
"https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl";,
 hash = 
"sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size 
= 96770, upload-time = "2026-01-11T11:21:52.647Z" },
+    { url = 
"https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl";,
 hash = 
"sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size 
= 107626, upload-time = "2026-01-11T11:21:53.459Z" },
+    { url = 
"https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl";,
 hash = 
"sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size 
= 94842, upload-time = "2026-01-11T11:21:54.831Z" },
+    { url = 
"https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size 
= 154894, upload-time = "2026-01-11T11:21:56.07Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl";,
 hash = 
"sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size 
= 149053, upload-time = "2026-01-11T11:21:57.467Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size 
= 243481, upload-time = "2026-01-11T11:21:58.661Z" },
+    { url = 
"https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size 
= 251720, upload-time = "2026-01-11T11:22:00.178Z" },
+    { url = 
"https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size 
= 247014, upload-time = "2026-01-11T11:22:01.238Z" },
+    { url = 
"https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size 
= 251820, upload-time = "2026-01-11T11:22:02.727Z" },
+    { url = 
"https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl";,
 hash = 
"sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size 
= 97712, upload-time = "2026-01-11T11:22:03.777Z" },
+    { url = 
"https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl";,
 hash = 
"sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size 
= 108296, upload-time = "2026-01-11T11:22:04.86Z" },
+    { url = 
"https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl";,
 hash = 
"sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size 
= 94553, upload-time = "2026-01-11T11:22:05.854Z" },
+    { url = 
"https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size 
= 154915, upload-time = "2026-01-11T11:22:06.703Z" },
+    { url = 
"https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl";,
 hash = 
"sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size 
= 149038, upload-time = "2026-01-11T11:22:07.56Z" },
+    { url = 
"https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size 
= 242245, upload-time = "2026-01-11T11:22:08.344Z" },
+    { url = 
"https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size 
= 250335, upload-time = "2026-01-11T11:22:09.951Z" },
+    { url = 
"https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size 
= 245962, upload-time = "2026-01-11T11:22:11.27Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size 
= 250396, upload-time = "2026-01-11T11:22:12.325Z" },
+    { url = 
"https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl";,
 hash = 
"sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size 
= 97530, upload-time = "2026-01-11T11:22:13.865Z" },
+    { url = 
"https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl";,
 hash = 
"sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size 
= 108227, upload-time = "2026-01-11T11:22:15.224Z" },
+    { url = 
"https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl";,
 hash = 
"sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size 
= 94748, upload-time = "2026-01-11T11:22:16.009Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl";,
 hash = 
"sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size 
= 154725, upload-time = "2026-01-11T11:22:17.269Z" },
+    { url = 
"https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl";,
 hash = 
"sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size 
= 148901, upload-time = "2026-01-11T11:22:18.287Z" },
+    { url = 
"https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size 
= 243375, upload-time = "2026-01-11T11:22:19.154Z" },
+    { url = 
"https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size 
= 250639, upload-time = "2026-01-11T11:22:20.168Z" },
+    { url = 
"https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size 
= 246897, upload-time = "2026-01-11T11:22:21.544Z" },
+    { url = 
"https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size 
= 254697, upload-time = "2026-01-11T11:22:23.058Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl";,
 hash = 
"sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size 
= 98567, upload-time = "2026-01-11T11:22:24.033Z" },
+    { url = 
"https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl";,
 hash = 
"sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size 
= 108556, upload-time = "2026-01-11T11:22:25.378Z" },
+    { url = 
"https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl";,
 hash = 
"sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size 
= 96014, upload-time = "2026-01-11T11:22:26.138Z" },
+    { url = 
"https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl";,
 hash = 
"sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size 
= 163339, upload-time = "2026-01-11T11:22:27.143Z" },
+    { url = 
"https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl";,
 hash = 
"sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size 
= 159490, upload-time = "2026-01-11T11:22:28.399Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size 
= 269398, upload-time = "2026-01-11T11:22:29.345Z" },
+    { url = 
"https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl";,
 hash = 
"sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size 
= 276515, upload-time = "2026-01-11T11:22:30.327Z" },
+    { url = 
"https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size 
= 273806, upload-time = "2026-01-11T11:22:32.56Z" },
+    { url = 
"https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size 
= 281340, upload-time = "2026-01-11T11:22:33.505Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl";,
 hash = 
"sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size 
= 108106, upload-time = "2026-01-11T11:22:34.451Z" },
+    { url = 
"https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl";,
 hash = 
"sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size 
= 120504, upload-time = "2026-01-11T11:22:35.764Z" },
+    { url = 
"https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl";,
 hash = 
"sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size 
= 99561, upload-time = "2026-01-11T11:22:36.624Z" },
+    { url = 
"https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl";,
 hash = 
"sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size 
= 14477, upload-time = "2026-01-11T11:22:37.446Z" },
+]
+
+[[package]]
+name = "tox"
+version = "4.46.0"
 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" }
+dependencies = [
+    { name = "cachetools" },
+    { name = "colorama" },
+    { name = "filelock" },
+    { name = "packaging" },
+    { name = "platformdirs" },
+    { name = "pluggy" },
+    { name = "pyproject-api" },
+    { name = "tomli", marker = "python_full_version < '3.11'" },
+    { name = "typing-extensions", marker = "python_full_version < '3.11'" },
+    { name = "virtualenv" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/bb/ba/140537bbf7dd267b37a1519ac1451b6c062d300cb64b7b273dfa1b2af9aa/tox-4.46.0.tar.gz";,
 hash = 
"sha256:b9d1aa187101dae184b7e6552f3b1ff85461e9e32f078851426e35a3c2009bc1", size 
= 249296, upload-time = "2026-02-24T17:53:36.171Z" }
 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/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl";,
 hash = 
"sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size 
= 132708, upload-time = "2024-11-27T22:38:21.659Z" },
-    { url = 
"https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl";,
 hash = 
"sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size 
= 123582, upload-time = "2024-11-27T22:38:22.693Z" },
-    { url = 
"https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl";,
 hash = 
"sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size 
= 232543, upload-time = "2024-11-27T22:38:24.367Z" },
-    { url = 
"https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl";,
 hash = 
"sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size 
= 241691, upload-time = "2024-11-27T22:38:26.081Z" },
-    { url = 
"https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl";,
 hash = 
"sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size 
= 251170, upload-time = "2024-11-27T22:38:27.921Z" },
-    { url = 
"https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl";,
 hash = 
"sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size 
= 236530, upload-time = "2024-11-27T22:38:29.591Z" },
-    { url = 
"https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl";,
 hash = 
"sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size 
= 258666, upload-time = "2024-11-27T22:38:30.639Z" },
-    { url = 
"https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl";,
 hash = 
"sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size 
= 243954, upload-time = "2024-11-27T22:38:31.702Z" },
-    { url = 
"https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl";,
 hash = 
"sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size 
= 98724, upload-time = "2024-11-27T22:38:32.837Z" },
-    { url = 
"https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl";,
 hash = 
"sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size 
= 109383, upload-time = "2024-11-27T22:38:34.455Z" },
-    { 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" },
+    { url = 
"https://files.pythonhosted.org/packages/e2/15/e344f22ae5adce77769cb93f03635674df40de2604e98a71a3193f632766/tox-4.46.0-py3-none-any.whl";,
 hash = 
"sha256:828f0a119a22028dbff7495d288e3601406478ab20c97891f66be5516d72e4c3", size 
= 200281, upload-time = "2026-02-24T17:53:34.228Z" },
+]
+
+[[package]]
+name = "tox-uv"
+version = "1.33.0"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "tox-uv-bare" },
+    { name = "uv" },
+]
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/9f/67/736f40388b5e1d1b828b236014be7dd3d62a10642122763e6928d950edad/tox_uv-1.33.0-py3-none-any.whl";,
 hash = 
"sha256:bb3055599940f111f3dead552dd7560b94339175ec58ffa7628ef59fad760d91", size 
= 5363, upload-time = "2026-02-25T13:22:52.186Z" },
+]
+
+[[package]]
+name = "tox-uv-bare"
+version = "1.33.0"
+source = { registry = "https://pypi.org/simple"; }
+dependencies = [
+    { name = "packaging" },
+    { name = "tomli", marker = "python_full_version < '3.11'" },
+    { name = "tox" },
+]
+sdist = { url = 
"https://files.pythonhosted.org/packages/07/e8/f927b6cb26dae64732cb8c31f20be009d264ecf34751e72cf8ae7c7db17b/tox_uv_bare-1.33.0.tar.gz";,
 hash = 
"sha256:34d8484a36ad121257f22823df154c246d831b84b01df91c4369a56cb4689d2e", size 
= 26995, upload-time = "2026-02-25T13:22:54.9Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/32/e5/0cae08b6c2908b4b8e51a91adaead58d06fd2393333aadc88c9a448da2c3/tox_uv_bare-1.33.0-py3-none-any.whl";,
 hash = 
"sha256:80b5c1f4f5eda2dfd3a9de569665ad2dccdfb128ed1ee9f69c1dacfd100f6b4a", size 
= 19528, upload-time = "2026-02-25T13:22:53.269Z" },
 ]
 
 [[package]]
 name = "typing-extensions"
-version = "4.14.0"
+version = "4.15.0"
+source = { registry = "https://pypi.org/simple"; }
+sdist = { url = 
"https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz";,
 hash = 
"sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size 
= 109391, upload-time = "2025-08-25T13:49:26.313Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl";,
 hash = 
"sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size 
= 44614, upload-time = "2025-08-25T13:49:24.86Z" },
+]
+
+[[package]]
+name = "uv"
+version = "0.10.5"
 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" }
+sdist = { url = 
"https://files.pythonhosted.org/packages/90/2f/472ff992c50e5947ef0570d291cfa3a70b423e5dcc6bee99b7a8e7b6da49/uv-0.10.5.tar.gz";,
 hash = 
"sha256:c45de48b7fa6dd034de8515a7d129f85f4e74080b9f09a7bfc0bcce2798f8023", size 
= 3919437, upload-time = "2026-02-24T00:55:11.392Z" }
+wheels = [
+    { url = 
"https://files.pythonhosted.org/packages/35/01/1521344a015f7fc01198f9d8560838adbeb9e80b835a23c25c712d8a8c08/uv-0.10.5-py3-none-linux_armv6l.whl";,
 hash = 
"sha256:d1ccf2e7cf08b8a1477195da50476fb645bf20907072a39074f482049056aa5d", size 
= 22401966, upload-time = "2026-02-24T00:55:09.111Z" },
+    { url = 
"https://files.pythonhosted.org/packages/3e/47/b4a4690f13d44f110ba7534a950a6ca63f61cc3d81c28f9c81afa9b74634/uv-0.10.5-py3-none-macosx_10_12_x86_64.whl";,
 hash = 
"sha256:63435e86321993dd5d90f440524f3f1b874b34aab30b7bf6752b48497117bfc4", size 
= 21504807, upload-time = "2026-02-24T00:55:18.55Z" },
+    { url = 
"https://files.pythonhosted.org/packages/61/58/28725e2d223b36812f692123934c1cbd7a6bc5261d6cf0f3850889768c66/uv-0.10.5-py3-none-macosx_11_0_arm64.whl";,
 hash = 
"sha256:2cec424513140aa179d1c4decfcf86201497df7bc5674c13a20882d3b2837c7e", size 
= 20194774, upload-time = "2026-02-24T00:54:49.789Z" },
+    { url = 
"https://files.pythonhosted.org/packages/6b/d4/87113bce59b9711e55995d2db66faffdb98952e371eab2d44fe4b0d79bf7/uv-0.10.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl";,
 hash = 
"sha256:3aa708beef7fab912d115ba1ccaad383a7006dc1a8e5ecdd9656574188221a84", size 
= 22044475, upload-time = "2026-02-24T00:54:56.924Z" },
+    { url = 
"https://files.pythonhosted.org/packages/7b/2c/af72b186786c4dd9a3d71d747cd0e02868b6eb7836b29c51e0d4cfe649de/uv-0.10.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl";,
 hash = 
"sha256:74c6d2d38160bbb2d596560f27875c3906c0e94e61c6279b5111d3f2d74dbcd9", size 
= 22038345, upload-time = "2026-02-24T00:54:59.245Z" },
+    { url = 
"https://files.pythonhosted.org/packages/61/8f/573edcdffe160093ef640b34690f13a2c6f35e03674fe52207bd9f63f23c/uv-0.10.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl";,
 hash = 
"sha256:f3ff5bab65eb305d1cf024c5eb091b12f3d7b40e5a78409fb0afb937b2614001", size 
= 22006975, upload-time = "2026-02-24T00:55:28.954Z" },
+    { url = 
"https://files.pythonhosted.org/packages/f0/28/9dbad27f80cc6b162f41c3becf154a1ba54177957ead4ae4faf3125b526f/uv-0.10.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl";,
 hash = 
"sha256:dd263e573a5259e6ce9854698e0c31e8ebdaa0a8d0701943db159854bbd6dcdf", size 
= 23326569, upload-time = "2026-02-24T00:55:33.966Z" },
+    { url = 
"https://files.pythonhosted.org/packages/1d/a0/f5ee404b9601bfb03d36241637d0d2ff1089115e532bcd77de0d29a0a89b/uv-0.10.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl";,
 hash = 
"sha256:faaa30c94ffeda248c29b7185ce4d5809de4c54f2a1c16f0120d50564473d9b4", size 
= 24197070, upload-time = "2026-02-24T00:55:06.621Z" },
+    { url = 
"https://files.pythonhosted.org/packages/dc/e8/c0c33168ca17f582727d33e629fa1673bc1e1c2411b174f2f78c1d16d287/uv-0.10.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl";,
 hash = 
"sha256:49db2d27555d6f7c69422d2d5f79ebe2dc4ed6a859a698d015d48de51e16aaab", size 
= 23277854, upload-time = "2026-02-24T00:55:31.444Z" },
+    { url = 
"https://files.pythonhosted.org/packages/8f/d9/4bb264bdb7f2e95efe09622cc6512288a842956bb4c2c3d6fe711eaef7df/uv-0.10.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl";,
 hash = 
"sha256:a8acf9be268ce2fc2c16117b5884f0724498d7191f8db2d12d8a7c7482652d38", size 
= 23252223, upload-time = "2026-02-24T00:55:16.256Z" },
+    { url = 
"https://files.pythonhosted.org/packages/fc/ac/b669f622c0e978754083aad3d7916594828ad5c3b634cb8374b7a841e153/uv-0.10.5-py3-none-manylinux_2_28_aarch64.whl";,
 hash = 
"sha256:0fbd426d2c215098cd8e08dfa36ad0a313ebe5eb90107ab7b3b8d5563b9b0c03", size 
= 22124089, upload-time = "2026-02-24T00:55:20.916Z" },
+    { url = 
"https://files.pythonhosted.org/packages/1f/0a/e9f44902757ec1723e8f1970463ce477ce11c79fa52a09001fbc8934128a/uv-0.10.5-py3-none-manylinux_2_31_riscv64.whl";,
 hash = 
"sha256:24825579973a05b7d482f1bba5e1b6d687d8e6ddf0ca088ff893e94ab34943a2", size 
= 22828770, upload-time = "2026-02-24T00:55:26.571Z" },
+    { url = 
"https://files.pythonhosted.org/packages/37/18/d69ba9636c560b771b96c08bcfb4424829cc53983d8c7b71e0d2f301e7fb/uv-0.10.5-py3-none-musllinux_1_1_i686.whl";,
 hash = 
"sha256:0338429ec4bb0b64620d05905a3fc1dc420df2a0e22b1a9b01dcc9e430067622", size 
= 22530138, upload-time = "2026-02-24T00:55:13.363Z" },
+    { url = 
"https://files.pythonhosted.org/packages/92/72/15ef087c4a4ab1531d77b267345a2321301b09345fbe6419f8a8b94ffc3d/uv-0.10.5-py3-none-musllinux_1_1_x86_64.whl";,
 hash = 
"sha256:515042b1f4a05396496a3db9ffc338b2f8f7bb39214fdbcb425b0462630f9270", size 
= 23448538, upload-time = "2026-02-24T00:54:53.364Z" },
+    { url = 
"https://files.pythonhosted.org/packages/c4/5c/b07bc4fd89fad1a0b7946d40469850552738613fcd678a4ecee5e892aa8c/uv-0.10.5-py3-none-win32.whl";,
 hash = 
"sha256:b235b4a5f25fb3bb93b96aebb6a2623eda0c2f48a6471b172a89e10444aa3626", size 
= 21507185, upload-time = "2026-02-24T00:55:01.646Z" },
+    { url = 
"https://files.pythonhosted.org/packages/43/31/c564541cd1a27001a245241e1ac82ef4132fb5d96cab13a4a19e91981eaf/uv-0.10.5-py3-none-win_amd64.whl";,
 hash = 
"sha256:4924af9facedde12eba2190463d84a4940062a875322e29ef59c8f447951e5c7", size 
= 23945906, upload-time = "2026-02-24T00:55:04.065Z" },
+    { url = 
"https://files.pythonhosted.org/packages/e0/f5/71fa52581b25d5aa8917b3d3956db9c3d1ed511d4785bb7c94bf02872160/uv-0.10.5-py3-none-win_arm64.whl";,
 hash = 
"sha256:43445370bb0729917b9a61d18bc3aec4e55c12e86463e6c4536fafde4d4da9e0", size 
= 22343346, upload-time = "2026-02-24T00:55:23.699Z" },
+]
+
+[[package]]
+name = "virtualenv"
+version = "20.39.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/ed/54/809199edc537dbace273495ac0884d13df26436e910a5ed4d0ec0a69806b/virtualenv-20.39.0.tar.gz";,
 hash = 
"sha256:a15f0cebd00d50074fd336a169d53422436a12dfe15149efec7072cfe817df8b", size 
= 5869141, upload-time = "2026-02-23T18:09:13.349Z" }
 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" },
+    { url = 
"https://files.pythonhosted.org/packages/f7/b4/8268da45f26f4fe84f6eae80a6ca1485ffb490a926afecff75fc48f61979/virtualenv-20.39.0-py3-none-any.whl";,
 hash = 
"sha256:44888bba3775990a152ea1f73f8e5f566d49f11bbd1de61d426fd7732770043e", size 
= 5839121, upload-time = "2026-02-23T18:09:11.173Z" },
 ]

Reply via email to