From 61c809637653b73da32d4358da668de37221ff84 Mon Sep 17 00:00:00 2001 From: Jae Date: Sun, 26 Oct 2025 10:56:28 -0600 Subject: [PATCH 1/6] chore: updated pyproject.toml and uv.lock files --- .../feature_engineering/pyproject.toml | 35 + eta_prediction/pyproject.toml | 1 - eta_prediction/uv.lock | 1553 ++++++++--------- 3 files changed, 811 insertions(+), 778 deletions(-) create mode 100644 eta_prediction/feature_engineering/pyproject.toml diff --git a/eta_prediction/feature_engineering/pyproject.toml b/eta_prediction/feature_engineering/pyproject.toml new file mode 100644 index 0000000..8e1026d --- /dev/null +++ b/eta_prediction/feature_engineering/pyproject.toml @@ -0,0 +1,35 @@ +[project] +name = "feature_engineering" +version = "0.1.0" +description = "Feature engineering utilities for GTFS realtime and schedule data (part of gtfs-django repository)" +readme = "README.md" +requires-python = ">=3.10" +authors = [ + { name = "maintainer", email = "maintainer@example.com" } +] +license = { text = "MIT" } + +dependencies = [ + "numpy>=1.26,<2", + "pandas>=2.2,<3", + "scikit-learn>=1.3,<2", + "scipy>=1.11,<2", + "joblib>=1.3,<2", + "tqdm>=4.66,<5", + "pyproj>=3.6,<4", + "shapely>=2.1,<3", + "geopandas>=0.14,<1", +] + +[project.optional-dependencies] +dev = [ + "pytest>=7.4,<8", + "black>=24.3,<25", + "isort>=5.13,<6", + "mypy>=1.11,<2", + "pre-commit>=3.4,<4", +] + +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/eta_prediction/pyproject.toml b/eta_prediction/pyproject.toml index c29b8cf..e5e5d10 100644 --- a/eta_prediction/pyproject.toml +++ b/eta_prediction/pyproject.toml @@ -16,7 +16,6 @@ dependencies = [ "matplotlib>=3.9.4", "pandas>=2.3.3", "psycopg>=3.2.11", - "pytest>=8.4.2", "requests>=2.31", ] diff --git a/eta_prediction/uv.lock b/eta_prediction/uv.lock index b2cf39f..33548c8 100644 --- a/eta_prediction/uv.lock +++ b/eta_prediction/uv.lock @@ -1,11 +1,10 @@ version = 1 revision = 3 -requires-python = ">=3.9" +requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.12'", "python_full_version == '3.11.*'", - "python_full_version == '3.10.*'", - "python_full_version < '3.10'", + "python_full_version < '3.11'", ] [manifest] @@ -38,6 +37,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/17/9c/fc2331f538fbf7eedba64b2052e99ccf9ba9d6888e2f41441ee28847004b/asgiref-3.10.0-py3-none-any.whl", hash = "sha256:aef8a81283a34d0ab31630c9b7dfe70c812c95eba78171367ca8745e88124734", size = 24050, upload-time = "2025-10-05T09:15:05.11Z" }, ] +[[package]] +name = "attrs" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, +] + [[package]] name = "billiard" version = "4.2.2" @@ -47,14 +55,47 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a6/80/ef8dff49aae0e4430f81842f7403e14e0ca59db7bbaf7af41245b67c6b25/billiard-4.2.2-py3-none-any.whl", hash = "sha256:4bc05dcf0d1cc6addef470723aac2a6232f3c7ed7475b0b580473a9145829457", size = 86896, upload-time = "2025-09-20T14:44:39.157Z" }, ] +[[package]] +name = "black" +version = "24.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/0d/cc2fb42b8c50d80143221515dd7e4766995bd07c56c9a3ed30baf080b6dc/black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875", size = 645813, upload-time = "2024-10-07T19:20:50.361Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/f3/465c0eb5cddf7dbbfe1fecd9b875d1dcf51b88923cd2c1d7e9ab95c6336b/black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812", size = 1623211, upload-time = "2024-10-07T19:26:12.43Z" }, + { url = "https://files.pythonhosted.org/packages/df/57/b6d2da7d200773fdfcc224ffb87052cf283cec4d7102fab450b4a05996d8/black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea", size = 1457139, upload-time = "2024-10-07T19:25:06.453Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c5/9023b7673904a5188f9be81f5e129fff69f51f5515655fbd1d5a4e80a47b/black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f", size = 1753774, upload-time = "2024-10-07T19:23:58.47Z" }, + { url = "https://files.pythonhosted.org/packages/e1/32/df7f18bd0e724e0d9748829765455d6643ec847b3f87e77456fc99d0edab/black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e", size = 1414209, upload-time = "2024-10-07T19:24:42.54Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cc/7496bb63a9b06a954d3d0ac9fe7a73f3bf1cd92d7a58877c27f4ad1e9d41/black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad", size = 1607468, upload-time = "2024-10-07T19:26:14.966Z" }, + { url = "https://files.pythonhosted.org/packages/2b/e3/69a738fb5ba18b5422f50b4f143544c664d7da40f09c13969b2fd52900e0/black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50", size = 1437270, upload-time = "2024-10-07T19:25:24.291Z" }, + { url = "https://files.pythonhosted.org/packages/c9/9b/2db8045b45844665c720dcfe292fdaf2e49825810c0103e1191515fc101a/black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392", size = 1737061, upload-time = "2024-10-07T19:23:52.18Z" }, + { url = "https://files.pythonhosted.org/packages/a3/95/17d4a09a5be5f8c65aa4a361444d95edc45def0de887810f508d3f65db7a/black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175", size = 1423293, upload-time = "2024-10-07T19:24:41.7Z" }, + { url = "https://files.pythonhosted.org/packages/90/04/bf74c71f592bcd761610bbf67e23e6a3cff824780761f536512437f1e655/black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3", size = 1644256, upload-time = "2024-10-07T19:27:53.355Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ea/a77bab4cf1887f4b2e0bce5516ea0b3ff7d04ba96af21d65024629afedb6/black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65", size = 1448534, upload-time = "2024-10-07T19:26:44.953Z" }, + { url = "https://files.pythonhosted.org/packages/4e/3e/443ef8bc1fbda78e61f79157f303893f3fddf19ca3c8989b163eb3469a12/black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f", size = 1761892, upload-time = "2024-10-07T19:24:10.264Z" }, + { url = "https://files.pythonhosted.org/packages/52/93/eac95ff229049a6901bc84fec6908a5124b8a0b7c26ea766b3b8a5debd22/black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8", size = 1434796, upload-time = "2024-10-07T19:25:06.239Z" }, + { url = "https://files.pythonhosted.org/packages/d0/a0/a993f58d4ecfba035e61fca4e9f64a2ecae838fc9f33ab798c62173ed75c/black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981", size = 1643986, upload-time = "2024-10-07T19:28:50.684Z" }, + { url = "https://files.pythonhosted.org/packages/37/d5/602d0ef5dfcace3fb4f79c436762f130abd9ee8d950fa2abdbf8bbc555e0/black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b", size = 1448085, upload-time = "2024-10-07T19:28:12.093Z" }, + { url = "https://files.pythonhosted.org/packages/47/6d/a3a239e938960df1a662b93d6230d4f3e9b4a22982d060fc38c42f45a56b/black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2", size = 1760928, upload-time = "2024-10-07T19:24:15.233Z" }, + { url = "https://files.pythonhosted.org/packages/dd/cf/af018e13b0eddfb434df4d9cd1b2b7892bab119f7a20123e93f6910982e8/black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b", size = 1436875, upload-time = "2024-10-07T19:24:42.762Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a7/4b27c50537ebca8bec139b872861f9d2bf501c5ec51fcf897cb924d9e264/black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d", size = 206898, upload-time = "2024-10-07T19:20:48.317Z" }, +] + [[package]] name = "celery" version = "5.5.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "billiard" }, - { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "click", version = "8.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "click" }, { name = "click-didyoumean" }, { name = "click-plugins" }, { name = "click-repl" }, @@ -76,6 +117,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, ] +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, +] + [[package]] name = "charset-normalizer" version = "3.4.3" @@ -137,46 +187,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ca/9a0983dd5c8e9733565cf3db4df2b0a2e9a82659fd8aa2a868ac6e4a991f/charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05", size = 207520, upload-time = "2025-08-09T07:57:11.026Z" }, - { url = "https://files.pythonhosted.org/packages/39/c6/99271dc37243a4f925b09090493fb96c9333d7992c6187f5cfe5312008d2/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e", size = 147307, upload-time = "2025-08-09T07:57:12.4Z" }, - { url = "https://files.pythonhosted.org/packages/e4/69/132eab043356bba06eb333cc2cc60c6340857d0a2e4ca6dc2b51312886b3/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99", size = 160448, upload-time = "2025-08-09T07:57:13.712Z" }, - { url = "https://files.pythonhosted.org/packages/04/9a/914d294daa4809c57667b77470533e65def9c0be1ef8b4c1183a99170e9d/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7", size = 157758, upload-time = "2025-08-09T07:57:14.979Z" }, - { url = "https://files.pythonhosted.org/packages/b0/a8/6f5bcf1bcf63cb45625f7c5cadca026121ff8a6c8a3256d8d8cd59302663/charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7", size = 152487, upload-time = "2025-08-09T07:57:16.332Z" }, - { url = "https://files.pythonhosted.org/packages/c4/72/d3d0e9592f4e504f9dea08b8db270821c909558c353dc3b457ed2509f2fb/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19", size = 150054, upload-time = "2025-08-09T07:57:17.576Z" }, - { url = "https://files.pythonhosted.org/packages/20/30/5f64fe3981677fe63fa987b80e6c01042eb5ff653ff7cec1b7bd9268e54e/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312", size = 161703, upload-time = "2025-08-09T07:57:20.012Z" }, - { url = "https://files.pythonhosted.org/packages/e1/ef/dd08b2cac9284fd59e70f7d97382c33a3d0a926e45b15fc21b3308324ffd/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc", size = 159096, upload-time = "2025-08-09T07:57:21.329Z" }, - { url = "https://files.pythonhosted.org/packages/45/8c/dcef87cfc2b3f002a6478f38906f9040302c68aebe21468090e39cde1445/charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34", size = 153852, upload-time = "2025-08-09T07:57:22.608Z" }, - { url = "https://files.pythonhosted.org/packages/63/86/9cbd533bd37883d467fcd1bd491b3547a3532d0fbb46de2b99feeebf185e/charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432", size = 99840, upload-time = "2025-08-09T07:57:23.883Z" }, - { url = "https://files.pythonhosted.org/packages/ce/d6/7e805c8e5c46ff9729c49950acc4ee0aeb55efb8b3a56687658ad10c3216/charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca", size = 107438, upload-time = "2025-08-09T07:57:25.287Z" }, { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, ] -[[package]] -name = "click" -version = "8.1.8" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" }, -] - [[package]] name = "click" version = "8.3.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", - "python_full_version == '3.10.*'", -] dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } wheels = [ @@ -188,8 +207,7 @@ name = "click-didyoumean" version = "0.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "click", version = "8.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "click" }, ] sdist = { url = "https://files.pythonhosted.org/packages/30/ce/217289b77c590ea1e7c24242d9ddd6e249e52c795ff10fac2c50062c48cb/click_didyoumean-0.3.1.tar.gz", hash = "sha256:4f82fdff0dbe64ef8ab2279bd6aa3f6a99c3b28c05aa09cbfc07c9d7fbb5a463", size = 3089, upload-time = "2024-03-24T08:22:07.499Z" } wheels = [ @@ -201,8 +219,7 @@ name = "click-plugins" version = "1.1.1.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "click", version = "8.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "click" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c3/a4/34847b59150da33690a36da3681d6bbc2ec14ee9a846bc30a6746e5984e4/click_plugins-1.1.1.2.tar.gz", hash = "sha256:d7af3984a99d243c131aa1a828331e7630f4a88a9741fd05c927b204bcf92261", size = 8343, upload-time = "2025-06-25T00:47:37.555Z" } wheels = [ @@ -214,8 +231,7 @@ name = "click-repl" version = "0.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "click", version = "8.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "click" }, { name = "prompt-toolkit" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cb/a2/57f4ac79838cfae6912f997b4d1a64a858fb0c86d7fcaae6f7b58d267fca/click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9", size = 10449, upload-time = "2023-06-15T12:43:51.141Z" } @@ -224,90 +240,24 @@ wheels = [ ] [[package]] -name = "colorama" -version = "0.4.6" +name = "cligj" +version = "0.7.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +dependencies = [ + { name = "click" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/0d/837dbd5d8430fd0f01ed72c4cfb2f548180f4c68c635df84ce87956cff32/cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27", size = 9803, upload-time = "2021-05-28T21:23:27.935Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, + { url = "https://files.pythonhosted.org/packages/73/86/43fa9f15c5b9fb6e82620428827cd3c284aa933431405d1bcf5231ae3d3e/cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df", size = 7069, upload-time = "2021-05-28T21:23:26.877Z" }, ] [[package]] -name = "contourpy" -version = "1.3.0" +name = "colorama" +version = "0.4.6" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f5/f6/31a8f28b4a2a4fa0e01085e542f3081ab0588eff8e589d39d775172c9792/contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4", size = 13464370, upload-time = "2024-08-27T21:00:03.328Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6c/e0/be8dcc796cfdd96708933e0e2da99ba4bb8f9b2caa9d560a50f3f09a65f3/contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7", size = 265366, upload-time = "2024-08-27T20:50:09.947Z" }, - { url = "https://files.pythonhosted.org/packages/50/d6/c953b400219443535d412fcbbc42e7a5e823291236bc0bb88936e3cc9317/contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42", size = 249226, upload-time = "2024-08-27T20:50:16.1Z" }, - { url = "https://files.pythonhosted.org/packages/6f/b4/6fffdf213ffccc28483c524b9dad46bb78332851133b36ad354b856ddc7c/contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7", size = 308460, upload-time = "2024-08-27T20:50:22.536Z" }, - { url = "https://files.pythonhosted.org/packages/cf/6c/118fc917b4050f0afe07179a6dcbe4f3f4ec69b94f36c9e128c4af480fb8/contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab", size = 347623, upload-time = "2024-08-27T20:50:28.806Z" }, - { url = "https://files.pythonhosted.org/packages/f9/a4/30ff110a81bfe3abf7b9673284d21ddce8cc1278f6f77393c91199da4c90/contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589", size = 317761, upload-time = "2024-08-27T20:50:35.126Z" }, - { url = "https://files.pythonhosted.org/packages/99/e6/d11966962b1aa515f5586d3907ad019f4b812c04e4546cc19ebf62b5178e/contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41", size = 322015, upload-time = "2024-08-27T20:50:40.318Z" }, - { url = "https://files.pythonhosted.org/packages/4d/e3/182383743751d22b7b59c3c753277b6aee3637049197624f333dac5b4c80/contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d", size = 1262672, upload-time = "2024-08-27T20:50:55.643Z" }, - { url = "https://files.pythonhosted.org/packages/78/53/974400c815b2e605f252c8fb9297e2204347d1755a5374354ee77b1ea259/contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223", size = 1321688, upload-time = "2024-08-27T20:51:11.293Z" }, - { url = "https://files.pythonhosted.org/packages/52/29/99f849faed5593b2926a68a31882af98afbeac39c7fdf7de491d9c85ec6a/contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f", size = 171145, upload-time = "2024-08-27T20:51:15.2Z" }, - { url = "https://files.pythonhosted.org/packages/a9/97/3f89bba79ff6ff2b07a3cbc40aa693c360d5efa90d66e914f0ff03b95ec7/contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b", size = 216019, upload-time = "2024-08-27T20:51:19.365Z" }, - { url = "https://files.pythonhosted.org/packages/b3/1f/9375917786cb39270b0ee6634536c0e22abf225825602688990d8f5c6c19/contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad", size = 266356, upload-time = "2024-08-27T20:51:24.146Z" }, - { url = "https://files.pythonhosted.org/packages/05/46/9256dd162ea52790c127cb58cfc3b9e3413a6e3478917d1f811d420772ec/contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49", size = 250915, upload-time = "2024-08-27T20:51:28.683Z" }, - { url = "https://files.pythonhosted.org/packages/e1/5d/3056c167fa4486900dfbd7e26a2fdc2338dc58eee36d490a0ed3ddda5ded/contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66", size = 310443, upload-time = "2024-08-27T20:51:33.675Z" }, - { url = "https://files.pythonhosted.org/packages/ca/c2/1a612e475492e07f11c8e267ea5ec1ce0d89971be496c195e27afa97e14a/contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081", size = 348548, upload-time = "2024-08-27T20:51:39.322Z" }, - { url = "https://files.pythonhosted.org/packages/45/cf/2c2fc6bb5874158277b4faf136847f0689e1b1a1f640a36d76d52e78907c/contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1", size = 319118, upload-time = "2024-08-27T20:51:44.717Z" }, - { url = "https://files.pythonhosted.org/packages/03/33/003065374f38894cdf1040cef474ad0546368eea7e3a51d48b8a423961f8/contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d", size = 323162, upload-time = "2024-08-27T20:51:49.683Z" }, - { url = "https://files.pythonhosted.org/packages/42/80/e637326e85e4105a802e42959f56cff2cd39a6b5ef68d5d9aee3ea5f0e4c/contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c", size = 1265396, upload-time = "2024-08-27T20:52:04.926Z" }, - { url = "https://files.pythonhosted.org/packages/7c/3b/8cbd6416ca1bbc0202b50f9c13b2e0b922b64be888f9d9ee88e6cfabfb51/contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb", size = 1324297, upload-time = "2024-08-27T20:52:21.843Z" }, - { url = "https://files.pythonhosted.org/packages/4d/2c/021a7afaa52fe891f25535506cc861c30c3c4e5a1c1ce94215e04b293e72/contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c", size = 171808, upload-time = "2024-08-27T20:52:25.163Z" }, - { url = "https://files.pythonhosted.org/packages/8d/2f/804f02ff30a7fae21f98198828d0857439ec4c91a96e20cf2d6c49372966/contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67", size = 217181, upload-time = "2024-08-27T20:52:29.13Z" }, - { url = "https://files.pythonhosted.org/packages/c9/92/8e0bbfe6b70c0e2d3d81272b58c98ac69ff1a4329f18c73bd64824d8b12e/contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f", size = 267838, upload-time = "2024-08-27T20:52:33.911Z" }, - { url = "https://files.pythonhosted.org/packages/e3/04/33351c5d5108460a8ce6d512307690b023f0cfcad5899499f5c83b9d63b1/contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6", size = 251549, upload-time = "2024-08-27T20:52:39.179Z" }, - { url = "https://files.pythonhosted.org/packages/51/3d/aa0fe6ae67e3ef9f178389e4caaaa68daf2f9024092aa3c6032e3d174670/contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639", size = 303177, upload-time = "2024-08-27T20:52:44.789Z" }, - { url = "https://files.pythonhosted.org/packages/56/c3/c85a7e3e0cab635575d3b657f9535443a6f5d20fac1a1911eaa4bbe1aceb/contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c", size = 341735, upload-time = "2024-08-27T20:52:51.05Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/20f7a211a7be966a53f474bc90b1a8202e9844b3f1ef85f3ae45a77151ee/contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06", size = 314679, upload-time = "2024-08-27T20:52:58.473Z" }, - { url = "https://files.pythonhosted.org/packages/6e/be/524e377567defac0e21a46e2a529652d165fed130a0d8a863219303cee18/contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09", size = 320549, upload-time = "2024-08-27T20:53:06.593Z" }, - { url = "https://files.pythonhosted.org/packages/0f/96/fdb2552a172942d888915f3a6663812e9bc3d359d53dafd4289a0fb462f0/contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd", size = 1263068, upload-time = "2024-08-27T20:53:23.442Z" }, - { url = "https://files.pythonhosted.org/packages/2a/25/632eab595e3140adfa92f1322bf8915f68c932bac468e89eae9974cf1c00/contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35", size = 1322833, upload-time = "2024-08-27T20:53:39.243Z" }, - { url = "https://files.pythonhosted.org/packages/73/e3/69738782e315a1d26d29d71a550dbbe3eb6c653b028b150f70c1a5f4f229/contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb", size = 172681, upload-time = "2024-08-27T20:53:43.05Z" }, - { url = "https://files.pythonhosted.org/packages/0c/89/9830ba00d88e43d15e53d64931e66b8792b46eb25e2050a88fec4a0df3d5/contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b", size = 218283, upload-time = "2024-08-27T20:53:47.232Z" }, - { url = "https://files.pythonhosted.org/packages/53/a1/d20415febfb2267af2d7f06338e82171824d08614084714fb2c1dac9901f/contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3", size = 267879, upload-time = "2024-08-27T20:53:51.597Z" }, - { url = "https://files.pythonhosted.org/packages/aa/45/5a28a3570ff6218d8bdfc291a272a20d2648104815f01f0177d103d985e1/contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7", size = 251573, upload-time = "2024-08-27T20:53:55.659Z" }, - { url = "https://files.pythonhosted.org/packages/39/1c/d3f51540108e3affa84f095c8b04f0aa833bb797bc8baa218a952a98117d/contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84", size = 303184, upload-time = "2024-08-27T20:54:00.225Z" }, - { url = "https://files.pythonhosted.org/packages/00/56/1348a44fb6c3a558c1a3a0cd23d329d604c99d81bf5a4b58c6b71aab328f/contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0", size = 340262, upload-time = "2024-08-27T20:54:05.234Z" }, - { url = "https://files.pythonhosted.org/packages/2b/23/00d665ba67e1bb666152131da07e0f24c95c3632d7722caa97fb61470eca/contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b", size = 313806, upload-time = "2024-08-27T20:54:09.889Z" }, - { url = "https://files.pythonhosted.org/packages/5a/42/3cf40f7040bb8362aea19af9a5fb7b32ce420f645dd1590edcee2c657cd5/contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da", size = 319710, upload-time = "2024-08-27T20:54:14.536Z" }, - { url = "https://files.pythonhosted.org/packages/05/32/f3bfa3fc083b25e1a7ae09197f897476ee68e7386e10404bdf9aac7391f0/contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14", size = 1264107, upload-time = "2024-08-27T20:54:29.735Z" }, - { url = "https://files.pythonhosted.org/packages/1c/1e/1019d34473a736664f2439542b890b2dc4c6245f5c0d8cdfc0ccc2cab80c/contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8", size = 1322458, upload-time = "2024-08-27T20:54:45.507Z" }, - { url = "https://files.pythonhosted.org/packages/22/85/4f8bfd83972cf8909a4d36d16b177f7b8bdd942178ea4bf877d4a380a91c/contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294", size = 172643, upload-time = "2024-08-27T20:55:52.754Z" }, - { url = "https://files.pythonhosted.org/packages/cc/4a/fb3c83c1baba64ba90443626c228ca14f19a87c51975d3b1de308dd2cf08/contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087", size = 218301, upload-time = "2024-08-27T20:55:56.509Z" }, - { url = "https://files.pythonhosted.org/packages/76/65/702f4064f397821fea0cb493f7d3bc95a5d703e20954dce7d6d39bacf378/contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8", size = 278972, upload-time = "2024-08-27T20:54:50.347Z" }, - { url = "https://files.pythonhosted.org/packages/80/85/21f5bba56dba75c10a45ec00ad3b8190dbac7fd9a8a8c46c6116c933e9cf/contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b", size = 263375, upload-time = "2024-08-27T20:54:54.909Z" }, - { url = "https://files.pythonhosted.org/packages/0a/64/084c86ab71d43149f91ab3a4054ccf18565f0a8af36abfa92b1467813ed6/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973", size = 307188, upload-time = "2024-08-27T20:55:00.184Z" }, - { url = "https://files.pythonhosted.org/packages/3d/ff/d61a4c288dc42da0084b8d9dc2aa219a850767165d7d9a9c364ff530b509/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18", size = 345644, upload-time = "2024-08-27T20:55:05.673Z" }, - { url = "https://files.pythonhosted.org/packages/ca/aa/00d2313d35ec03f188e8f0786c2fc61f589306e02fdc158233697546fd58/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8", size = 317141, upload-time = "2024-08-27T20:55:11.047Z" }, - { url = "https://files.pythonhosted.org/packages/8d/6a/b5242c8cb32d87f6abf4f5e3044ca397cb1a76712e3fa2424772e3ff495f/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6", size = 323469, upload-time = "2024-08-27T20:55:15.914Z" }, - { url = "https://files.pythonhosted.org/packages/6f/a6/73e929d43028a9079aca4bde107494864d54f0d72d9db508a51ff0878593/contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2", size = 1260894, upload-time = "2024-08-27T20:55:31.553Z" }, - { url = "https://files.pythonhosted.org/packages/2b/1e/1e726ba66eddf21c940821df8cf1a7d15cb165f0682d62161eaa5e93dae1/contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927", size = 1314829, upload-time = "2024-08-27T20:55:47.837Z" }, - { url = "https://files.pythonhosted.org/packages/b3/e3/b9f72758adb6ef7397327ceb8b9c39c75711affb220e4f53c745ea1d5a9a/contourpy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8", size = 265518, upload-time = "2024-08-27T20:56:01.333Z" }, - { url = "https://files.pythonhosted.org/packages/ec/22/19f5b948367ab5260fb41d842c7a78dae645603881ea6bc39738bcfcabf6/contourpy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c", size = 249350, upload-time = "2024-08-27T20:56:05.432Z" }, - { url = "https://files.pythonhosted.org/packages/26/76/0c7d43263dd00ae21a91a24381b7e813d286a3294d95d179ef3a7b9fb1d7/contourpy-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca", size = 309167, upload-time = "2024-08-27T20:56:10.034Z" }, - { url = "https://files.pythonhosted.org/packages/96/3b/cadff6773e89f2a5a492c1a8068e21d3fccaf1a1c1df7d65e7c8e3ef60ba/contourpy-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f", size = 348279, upload-time = "2024-08-27T20:56:15.41Z" }, - { url = "https://files.pythonhosted.org/packages/e1/86/158cc43aa549d2081a955ab11c6bdccc7a22caacc2af93186d26f5f48746/contourpy-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc", size = 318519, upload-time = "2024-08-27T20:56:21.813Z" }, - { url = "https://files.pythonhosted.org/packages/05/11/57335544a3027e9b96a05948c32e566328e3a2f84b7b99a325b7a06d2b06/contourpy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2", size = 321922, upload-time = "2024-08-27T20:56:26.983Z" }, - { url = "https://files.pythonhosted.org/packages/0b/e3/02114f96543f4a1b694333b92a6dcd4f8eebbefcc3a5f3bbb1316634178f/contourpy-1.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e", size = 1258017, upload-time = "2024-08-27T20:56:42.246Z" }, - { url = "https://files.pythonhosted.org/packages/f3/3b/bfe4c81c6d5881c1c643dde6620be0b42bf8aab155976dd644595cfab95c/contourpy-1.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800", size = 1316773, upload-time = "2024-08-27T20:56:58.58Z" }, - { url = "https://files.pythonhosted.org/packages/f1/17/c52d2970784383cafb0bd918b6fb036d98d96bbf0bc1befb5d1e31a07a70/contourpy-1.3.0-cp39-cp39-win32.whl", hash = "sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5", size = 171353, upload-time = "2024-08-27T20:57:02.718Z" }, - { url = "https://files.pythonhosted.org/packages/53/23/db9f69676308e094d3c45f20cc52e12d10d64f027541c995d89c11ad5c75/contourpy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843", size = 211817, upload-time = "2024-08-27T20:57:06.328Z" }, - { url = "https://files.pythonhosted.org/packages/d1/09/60e486dc2b64c94ed33e58dcfb6f808192c03dfc5574c016218b9b7680dc/contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c", size = 261886, upload-time = "2024-08-27T20:57:10.863Z" }, - { url = "https://files.pythonhosted.org/packages/19/20/b57f9f7174fcd439a7789fb47d764974ab646fa34d1790551de386457a8e/contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779", size = 311008, upload-time = "2024-08-27T20:57:15.588Z" }, - { url = "https://files.pythonhosted.org/packages/74/fc/5040d42623a1845d4f17a418e590fd7a79ae8cb2bad2b2f83de63c3bdca4/contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4", size = 215690, upload-time = "2024-08-27T20:57:19.321Z" }, - { url = "https://files.pythonhosted.org/packages/2b/24/dc3dcd77ac7460ab7e9d2b01a618cb31406902e50e605a8d6091f0a8f7cc/contourpy-1.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0", size = 261894, upload-time = "2024-08-27T20:57:23.873Z" }, - { url = "https://files.pythonhosted.org/packages/b1/db/531642a01cfec39d1682e46b5457b07cf805e3c3c584ec27e2a6223f8f6c/contourpy-1.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102", size = 311099, upload-time = "2024-08-27T20:57:28.58Z" }, - { url = "https://files.pythonhosted.org/packages/38/1e/94bda024d629f254143a134eead69e21c836429a2a6ce82209a00ddcb79a/contourpy-1.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb", size = 215838, upload-time = "2024-08-27T20:57:32.913Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] @@ -315,10 +265,10 @@ name = "contourpy" version = "1.3.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version == '3.10.*'", + "python_full_version < '3.11'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, + { name = "numpy", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" } wheels = [ @@ -389,7 +339,7 @@ resolution-markers = [ "python_full_version == '3.11.*'", ] dependencies = [ - { name = "numpy", version = "2.3.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ @@ -476,48 +426,22 @@ wheels = [ ] [[package]] -name = "datetime" -version = "5.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pytz" }, - { name = "zope-interface" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2f/66/e284b9978fede35185e5d18fb3ae855b8f573d8c90a56de5f6d03e8ef99e/DateTime-5.5.tar.gz", hash = "sha256:21ec6331f87a7fcb57bd7c59e8a68bfffe6fcbf5acdbbc7b356d6a9a020191d3", size = 63671, upload-time = "2024-03-21T07:26:50.211Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/78/8e382b8cb4346119e2e04270b6eb4a01c5ee70b47a8a0244ecdb157204f7/DateTime-5.5-py3-none-any.whl", hash = "sha256:0abf6c51cb4ba7cee775ca46ccc727f3afdde463be28dbbe8803631fefd4a120", size = 52649, upload-time = "2024-03-21T07:26:47.849Z" }, -] - -[[package]] -name = "django" -version = "4.2.25" +name = "distlib" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "asgiref", marker = "python_full_version < '3.10'" }, - { name = "sqlparse", marker = "python_full_version < '3.10'" }, - { name = "tzdata", marker = "python_full_version < '3.10' and sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/de/f1/230c6c20a77f8f1812c01dfd0166416e7c000a43e05f701b0b83301ebfc1/django-4.2.25.tar.gz", hash = "sha256:2391ab3d78191caaae2c963c19fd70b99e9751008da22a0adcc667c5a4f8d311", size = 10456257, upload-time = "2025-10-01T15:05:55.963Z" } +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/35/5d/2210dcf9a03931be94072deab1de2d3b73fa62ce91714eaea9e69f6e35c6/django-4.2.25-py3-none-any.whl", hash = "sha256:9584cf26b174b35620e53c2558b09d7eb180a655a3470474f513ff9acb494f8c", size = 7993964, upload-time = "2025-10-01T15:05:46.545Z" }, + { 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 = "django" version = "5.2.7" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", - "python_full_version == '3.10.*'", -] dependencies = [ - { name = "asgiref", marker = "python_full_version >= '3.10'" }, - { name = "sqlparse", marker = "python_full_version >= '3.10'" }, - { name = "tzdata", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" }, + { name = "asgiref" }, + { name = "sqlparse" }, + { name = "tzdata", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b1/96/bd84e2bb997994de8bcda47ae4560991084e86536541d7214393880f01a8/django-5.2.7.tar.gz", hash = "sha256:e0f6f12e2551b1716a95a63a1366ca91bbcd7be059862c1b18f989b1da356cdd", size = 10865812, upload-time = "2025-10-01T14:22:12.081Z" } wheels = [ @@ -541,23 +465,85 @@ name = "feature-engineering" version = "0.1.0" source = { editable = "feature_engineering" } dependencies = [ - { name = "datetime" }, - { name = "django", version = "4.2.25", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "django", version = "5.2.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "psycopg" }, + { name = "geopandas" }, + { name = "joblib" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "pyproj", version = "3.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pyproj", version = "3.7.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scikit-learn" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "scipy", version = "1.16.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "shapely" }, + { name = "tqdm" }, +] + +[package.optional-dependencies] +dev = [ + { name = "black" }, + { name = "isort" }, + { name = "mypy" }, + { name = "pre-commit" }, { name = "pytest" }, - { name = "requests" }, - { name = "typing" }, ] [package.metadata] requires-dist = [ - { name = "datetime", specifier = ">=5.5" }, - { name = "django", specifier = ">=4.2.25" }, - { name = "psycopg", specifier = ">=3.2.11" }, - { name = "pytest", specifier = ">=8.4.2" }, - { name = "requests", specifier = ">=2.32.5" }, - { name = "typing", specifier = ">=3.10.0.0" }, + { name = "black", marker = "extra == 'dev'", specifier = ">=24.3,<25" }, + { name = "geopandas", specifier = ">=0.14,<1" }, + { name = "isort", marker = "extra == 'dev'", specifier = ">=5.13,<6" }, + { name = "joblib", specifier = ">=1.3,<2" }, + { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.11,<2" }, + { name = "numpy", specifier = ">=1.26,<2" }, + { name = "pandas", specifier = ">=2.2,<3" }, + { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=3.4,<4" }, + { name = "pyproj", specifier = ">=3.6,<4" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=7.4,<8" }, + { name = "scikit-learn", specifier = ">=1.3,<2" }, + { name = "scipy", specifier = ">=1.11,<2" }, + { name = "shapely", specifier = ">=2.1,<3" }, + { name = "tqdm", specifier = ">=4.66,<5" }, +] +provides-extras = ["dev"] + +[[package]] +name = "filelock" +version = "3.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, +] + +[[package]] +name = "fiona" +version = "1.10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "certifi" }, + { name = "click" }, + { name = "click-plugins" }, + { name = "cligj" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/51/e0/71b63839cc609e1d62cea2fc9774aa605ece7ea78af823ff7a8f1c560e72/fiona-1.10.1.tar.gz", hash = "sha256:b00ae357669460c6491caba29c2022ff0acfcbde86a95361ea8ff5cd14a86b68", size = 444606, upload-time = "2024-09-16T20:15:47.074Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/34/c7e681703db8f8509907ebe6326c5b4fd933f8ae9a7d3ab7a51e507f230e/fiona-1.10.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:6e2a94beebda24e5db8c3573fe36110d474d4a12fac0264a3e083c75e9d63829", size = 16143634, upload-time = "2024-09-16T20:14:20.089Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2c/7f1968ecc17350db3c87d0feb59852ea50e7d8688a63659879d92badf90a/fiona-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc7366f99bdc18ec99441b9e50246fdf5e72923dc9cbb00267b2bf28edd142ba", size = 14750325, upload-time = "2024-09-16T20:14:23.762Z" }, + { url = "https://files.pythonhosted.org/packages/75/cb/73805030100447d40408c8a0f63ec146fb2b6e82692d0c194655c28b6783/fiona-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c32f424b0641c79f4036b96c2e80322fb181b4e415c8cd02d182baef55e6730", size = 17294868, upload-time = "2024-09-16T20:14:26.847Z" }, + { url = "https://files.pythonhosted.org/packages/ca/a3/57d33c2f16a2a6b27911d83301a697ed1491dca48d2f1dd2ed3b58a66244/fiona-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:9a67bd88918e87d64168bc9c00d9816d8bb07353594b5ce6c57252979d5dc86e", size = 24480225, upload-time = "2024-09-16T20:14:30.749Z" }, + { url = "https://files.pythonhosted.org/packages/2d/b9/7a8356cfaff8ef162bad44283554d3171e13032635b4f8e10e694a9596ee/fiona-1.10.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:98fe556058b370da07a84f6537c286f87eb4af2343d155fbd3fba5d38ac17ed7", size = 16144293, upload-time = "2024-09-16T20:14:34.519Z" }, + { url = "https://files.pythonhosted.org/packages/65/0c/e8070b15c8303f60bd4444a120842597ccd6ed550548948e2e36cffbaa93/fiona-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:be29044d4aeebae92944b738160dc5f9afc4cdf04f551d59e803c5b910e17520", size = 14752213, upload-time = "2024-09-16T20:14:37.763Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2e/3f80ba2fda9b8686681f0a1b18c8e95ad152ada1d6fb1d3f25281d9229fd/fiona-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94bd3d448f09f85439e4b77c38b9de1aebe3eef24acc72bd631f75171cdfde51", size = 17272183, upload-time = "2024-09-16T20:14:42.389Z" }, + { url = "https://files.pythonhosted.org/packages/95/32/c1d53b4d77926414ffdf5bd38344e900e378ae9ccb2a65754cdb6d5344c2/fiona-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:30594c0cd8682c43fd01e7cdbe000f94540f8fa3b7cb5901e805c88c4ff2058b", size = 24489398, upload-time = "2024-09-16T20:14:46.233Z" }, + { url = "https://files.pythonhosted.org/packages/73/ab/036c418d531afb74abe4ca9a8be487b863901fe7b42ddba1ba2fb0681d77/fiona-1.10.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:7338b8c68beb7934bde4ec9f49eb5044e5e484b92d940bc3ec27defdb2b06c67", size = 16114589, upload-time = "2024-09-16T20:14:49.307Z" }, + { url = "https://files.pythonhosted.org/packages/ba/45/693c1cca53023aaf6e3adc11422080f5fa427484e7b85e48f19c40d6357f/fiona-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8c77fcfd3cdb0d3c97237965f8c60d1696a64923deeeb2d0b9810286cbe25911", size = 14754603, upload-time = "2024-09-16T20:14:53.829Z" }, + { url = "https://files.pythonhosted.org/packages/dc/78/be204fb409b59876ef4658710a022794f16f779a3e9e7df654acc38b2104/fiona-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:537872cbc9bda7fcdf73851c91bc5338fca2b502c4c17049ccecaa13cde1f18f", size = 17223639, upload-time = "2024-09-16T20:14:57.146Z" }, + { url = "https://files.pythonhosted.org/packages/7e/0d/914fd3c4c32043c2c512fa5021e83b2348e1b7a79365d75a0a37cb545362/fiona-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:41cde2c52c614457e9094ea44b0d30483540789e62fe0fa758c2a2963e980817", size = 24464921, upload-time = "2024-09-16T20:15:01.121Z" }, + { url = "https://files.pythonhosted.org/packages/c5/e0/665ce969cab6339c19527318534236e5e4184ee03b38cd474497ebd22f4d/fiona-1.10.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:a00b05935c9900678b2ca660026b39efc4e4b916983915d595964eb381763ae7", size = 16106571, upload-time = "2024-09-16T20:15:04.198Z" }, + { url = "https://files.pythonhosted.org/packages/23/c8/150094fbc4220d22217f480cc67b6ee4c2f4324b4b58cd25527cd5905937/fiona-1.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f78b781d5bcbbeeddf1d52712f33458775dbb9fd1b2a39882c83618348dd730f", size = 14738178, upload-time = "2024-09-16T20:15:06.848Z" }, + { url = "https://files.pythonhosted.org/packages/20/83/63da54032c0c03d4921b854111e33d3a1dadec5d2b7e741fba6c8c6486a6/fiona-1.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ceeb38e3cd30d91d68858d0817a1bb0c4f96340d334db4b16a99edb0902d35", size = 17221414, upload-time = "2024-09-16T20:15:09.606Z" }, + { url = "https://files.pythonhosted.org/packages/60/14/5ef47002ef19bd5cfbc7a74b21c30ef83f22beb80609314ce0328989ceda/fiona-1.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:15751c90e29cee1e01fcfedf42ab85987e32f0b593cf98d88ed52199ef5ca623", size = 24461486, upload-time = "2024-09-16T20:15:13.399Z" }, ] [[package]] @@ -614,17 +600,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/d4/ff19976305e0c05aa3340c805475abb00224c954d3c65e82c0a69633d55d/fonttools-4.60.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f0e8817c7d1a0c2eedebf57ef9a9896f3ea23324769a9a2061a80fe8852705ed", size = 4974184, upload-time = "2025-09-29T21:12:55.962Z" }, { url = "https://files.pythonhosted.org/packages/63/22/8553ff6166f5cd21cfaa115aaacaa0dc73b91c079a8cfd54a482cbc0f4f5/fonttools-4.60.1-cp314-cp314t-win32.whl", hash = "sha256:1410155d0e764a4615774e5c2c6fc516259fe3eca5882f034eb9bfdbee056259", size = 2282241, upload-time = "2025-09-29T21:12:58.179Z" }, { url = "https://files.pythonhosted.org/packages/8a/cb/fa7b4d148e11d5a72761a22e595344133e83a9507a4c231df972e657579b/fonttools-4.60.1-cp314-cp314t-win_amd64.whl", hash = "sha256:022beaea4b73a70295b688f817ddc24ed3e3418b5036ffcd5658141184ef0d0c", size = 2345760, upload-time = "2025-09-29T21:13:00.375Z" }, - { url = "https://files.pythonhosted.org/packages/a4/7f/1c9a6cc6e7374ab59bbe91cb3b8a65ce0907c59f8f35368bb3bf941bd458/fonttools-4.60.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:122e1a8ada290423c493491d002f622b1992b1ab0b488c68e31c413390dc7eb2", size = 2816178, upload-time = "2025-09-29T21:13:02.915Z" }, - { url = "https://files.pythonhosted.org/packages/ca/ac/acb4dcf1932566c0b57b5261f93a8b97cb3ebae08d07aff1288e7c9d7faa/fonttools-4.60.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a140761c4ff63d0cb9256ac752f230460ee225ccef4ad8f68affc723c88e2036", size = 2349175, upload-time = "2025-09-29T21:13:05.432Z" }, - { url = "https://files.pythonhosted.org/packages/3e/ac/0b2f8d62c857adfe96551d56abbbc3d2eda2e4715a2e91c5eb7815bb38e1/fonttools-4.60.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eae96373e4b7c9e45d099d7a523444e3554360927225c1cdae221a58a45b856", size = 4840452, upload-time = "2025-09-29T21:13:08.679Z" }, - { url = "https://files.pythonhosted.org/packages/2d/e1/b2e2ae805f263507e050f1ebfc2fb3654124161f3bea466a1b2a4485c705/fonttools-4.60.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:596ecaca36367027d525b3b426d8a8208169d09edcf8c7506aceb3a38bfb55c7", size = 4774040, upload-time = "2025-09-29T21:13:11.424Z" }, - { url = "https://files.pythonhosted.org/packages/9d/91/05949ba6f757014f343632b142543576eb100aeb261c036b86e7d1fc50f0/fonttools-4.60.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ee06fc57512144d8b0445194c2da9f190f61ad51e230f14836286470c99f854", size = 4823746, upload-time = "2025-09-29T21:13:14.08Z" }, - { url = "https://files.pythonhosted.org/packages/1b/cf/db9a1bd8d835dc17f09104f83b9d8c078d7bebbaaa9bd41378bf10f025de/fonttools-4.60.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b42d86938e8dda1cd9a1a87a6d82f1818eaf933348429653559a458d027446da", size = 4934001, upload-time = "2025-09-29T21:13:16.435Z" }, - { url = "https://files.pythonhosted.org/packages/87/4a/c58503524f7e6c73eb33b944f27535460e1050a58c99bd5b441242fcca86/fonttools-4.60.1-cp39-cp39-win32.whl", hash = "sha256:8b4eb332f9501cb1cd3d4d099374a1e1306783ff95489a1026bde9eb02ccc34a", size = 1499091, upload-time = "2025-09-29T21:13:19.072Z" }, - { url = "https://files.pythonhosted.org/packages/69/8f/3394936411aec5f26a1fdf8d7fdc1da7c276e0c627cd71b7b266b2431681/fonttools-4.60.1-cp39-cp39-win_amd64.whl", hash = "sha256:7473a8ed9ed09aeaa191301244a5a9dbe46fe0bf54f9d6cd21d83044c3321217", size = 1543835, upload-time = "2025-09-29T21:13:21.606Z" }, { url = "https://files.pythonhosted.org/packages/c7/93/0dd45cd283c32dea1545151d8c3637b4b8c53cdb3a625aeb2885b184d74d/fonttools-4.60.1-py3-none-any.whl", hash = "sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb", size = 1143175, upload-time = "2025-09-29T21:13:24.134Z" }, ] +[[package]] +name = "geopandas" +version = "0.14.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fiona" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pandas" }, + { name = "pyproj", version = "3.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pyproj", version = "3.7.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "shapely" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/79/79af2645d40d590a466f8329ab04c2d4fffc811e6713d1c1580dcfdf285c/geopandas-0.14.4.tar.gz", hash = "sha256:56765be9d58e2c743078085db3bd07dc6be7719f0dbe1dfdc1d705cb80be7c25", size = 1106304, upload-time = "2024-04-28T13:49:27.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/b0/69fa7a0f55122847506a42fea6988d03b34136938082f142151bc9d9f7e7/geopandas-0.14.4-py3-none-any.whl", hash = "sha256:3bb6473cb59d51e1a7fe2dbc24a1a063fb0ebdeddf3ce08ddbf8c7ddc99689aa", size = 1109913, upload-time = "2024-04-28T13:49:24.25Z" }, +] + [[package]] name = "gtfs-realtime-bindings" version = "1.0.0" @@ -641,14 +637,11 @@ version = "0.1.0" source = { virtual = "." } dependencies = [ { name = "celery" }, - { name = "django", version = "4.2.25", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "django", version = "5.2.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "django" }, { name = "gtfs-realtime-bindings" }, - { name = "matplotlib", version = "3.9.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "matplotlib", version = "3.10.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "matplotlib" }, { name = "pandas" }, { name = "psycopg" }, - { name = "pytest" }, { name = "requests" }, ] @@ -660,169 +653,58 @@ requires-dist = [ { name = "matplotlib", specifier = ">=3.9.4" }, { name = "pandas", specifier = ">=2.3.3" }, { name = "psycopg", specifier = ">=3.2.11" }, - { name = "pytest", specifier = ">=8.4.2" }, { name = "requests", specifier = ">=2.31" }, ] [[package]] -name = "idna" -version = "3.10" +name = "identify" +version = "2.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/e7/685de97986c916a6d93b3876139e00eef26ad5bbbd61925d670ae8013449/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf", size = 99311, upload-time = "2025-10-02T17:43:40.631Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" }, ] [[package]] -name = "importlib-resources" -version = "6.5.2" +name = "idna" +version = "3.10" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "zipp", marker = "python_full_version < '3.10'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cf/8c/f834fbf984f691b4f7ff60f50b514cc3de5cc08abfc3295564dd89c5e2e7/importlib_resources-6.5.2.tar.gz", hash = "sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c", size = 44693, upload-time = "2025-01-03T18:51:56.698Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl", hash = "sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec", size = 37461, upload-time = "2025-01-03T18:51:54.306Z" }, + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] [[package]] name = "iniconfig" -version = "2.1.0" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] -name = "iniconfig" -version = "2.3.0" +name = "isort" +version = "5.13.2" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", - "python_full_version == '3.10.*'", -] -sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/f9/c1eb8635a24e87ade2efce21e3ce8cd6b8630bb685ddc9cdaca1349b2eb5/isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", size = 175303, upload-time = "2023-12-13T20:37:26.124Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b3/8def84f539e7d2289a02f0524b944b15d7c75dab7628bedf1c4f0992029c/isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6", size = 92310, upload-time = "2023-12-13T20:37:23.244Z" }, ] [[package]] -name = "kiwisolver" -version = "1.4.7" +name = "joblib" +version = "1.5.2" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -sdist = { url = "https://files.pythonhosted.org/packages/85/4d/2255e1c76304cbd60b48cee302b66d1dde4468dc5b1160e4b7cb43778f2a/kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60", size = 97286, upload-time = "2024-09-04T09:39:44.302Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/97/14/fc943dd65268a96347472b4fbe5dcc2f6f55034516f80576cd0dd3a8930f/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6", size = 122440, upload-time = "2024-09-04T09:03:44.9Z" }, - { url = "https://files.pythonhosted.org/packages/1e/46/e68fed66236b69dd02fcdb506218c05ac0e39745d696d22709498896875d/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17", size = 65758, upload-time = "2024-09-04T09:03:46.582Z" }, - { url = "https://files.pythonhosted.org/packages/ef/fa/65de49c85838681fc9cb05de2a68067a683717321e01ddafb5b8024286f0/kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9", size = 64311, upload-time = "2024-09-04T09:03:47.973Z" }, - { url = "https://files.pythonhosted.org/packages/42/9c/cc8d90f6ef550f65443bad5872ffa68f3dee36de4974768628bea7c14979/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9", size = 1637109, upload-time = "2024-09-04T09:03:49.281Z" }, - { url = "https://files.pythonhosted.org/packages/55/91/0a57ce324caf2ff5403edab71c508dd8f648094b18cfbb4c8cc0fde4a6ac/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c", size = 1617814, upload-time = "2024-09-04T09:03:51.444Z" }, - { url = "https://files.pythonhosted.org/packages/12/5d/c36140313f2510e20207708adf36ae4919416d697ee0236b0ddfb6fd1050/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599", size = 1400881, upload-time = "2024-09-04T09:03:53.357Z" }, - { url = "https://files.pythonhosted.org/packages/56/d0/786e524f9ed648324a466ca8df86298780ef2b29c25313d9a4f16992d3cf/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05", size = 1512972, upload-time = "2024-09-04T09:03:55.082Z" }, - { url = "https://files.pythonhosted.org/packages/67/5a/77851f2f201e6141d63c10a0708e996a1363efaf9e1609ad0441b343763b/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407", size = 1444787, upload-time = "2024-09-04T09:03:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/06/5f/1f5eaab84355885e224a6fc8d73089e8713dc7e91c121f00b9a1c58a2195/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278", size = 2199212, upload-time = "2024-09-04T09:03:58.557Z" }, - { url = "https://files.pythonhosted.org/packages/b5/28/9152a3bfe976a0ae21d445415defc9d1cd8614b2910b7614b30b27a47270/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5", size = 2346399, upload-time = "2024-09-04T09:04:00.178Z" }, - { url = "https://files.pythonhosted.org/packages/26/f6/453d1904c52ac3b400f4d5e240ac5fec25263716723e44be65f4d7149d13/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad", size = 2308688, upload-time = "2024-09-04T09:04:02.216Z" }, - { url = "https://files.pythonhosted.org/packages/5a/9a/d4968499441b9ae187e81745e3277a8b4d7c60840a52dc9d535a7909fac3/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895", size = 2445493, upload-time = "2024-09-04T09:04:04.571Z" }, - { url = "https://files.pythonhosted.org/packages/07/c9/032267192e7828520dacb64dfdb1d74f292765f179e467c1cba97687f17d/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3", size = 2262191, upload-time = "2024-09-04T09:04:05.969Z" }, - { url = "https://files.pythonhosted.org/packages/6c/ad/db0aedb638a58b2951da46ddaeecf204be8b4f5454df020d850c7fa8dca8/kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc", size = 46644, upload-time = "2024-09-04T09:04:07.408Z" }, - { url = "https://files.pythonhosted.org/packages/12/ca/d0f7b7ffbb0be1e7c2258b53554efec1fd652921f10d7d85045aff93ab61/kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c", size = 55877, upload-time = "2024-09-04T09:04:08.869Z" }, - { url = "https://files.pythonhosted.org/packages/97/6c/cfcc128672f47a3e3c0d918ecb67830600078b025bfc32d858f2e2d5c6a4/kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a", size = 48347, upload-time = "2024-09-04T09:04:10.106Z" }, - { url = "https://files.pythonhosted.org/packages/e9/44/77429fa0a58f941d6e1c58da9efe08597d2e86bf2b2cce6626834f49d07b/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54", size = 122442, upload-time = "2024-09-04T09:04:11.432Z" }, - { url = "https://files.pythonhosted.org/packages/e5/20/8c75caed8f2462d63c7fd65e16c832b8f76cda331ac9e615e914ee80bac9/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95", size = 65762, upload-time = "2024-09-04T09:04:12.468Z" }, - { url = "https://files.pythonhosted.org/packages/f4/98/fe010f15dc7230f45bc4cf367b012d651367fd203caaa992fd1f5963560e/kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935", size = 64319, upload-time = "2024-09-04T09:04:13.635Z" }, - { url = "https://files.pythonhosted.org/packages/8b/1b/b5d618f4e58c0675654c1e5051bcf42c776703edb21c02b8c74135541f60/kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb", size = 1334260, upload-time = "2024-09-04T09:04:14.878Z" }, - { url = "https://files.pythonhosted.org/packages/b8/01/946852b13057a162a8c32c4c8d2e9ed79f0bb5d86569a40c0b5fb103e373/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02", size = 1426589, upload-time = "2024-09-04T09:04:16.514Z" }, - { url = "https://files.pythonhosted.org/packages/70/d1/c9f96df26b459e15cf8a965304e6e6f4eb291e0f7a9460b4ad97b047561e/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51", size = 1541080, upload-time = "2024-09-04T09:04:18.322Z" }, - { url = "https://files.pythonhosted.org/packages/d3/73/2686990eb8b02d05f3de759d6a23a4ee7d491e659007dd4c075fede4b5d0/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052", size = 1470049, upload-time = "2024-09-04T09:04:20.266Z" }, - { url = "https://files.pythonhosted.org/packages/a7/4b/2db7af3ed3af7c35f388d5f53c28e155cd402a55432d800c543dc6deb731/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18", size = 1426376, upload-time = "2024-09-04T09:04:22.419Z" }, - { url = "https://files.pythonhosted.org/packages/05/83/2857317d04ea46dc5d115f0df7e676997bbd968ced8e2bd6f7f19cfc8d7f/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545", size = 2222231, upload-time = "2024-09-04T09:04:24.526Z" }, - { url = "https://files.pythonhosted.org/packages/0d/b5/866f86f5897cd4ab6d25d22e403404766a123f138bd6a02ecb2cdde52c18/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b", size = 2368634, upload-time = "2024-09-04T09:04:25.899Z" }, - { url = "https://files.pythonhosted.org/packages/c1/ee/73de8385403faba55f782a41260210528fe3273d0cddcf6d51648202d6d0/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36", size = 2329024, upload-time = "2024-09-04T09:04:28.523Z" }, - { url = "https://files.pythonhosted.org/packages/a1/e7/cd101d8cd2cdfaa42dc06c433df17c8303d31129c9fdd16c0ea37672af91/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3", size = 2468484, upload-time = "2024-09-04T09:04:30.547Z" }, - { url = "https://files.pythonhosted.org/packages/e1/72/84f09d45a10bc57a40bb58b81b99d8f22b58b2040c912b7eb97ebf625bf2/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523", size = 2284078, upload-time = "2024-09-04T09:04:33.218Z" }, - { url = "https://files.pythonhosted.org/packages/d2/d4/71828f32b956612dc36efd7be1788980cb1e66bfb3706e6dec9acad9b4f9/kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d", size = 46645, upload-time = "2024-09-04T09:04:34.371Z" }, - { url = "https://files.pythonhosted.org/packages/a1/65/d43e9a20aabcf2e798ad1aff6c143ae3a42cf506754bcb6a7ed8259c8425/kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b", size = 56022, upload-time = "2024-09-04T09:04:35.786Z" }, - { url = "https://files.pythonhosted.org/packages/35/b3/9f75a2e06f1b4ca00b2b192bc2b739334127d27f1d0625627ff8479302ba/kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376", size = 48536, upload-time = "2024-09-04T09:04:37.525Z" }, - { url = "https://files.pythonhosted.org/packages/97/9c/0a11c714cf8b6ef91001c8212c4ef207f772dd84540104952c45c1f0a249/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2", size = 121808, upload-time = "2024-09-04T09:04:38.637Z" }, - { url = "https://files.pythonhosted.org/packages/f2/d8/0fe8c5f5d35878ddd135f44f2af0e4e1d379e1c7b0716f97cdcb88d4fd27/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a", size = 65531, upload-time = "2024-09-04T09:04:39.694Z" }, - { url = "https://files.pythonhosted.org/packages/80/c5/57fa58276dfdfa612241d640a64ca2f76adc6ffcebdbd135b4ef60095098/kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee", size = 63894, upload-time = "2024-09-04T09:04:41.6Z" }, - { url = "https://files.pythonhosted.org/packages/8b/e9/26d3edd4c4ad1c5b891d8747a4f81b1b0aba9fb9721de6600a4adc09773b/kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640", size = 1369296, upload-time = "2024-09-04T09:04:42.886Z" }, - { url = "https://files.pythonhosted.org/packages/b6/67/3f4850b5e6cffb75ec40577ddf54f7b82b15269cc5097ff2e968ee32ea7d/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f", size = 1461450, upload-time = "2024-09-04T09:04:46.284Z" }, - { url = "https://files.pythonhosted.org/packages/52/be/86cbb9c9a315e98a8dc6b1d23c43cffd91d97d49318854f9c37b0e41cd68/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483", size = 1579168, upload-time = "2024-09-04T09:04:47.91Z" }, - { url = "https://files.pythonhosted.org/packages/0f/00/65061acf64bd5fd34c1f4ae53f20b43b0a017a541f242a60b135b9d1e301/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258", size = 1507308, upload-time = "2024-09-04T09:04:49.465Z" }, - { url = "https://files.pythonhosted.org/packages/21/e4/c0b6746fd2eb62fe702118b3ca0cb384ce95e1261cfada58ff693aeec08a/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e", size = 1464186, upload-time = "2024-09-04T09:04:50.949Z" }, - { url = "https://files.pythonhosted.org/packages/0a/0f/529d0a9fffb4d514f2782c829b0b4b371f7f441d61aa55f1de1c614c4ef3/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107", size = 2247877, upload-time = "2024-09-04T09:04:52.388Z" }, - { url = "https://files.pythonhosted.org/packages/d1/e1/66603ad779258843036d45adcbe1af0d1a889a07af4635f8b4ec7dccda35/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948", size = 2404204, upload-time = "2024-09-04T09:04:54.385Z" }, - { url = "https://files.pythonhosted.org/packages/8d/61/de5fb1ca7ad1f9ab7970e340a5b833d735df24689047de6ae71ab9d8d0e7/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038", size = 2352461, upload-time = "2024-09-04T09:04:56.307Z" }, - { url = "https://files.pythonhosted.org/packages/ba/d2/0edc00a852e369827f7e05fd008275f550353f1f9bcd55db9363d779fc63/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383", size = 2501358, upload-time = "2024-09-04T09:04:57.922Z" }, - { url = "https://files.pythonhosted.org/packages/84/15/adc15a483506aec6986c01fb7f237c3aec4d9ed4ac10b756e98a76835933/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520", size = 2314119, upload-time = "2024-09-04T09:04:59.332Z" }, - { url = "https://files.pythonhosted.org/packages/36/08/3a5bb2c53c89660863a5aa1ee236912269f2af8762af04a2e11df851d7b2/kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b", size = 46367, upload-time = "2024-09-04T09:05:00.804Z" }, - { url = "https://files.pythonhosted.org/packages/19/93/c05f0a6d825c643779fc3c70876bff1ac221f0e31e6f701f0e9578690d70/kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb", size = 55884, upload-time = "2024-09-04T09:05:01.924Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f9/3828d8f21b6de4279f0667fb50a9f5215e6fe57d5ec0d61905914f5b6099/kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a", size = 48528, upload-time = "2024-09-04T09:05:02.983Z" }, - { url = "https://files.pythonhosted.org/packages/c4/06/7da99b04259b0f18b557a4effd1b9c901a747f7fdd84cf834ccf520cb0b2/kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e", size = 121913, upload-time = "2024-09-04T09:05:04.072Z" }, - { url = "https://files.pythonhosted.org/packages/97/f5/b8a370d1aa593c17882af0a6f6755aaecd643640c0ed72dcfd2eafc388b9/kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6", size = 65627, upload-time = "2024-09-04T09:05:05.119Z" }, - { url = "https://files.pythonhosted.org/packages/2a/fc/6c0374f7503522539e2d4d1b497f5ebad3f8ed07ab51aed2af988dd0fb65/kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750", size = 63888, upload-time = "2024-09-04T09:05:06.191Z" }, - { url = "https://files.pythonhosted.org/packages/bf/3e/0b7172793d0f41cae5c923492da89a2ffcd1adf764c16159ca047463ebd3/kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d", size = 1369145, upload-time = "2024-09-04T09:05:07.919Z" }, - { url = "https://files.pythonhosted.org/packages/77/92/47d050d6f6aced2d634258123f2688fbfef8ded3c5baf2c79d94d91f1f58/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379", size = 1461448, upload-time = "2024-09-04T09:05:10.01Z" }, - { url = "https://files.pythonhosted.org/packages/9c/1b/8f80b18e20b3b294546a1adb41701e79ae21915f4175f311a90d042301cf/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c", size = 1578750, upload-time = "2024-09-04T09:05:11.598Z" }, - { url = "https://files.pythonhosted.org/packages/a4/fe/fe8e72f3be0a844f257cadd72689c0848c6d5c51bc1d60429e2d14ad776e/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34", size = 1507175, upload-time = "2024-09-04T09:05:13.22Z" }, - { url = "https://files.pythonhosted.org/packages/39/fa/cdc0b6105d90eadc3bee525fecc9179e2b41e1ce0293caaf49cb631a6aaf/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1", size = 1463963, upload-time = "2024-09-04T09:05:15.925Z" }, - { url = "https://files.pythonhosted.org/packages/6e/5c/0c03c4e542720c6177d4f408e56d1c8315899db72d46261a4e15b8b33a41/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f", size = 2248220, upload-time = "2024-09-04T09:05:17.434Z" }, - { url = "https://files.pythonhosted.org/packages/3d/ee/55ef86d5a574f4e767df7da3a3a7ff4954c996e12d4fbe9c408170cd7dcc/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b", size = 2404463, upload-time = "2024-09-04T09:05:18.997Z" }, - { url = "https://files.pythonhosted.org/packages/0f/6d/73ad36170b4bff4825dc588acf4f3e6319cb97cd1fb3eb04d9faa6b6f212/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27", size = 2352842, upload-time = "2024-09-04T09:05:21.299Z" }, - { url = "https://files.pythonhosted.org/packages/0b/16/fa531ff9199d3b6473bb4d0f47416cdb08d556c03b8bc1cccf04e756b56d/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a", size = 2501635, upload-time = "2024-09-04T09:05:23.588Z" }, - { url = "https://files.pythonhosted.org/packages/78/7e/aa9422e78419db0cbe75fb86d8e72b433818f2e62e2e394992d23d23a583/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee", size = 2314556, upload-time = "2024-09-04T09:05:25.907Z" }, - { url = "https://files.pythonhosted.org/packages/a8/b2/15f7f556df0a6e5b3772a1e076a9d9f6c538ce5f05bd590eca8106508e06/kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07", size = 46364, upload-time = "2024-09-04T09:05:27.184Z" }, - { url = "https://files.pythonhosted.org/packages/0b/db/32e897e43a330eee8e4770bfd2737a9584b23e33587a0812b8e20aac38f7/kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76", size = 55887, upload-time = "2024-09-04T09:05:28.372Z" }, - { url = "https://files.pythonhosted.org/packages/c8/a4/df2bdca5270ca85fd25253049eb6708d4127be2ed0e5c2650217450b59e9/kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650", size = 48530, upload-time = "2024-09-04T09:05:30.225Z" }, - { url = "https://files.pythonhosted.org/packages/11/88/37ea0ea64512997b13d69772db8dcdc3bfca5442cda3a5e4bb943652ee3e/kiwisolver-1.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f9362ecfca44c863569d3d3c033dbe8ba452ff8eed6f6b5806382741a1334bd", size = 122449, upload-time = "2024-09-04T09:05:55.311Z" }, - { url = "https://files.pythonhosted.org/packages/4e/45/5a5c46078362cb3882dcacad687c503089263c017ca1241e0483857791eb/kiwisolver-1.4.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e8df2eb9b2bac43ef8b082e06f750350fbbaf2887534a5be97f6cf07b19d9583", size = 65757, upload-time = "2024-09-04T09:05:56.906Z" }, - { url = "https://files.pythonhosted.org/packages/8a/be/a6ae58978772f685d48dd2e84460937761c53c4bbd84e42b0336473d9775/kiwisolver-1.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f32d6edbc638cde7652bd690c3e728b25332acbadd7cad670cc4a02558d9c417", size = 64312, upload-time = "2024-09-04T09:05:58.384Z" }, - { url = "https://files.pythonhosted.org/packages/f4/04/18ef6f452d311e1e1eb180c9bf5589187fa1f042db877e6fe443ef10099c/kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e2e6c39bd7b9372b0be21456caab138e8e69cc0fc1190a9dfa92bd45a1e6e904", size = 1626966, upload-time = "2024-09-04T09:05:59.855Z" }, - { url = "https://files.pythonhosted.org/packages/21/b1/40655f6c3fa11ce740e8a964fa8e4c0479c87d6a7944b95af799c7a55dfe/kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dda56c24d869b1193fcc763f1284b9126550eaf84b88bbc7256e15028f19188a", size = 1607044, upload-time = "2024-09-04T09:06:02.16Z" }, - { url = "https://files.pythonhosted.org/packages/fd/93/af67dbcfb9b3323bbd2c2db1385a7139d8f77630e4a37bb945b57188eb2d/kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79849239c39b5e1fd906556c474d9b0439ea6792b637511f3fe3a41158d89ca8", size = 1391879, upload-time = "2024-09-04T09:06:03.908Z" }, - { url = "https://files.pythonhosted.org/packages/40/6f/d60770ef98e77b365d96061d090c0cd9e23418121c55fff188fa4bdf0b54/kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e3bc157fed2a4c02ec468de4ecd12a6e22818d4f09cde2c31ee3226ffbefab2", size = 1504751, upload-time = "2024-09-04T09:06:05.58Z" }, - { url = "https://files.pythonhosted.org/packages/fa/3a/5f38667d313e983c432f3fcd86932177519ed8790c724e07d77d1de0188a/kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3da53da805b71e41053dc670f9a820d1157aae77b6b944e08024d17bcd51ef88", size = 1436990, upload-time = "2024-09-04T09:06:08.126Z" }, - { url = "https://files.pythonhosted.org/packages/cb/3b/1520301a47326e6a6043b502647e42892be33b3f051e9791cc8bb43f1a32/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8705f17dfeb43139a692298cb6637ee2e59c0194538153e83e9ee0c75c2eddde", size = 2191122, upload-time = "2024-09-04T09:06:10.345Z" }, - { url = "https://files.pythonhosted.org/packages/cf/c4/eb52da300c166239a2233f1f9c4a1b767dfab98fae27681bfb7ea4873cb6/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:82a5c2f4b87c26bb1a0ef3d16b5c4753434633b83d365cc0ddf2770c93829e3c", size = 2338126, upload-time = "2024-09-04T09:06:12.321Z" }, - { url = "https://files.pythonhosted.org/packages/1a/cb/42b92fd5eadd708dd9107c089e817945500685f3437ce1fd387efebc6d6e/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce8be0466f4c0d585cdb6c1e2ed07232221df101a4c6f28821d2aa754ca2d9e2", size = 2298313, upload-time = "2024-09-04T09:06:14.562Z" }, - { url = "https://files.pythonhosted.org/packages/4f/eb/be25aa791fe5fc75a8b1e0c965e00f942496bc04635c9aae8035f6b76dcd/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:409afdfe1e2e90e6ee7fc896f3df9a7fec8e793e58bfa0d052c8a82f99c37abb", size = 2437784, upload-time = "2024-09-04T09:06:16.767Z" }, - { url = "https://files.pythonhosted.org/packages/c5/22/30a66be7f3368d76ff95689e1c2e28d382383952964ab15330a15d8bfd03/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5b9c3f4ee0b9a439d2415012bd1b1cc2df59e4d6a9939f4d669241d30b414327", size = 2253988, upload-time = "2024-09-04T09:06:18.705Z" }, - { url = "https://files.pythonhosted.org/packages/35/d3/5f2ecb94b5211c8a04f218a76133cc8d6d153b0f9cd0b45fad79907f0689/kiwisolver-1.4.7-cp39-cp39-win32.whl", hash = "sha256:a79ae34384df2b615eefca647a2873842ac3b596418032bef9a7283675962644", size = 46980, upload-time = "2024-09-04T09:06:20.106Z" }, - { url = "https://files.pythonhosted.org/packages/ef/17/cd10d020578764ea91740204edc6b3236ed8106228a46f568d716b11feb2/kiwisolver-1.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:cf0438b42121a66a3a667de17e779330fc0f20b0d97d59d2f2121e182b0505e4", size = 55847, upload-time = "2024-09-04T09:06:21.407Z" }, - { url = "https://files.pythonhosted.org/packages/91/84/32232502020bd78d1d12be7afde15811c64a95ed1f606c10456db4e4c3ac/kiwisolver-1.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:764202cc7e70f767dab49e8df52c7455e8de0df5d858fa801a11aa0d882ccf3f", size = 48494, upload-time = "2024-09-04T09:06:22.648Z" }, - { url = "https://files.pythonhosted.org/packages/ac/59/741b79775d67ab67ced9bb38552da688c0305c16e7ee24bba7a2be253fb7/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643", size = 59491, upload-time = "2024-09-04T09:06:24.188Z" }, - { url = "https://files.pythonhosted.org/packages/58/cc/fb239294c29a5656e99e3527f7369b174dd9cc7c3ef2dea7cb3c54a8737b/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706", size = 57648, upload-time = "2024-09-04T09:06:25.559Z" }, - { url = "https://files.pythonhosted.org/packages/3b/ef/2f009ac1f7aab9f81efb2d837301d255279d618d27b6015780115ac64bdd/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6", size = 84257, upload-time = "2024-09-04T09:06:27.038Z" }, - { url = "https://files.pythonhosted.org/packages/81/e1/c64f50987f85b68b1c52b464bb5bf73e71570c0f7782d626d1eb283ad620/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2", size = 80906, upload-time = "2024-09-04T09:06:28.48Z" }, - { url = "https://files.pythonhosted.org/packages/fd/71/1687c5c0a0be2cee39a5c9c389e546f9c6e215e46b691d00d9f646892083/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4", size = 79951, upload-time = "2024-09-04T09:06:29.966Z" }, - { url = "https://files.pythonhosted.org/packages/ea/8b/d7497df4a1cae9367adf21665dd1f896c2a7aeb8769ad77b662c5e2bcce7/kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a", size = 55715, upload-time = "2024-09-04T09:06:31.489Z" }, - { url = "https://files.pythonhosted.org/packages/d5/df/ce37d9b26f07ab90880923c94d12a6ff4d27447096b4c849bfc4339ccfdf/kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b01aac285f91ca889c800042c35ad3b239e704b150cfd3382adfc9dcc780e39", size = 58666, upload-time = "2024-09-04T09:06:43.756Z" }, - { url = "https://files.pythonhosted.org/packages/b0/d3/e4b04f43bc629ac8e186b77b2b1a251cdfa5b7610fa189dc0db622672ce6/kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48be928f59a1f5c8207154f935334d374e79f2b5d212826307d072595ad76a2e", size = 57088, upload-time = "2024-09-04T09:06:45.406Z" }, - { url = "https://files.pythonhosted.org/packages/30/1c/752df58e2d339e670a535514d2db4fe8c842ce459776b8080fbe08ebb98e/kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f37cfe618a117e50d8c240555331160d73d0411422b59b5ee217843d7b693608", size = 84321, upload-time = "2024-09-04T09:06:47.557Z" }, - { url = "https://files.pythonhosted.org/packages/f0/f8/fe6484e847bc6e238ec9f9828089fb2c0bb53f2f5f3a79351fde5b565e4f/kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599b5c873c63a1f6ed7eead644a8a380cfbdf5db91dcb6f85707aaab213b1674", size = 80776, upload-time = "2024-09-04T09:06:49.235Z" }, - { url = "https://files.pythonhosted.org/packages/9b/57/d7163c0379f250ef763aba85330a19feefb5ce6cb541ade853aaba881524/kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:801fa7802e5cfabe3ab0c81a34c323a319b097dfb5004be950482d882f3d7225", size = 79984, upload-time = "2024-09-04T09:06:51.336Z" }, - { url = "https://files.pythonhosted.org/packages/8c/95/4a103776c265d13b3d2cd24fb0494d4e04ea435a8ef97e1b2c026d43250b/kiwisolver-1.4.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0c6c43471bc764fad4bc99c5c2d6d16a676b1abf844ca7c8702bdae92df01ee0", size = 55811, upload-time = "2024-09-04T09:06:53.078Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/e8/5d/447af5ea094b9e4c4054f82e223ada074c552335b9b4b2d14bd9b35a67c4/joblib-1.5.2.tar.gz", hash = "sha256:3faa5c39054b2f03ca547da9b2f52fde67c06240c31853f306aea97f13647b55", size = 331077, upload-time = "2025-08-27T12:15:46.575Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/e8/685f47e0d754320684db4425a0967f7d3fa70126bffd76110b7009a0090f/joblib-1.5.2-py3-none-any.whl", hash = "sha256:4e1f0bdbb987e6d843c70cf43714cb276623def372df3c22fe5266b2670bc241", size = 308396, upload-time = "2025-08-27T12:15:45.188Z" }, ] [[package]] name = "kiwisolver" version = "1.4.9" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", - "python_full_version == '3.10.*'", -] sdist = { url = "https://files.pythonhosted.org/packages/5c/3c/85844f1b0feb11ee581ac23fe5fce65cd049a200c1446708cc1b7f922875/kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d", size = 97564, upload-time = "2025-08-10T21:27:49.279Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c6/5d/8ce64e36d4e3aac5ca96996457dcf33e34e6051492399a3f1fec5657f30b/kiwisolver-1.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b4b4d74bda2b8ebf4da5bd42af11d02d04428b2c32846e4c2c93219df8a7987b", size = 124159, upload-time = "2025-08-10T21:25:35.472Z" }, @@ -942,90 +824,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/70/a07dcf4f62598c8ad579df241af55ced65bed76e42e45d3c368a6d82dbc1/kombu-5.5.4-py3-none-any.whl", hash = "sha256:a12ed0557c238897d8e518f1d1fdf84bd1516c5e305af2dacd85c2015115feb8", size = 210034, upload-time = "2025-06-01T10:19:20.436Z" }, ] -[[package]] -name = "matplotlib" -version = "3.9.4" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "contourpy", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "cycler", marker = "python_full_version < '3.10'" }, - { name = "fonttools", marker = "python_full_version < '3.10'" }, - { name = "importlib-resources", marker = "python_full_version < '3.10'" }, - { name = "kiwisolver", version = "1.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "packaging", marker = "python_full_version < '3.10'" }, - { name = "pillow", version = "11.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pyparsing", marker = "python_full_version < '3.10'" }, - { name = "python-dateutil", marker = "python_full_version < '3.10'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/df/17/1747b4154034befd0ed33b52538f5eb7752d05bb51c5e2a31470c3bc7d52/matplotlib-3.9.4.tar.gz", hash = "sha256:1e00e8be7393cbdc6fedfa8a6fba02cf3e83814b285db1c60b906a023ba41bc3", size = 36106529, upload-time = "2024-12-13T05:56:34.184Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/94/27d2e2c30d54b56c7b764acc1874a909e34d1965a427fc7092bb6a588b63/matplotlib-3.9.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c5fdd7abfb706dfa8d307af64a87f1a862879ec3cd8d0ec8637458f0885b9c50", size = 7885089, upload-time = "2024-12-13T05:54:24.224Z" }, - { url = "https://files.pythonhosted.org/packages/c6/25/828273307e40a68eb8e9df832b6b2aaad075864fdc1de4b1b81e40b09e48/matplotlib-3.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d89bc4e85e40a71d1477780366c27fb7c6494d293e1617788986f74e2a03d7ff", size = 7770600, upload-time = "2024-12-13T05:54:27.214Z" }, - { url = "https://files.pythonhosted.org/packages/f2/65/f841a422ec994da5123368d76b126acf4fc02ea7459b6e37c4891b555b83/matplotlib-3.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddf9f3c26aae695c5daafbf6b94e4c1a30d6cd617ba594bbbded3b33a1fcfa26", size = 8200138, upload-time = "2024-12-13T05:54:29.497Z" }, - { url = "https://files.pythonhosted.org/packages/07/06/272aca07a38804d93b6050813de41ca7ab0e29ba7a9dd098e12037c919a9/matplotlib-3.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18ebcf248030173b59a868fda1fe42397253f6698995b55e81e1f57431d85e50", size = 8312711, upload-time = "2024-12-13T05:54:34.396Z" }, - { url = "https://files.pythonhosted.org/packages/98/37/f13e23b233c526b7e27ad61be0a771894a079e0f7494a10d8d81557e0e9a/matplotlib-3.9.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:974896ec43c672ec23f3f8c648981e8bc880ee163146e0312a9b8def2fac66f5", size = 9090622, upload-time = "2024-12-13T05:54:36.808Z" }, - { url = "https://files.pythonhosted.org/packages/4f/8c/b1f5bd2bd70e60f93b1b54c4d5ba7a992312021d0ddddf572f9a1a6d9348/matplotlib-3.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:4598c394ae9711cec135639374e70871fa36b56afae17bdf032a345be552a88d", size = 7828211, upload-time = "2024-12-13T05:54:40.596Z" }, - { url = "https://files.pythonhosted.org/packages/74/4b/65be7959a8fa118a3929b49a842de5b78bb55475236fcf64f3e308ff74a0/matplotlib-3.9.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d4dd29641d9fb8bc4492420c5480398dd40a09afd73aebe4eb9d0071a05fbe0c", size = 7894430, upload-time = "2024-12-13T05:54:44.049Z" }, - { url = "https://files.pythonhosted.org/packages/e9/18/80f70d91896e0a517b4a051c3fd540daa131630fd75e02e250365353b253/matplotlib-3.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30e5b22e8bcfb95442bf7d48b0d7f3bdf4a450cbf68986ea45fca3d11ae9d099", size = 7780045, upload-time = "2024-12-13T05:54:46.414Z" }, - { url = "https://files.pythonhosted.org/packages/a2/73/ccb381026e3238c5c25c3609ba4157b2d1a617ec98d65a8b4ee4e1e74d02/matplotlib-3.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bb0030d1d447fd56dcc23b4c64a26e44e898f0416276cac1ebc25522e0ac249", size = 8209906, upload-time = "2024-12-13T05:54:49.459Z" }, - { url = "https://files.pythonhosted.org/packages/ab/33/1648da77b74741c89f5ea95cbf42a291b4b364f2660b316318811404ed97/matplotlib-3.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aca90ed222ac3565d2752b83dbb27627480d27662671e4d39da72e97f657a423", size = 8322873, upload-time = "2024-12-13T05:54:53.066Z" }, - { url = "https://files.pythonhosted.org/packages/57/d3/8447ba78bc6593c9044c372d1609f8ea10fb1e071e7a9e0747bea74fc16c/matplotlib-3.9.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a181b2aa2906c608fcae72f977a4a2d76e385578939891b91c2550c39ecf361e", size = 9099566, upload-time = "2024-12-13T05:54:55.522Z" }, - { url = "https://files.pythonhosted.org/packages/23/e1/4f0e237bf349c02ff9d1b6e7109f1a17f745263809b9714a8576dc17752b/matplotlib-3.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:1f6882828231eca17f501c4dcd98a05abb3f03d157fbc0769c6911fe08b6cfd3", size = 7838065, upload-time = "2024-12-13T05:54:58.337Z" }, - { url = "https://files.pythonhosted.org/packages/1a/2b/c918bf6c19d6445d1cefe3d2e42cb740fb997e14ab19d4daeb6a7ab8a157/matplotlib-3.9.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dfc48d67e6661378a21c2983200a654b72b5c5cdbd5d2cf6e5e1ece860f0cc70", size = 7891131, upload-time = "2024-12-13T05:55:02.837Z" }, - { url = "https://files.pythonhosted.org/packages/c1/e5/b4e8fc601ca302afeeabf45f30e706a445c7979a180e3a978b78b2b681a4/matplotlib-3.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47aef0fab8332d02d68e786eba8113ffd6f862182ea2999379dec9e237b7e483", size = 7776365, upload-time = "2024-12-13T05:55:05.158Z" }, - { url = "https://files.pythonhosted.org/packages/99/06/b991886c506506476e5d83625c5970c656a491b9f80161458fed94597808/matplotlib-3.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fba1f52c6b7dc764097f52fd9ab627b90db452c9feb653a59945de16752e965f", size = 8200707, upload-time = "2024-12-13T05:55:09.48Z" }, - { url = "https://files.pythonhosted.org/packages/c3/e2/556b627498cb27e61026f2d1ba86a78ad1b836fef0996bef5440e8bc9559/matplotlib-3.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:173ac3748acaac21afcc3fa1633924609ba1b87749006bc25051c52c422a5d00", size = 8313761, upload-time = "2024-12-13T05:55:12.95Z" }, - { url = "https://files.pythonhosted.org/packages/58/ff/165af33ec766ff818306ea88e91f9f60d2a6ed543be1eb122a98acbf3b0d/matplotlib-3.9.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320edea0cadc07007765e33f878b13b3738ffa9745c5f707705692df70ffe0e0", size = 9095284, upload-time = "2024-12-13T05:55:16.199Z" }, - { url = "https://files.pythonhosted.org/packages/9f/8b/3d0c7a002db3b1ed702731c2a9a06d78d035f1f2fb0fb936a8e43cc1e9f4/matplotlib-3.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a4a4cfc82330b27042a7169533da7991e8789d180dd5b3daeaee57d75cd5a03b", size = 7841160, upload-time = "2024-12-13T05:55:19.991Z" }, - { url = "https://files.pythonhosted.org/packages/49/b1/999f89a7556d101b23a2f0b54f1b6e140d73f56804da1398f2f0bc0924bc/matplotlib-3.9.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:37eeffeeca3c940985b80f5b9a7b95ea35671e0e7405001f249848d2b62351b6", size = 7891499, upload-time = "2024-12-13T05:55:22.142Z" }, - { url = "https://files.pythonhosted.org/packages/87/7b/06a32b13a684977653396a1bfcd34d4e7539c5d55c8cbfaa8ae04d47e4a9/matplotlib-3.9.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3e7465ac859ee4abcb0d836137cd8414e7bb7ad330d905abced457217d4f0f45", size = 7776802, upload-time = "2024-12-13T05:55:25.947Z" }, - { url = "https://files.pythonhosted.org/packages/65/87/ac498451aff739e515891bbb92e566f3c7ef31891aaa878402a71f9b0910/matplotlib-3.9.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4c12302c34afa0cf061bea23b331e747e5e554b0fa595c96e01c7b75bc3b858", size = 8200802, upload-time = "2024-12-13T05:55:28.461Z" }, - { url = "https://files.pythonhosted.org/packages/f8/6b/9eb761c00e1cb838f6c92e5f25dcda3f56a87a52f6cb8fdfa561e6cf6a13/matplotlib-3.9.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b8c97917f21b75e72108b97707ba3d48f171541a74aa2a56df7a40626bafc64", size = 8313880, upload-time = "2024-12-13T05:55:30.965Z" }, - { url = "https://files.pythonhosted.org/packages/d7/a2/c8eaa600e2085eec7e38cbbcc58a30fc78f8224939d31d3152bdafc01fd1/matplotlib-3.9.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0229803bd7e19271b03cb09f27db76c918c467aa4ce2ae168171bc67c3f508df", size = 9094637, upload-time = "2024-12-13T05:55:33.701Z" }, - { url = "https://files.pythonhosted.org/packages/71/1f/c6e1daea55b7bfeb3d84c6cb1abc449f6a02b181e7e2a5e4db34c3afb793/matplotlib-3.9.4-cp313-cp313-win_amd64.whl", hash = "sha256:7c0d8ef442ebf56ff5e206f8083d08252ee738e04f3dc88ea882853a05488799", size = 7841311, upload-time = "2024-12-13T05:55:36.737Z" }, - { url = "https://files.pythonhosted.org/packages/c0/3a/2757d3f7d388b14dd48f5a83bea65b6d69f000e86b8f28f74d86e0d375bd/matplotlib-3.9.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a04c3b00066a688834356d196136349cb32f5e1003c55ac419e91585168b88fb", size = 7919989, upload-time = "2024-12-13T05:55:39.024Z" }, - { url = "https://files.pythonhosted.org/packages/24/28/f5077c79a4f521589a37fe1062d6a6ea3534e068213f7357e7cfffc2e17a/matplotlib-3.9.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:04c519587f6c210626741a1e9a68eefc05966ede24205db8982841826af5871a", size = 7809417, upload-time = "2024-12-13T05:55:42.412Z" }, - { url = "https://files.pythonhosted.org/packages/36/c8/c523fd2963156692916a8eb7d4069084cf729359f7955cf09075deddfeaf/matplotlib-3.9.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308afbf1a228b8b525fcd5cec17f246bbbb63b175a3ef6eb7b4d33287ca0cf0c", size = 8226258, upload-time = "2024-12-13T05:55:47.259Z" }, - { url = "https://files.pythonhosted.org/packages/f6/88/499bf4b8fa9349b6f5c0cf4cead0ebe5da9d67769129f1b5651e5ac51fbc/matplotlib-3.9.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb3b02246ddcffd3ce98e88fed5b238bc5faff10dbbaa42090ea13241d15764", size = 8335849, upload-time = "2024-12-13T05:55:49.763Z" }, - { url = "https://files.pythonhosted.org/packages/b8/9f/20a4156b9726188646a030774ee337d5ff695a965be45ce4dbcb9312c170/matplotlib-3.9.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8a75287e9cb9eee48cb79ec1d806f75b29c0fde978cb7223a1f4c5848d696041", size = 9102152, upload-time = "2024-12-13T05:55:51.997Z" }, - { url = "https://files.pythonhosted.org/packages/10/11/237f9c3a4e8d810b1759b67ff2da7c32c04f9c80aa475e7beb36ed43a8fb/matplotlib-3.9.4-cp313-cp313t-win_amd64.whl", hash = "sha256:488deb7af140f0ba86da003e66e10d55ff915e152c78b4b66d231638400b1965", size = 7896987, upload-time = "2024-12-13T05:55:55.941Z" }, - { url = "https://files.pythonhosted.org/packages/56/eb/501b465c9fef28f158e414ea3a417913dc2ac748564c7ed41535f23445b4/matplotlib-3.9.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3c3724d89a387ddf78ff88d2a30ca78ac2b4c89cf37f2db4bd453c34799e933c", size = 7885919, upload-time = "2024-12-13T05:55:59.66Z" }, - { url = "https://files.pythonhosted.org/packages/da/36/236fbd868b6c91309a5206bd90c3f881f4f44b2d997cd1d6239ef652f878/matplotlib-3.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d5f0a8430ffe23d7e32cfd86445864ccad141797f7d25b7c41759a5b5d17cfd7", size = 7771486, upload-time = "2024-12-13T05:56:04.264Z" }, - { url = "https://files.pythonhosted.org/packages/e0/4b/105caf2d54d5ed11d9f4335398f5103001a03515f2126c936a752ccf1461/matplotlib-3.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bb0141a21aef3b64b633dc4d16cbd5fc538b727e4958be82a0e1c92a234160e", size = 8201838, upload-time = "2024-12-13T05:56:06.792Z" }, - { url = "https://files.pythonhosted.org/packages/5d/a7/bb01188fb4013d34d274caf44a2f8091255b0497438e8b6c0a7c1710c692/matplotlib-3.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57aa235109e9eed52e2c2949db17da185383fa71083c00c6c143a60e07e0888c", size = 8314492, upload-time = "2024-12-13T05:56:09.964Z" }, - { url = "https://files.pythonhosted.org/packages/33/19/02e1a37f7141fc605b193e927d0a9cdf9dc124a20b9e68793f4ffea19695/matplotlib-3.9.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b18c600061477ccfdd1e6fd050c33d8be82431700f3452b297a56d9ed7037abb", size = 9092500, upload-time = "2024-12-13T05:56:13.55Z" }, - { url = "https://files.pythonhosted.org/packages/57/68/c2feb4667adbf882ffa4b3e0ac9967f848980d9f8b5bebd86644aa67ce6a/matplotlib-3.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:ef5f2d1b67d2d2145ff75e10f8c008bfbf71d45137c4b648c87193e7dd053eac", size = 7822962, upload-time = "2024-12-13T05:56:16.358Z" }, - { url = "https://files.pythonhosted.org/packages/0c/22/2ef6a364cd3f565442b0b055e0599744f1e4314ec7326cdaaa48a4d864d7/matplotlib-3.9.4-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:44e0ed786d769d85bc787b0606a53f2d8d2d1d3c8a2608237365e9121c1a338c", size = 7877995, upload-time = "2024-12-13T05:56:18.805Z" }, - { url = "https://files.pythonhosted.org/packages/87/b8/2737456e566e9f4d94ae76b8aa0d953d9acb847714f9a7ad80184474f5be/matplotlib-3.9.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:09debb9ce941eb23ecdbe7eab972b1c3e0276dcf01688073faff7b0f61d6c6ca", size = 7769300, upload-time = "2024-12-13T05:56:21.315Z" }, - { url = "https://files.pythonhosted.org/packages/b2/1f/e709c6ec7b5321e6568769baa288c7178e60a93a9da9e682b39450da0e29/matplotlib-3.9.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcc53cf157a657bfd03afab14774d54ba73aa84d42cfe2480c91bd94873952db", size = 8313423, upload-time = "2024-12-13T05:56:26.719Z" }, - { url = "https://files.pythonhosted.org/packages/5e/b6/5a1f868782cd13f053a679984e222007ecff654a9bfbac6b27a65f4eeb05/matplotlib-3.9.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ad45da51be7ad02387801fd154ef74d942f49fe3fcd26a64c94842ba7ec0d865", size = 7854624, upload-time = "2024-12-13T05:56:29.359Z" }, -] - [[package]] name = "matplotlib" version = "3.10.7" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", - "python_full_version == '3.10.*'", -] dependencies = [ - { name = "contourpy", version = "1.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, + { name = "contourpy", version = "1.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "contourpy", version = "1.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "cycler", marker = "python_full_version >= '3.10'" }, - { name = "fonttools", marker = "python_full_version >= '3.10'" }, - { name = "kiwisolver", version = "1.4.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, - { name = "numpy", version = "2.3.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "packaging", marker = "python_full_version >= '3.10'" }, - { name = "pillow", version = "12.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "pyparsing", marker = "python_full_version >= '3.10'" }, - { name = "python-dateutil", marker = "python_full_version >= '3.10'" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ae/e2/d2d5295be2f44c678ebaf3544ba32d20c1f9ef08c49fe47f496180e1db15/matplotlib-3.10.7.tar.gz", hash = "sha256:a06ba7e2a2ef9131c79c49e63dad355d2d878413a0376c1727c8b9335ff731c7", size = 34804865, upload-time = "2025-10-09T00:28:00.669Z" } wheels = [ @@ -1086,208 +899,98 @@ wheels = [ ] [[package]] -name = "numpy" -version = "2.0.2" +name = "mypy" +version = "1.18.2" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -sdist = { url = "https://files.pythonhosted.org/packages/a9/75/10dd1f8116a8b796cb2c737b674e02d02e80454bda953fa7e65d8c12b016/numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78", size = 18902015, upload-time = "2024-08-26T20:19:40.945Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/21/91/3495b3237510f79f5d81f2508f9f13fea78ebfdf07538fc7444badda173d/numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece", size = 21165245, upload-time = "2024-08-26T20:04:14.625Z" }, - { url = "https://files.pythonhosted.org/packages/05/33/26178c7d437a87082d11019292dce6d3fe6f0e9026b7b2309cbf3e489b1d/numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04", size = 13738540, upload-time = "2024-08-26T20:04:36.784Z" }, - { url = "https://files.pythonhosted.org/packages/ec/31/cc46e13bf07644efc7a4bf68df2df5fb2a1a88d0cd0da9ddc84dc0033e51/numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66", size = 5300623, upload-time = "2024-08-26T20:04:46.491Z" }, - { url = "https://files.pythonhosted.org/packages/6e/16/7bfcebf27bb4f9d7ec67332ffebee4d1bf085c84246552d52dbb548600e7/numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b", size = 6901774, upload-time = "2024-08-26T20:04:58.173Z" }, - { url = "https://files.pythonhosted.org/packages/f9/a3/561c531c0e8bf082c5bef509d00d56f82e0ea7e1e3e3a7fc8fa78742a6e5/numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd", size = 13907081, upload-time = "2024-08-26T20:05:19.098Z" }, - { url = "https://files.pythonhosted.org/packages/fa/66/f7177ab331876200ac7563a580140643d1179c8b4b6a6b0fc9838de2a9b8/numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318", size = 19523451, upload-time = "2024-08-26T20:05:47.479Z" }, - { url = "https://files.pythonhosted.org/packages/25/7f/0b209498009ad6453e4efc2c65bcdf0ae08a182b2b7877d7ab38a92dc542/numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8", size = 19927572, upload-time = "2024-08-26T20:06:17.137Z" }, - { url = "https://files.pythonhosted.org/packages/3e/df/2619393b1e1b565cd2d4c4403bdd979621e2c4dea1f8532754b2598ed63b/numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326", size = 14400722, upload-time = "2024-08-26T20:06:39.16Z" }, - { url = "https://files.pythonhosted.org/packages/22/ad/77e921b9f256d5da36424ffb711ae79ca3f451ff8489eeca544d0701d74a/numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97", size = 6472170, upload-time = "2024-08-26T20:06:50.361Z" }, - { url = "https://files.pythonhosted.org/packages/10/05/3442317535028bc29cf0c0dd4c191a4481e8376e9f0db6bcf29703cadae6/numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131", size = 15905558, upload-time = "2024-08-26T20:07:13.881Z" }, - { url = "https://files.pythonhosted.org/packages/8b/cf/034500fb83041aa0286e0fb16e7c76e5c8b67c0711bb6e9e9737a717d5fe/numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448", size = 21169137, upload-time = "2024-08-26T20:07:45.345Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d9/32de45561811a4b87fbdee23b5797394e3d1504b4a7cf40c10199848893e/numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195", size = 13703552, upload-time = "2024-08-26T20:08:06.666Z" }, - { url = "https://files.pythonhosted.org/packages/c1/ca/2f384720020c7b244d22508cb7ab23d95f179fcfff33c31a6eeba8d6c512/numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57", size = 5298957, upload-time = "2024-08-26T20:08:15.83Z" }, - { url = "https://files.pythonhosted.org/packages/0e/78/a3e4f9fb6aa4e6fdca0c5428e8ba039408514388cf62d89651aade838269/numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a", size = 6905573, upload-time = "2024-08-26T20:08:27.185Z" }, - { url = "https://files.pythonhosted.org/packages/a0/72/cfc3a1beb2caf4efc9d0b38a15fe34025230da27e1c08cc2eb9bfb1c7231/numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669", size = 13914330, upload-time = "2024-08-26T20:08:48.058Z" }, - { url = "https://files.pythonhosted.org/packages/ba/a8/c17acf65a931ce551fee11b72e8de63bf7e8a6f0e21add4c937c83563538/numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951", size = 19534895, upload-time = "2024-08-26T20:09:16.536Z" }, - { url = "https://files.pythonhosted.org/packages/ba/86/8767f3d54f6ae0165749f84648da9dcc8cd78ab65d415494962c86fac80f/numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9", size = 19937253, upload-time = "2024-08-26T20:09:46.263Z" }, - { url = "https://files.pythonhosted.org/packages/df/87/f76450e6e1c14e5bb1eae6836478b1028e096fd02e85c1c37674606ab752/numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15", size = 14414074, upload-time = "2024-08-26T20:10:08.483Z" }, - { url = "https://files.pythonhosted.org/packages/5c/ca/0f0f328e1e59f73754f06e1adfb909de43726d4f24c6a3f8805f34f2b0fa/numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4", size = 6470640, upload-time = "2024-08-26T20:10:19.732Z" }, - { url = "https://files.pythonhosted.org/packages/eb/57/3a3f14d3a759dcf9bf6e9eda905794726b758819df4663f217d658a58695/numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc", size = 15910230, upload-time = "2024-08-26T20:10:43.413Z" }, - { url = "https://files.pythonhosted.org/packages/45/40/2e117be60ec50d98fa08c2f8c48e09b3edea93cfcabd5a9ff6925d54b1c2/numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b", size = 20895803, upload-time = "2024-08-26T20:11:13.916Z" }, - { url = "https://files.pythonhosted.org/packages/46/92/1b8b8dee833f53cef3e0a3f69b2374467789e0bb7399689582314df02651/numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e", size = 13471835, upload-time = "2024-08-26T20:11:34.779Z" }, - { url = "https://files.pythonhosted.org/packages/7f/19/e2793bde475f1edaea6945be141aef6c8b4c669b90c90a300a8954d08f0a/numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c", size = 5038499, upload-time = "2024-08-26T20:11:43.902Z" }, - { url = "https://files.pythonhosted.org/packages/e3/ff/ddf6dac2ff0dd50a7327bcdba45cb0264d0e96bb44d33324853f781a8f3c/numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c", size = 6633497, upload-time = "2024-08-26T20:11:55.09Z" }, - { url = "https://files.pythonhosted.org/packages/72/21/67f36eac8e2d2cd652a2e69595a54128297cdcb1ff3931cfc87838874bd4/numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692", size = 13621158, upload-time = "2024-08-26T20:12:14.95Z" }, - { url = "https://files.pythonhosted.org/packages/39/68/e9f1126d757653496dbc096cb429014347a36b228f5a991dae2c6b6cfd40/numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a", size = 19236173, upload-time = "2024-08-26T20:12:44.049Z" }, - { url = "https://files.pythonhosted.org/packages/d1/e9/1f5333281e4ebf483ba1c888b1d61ba7e78d7e910fdd8e6499667041cc35/numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c", size = 19634174, upload-time = "2024-08-26T20:13:13.634Z" }, - { url = "https://files.pythonhosted.org/packages/71/af/a469674070c8d8408384e3012e064299f7a2de540738a8e414dcfd639996/numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded", size = 14099701, upload-time = "2024-08-26T20:13:34.851Z" }, - { url = "https://files.pythonhosted.org/packages/d0/3d/08ea9f239d0e0e939b6ca52ad403c84a2bce1bde301a8eb4888c1c1543f1/numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5", size = 6174313, upload-time = "2024-08-26T20:13:45.653Z" }, - { url = "https://files.pythonhosted.org/packages/b2/b5/4ac39baebf1fdb2e72585c8352c56d063b6126be9fc95bd2bb5ef5770c20/numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a", size = 15606179, upload-time = "2024-08-26T20:14:08.786Z" }, - { url = "https://files.pythonhosted.org/packages/43/c1/41c8f6df3162b0c6ffd4437d729115704bd43363de0090c7f913cfbc2d89/numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c", size = 21169942, upload-time = "2024-08-26T20:14:40.108Z" }, - { url = "https://files.pythonhosted.org/packages/39/bc/fd298f308dcd232b56a4031fd6ddf11c43f9917fbc937e53762f7b5a3bb1/numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd", size = 13711512, upload-time = "2024-08-26T20:15:00.985Z" }, - { url = "https://files.pythonhosted.org/packages/96/ff/06d1aa3eeb1c614eda245c1ba4fb88c483bee6520d361641331872ac4b82/numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b", size = 5306976, upload-time = "2024-08-26T20:15:10.876Z" }, - { url = "https://files.pythonhosted.org/packages/2d/98/121996dcfb10a6087a05e54453e28e58694a7db62c5a5a29cee14c6e047b/numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729", size = 6906494, upload-time = "2024-08-26T20:15:22.055Z" }, - { url = "https://files.pythonhosted.org/packages/15/31/9dffc70da6b9bbf7968f6551967fc21156207366272c2a40b4ed6008dc9b/numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1", size = 13912596, upload-time = "2024-08-26T20:15:42.452Z" }, - { url = "https://files.pythonhosted.org/packages/b9/14/78635daab4b07c0930c919d451b8bf8c164774e6a3413aed04a6d95758ce/numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd", size = 19526099, upload-time = "2024-08-26T20:16:11.048Z" }, - { url = "https://files.pythonhosted.org/packages/26/4c/0eeca4614003077f68bfe7aac8b7496f04221865b3a5e7cb230c9d055afd/numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d", size = 19932823, upload-time = "2024-08-26T20:16:40.171Z" }, - { url = "https://files.pythonhosted.org/packages/f1/46/ea25b98b13dccaebddf1a803f8c748680d972e00507cd9bc6dcdb5aa2ac1/numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d", size = 14404424, upload-time = "2024-08-26T20:17:02.604Z" }, - { url = "https://files.pythonhosted.org/packages/c8/a6/177dd88d95ecf07e722d21008b1b40e681a929eb9e329684d449c36586b2/numpy-2.0.2-cp39-cp39-win32.whl", hash = "sha256:905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa", size = 6476809, upload-time = "2024-08-26T20:17:13.553Z" }, - { url = "https://files.pythonhosted.org/packages/ea/2b/7fc9f4e7ae5b507c1a3a21f0f15ed03e794c1242ea8a242ac158beb56034/numpy-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73", size = 15911314, upload-time = "2024-08-26T20:17:36.72Z" }, - { url = "https://files.pythonhosted.org/packages/8f/3b/df5a870ac6a3be3a86856ce195ef42eec7ae50d2a202be1f5a4b3b340e14/numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8", size = 21025288, upload-time = "2024-08-26T20:18:07.732Z" }, - { url = "https://files.pythonhosted.org/packages/2c/97/51af92f18d6f6f2d9ad8b482a99fb74e142d71372da5d834b3a2747a446e/numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4", size = 6762793, upload-time = "2024-08-26T20:18:19.125Z" }, - { url = "https://files.pythonhosted.org/packages/12/46/de1fbd0c1b5ccaa7f9a005b66761533e2f6a3e560096682683a223631fe9/numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c", size = 19334885, upload-time = "2024-08-26T20:18:47.237Z" }, - { url = "https://files.pythonhosted.org/packages/cc/dc/d330a6faefd92b446ec0f0dfea4c3207bb1fef3c4771d19cf4543efd2c78/numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385", size = 15828784, upload-time = "2024-08-26T20:19:11.19Z" }, +dependencies = [ + { 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" } +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" }, ] [[package]] -name = "numpy" -version = "2.2.6" +name = "mypy-extensions" +version = "1.1.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version == '3.10.*'", -] -sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, - { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, - { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, - { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, - { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, - { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, - { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, - { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, - { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, - { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, - { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, - { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, - { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, - { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, - { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, - { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, - { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, - { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, - { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, - { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, - { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, - { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, - { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, - { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, - { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, - { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, - { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, - { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, - { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, - { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, - { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, - { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, - { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, - { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, - { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, - { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, - { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, - { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, - { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, - { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, - { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, - { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, - { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, - { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, - { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, - { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, - { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, - { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, - { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, - { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, - { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] [[package]] -name = "numpy" -version = "2.3.4" +name = "nodeenv" +version = "1.9.1" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b5/f4/098d2270d52b41f1bd7db9fc288aaa0400cb48c2a3e2af6fa365d9720947/numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a", size = 20582187, upload-time = "2025-10-15T16:18:11.77Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/60/e7/0e07379944aa8afb49a556a2b54587b828eb41dc9adc56fb7615b678ca53/numpy-2.3.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e78aecd2800b32e8347ce49316d3eaf04aed849cd5b38e0af39f829a4e59f5eb", size = 21259519, upload-time = "2025-10-15T16:15:19.012Z" }, - { url = "https://files.pythonhosted.org/packages/d0/cb/5a69293561e8819b09e34ed9e873b9a82b5f2ade23dce4c51dc507f6cfe1/numpy-2.3.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7fd09cc5d65bda1e79432859c40978010622112e9194e581e3415a3eccc7f43f", size = 14452796, upload-time = "2025-10-15T16:15:23.094Z" }, - { url = "https://files.pythonhosted.org/packages/e4/04/ff11611200acd602a1e5129e36cfd25bf01ad8e5cf927baf2e90236eb02e/numpy-2.3.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:1b219560ae2c1de48ead517d085bc2d05b9433f8e49d0955c82e8cd37bd7bf36", size = 5381639, upload-time = "2025-10-15T16:15:25.572Z" }, - { url = "https://files.pythonhosted.org/packages/ea/77/e95c757a6fe7a48d28a009267408e8aa382630cc1ad1db7451b3bc21dbb4/numpy-2.3.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:bafa7d87d4c99752d07815ed7a2c0964f8ab311eb8168f41b910bd01d15b6032", size = 6914296, upload-time = "2025-10-15T16:15:27.079Z" }, - { url = "https://files.pythonhosted.org/packages/a3/d2/137c7b6841c942124eae921279e5c41b1c34bab0e6fc60c7348e69afd165/numpy-2.3.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36dc13af226aeab72b7abad501d370d606326a0029b9f435eacb3b8c94b8a8b7", size = 14591904, upload-time = "2025-10-15T16:15:29.044Z" }, - { url = "https://files.pythonhosted.org/packages/bb/32/67e3b0f07b0aba57a078c4ab777a9e8e6bc62f24fb53a2337f75f9691699/numpy-2.3.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7b2f9a18b5ff9824a6af80de4f37f4ec3c2aab05ef08f51c77a093f5b89adda", size = 16939602, upload-time = "2025-10-15T16:15:31.106Z" }, - { url = "https://files.pythonhosted.org/packages/95/22/9639c30e32c93c4cee3ccdb4b09c2d0fbff4dcd06d36b357da06146530fb/numpy-2.3.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9984bd645a8db6ca15d850ff996856d8762c51a2239225288f08f9050ca240a0", size = 16372661, upload-time = "2025-10-15T16:15:33.546Z" }, - { url = "https://files.pythonhosted.org/packages/12/e9/a685079529be2b0156ae0c11b13d6be647743095bb51d46589e95be88086/numpy-2.3.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:64c5825affc76942973a70acf438a8ab618dbd692b84cd5ec40a0a0509edc09a", size = 18884682, upload-time = "2025-10-15T16:15:36.105Z" }, - { url = "https://files.pythonhosted.org/packages/cf/85/f6f00d019b0cc741e64b4e00ce865a57b6bed945d1bbeb1ccadbc647959b/numpy-2.3.4-cp311-cp311-win32.whl", hash = "sha256:ed759bf7a70342f7817d88376eb7142fab9fef8320d6019ef87fae05a99874e1", size = 6570076, upload-time = "2025-10-15T16:15:38.225Z" }, - { url = "https://files.pythonhosted.org/packages/7d/10/f8850982021cb90e2ec31990291f9e830ce7d94eef432b15066e7cbe0bec/numpy-2.3.4-cp311-cp311-win_amd64.whl", hash = "sha256:faba246fb30ea2a526c2e9645f61612341de1a83fb1e0c5edf4ddda5a9c10996", size = 13089358, upload-time = "2025-10-15T16:15:40.404Z" }, - { url = "https://files.pythonhosted.org/packages/d1/ad/afdd8351385edf0b3445f9e24210a9c3971ef4de8fd85155462fc4321d79/numpy-2.3.4-cp311-cp311-win_arm64.whl", hash = "sha256:4c01835e718bcebe80394fd0ac66c07cbb90147ebbdad3dcecd3f25de2ae7e2c", size = 10462292, upload-time = "2025-10-15T16:15:42.896Z" }, - { url = "https://files.pythonhosted.org/packages/96/7a/02420400b736f84317e759291b8edaeee9dc921f72b045475a9cbdb26b17/numpy-2.3.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ef1b5a3e808bc40827b5fa2c8196151a4c5abe110e1726949d7abddfe5c7ae11", size = 20957727, upload-time = "2025-10-15T16:15:44.9Z" }, - { url = "https://files.pythonhosted.org/packages/18/90/a014805d627aa5750f6f0e878172afb6454552da929144b3c07fcae1bb13/numpy-2.3.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2f91f496a87235c6aaf6d3f3d89b17dba64996abadccb289f48456cff931ca9", size = 14187262, upload-time = "2025-10-15T16:15:47.761Z" }, - { url = "https://files.pythonhosted.org/packages/c7/e4/0a94b09abe89e500dc748e7515f21a13e30c5c3fe3396e6d4ac108c25fca/numpy-2.3.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f77e5b3d3da652b474cc80a14084927a5e86a5eccf54ca8ca5cbd697bf7f2667", size = 5115992, upload-time = "2025-10-15T16:15:50.144Z" }, - { url = "https://files.pythonhosted.org/packages/88/dd/db77c75b055c6157cbd4f9c92c4458daef0dd9cbe6d8d2fe7f803cb64c37/numpy-2.3.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:8ab1c5f5ee40d6e01cbe96de5863e39b215a4d24e7d007cad56c7184fdf4aeef", size = 6648672, upload-time = "2025-10-15T16:15:52.442Z" }, - { url = "https://files.pythonhosted.org/packages/e1/e6/e31b0d713719610e406c0ea3ae0d90760465b086da8783e2fd835ad59027/numpy-2.3.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77b84453f3adcb994ddbd0d1c5d11db2d6bda1a2b7fd5ac5bd4649d6f5dc682e", size = 14284156, upload-time = "2025-10-15T16:15:54.351Z" }, - { url = "https://files.pythonhosted.org/packages/f9/58/30a85127bfee6f108282107caf8e06a1f0cc997cb6b52cdee699276fcce4/numpy-2.3.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4121c5beb58a7f9e6dfdee612cb24f4df5cd4db6e8261d7f4d7450a997a65d6a", size = 16641271, upload-time = "2025-10-15T16:15:56.67Z" }, - { url = "https://files.pythonhosted.org/packages/06/f2/2e06a0f2adf23e3ae29283ad96959267938d0efd20a2e25353b70065bfec/numpy-2.3.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65611ecbb00ac9846efe04db15cbe6186f562f6bb7e5e05f077e53a599225d16", size = 16059531, upload-time = "2025-10-15T16:15:59.412Z" }, - { url = "https://files.pythonhosted.org/packages/b0/e7/b106253c7c0d5dc352b9c8fab91afd76a93950998167fa3e5afe4ef3a18f/numpy-2.3.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dabc42f9c6577bcc13001b8810d300fe814b4cfbe8a92c873f269484594f9786", size = 18578983, upload-time = "2025-10-15T16:16:01.804Z" }, - { url = "https://files.pythonhosted.org/packages/73/e3/04ecc41e71462276ee867ccbef26a4448638eadecf1bc56772c9ed6d0255/numpy-2.3.4-cp312-cp312-win32.whl", hash = "sha256:a49d797192a8d950ca59ee2d0337a4d804f713bb5c3c50e8db26d49666e351dc", size = 6291380, upload-time = "2025-10-15T16:16:03.938Z" }, - { url = "https://files.pythonhosted.org/packages/3d/a8/566578b10d8d0e9955b1b6cd5db4e9d4592dd0026a941ff7994cedda030a/numpy-2.3.4-cp312-cp312-win_amd64.whl", hash = "sha256:985f1e46358f06c2a09921e8921e2c98168ed4ae12ccd6e5e87a4f1857923f32", size = 12787999, upload-time = "2025-10-15T16:16:05.801Z" }, - { url = "https://files.pythonhosted.org/packages/58/22/9c903a957d0a8071b607f5b1bff0761d6e608b9a965945411f867d515db1/numpy-2.3.4-cp312-cp312-win_arm64.whl", hash = "sha256:4635239814149e06e2cb9db3dd584b2fa64316c96f10656983b8026a82e6e4db", size = 10197412, upload-time = "2025-10-15T16:16:07.854Z" }, - { url = "https://files.pythonhosted.org/packages/57/7e/b72610cc91edf138bc588df5150957a4937221ca6058b825b4725c27be62/numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966", size = 20950335, upload-time = "2025-10-15T16:16:10.304Z" }, - { url = "https://files.pythonhosted.org/packages/3e/46/bdd3370dcea2f95ef14af79dbf81e6927102ddf1cc54adc0024d61252fd9/numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3", size = 14179878, upload-time = "2025-10-15T16:16:12.595Z" }, - { url = "https://files.pythonhosted.org/packages/ac/01/5a67cb785bda60f45415d09c2bc245433f1c68dd82eef9c9002c508b5a65/numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197", size = 5108673, upload-time = "2025-10-15T16:16:14.877Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cd/8428e23a9fcebd33988f4cb61208fda832800ca03781f471f3727a820704/numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e", size = 6641438, upload-time = "2025-10-15T16:16:16.805Z" }, - { url = "https://files.pythonhosted.org/packages/3e/d1/913fe563820f3c6b079f992458f7331278dcd7ba8427e8e745af37ddb44f/numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7", size = 14281290, upload-time = "2025-10-15T16:16:18.764Z" }, - { url = "https://files.pythonhosted.org/packages/9e/7e/7d306ff7cb143e6d975cfa7eb98a93e73495c4deabb7d1b5ecf09ea0fd69/numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953", size = 16636543, upload-time = "2025-10-15T16:16:21.072Z" }, - { url = "https://files.pythonhosted.org/packages/47/6a/8cfc486237e56ccfb0db234945552a557ca266f022d281a2f577b98e955c/numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37", size = 16056117, upload-time = "2025-10-15T16:16:23.369Z" }, - { url = "https://files.pythonhosted.org/packages/b1/0e/42cb5e69ea901e06ce24bfcc4b5664a56f950a70efdcf221f30d9615f3f3/numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd", size = 18577788, upload-time = "2025-10-15T16:16:27.496Z" }, - { url = "https://files.pythonhosted.org/packages/86/92/41c3d5157d3177559ef0a35da50f0cda7fa071f4ba2306dd36818591a5bc/numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646", size = 6282620, upload-time = "2025-10-15T16:16:29.811Z" }, - { url = "https://files.pythonhosted.org/packages/09/97/fd421e8bc50766665ad35536c2bb4ef916533ba1fdd053a62d96cc7c8b95/numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d", size = 12784672, upload-time = "2025-10-15T16:16:31.589Z" }, - { url = "https://files.pythonhosted.org/packages/ad/df/5474fb2f74970ca8eb978093969b125a84cc3d30e47f82191f981f13a8a0/numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc", size = 10196702, upload-time = "2025-10-15T16:16:33.902Z" }, - { url = "https://files.pythonhosted.org/packages/11/83/66ac031464ec1767ea3ed48ce40f615eb441072945e98693bec0bcd056cc/numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879", size = 21049003, upload-time = "2025-10-15T16:16:36.101Z" }, - { url = "https://files.pythonhosted.org/packages/5f/99/5b14e0e686e61371659a1d5bebd04596b1d72227ce36eed121bb0aeab798/numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562", size = 14302980, upload-time = "2025-10-15T16:16:39.124Z" }, - { url = "https://files.pythonhosted.org/packages/2c/44/e9486649cd087d9fc6920e3fc3ac2aba10838d10804b1e179fb7cbc4e634/numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a", size = 5231472, upload-time = "2025-10-15T16:16:41.168Z" }, - { url = "https://files.pythonhosted.org/packages/3e/51/902b24fa8887e5fe2063fd61b1895a476d0bbf46811ab0c7fdf4bd127345/numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6", size = 6739342, upload-time = "2025-10-15T16:16:43.777Z" }, - { url = "https://files.pythonhosted.org/packages/34/f1/4de9586d05b1962acdcdb1dc4af6646361a643f8c864cef7c852bf509740/numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7", size = 14354338, upload-time = "2025-10-15T16:16:46.081Z" }, - { url = "https://files.pythonhosted.org/packages/1f/06/1c16103b425de7969d5a76bdf5ada0804b476fed05d5f9e17b777f1cbefd/numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0", size = 16702392, upload-time = "2025-10-15T16:16:48.455Z" }, - { url = "https://files.pythonhosted.org/packages/34/b2/65f4dc1b89b5322093572b6e55161bb42e3e0487067af73627f795cc9d47/numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f", size = 16134998, upload-time = "2025-10-15T16:16:51.114Z" }, - { url = "https://files.pythonhosted.org/packages/d4/11/94ec578896cdb973aaf56425d6c7f2aff4186a5c00fac15ff2ec46998b46/numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64", size = 18651574, upload-time = "2025-10-15T16:16:53.429Z" }, - { url = "https://files.pythonhosted.org/packages/62/b7/7efa763ab33dbccf56dade36938a77345ce8e8192d6b39e470ca25ff3cd0/numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb", size = 6413135, upload-time = "2025-10-15T16:16:55.992Z" }, - { url = "https://files.pythonhosted.org/packages/43/70/aba4c38e8400abcc2f345e13d972fb36c26409b3e644366db7649015f291/numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c", size = 12928582, upload-time = "2025-10-15T16:16:57.943Z" }, - { url = "https://files.pythonhosted.org/packages/67/63/871fad5f0073fc00fbbdd7232962ea1ac40eeaae2bba66c76214f7954236/numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40", size = 10266691, upload-time = "2025-10-15T16:17:00.048Z" }, - { url = "https://files.pythonhosted.org/packages/72/71/ae6170143c115732470ae3a2d01512870dd16e0953f8a6dc89525696069b/numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e", size = 20955580, upload-time = "2025-10-15T16:17:02.509Z" }, - { url = "https://files.pythonhosted.org/packages/af/39/4be9222ffd6ca8a30eda033d5f753276a9c3426c397bb137d8e19dedd200/numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff", size = 14188056, upload-time = "2025-10-15T16:17:04.873Z" }, - { url = "https://files.pythonhosted.org/packages/6c/3d/d85f6700d0a4aa4f9491030e1021c2b2b7421b2b38d01acd16734a2bfdc7/numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f", size = 5116555, upload-time = "2025-10-15T16:17:07.499Z" }, - { url = "https://files.pythonhosted.org/packages/bf/04/82c1467d86f47eee8a19a464c92f90a9bb68ccf14a54c5224d7031241ffb/numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b", size = 6643581, upload-time = "2025-10-15T16:17:09.774Z" }, - { url = "https://files.pythonhosted.org/packages/0c/d3/c79841741b837e293f48bd7db89d0ac7a4f2503b382b78a790ef1dc778a5/numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7", size = 14299186, upload-time = "2025-10-15T16:17:11.937Z" }, - { url = "https://files.pythonhosted.org/packages/e8/7e/4a14a769741fbf237eec5a12a2cbc7a4c4e061852b6533bcb9e9a796c908/numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2", size = 16638601, upload-time = "2025-10-15T16:17:14.391Z" }, - { url = "https://files.pythonhosted.org/packages/93/87/1c1de269f002ff0a41173fe01dcc925f4ecff59264cd8f96cf3b60d12c9b/numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52", size = 16074219, upload-time = "2025-10-15T16:17:17.058Z" }, - { url = "https://files.pythonhosted.org/packages/cd/28/18f72ee77408e40a76d691001ae599e712ca2a47ddd2c4f695b16c65f077/numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26", size = 18576702, upload-time = "2025-10-15T16:17:19.379Z" }, - { url = "https://files.pythonhosted.org/packages/c3/76/95650169b465ececa8cf4b2e8f6df255d4bf662775e797ade2025cc51ae6/numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc", size = 6337136, upload-time = "2025-10-15T16:17:22.886Z" }, - { url = "https://files.pythonhosted.org/packages/dc/89/a231a5c43ede5d6f77ba4a91e915a87dea4aeea76560ba4d2bf185c683f0/numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9", size = 12920542, upload-time = "2025-10-15T16:17:24.783Z" }, - { url = "https://files.pythonhosted.org/packages/0d/0c/ae9434a888f717c5ed2ff2393b3f344f0ff6f1c793519fa0c540461dc530/numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868", size = 10480213, upload-time = "2025-10-15T16:17:26.935Z" }, - { url = "https://files.pythonhosted.org/packages/83/4b/c4a5f0841f92536f6b9592694a5b5f68c9ab37b775ff342649eadf9055d3/numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec", size = 21052280, upload-time = "2025-10-15T16:17:29.638Z" }, - { url = "https://files.pythonhosted.org/packages/3e/80/90308845fc93b984d2cc96d83e2324ce8ad1fd6efea81b324cba4b673854/numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3", size = 14302930, upload-time = "2025-10-15T16:17:32.384Z" }, - { url = "https://files.pythonhosted.org/packages/3d/4e/07439f22f2a3b247cec4d63a713faae55e1141a36e77fb212881f7cda3fb/numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365", size = 5231504, upload-time = "2025-10-15T16:17:34.515Z" }, - { url = "https://files.pythonhosted.org/packages/ab/de/1e11f2547e2fe3d00482b19721855348b94ada8359aef5d40dd57bfae9df/numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252", size = 6739405, upload-time = "2025-10-15T16:17:36.128Z" }, - { url = "https://files.pythonhosted.org/packages/3b/40/8cd57393a26cebe2e923005db5134a946c62fa56a1087dc7c478f3e30837/numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e", size = 14354866, upload-time = "2025-10-15T16:17:38.884Z" }, - { url = "https://files.pythonhosted.org/packages/93/39/5b3510f023f96874ee6fea2e40dfa99313a00bf3ab779f3c92978f34aace/numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0", size = 16703296, upload-time = "2025-10-15T16:17:41.564Z" }, - { url = "https://files.pythonhosted.org/packages/41/0d/19bb163617c8045209c1996c4e427bccbc4bbff1e2c711f39203c8ddbb4a/numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0", size = 16136046, upload-time = "2025-10-15T16:17:43.901Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c1/6dba12fdf68b02a21ac411c9df19afa66bed2540f467150ca64d246b463d/numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f", size = 18652691, upload-time = "2025-10-15T16:17:46.247Z" }, - { url = "https://files.pythonhosted.org/packages/f8/73/f85056701dbbbb910c51d846c58d29fd46b30eecd2b6ba760fc8b8a1641b/numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d", size = 6485782, upload-time = "2025-10-15T16:17:48.872Z" }, - { url = "https://files.pythonhosted.org/packages/17/90/28fa6f9865181cb817c2471ee65678afa8a7e2a1fb16141473d5fa6bacc3/numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6", size = 13113301, upload-time = "2025-10-15T16:17:50.938Z" }, - { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532, upload-time = "2025-10-15T16:17:53.48Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b6/64898f51a86ec88ca1257a59c1d7fd077b60082a119affefcdf1dd0df8ca/numpy-2.3.4-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6e274603039f924c0fe5cb73438fa9246699c78a6df1bd3decef9ae592ae1c05", size = 21131552, upload-time = "2025-10-15T16:17:55.845Z" }, - { url = "https://files.pythonhosted.org/packages/ce/4c/f135dc6ebe2b6a3c77f4e4838fa63d350f85c99462012306ada1bd4bc460/numpy-2.3.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d149aee5c72176d9ddbc6803aef9c0f6d2ceeea7626574fc68518da5476fa346", size = 14377796, upload-time = "2025-10-15T16:17:58.308Z" }, - { url = "https://files.pythonhosted.org/packages/d0/a4/f33f9c23fcc13dd8412fc8614559b5b797e0aba9d8e01dfa8bae10c84004/numpy-2.3.4-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:6d34ed9db9e6395bb6cd33286035f73a59b058169733a9db9f85e650b88df37e", size = 5306904, upload-time = "2025-10-15T16:18:00.596Z" }, - { url = "https://files.pythonhosted.org/packages/28/af/c44097f25f834360f9fb960fa082863e0bad14a42f36527b2a121abdec56/numpy-2.3.4-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:fdebe771ca06bb8d6abce84e51dca9f7921fe6ad34a0c914541b063e9a68928b", size = 6819682, upload-time = "2025-10-15T16:18:02.32Z" }, - { url = "https://files.pythonhosted.org/packages/c5/8c/cd283b54c3c2b77e188f63e23039844f56b23bba1712318288c13fe86baf/numpy-2.3.4-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e92defe6c08211eb77902253b14fe5b480ebc5112bc741fd5e9cd0608f847", size = 14422300, upload-time = "2025-10-15T16:18:04.271Z" }, - { url = "https://files.pythonhosted.org/packages/b0/f0/8404db5098d92446b3e3695cf41c6f0ecb703d701cb0b7566ee2177f2eee/numpy-2.3.4-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13b9062e4f5c7ee5c7e5be96f29ba71bc5a37fed3d1d77c37390ae00724d296d", size = 16760806, upload-time = "2025-10-15T16:18:06.668Z" }, - { url = "https://files.pythonhosted.org/packages/95/8e/2844c3959ce9a63acc7c8e50881133d86666f0420bcde695e115ced0920f/numpy-2.3.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:81b3a59793523e552c4a96109dde028aa4448ae06ccac5a76ff6532a85558a7f", size = 12973130, upload-time = "2025-10-15T16:18:09.397Z" }, + +[[package]] +name = "numpy" +version = "1.26.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129, upload-time = "2024-02-06T00:26:44.495Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/94/ace0fdea5241a27d13543ee117cbc65868e82213fb31a8eb7fe9ff23f313/numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", size = 20631468, upload-time = "2024-02-05T23:48:01.194Z" }, + { url = "https://files.pythonhosted.org/packages/20/f7/b24208eba89f9d1b58c1668bc6c8c4fd472b20c45573cb767f59d49fb0f6/numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", size = 13966411, upload-time = "2024-02-05T23:48:29.038Z" }, + { url = "https://files.pythonhosted.org/packages/fc/a5/4beee6488160798683eed5bdb7eead455892c3b4e1f78d79d8d3f3b084ac/numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", size = 14219016, upload-time = "2024-02-05T23:48:54.098Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d7/ecf66c1cd12dc28b4040b15ab4d17b773b87fa9d29ca16125de01adb36cd/numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f", size = 18240889, upload-time = "2024-02-05T23:49:25.361Z" }, + { url = "https://files.pythonhosted.org/packages/24/03/6f229fe3187546435c4f6f89f6d26c129d4f5bed40552899fcf1f0bf9e50/numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", size = 13876746, upload-time = "2024-02-05T23:49:51.983Z" }, + { url = "https://files.pythonhosted.org/packages/39/fe/39ada9b094f01f5a35486577c848fe274e374bbf8d8f472e1423a0bbd26d/numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", size = 18078620, upload-time = "2024-02-05T23:50:22.515Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ef/6ad11d51197aad206a9ad2286dc1aac6a378059e06e8cf22cd08ed4f20dc/numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", size = 5972659, upload-time = "2024-02-05T23:50:35.834Z" }, + { url = "https://files.pythonhosted.org/packages/19/77/538f202862b9183f54108557bfda67e17603fc560c384559e769321c9d92/numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", size = 15808905, upload-time = "2024-02-05T23:51:03.701Z" }, + { url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554, upload-time = "2024-02-05T23:51:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127, upload-time = "2024-02-05T23:52:15.314Z" }, + { url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994, upload-time = "2024-02-05T23:52:47.569Z" }, + { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005, upload-time = "2024-02-05T23:53:15.637Z" }, + { url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297, upload-time = "2024-02-05T23:53:42.16Z" }, + { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567, upload-time = "2024-02-05T23:54:11.696Z" }, + { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812, upload-time = "2024-02-05T23:54:26.453Z" }, + { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913, upload-time = "2024-02-05T23:54:53.933Z" }, + { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901, upload-time = "2024-02-05T23:55:32.801Z" }, + { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868, upload-time = "2024-02-05T23:55:56.28Z" }, + { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109, upload-time = "2024-02-05T23:56:20.368Z" }, + { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613, upload-time = "2024-02-05T23:56:56.054Z" }, + { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172, upload-time = "2024-02-05T23:57:21.56Z" }, + { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643, upload-time = "2024-02-05T23:57:56.585Z" }, + { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803, upload-time = "2024-02-05T23:58:08.963Z" }, + { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754, upload-time = "2024-02-05T23:58:36.364Z" }, ] [[package]] @@ -1304,9 +1007,7 @@ name = "pandas" version = "2.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, - { name = "numpy", version = "2.3.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "python-dateutil" }, { name = "pytz" }, { name = "tzdata" }, @@ -1360,140 +1061,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, - { url = "https://files.pythonhosted.org/packages/56/b4/52eeb530a99e2a4c55ffcd352772b599ed4473a0f892d127f4147cf0f88e/pandas-2.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c503ba5216814e295f40711470446bc3fd00f0faea8a086cbc688808e26f92a2", size = 11567720, upload-time = "2025-09-29T23:33:06.209Z" }, - { url = "https://files.pythonhosted.org/packages/48/4a/2d8b67632a021bced649ba940455ed441ca854e57d6e7658a6024587b083/pandas-2.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a637c5cdfa04b6d6e2ecedcb81fc52ffb0fd78ce2ebccc9ea964df9f658de8c8", size = 10810302, upload-time = "2025-09-29T23:33:35.846Z" }, - { url = "https://files.pythonhosted.org/packages/13/e6/d2465010ee0569a245c975dc6967b801887068bc893e908239b1f4b6c1ac/pandas-2.3.3-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:854d00d556406bffe66a4c0802f334c9ad5a96b4f1f868adf036a21b11ef13ff", size = 12154874, upload-time = "2025-09-29T23:33:49.939Z" }, - { url = "https://files.pythonhosted.org/packages/1f/18/aae8c0aa69a386a3255940e9317f793808ea79d0a525a97a903366bb2569/pandas-2.3.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf1f8a81d04ca90e32a0aceb819d34dbd378a98bf923b6398b9a3ec0bf44de29", size = 12790141, upload-time = "2025-09-29T23:34:05.655Z" }, - { url = "https://files.pythonhosted.org/packages/f7/26/617f98de789de00c2a444fbe6301bb19e66556ac78cff933d2c98f62f2b4/pandas-2.3.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:23ebd657a4d38268c7dfbdf089fbc31ea709d82e4923c5ffd4fbd5747133ce73", size = 13208697, upload-time = "2025-09-29T23:34:21.835Z" }, - { url = "https://files.pythonhosted.org/packages/b9/fb/25709afa4552042bd0e15717c75e9b4a2294c3dc4f7e6ea50f03c5136600/pandas-2.3.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5554c929ccc317d41a5e3d1234f3be588248e61f08a74dd17c9eabb535777dc9", size = 13879233, upload-time = "2025-09-29T23:34:35.079Z" }, - { url = "https://files.pythonhosted.org/packages/98/af/7be05277859a7bc399da8ba68b88c96b27b48740b6cf49688899c6eb4176/pandas-2.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:d3e28b3e83862ccf4d85ff19cf8c20b2ae7e503881711ff2d534dc8f761131aa", size = 11359119, upload-time = "2025-09-29T23:34:46.339Z" }, ] [[package]] -name = "pillow" -version = "11.3.0" +name = "pathspec" +version = "0.12.1" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/5d/45a3553a253ac8763f3561371432a90bdbe6000fbdcf1397ffe502aa206c/pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860", size = 5316554, upload-time = "2025-07-01T09:13:39.342Z" }, - { url = "https://files.pythonhosted.org/packages/7c/c8/67c12ab069ef586a25a4a79ced553586748fad100c77c0ce59bb4983ac98/pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad", size = 4686548, upload-time = "2025-07-01T09:13:41.835Z" }, - { url = "https://files.pythonhosted.org/packages/2f/bd/6741ebd56263390b382ae4c5de02979af7f8bd9807346d068700dd6d5cf9/pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0", size = 5859742, upload-time = "2025-07-03T13:09:47.439Z" }, - { url = "https://files.pythonhosted.org/packages/ca/0b/c412a9e27e1e6a829e6ab6c2dca52dd563efbedf4c9c6aa453d9a9b77359/pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b", size = 7633087, upload-time = "2025-07-03T13:09:51.796Z" }, - { url = "https://files.pythonhosted.org/packages/59/9d/9b7076aaf30f5dd17e5e5589b2d2f5a5d7e30ff67a171eb686e4eecc2adf/pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50", size = 5963350, upload-time = "2025-07-01T09:13:43.865Z" }, - { url = "https://files.pythonhosted.org/packages/f0/16/1a6bf01fb622fb9cf5c91683823f073f053005c849b1f52ed613afcf8dae/pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae", size = 6631840, upload-time = "2025-07-01T09:13:46.161Z" }, - { url = "https://files.pythonhosted.org/packages/7b/e6/6ff7077077eb47fde78739e7d570bdcd7c10495666b6afcd23ab56b19a43/pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9", size = 6074005, upload-time = "2025-07-01T09:13:47.829Z" }, - { url = "https://files.pythonhosted.org/packages/c3/3a/b13f36832ea6d279a697231658199e0a03cd87ef12048016bdcc84131601/pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e", size = 6708372, upload-time = "2025-07-01T09:13:52.145Z" }, - { url = "https://files.pythonhosted.org/packages/6c/e4/61b2e1a7528740efbc70b3d581f33937e38e98ef3d50b05007267a55bcb2/pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6", size = 6277090, upload-time = "2025-07-01T09:13:53.915Z" }, - { url = "https://files.pythonhosted.org/packages/a9/d3/60c781c83a785d6afbd6a326ed4d759d141de43aa7365725cbcd65ce5e54/pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f", size = 6985988, upload-time = "2025-07-01T09:13:55.699Z" }, - { url = "https://files.pythonhosted.org/packages/9f/28/4f4a0203165eefb3763939c6789ba31013a2e90adffb456610f30f613850/pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f", size = 2422899, upload-time = "2025-07-01T09:13:57.497Z" }, - { url = "https://files.pythonhosted.org/packages/db/26/77f8ed17ca4ffd60e1dcd220a6ec6d71210ba398cfa33a13a1cd614c5613/pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", size = 5316531, upload-time = "2025-07-01T09:13:59.203Z" }, - { url = "https://files.pythonhosted.org/packages/cb/39/ee475903197ce709322a17a866892efb560f57900d9af2e55f86db51b0a5/pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", size = 4686560, upload-time = "2025-07-01T09:14:01.101Z" }, - { url = "https://files.pythonhosted.org/packages/d5/90/442068a160fd179938ba55ec8c97050a612426fae5ec0a764e345839f76d/pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", size = 5870978, upload-time = "2025-07-03T13:09:55.638Z" }, - { url = "https://files.pythonhosted.org/packages/13/92/dcdd147ab02daf405387f0218dcf792dc6dd5b14d2573d40b4caeef01059/pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", size = 7641168, upload-time = "2025-07-03T13:10:00.37Z" }, - { url = "https://files.pythonhosted.org/packages/6e/db/839d6ba7fd38b51af641aa904e2960e7a5644d60ec754c046b7d2aee00e5/pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", size = 5973053, upload-time = "2025-07-01T09:14:04.491Z" }, - { url = "https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", size = 6640273, upload-time = "2025-07-01T09:14:06.235Z" }, - { url = "https://files.pythonhosted.org/packages/45/ad/931694675ede172e15b2ff03c8144a0ddaea1d87adb72bb07655eaffb654/pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", size = 6082043, upload-time = "2025-07-01T09:14:07.978Z" }, - { url = "https://files.pythonhosted.org/packages/3a/04/ba8f2b11fc80d2dd462d7abec16351b45ec99cbbaea4387648a44190351a/pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", size = 6715516, upload-time = "2025-07-01T09:14:10.233Z" }, - { url = "https://files.pythonhosted.org/packages/48/59/8cd06d7f3944cc7d892e8533c56b0acb68399f640786313275faec1e3b6f/pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", size = 6274768, upload-time = "2025-07-01T09:14:11.921Z" }, - { url = "https://files.pythonhosted.org/packages/f1/cc/29c0f5d64ab8eae20f3232da8f8571660aa0ab4b8f1331da5c2f5f9a938e/pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", size = 6986055, upload-time = "2025-07-01T09:14:13.623Z" }, - { url = "https://files.pythonhosted.org/packages/c6/df/90bd886fabd544c25addd63e5ca6932c86f2b701d5da6c7839387a076b4a/pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", size = 2423079, upload-time = "2025-07-01T09:14:15.268Z" }, - { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" }, - { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" }, - { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" }, - { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" }, - { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" }, - { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" }, - { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" }, - { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload-time = "2025-07-01T09:14:27.053Z" }, - { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload-time = "2025-07-01T09:14:30.104Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload-time = "2025-07-01T09:14:31.899Z" }, - { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload-time = "2025-07-01T09:14:33.709Z" }, - { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, - { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, - { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, - { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, - { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, - { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, - { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, - { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, - { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, - { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, - { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, - { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, - { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, - { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, - { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, - { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, - { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, - { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, - { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, - { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, - { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, - { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, - { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, - { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, - { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, - { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, - { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, - { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, - { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, - { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, - { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, - { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, - { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, - { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, - { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, - { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8e/9c089f01677d1264ab8648352dcb7773f37da6ad002542760c80107da816/pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f", size = 5316478, upload-time = "2025-07-01T09:15:52.209Z" }, - { url = "https://files.pythonhosted.org/packages/b5/a9/5749930caf674695867eb56a581e78eb5f524b7583ff10b01b6e5048acb3/pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081", size = 4686522, upload-time = "2025-07-01T09:15:54.162Z" }, - { url = "https://files.pythonhosted.org/packages/43/46/0b85b763eb292b691030795f9f6bb6fcaf8948c39413c81696a01c3577f7/pillow-11.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4", size = 5853376, upload-time = "2025-07-03T13:11:01.066Z" }, - { url = "https://files.pythonhosted.org/packages/5e/c6/1a230ec0067243cbd60bc2dad5dc3ab46a8a41e21c15f5c9b52b26873069/pillow-11.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc", size = 7626020, upload-time = "2025-07-03T13:11:06.479Z" }, - { url = "https://files.pythonhosted.org/packages/63/dd/f296c27ffba447bfad76c6a0c44c1ea97a90cb9472b9304c94a732e8dbfb/pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06", size = 5956732, upload-time = "2025-07-01T09:15:56.111Z" }, - { url = "https://files.pythonhosted.org/packages/a5/a0/98a3630f0b57f77bae67716562513d3032ae70414fcaf02750279c389a9e/pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a", size = 6624404, upload-time = "2025-07-01T09:15:58.245Z" }, - { url = "https://files.pythonhosted.org/packages/de/e6/83dfba5646a290edd9a21964da07674409e410579c341fc5b8f7abd81620/pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978", size = 6067760, upload-time = "2025-07-01T09:16:00.003Z" }, - { url = "https://files.pythonhosted.org/packages/bc/41/15ab268fe6ee9a2bc7391e2bbb20a98d3974304ab1a406a992dcb297a370/pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d", size = 6700534, upload-time = "2025-07-01T09:16:02.29Z" }, - { url = "https://files.pythonhosted.org/packages/64/79/6d4f638b288300bed727ff29f2a3cb63db054b33518a95f27724915e3fbc/pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71", size = 6277091, upload-time = "2025-07-01T09:16:04.4Z" }, - { url = "https://files.pythonhosted.org/packages/46/05/4106422f45a05716fd34ed21763f8ec182e8ea00af6e9cb05b93a247361a/pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada", size = 6986091, upload-time = "2025-07-01T09:16:06.342Z" }, - { url = "https://files.pythonhosted.org/packages/63/c6/287fd55c2c12761d0591549d48885187579b7c257bef0c6660755b0b59ae/pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb", size = 2422632, upload-time = "2025-07-01T09:16:08.142Z" }, - { url = "https://files.pythonhosted.org/packages/6f/8b/209bd6b62ce8367f47e68a218bffac88888fdf2c9fcf1ecadc6c3ec1ebc7/pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967", size = 5270556, upload-time = "2025-07-01T09:16:09.961Z" }, - { url = "https://files.pythonhosted.org/packages/2e/e6/231a0b76070c2cfd9e260a7a5b504fb72da0a95279410fa7afd99d9751d6/pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe", size = 4654625, upload-time = "2025-07-01T09:16:11.913Z" }, - { url = "https://files.pythonhosted.org/packages/13/f4/10cf94fda33cb12765f2397fc285fa6d8eb9c29de7f3185165b702fc7386/pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c", size = 4874207, upload-time = "2025-07-03T13:11:10.201Z" }, - { url = "https://files.pythonhosted.org/packages/72/c9/583821097dc691880c92892e8e2d41fe0a5a3d6021f4963371d2f6d57250/pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25", size = 6583939, upload-time = "2025-07-03T13:11:15.68Z" }, - { url = "https://files.pythonhosted.org/packages/3b/8e/5c9d410f9217b12320efc7c413e72693f48468979a013ad17fd690397b9a/pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27", size = 4957166, upload-time = "2025-07-01T09:16:13.74Z" }, - { url = "https://files.pythonhosted.org/packages/62/bb/78347dbe13219991877ffb3a91bf09da8317fbfcd4b5f9140aeae020ad71/pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a", size = 5581482, upload-time = "2025-07-01T09:16:16.107Z" }, - { url = "https://files.pythonhosted.org/packages/d9/28/1000353d5e61498aaeaaf7f1e4b49ddb05f2c6575f9d4f9f914a3538b6e1/pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f", size = 6984596, upload-time = "2025-07-01T09:16:18.07Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e3/6fa84033758276fb31da12e5fb66ad747ae83b93c67af17f8c6ff4cc8f34/pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", size = 5270566, upload-time = "2025-07-01T09:16:19.801Z" }, - { url = "https://files.pythonhosted.org/packages/5b/ee/e8d2e1ab4892970b561e1ba96cbd59c0d28cf66737fc44abb2aec3795a4e/pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", size = 4654618, upload-time = "2025-07-01T09:16:21.818Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6d/17f80f4e1f0761f02160fc433abd4109fa1548dcfdca46cfdadaf9efa565/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3", size = 4874248, upload-time = "2025-07-03T13:11:20.738Z" }, - { url = "https://files.pythonhosted.org/packages/de/5f/c22340acd61cef960130585bbe2120e2fd8434c214802f07e8c03596b17e/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", size = 6583963, upload-time = "2025-07-03T13:11:26.283Z" }, - { url = "https://files.pythonhosted.org/packages/31/5e/03966aedfbfcbb4d5f8aa042452d3361f325b963ebbadddac05b122e47dd/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", size = 4957170, upload-time = "2025-07-01T09:16:23.762Z" }, - { url = "https://files.pythonhosted.org/packages/cc/2d/e082982aacc927fc2cab48e1e731bdb1643a1406acace8bed0900a61464e/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", size = 5581505, upload-time = "2025-07-01T09:16:25.593Z" }, - { url = "https://files.pythonhosted.org/packages/34/e7/ae39f538fd6844e982063c3a5e4598b8ced43b9633baa3a85ef33af8c05c/pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", size = 6984598, upload-time = "2025-07-01T09:16:27.732Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] name = "pillow" version = "12.0.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", - "python_full_version == '3.10.*'", -] sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5d/08/26e68b6b5da219c2a2cb7b563af008b53bb8e6b6fcb3fa40715fcdb2523a/pillow-12.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b", size = 5289809, upload-time = "2025-10-15T18:21:27.791Z" }, @@ -1588,6 +1170,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/95/7e/f896623c3c635a90537ac093c6a618ebe1a90d87206e42309cb5d98a1b9e/pillow-12.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5", size = 6997850, upload-time = "2025-10-15T18:24:11.495Z" }, ] +[[package]] +name = "platformdirs" +version = "4.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -1597,6 +1188,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "pre-commit" +version = "3.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/10/97ee2fa54dff1e9da9badbc5e35d0bbaef0776271ea5907eccf64140f72f/pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af", size = 177815, upload-time = "2024-07-28T19:59:01.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/92/caae8c86e94681b42c246f0bca35c059a2f0529e5b92619f6aba4cf7e7b6/pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f", size = 204643, upload-time = "2024-07-28T19:58:59.335Z" }, +] + [[package]] name = "prompt-toolkit" version = "3.0.52" @@ -1620,8 +1227,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/10/56/a8a3f4e7190837139e68c7002ec749190a163af3e330f65d90309145a210/protobuf-6.32.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d8c7e6eb619ffdf105ee4ab76af5a68b60a9d0f66da3ea12d1640e6d8dab7281", size = 426454, upload-time = "2025-09-11T21:38:34.076Z" }, { url = "https://files.pythonhosted.org/packages/3f/be/8dd0a927c559b37d7a6c8ab79034fd167dcc1f851595f2e641ad62be8643/protobuf-6.32.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:2f5b80a49e1eb7b86d85fcd23fe92df154b9730a725c3b38c4e43b9d77018bf4", size = 322874, upload-time = "2025-09-11T21:38:35.509Z" }, { url = "https://files.pythonhosted.org/packages/5c/f6/88d77011b605ef979aace37b7703e4eefad066f7e84d935e5a696515c2dd/protobuf-6.32.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:b1864818300c297265c83a4982fd3169f97122c299f56a56e2445c3698d34710", size = 322013, upload-time = "2025-09-11T21:38:37.017Z" }, - { url = "https://files.pythonhosted.org/packages/05/9d/d6f1a8b6657296920c58f6b85f7bca55fa27e3ca7fc5914604d89cd0250b/protobuf-6.32.1-cp39-cp39-win32.whl", hash = "sha256:68ff170bac18c8178f130d1ccb94700cf72852298e016a2443bdb9502279e5f1", size = 424505, upload-time = "2025-09-11T21:38:38.415Z" }, - { url = "https://files.pythonhosted.org/packages/ed/cd/891bd2d23558f52392a5687b2406a741e2e28d629524c88aade457029acd/protobuf-6.32.1-cp39-cp39-win_amd64.whl", hash = "sha256:d0975d0b2f3e6957111aa3935d08a0eb7e006b1505d825f862a1fffc8348e122", size = 435825, upload-time = "2025-09-11T21:38:39.773Z" }, { url = "https://files.pythonhosted.org/packages/97/b7/15cc7d93443d6c6a84626ae3258a91f4c6ac8c0edd5df35ea7658f71b79c/protobuf-6.32.1-py3-none-any.whl", hash = "sha256:2601b779fc7d32a866c6b4404f9d42a3f67c5b9f3f15b4db3cccabe06b95c346", size = 169289, upload-time = "2025-09-11T21:38:41.234Z" }, ] @@ -1639,40 +1244,144 @@ wheels = [ ] [[package]] -name = "pygments" -version = "2.19.2" +name = "pyparsing" +version = "3.2.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, + { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, ] [[package]] -name = "pyparsing" -version = "3.2.5" +name = "pyproj" +version = "3.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "certifi", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/10/a8480ea27ea4bbe896c168808854d00f2a9b49f95c0319ddcbba693c8a90/pyproj-3.7.1.tar.gz", hash = "sha256:60d72facd7b6b79853f19744779abcd3f804c4e0d4fa8815469db20c9f640a47", size = 226339, upload-time = "2025-02-16T04:28:46.621Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, + { url = "https://files.pythonhosted.org/packages/25/a3/c4cd4bba5b336075f145fe784fcaf4ef56ffbc979833303303e7a659dda2/pyproj-3.7.1-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:bf09dbeb333c34e9c546364e7df1ff40474f9fddf9e70657ecb0e4f670ff0b0e", size = 6262524, upload-time = "2025-02-16T04:27:19.725Z" }, + { url = "https://files.pythonhosted.org/packages/40/45/4fdf18f4cc1995f1992771d2a51cf186a9d7a8ec973c9693f8453850c707/pyproj-3.7.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:6575b2e53cc9e3e461ad6f0692a5564b96e7782c28631c7771c668770915e169", size = 4665102, upload-time = "2025-02-16T04:27:24.428Z" }, + { url = "https://files.pythonhosted.org/packages/0c/d2/360eb127380106cee83569954ae696b88a891c804d7a93abe3fbc15f5976/pyproj-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cb516ee35ed57789b46b96080edf4e503fdb62dbb2e3c6581e0d6c83fca014b", size = 9432667, upload-time = "2025-02-16T04:27:27.04Z" }, + { url = "https://files.pythonhosted.org/packages/76/a5/c6e11b9a99ce146741fb4d184d5c468446c6d6015b183cae82ac822a6cfa/pyproj-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e47c4e93b88d99dd118875ee3ca0171932444cdc0b52d493371b5d98d0f30ee", size = 9259185, upload-time = "2025-02-16T04:27:30.35Z" }, + { url = "https://files.pythonhosted.org/packages/41/56/a3c15c42145797a99363fa0fdb4e9805dccb8b4a76a6d7b2cdf36ebcc2a1/pyproj-3.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3e8d276caeae34fcbe4813855d0d97b9b825bab8d7a8b86d859c24a6213a5a0d", size = 10469103, upload-time = "2025-02-16T04:27:33.542Z" }, + { url = "https://files.pythonhosted.org/packages/ef/73/c9194c2802fefe2a4fd4230bdd5ab083e7604e93c64d0356fa49c363bad6/pyproj-3.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f173f851ee75e54acdaa053382b6825b400cb2085663a9bb073728a59c60aebb", size = 10401391, upload-time = "2025-02-16T04:27:36.051Z" }, + { url = "https://files.pythonhosted.org/packages/c5/1d/ce8bb5b9251b04d7c22d63619bb3db3d2397f79000a9ae05b3fd86a5837e/pyproj-3.7.1-cp310-cp310-win32.whl", hash = "sha256:f550281ed6e5ea88fcf04a7c6154e246d5714be495c50c9e8e6b12d3fb63e158", size = 5869997, upload-time = "2025-02-16T04:27:38.302Z" }, + { url = "https://files.pythonhosted.org/packages/09/6a/ca145467fd2e5b21e3d5b8c2b9645dcfb3b68f08b62417699a1f5689008e/pyproj-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3537668992a709a2e7f068069192138618c00d0ba113572fdd5ee5ffde8222f3", size = 6278581, upload-time = "2025-02-16T04:27:41.051Z" }, + { url = "https://files.pythonhosted.org/packages/ab/0d/63670fc527e664068b70b7cab599aa38b7420dd009bdc29ea257e7f3dfb3/pyproj-3.7.1-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:a94e26c1a4950cea40116775588a2ca7cf56f1f434ff54ee35a84718f3841a3d", size = 6264315, upload-time = "2025-02-16T04:27:44.539Z" }, + { url = "https://files.pythonhosted.org/packages/25/9d/cbaf82cfb290d1f1fa42feb9ba9464013bb3891e40c4199f8072112e4589/pyproj-3.7.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:263b54ba5004b6b957d55757d846fc5081bc02980caa0279c4fc95fa0fff6067", size = 4666267, upload-time = "2025-02-16T04:27:47.019Z" }, + { url = "https://files.pythonhosted.org/packages/79/53/24f9f9b8918c0550f3ff49ad5de4cf3f0688c9f91ff191476db8979146fe/pyproj-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6d6a2ccd5607cd15ef990c51e6f2dd27ec0a741e72069c387088bba3aab60fa", size = 9680510, upload-time = "2025-02-16T04:27:49.239Z" }, + { url = "https://files.pythonhosted.org/packages/3c/ac/12fab74a908d40b63174dc704587febd0729414804bbfd873cabe504ff2d/pyproj-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c5dcf24ede53d8abab7d8a77f69ff1936c6a8843ef4fcc574646e4be66e5739", size = 9493619, upload-time = "2025-02-16T04:27:52.65Z" }, + { url = "https://files.pythonhosted.org/packages/c4/45/26311d6437135da2153a178125db5dfb6abce831ce04d10ec207eabac70a/pyproj-3.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3c2e7449840a44ce860d8bea2c6c1c4bc63fa07cba801dcce581d14dcb031a02", size = 10709755, upload-time = "2025-02-16T04:27:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/99/52/4ecd0986f27d0e6c8ee3a7bc5c63da15acd30ac23034f871325b297e61fd/pyproj-3.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0829865c1d3a3543f918b3919dc601eea572d6091c0dd175e1a054db9c109274", size = 10642970, upload-time = "2025-02-16T04:27:58.343Z" }, + { url = "https://files.pythonhosted.org/packages/3f/a5/d3bfc018fc92195a000d1d28acc1f3f1df15ff9f09ece68f45a2636c0134/pyproj-3.7.1-cp311-cp311-win32.whl", hash = "sha256:6181960b4b812e82e588407fe5c9c68ada267c3b084db078f248db5d7f45d18a", size = 5868295, upload-time = "2025-02-16T04:28:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/92/39/ef6f06a5b223dbea308cfcbb7a0f72e7b506aef1850e061b2c73b0818715/pyproj-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ad0ff443a785d84e2b380869fdd82e6bfc11eba6057d25b4409a9bbfa867970", size = 6279871, upload-time = "2025-02-16T04:28:04.988Z" }, + { url = "https://files.pythonhosted.org/packages/e6/c9/876d4345b8d17f37ac59ebd39f8fa52fc6a6a9891a420f72d050edb6b899/pyproj-3.7.1-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:2781029d90df7f8d431e29562a3f2d8eafdf233c4010d6fc0381858dc7373217", size = 6264087, upload-time = "2025-02-16T04:28:09.036Z" }, + { url = "https://files.pythonhosted.org/packages/ff/e6/5f8691f8c90e7f402cc80a6276eb19d2ec1faa150d5ae2dd9c7b0a254da8/pyproj-3.7.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d61bf8ab04c73c1da08eedaf21a103b72fa5b0a9b854762905f65ff8b375d394", size = 4669628, upload-time = "2025-02-16T04:28:10.944Z" }, + { url = "https://files.pythonhosted.org/packages/42/ec/16475bbb79c1c68845c0a0d9c60c4fb31e61b8a2a20bc18b1a81e81c7f68/pyproj-3.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04abc517a8555d1b05fcee768db3280143fe42ec39fdd926a2feef31631a1f2f", size = 9721415, upload-time = "2025-02-16T04:28:13.342Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a3/448f05b15e318bd6bea9a32cfaf11e886c4ae61fa3eee6e09ed5c3b74bb2/pyproj-3.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084c0a475688f934d386c2ab3b6ce03398a473cd48adfda70d9ab8f87f2394a0", size = 9556447, upload-time = "2025-02-16T04:28:15.818Z" }, + { url = "https://files.pythonhosted.org/packages/6a/ae/bd15fe8d8bd914ead6d60bca7f895a4e6f8ef7e3928295134ff9a7dad14c/pyproj-3.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a20727a23b1e49c7dc7fe3c3df8e56a8a7acdade80ac2f5cca29d7ca5564c145", size = 10758317, upload-time = "2025-02-16T04:28:18.338Z" }, + { url = "https://files.pythonhosted.org/packages/9d/d9/5ccefb8bca925f44256b188a91c31238cae29ab6ee7f53661ecc04616146/pyproj-3.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bf84d766646f1ebd706d883755df4370aaf02b48187cedaa7e4239f16bc8213d", size = 10771259, upload-time = "2025-02-16T04:28:20.822Z" }, + { url = "https://files.pythonhosted.org/packages/2a/7d/31dedff9c35fa703162f922eeb0baa6c44a3288469a5fd88d209e2892f9e/pyproj-3.7.1-cp312-cp312-win32.whl", hash = "sha256:5f0da2711364d7cb9f115b52289d4a9b61e8bca0da57f44a3a9d6fc9bdeb7274", size = 5859914, upload-time = "2025-02-16T04:28:23.303Z" }, + { url = "https://files.pythonhosted.org/packages/3e/47/c6ab03d6564a7c937590cff81a2742b5990f096cce7c1a622d325be340ee/pyproj-3.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:aee664a9d806612af30a19dba49e55a7a78ebfec3e9d198f6a6176e1d140ec98", size = 6273196, upload-time = "2025-02-16T04:28:25.227Z" }, + { url = "https://files.pythonhosted.org/packages/ef/01/984828464c9960036c602753fc0f21f24f0aa9043c18fa3f2f2b66a86340/pyproj-3.7.1-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:5f8d02ef4431dee414d1753d13fa82a21a2f61494737b5f642ea668d76164d6d", size = 6253062, upload-time = "2025-02-16T04:28:27.861Z" }, + { url = "https://files.pythonhosted.org/packages/68/65/6ecdcdc829811a2c160cdfe2f068a009fc572fd4349664f758ccb0853a7c/pyproj-3.7.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:0b853ae99bda66cbe24b4ccfe26d70601d84375940a47f553413d9df570065e0", size = 4660548, upload-time = "2025-02-16T04:28:29.526Z" }, + { url = "https://files.pythonhosted.org/packages/67/da/dda94c4490803679230ba4c17a12f151b307a0d58e8110820405ca2d98db/pyproj-3.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83db380c52087f9e9bdd8a527943b2e7324f275881125e39475c4f9277bdeec4", size = 9662464, upload-time = "2025-02-16T04:28:31.437Z" }, + { url = "https://files.pythonhosted.org/packages/6f/57/f61b7d22c91ae1d12ee00ac4c0038714e774ebcd851b9133e5f4f930dd40/pyproj-3.7.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b35ed213892e211a3ce2bea002aa1183e1a2a9b79e51bb3c6b15549a831ae528", size = 9497461, upload-time = "2025-02-16T04:28:33.848Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f6/932128236f79d2ac7d39fe1a19667fdf7155d9a81d31fb9472a7a497790f/pyproj-3.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a8b15b0463d1303bab113d1a6af2860a0d79013c3a66fcc5475ce26ef717fd4f", size = 10708869, upload-time = "2025-02-16T04:28:37.34Z" }, + { url = "https://files.pythonhosted.org/packages/1d/0d/07ac7712994454a254c383c0d08aff9916a2851e6512d59da8dc369b1b02/pyproj-3.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:87229e42b75e89f4dad6459200f92988c5998dfb093c7c631fb48524c86cd5dc", size = 10729260, upload-time = "2025-02-16T04:28:40.639Z" }, + { url = "https://files.pythonhosted.org/packages/b0/d0/9c604bc72c37ba69b867b6df724d6a5af6789e8c375022c952f65b2af558/pyproj-3.7.1-cp313-cp313-win32.whl", hash = "sha256:d666c3a3faaf3b1d7fc4a544059c4eab9d06f84a604b070b7aa2f318e227798e", size = 5855462, upload-time = "2025-02-16T04:28:42.827Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/68a2b7f5fb6400c64aad82d72bcc4bc531775e62eedff993a77c780defd0/pyproj-3.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:d3caac7473be22b6d6e102dde6c46de73b96bc98334e577dfaee9886f102ea2e", size = 6266573, upload-time = "2025-02-16T04:28:44.727Z" }, +] + +[[package]] +name = "pyproj" +version = "3.7.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", +] +dependencies = [ + { name = "certifi", marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/90/67bd7260b4ea9b8b20b4f58afef6c223ecb3abf368eb4ec5bc2cdef81b49/pyproj-3.7.2.tar.gz", hash = "sha256:39a0cf1ecc7e282d1d30f36594ebd55c9fae1fda8a2622cee5d100430628f88c", size = 226279, upload-time = "2025-08-14T12:05:42.18Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/bd/f205552cd1713b08f93b09e39a3ec99edef0b3ebbbca67b486fdf1abe2de/pyproj-3.7.2-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:2514d61f24c4e0bb9913e2c51487ecdaeca5f8748d8313c933693416ca41d4d5", size = 6227022, upload-time = "2025-08-14T12:03:51.474Z" }, + { url = "https://files.pythonhosted.org/packages/75/4c/9a937e659b8b418ab573c6d340d27e68716928953273e0837e7922fcac34/pyproj-3.7.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:8693ca3892d82e70de077701ee76dd13d7bca4ae1c9d1e739d72004df015923a", size = 4625810, upload-time = "2025-08-14T12:03:53.808Z" }, + { url = "https://files.pythonhosted.org/packages/c0/7d/a9f41e814dc4d1dc54e95b2ccaf0b3ebe3eb18b1740df05fe334724c3d89/pyproj-3.7.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5e26484d80fea56273ed1555abaea161e9661d81a6c07815d54b8e883d4ceb25", size = 9638694, upload-time = "2025-08-14T12:03:55.669Z" }, + { url = "https://files.pythonhosted.org/packages/ad/ab/9bdb4a6216b712a1f9aab1c0fcbee5d3726f34a366f29c3e8c08a78d6b70/pyproj-3.7.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:281cb92847814e8018010c48b4069ff858a30236638631c1a91dd7bfa68f8a8a", size = 9493977, upload-time = "2025-08-14T12:03:57.937Z" }, + { url = "https://files.pythonhosted.org/packages/c9/db/2db75b1b6190f1137b1c4e8ef6a22e1c338e46320f6329bfac819143e063/pyproj-3.7.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9c8577f0b7bb09118ec2e57e3babdc977127dd66326d6c5d755c76b063e6d9dc", size = 10841151, upload-time = "2025-08-14T12:04:00.271Z" }, + { url = "https://files.pythonhosted.org/packages/89/f7/989643394ba23a286e9b7b3f09981496172f9e0d4512457ffea7dc47ffc7/pyproj-3.7.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a23f59904fac3a5e7364b3aa44d288234af267ca041adb2c2b14a903cd5d3ac5", size = 10751585, upload-time = "2025-08-14T12:04:02.228Z" }, + { url = "https://files.pythonhosted.org/packages/53/6d/ad928fe975a6c14a093c92e6a319ca18f479f3336bb353a740bdba335681/pyproj-3.7.2-cp311-cp311-win32.whl", hash = "sha256:f2af4ed34b2cf3e031a2d85b067a3ecbd38df073c567e04b52fa7a0202afde8a", size = 5908533, upload-time = "2025-08-14T12:04:04.821Z" }, + { url = "https://files.pythonhosted.org/packages/79/e0/b95584605cec9ed50b7ebaf7975d1c4ddeec5a86b7a20554ed8b60042bd7/pyproj-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:0b7cb633565129677b2a183c4d807c727d1c736fcb0568a12299383056e67433", size = 6320742, upload-time = "2025-08-14T12:04:06.357Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4d/536e8f93bca808175c2d0a5ac9fdf69b960d8ab6b14f25030dccb07464d7/pyproj-3.7.2-cp311-cp311-win_arm64.whl", hash = "sha256:38b08d85e3a38e455625b80e9eb9f78027c8e2649a21dec4df1f9c3525460c71", size = 6245772, upload-time = "2025-08-14T12:04:08.365Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ab/9893ea9fb066be70ed9074ae543914a618c131ed8dff2da1e08b3a4df4db/pyproj-3.7.2-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:0a9bb26a6356fb5b033433a6d1b4542158fb71e3c51de49b4c318a1dff3aeaab", size = 6219832, upload-time = "2025-08-14T12:04:10.264Z" }, + { url = "https://files.pythonhosted.org/packages/53/78/4c64199146eed7184eb0e85bedec60a4aa8853b6ffe1ab1f3a8b962e70a0/pyproj-3.7.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:567caa03021178861fad27fabde87500ec6d2ee173dd32f3e2d9871e40eebd68", size = 4620650, upload-time = "2025-08-14T12:04:11.978Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ac/14a78d17943898a93ef4f8c6a9d4169911c994e3161e54a7cedeba9d8dde/pyproj-3.7.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:c203101d1dc3c038a56cff0447acc515dd29d6e14811406ac539c21eed422b2a", size = 9667087, upload-time = "2025-08-14T12:04:13.964Z" }, + { url = "https://files.pythonhosted.org/packages/b8/be/212882c450bba74fc8d7d35cbd57e4af84792f0a56194819d98106b075af/pyproj-3.7.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:1edc34266c0c23ced85f95a1ee8b47c9035eae6aca5b6b340327250e8e281630", size = 9552797, upload-time = "2025-08-14T12:04:16.624Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c0/c0f25c87b5d2a8686341c53c1792a222a480d6c9caf60311fec12c99ec26/pyproj-3.7.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aa9f26c21bc0e2dc3d224cb1eb4020cf23e76af179a7c66fea49b828611e4260", size = 10837036, upload-time = "2025-08-14T12:04:18.733Z" }, + { url = "https://files.pythonhosted.org/packages/5d/37/5cbd6772addde2090c91113332623a86e8c7d583eccb2ad02ea634c4a89f/pyproj-3.7.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9428b318530625cb389b9ddc9c51251e172808a4af79b82809376daaeabe5e9", size = 10775952, upload-time = "2025-08-14T12:04:20.709Z" }, + { url = "https://files.pythonhosted.org/packages/69/a1/dc250e3cf83eb4b3b9a2cf86fdb5e25288bd40037ae449695550f9e96b2f/pyproj-3.7.2-cp312-cp312-win32.whl", hash = "sha256:b3d99ed57d319da042f175f4554fc7038aa4bcecc4ac89e217e350346b742c9d", size = 5898872, upload-time = "2025-08-14T12:04:22.485Z" }, + { url = "https://files.pythonhosted.org/packages/4a/a6/6fe724b72b70f2b00152d77282e14964d60ab092ec225e67c196c9b463e5/pyproj-3.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:11614a054cd86a2ed968a657d00987a86eeb91fdcbd9ad3310478685dc14a128", size = 6312176, upload-time = "2025-08-14T12:04:24.736Z" }, + { url = "https://files.pythonhosted.org/packages/5d/68/915cc32c02a91e76d02c8f55d5a138d6ef9e47a0d96d259df98f4842e558/pyproj-3.7.2-cp312-cp312-win_arm64.whl", hash = "sha256:509a146d1398bafe4f53273398c3bb0b4732535065fa995270e52a9d3676bca3", size = 6233452, upload-time = "2025-08-14T12:04:27.287Z" }, + { url = "https://files.pythonhosted.org/packages/be/14/faf1b90d267cea68d7e70662e7f88cefdb1bc890bd596c74b959e0517a72/pyproj-3.7.2-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:19466e529b1b15eeefdf8ff26b06fa745856c044f2f77bf0edbae94078c1dfa1", size = 6214580, upload-time = "2025-08-14T12:04:28.804Z" }, + { url = "https://files.pythonhosted.org/packages/35/48/da9a45b184d375f62667f62eba0ca68569b0bd980a0bb7ffcc1d50440520/pyproj-3.7.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:c79b9b84c4a626c5dc324c0d666be0bfcebd99f7538d66e8898c2444221b3da7", size = 4615388, upload-time = "2025-08-14T12:04:30.553Z" }, + { url = "https://files.pythonhosted.org/packages/5e/e7/d2b459a4a64bca328b712c1b544e109df88e5c800f7c143cfbc404d39bfb/pyproj-3.7.2-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:ceecf374cacca317bc09e165db38ac548ee3cad07c3609442bd70311c59c21aa", size = 9628455, upload-time = "2025-08-14T12:04:32.435Z" }, + { url = "https://files.pythonhosted.org/packages/f8/85/c2b1706e51942de19076eff082f8495e57d5151364e78b5bef4af4a1d94a/pyproj-3.7.2-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5141a538ffdbe4bfd157421828bb2e07123a90a7a2d6f30fa1462abcfb5ce681", size = 9514269, upload-time = "2025-08-14T12:04:34.599Z" }, + { url = "https://files.pythonhosted.org/packages/34/38/07a9b89ae7467872f9a476883a5bad9e4f4d1219d31060f0f2b282276cbe/pyproj-3.7.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f000841e98ea99acbb7b8ca168d67773b0191de95187228a16110245c5d954d5", size = 10808437, upload-time = "2025-08-14T12:04:36.485Z" }, + { url = "https://files.pythonhosted.org/packages/12/56/fda1daeabbd39dec5b07f67233d09f31facb762587b498e6fc4572be9837/pyproj-3.7.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8115faf2597f281a42ab608ceac346b4eb1383d3b45ab474fd37341c4bf82a67", size = 10745540, upload-time = "2025-08-14T12:04:38.568Z" }, + { url = "https://files.pythonhosted.org/packages/0d/90/c793182cbba65a39a11db2ac6b479fe76c59e6509ae75e5744c344a0da9d/pyproj-3.7.2-cp313-cp313-win32.whl", hash = "sha256:f18c0579dd6be00b970cb1a6719197fceecc407515bab37da0066f0184aafdf3", size = 5896506, upload-time = "2025-08-14T12:04:41.059Z" }, + { url = "https://files.pythonhosted.org/packages/be/0f/747974129cf0d800906f81cd25efd098c96509026e454d4b66868779ab04/pyproj-3.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:bb41c29d5f60854b1075853fe80c58950b398d4ebb404eb532536ac8d2834ed7", size = 6310195, upload-time = "2025-08-14T12:04:42.974Z" }, + { url = "https://files.pythonhosted.org/packages/82/64/fc7598a53172c4931ec6edf5228280663063150625d3f6423b4c20f9daff/pyproj-3.7.2-cp313-cp313-win_arm64.whl", hash = "sha256:2b617d573be4118c11cd96b8891a0b7f65778fa7733ed8ecdb297a447d439100", size = 6230748, upload-time = "2025-08-14T12:04:44.491Z" }, + { url = "https://files.pythonhosted.org/packages/aa/f0/611dd5cddb0d277f94b7af12981f56e1441bf8d22695065d4f0df5218498/pyproj-3.7.2-cp313-cp313t-macosx_13_0_x86_64.whl", hash = "sha256:d27b48f0e81beeaa2b4d60c516c3a1cfbb0c7ff6ef71256d8e9c07792f735279", size = 6241729, upload-time = "2025-08-14T12:04:46.274Z" }, + { url = "https://files.pythonhosted.org/packages/15/93/40bd4a6c523ff9965e480870611aed7eda5aa2c6128c6537345a2b77b542/pyproj-3.7.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:55a3610d75023c7b1c6e583e48ef8f62918e85a2ae81300569d9f104d6684bb6", size = 4652497, upload-time = "2025-08-14T12:04:48.203Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ae/7150ead53c117880b35e0d37960d3138fe640a235feb9605cb9386f50bb0/pyproj-3.7.2-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:8d7349182fa622696787cc9e195508d2a41a64765da9b8a6bee846702b9e6220", size = 9942610, upload-time = "2025-08-14T12:04:49.652Z" }, + { url = "https://files.pythonhosted.org/packages/d8/17/7a4a7eafecf2b46ab64e5c08176c20ceb5844b503eaa551bf12ccac77322/pyproj-3.7.2-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:d230b186eb876ed4f29a7c5ee310144c3a0e44e89e55f65fb3607e13f6db337c", size = 9692390, upload-time = "2025-08-14T12:04:51.731Z" }, + { url = "https://files.pythonhosted.org/packages/c3/55/ae18f040f6410f0ea547a21ada7ef3e26e6c82befa125b303b02759c0e9d/pyproj-3.7.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:237499c7862c578d0369e2b8ac56eec550e391a025ff70e2af8417139dabb41c", size = 11047596, upload-time = "2025-08-14T12:04:53.748Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2e/d3fff4d2909473f26ae799f9dda04caa322c417a51ff3b25763f7d03b233/pyproj-3.7.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8c225f5978abd506fd9a78eaaf794435e823c9156091cabaab5374efb29d7f69", size = 10896975, upload-time = "2025-08-14T12:04:55.875Z" }, + { url = "https://files.pythonhosted.org/packages/f2/bc/8fc7d3963d87057b7b51ebe68c1e7c51c23129eee5072ba6b86558544a46/pyproj-3.7.2-cp313-cp313t-win32.whl", hash = "sha256:2da731876d27639ff9d2d81c151f6ab90a1546455fabd93368e753047be344a2", size = 5953057, upload-time = "2025-08-14T12:04:58.466Z" }, + { url = "https://files.pythonhosted.org/packages/cc/27/ea9809966cc47d2d51e6d5ae631ea895f7c7c7b9b3c29718f900a8f7d197/pyproj-3.7.2-cp313-cp313t-win_amd64.whl", hash = "sha256:f54d91ae18dd23b6c0ab48126d446820e725419da10617d86a1b69ada6d881d3", size = 6375414, upload-time = "2025-08-14T12:04:59.861Z" }, + { url = "https://files.pythonhosted.org/packages/5b/f8/1ef0129fba9a555c658e22af68989f35e7ba7b9136f25758809efec0cd6e/pyproj-3.7.2-cp313-cp313t-win_arm64.whl", hash = "sha256:fc52ba896cfc3214dc9f9ca3c0677a623e8fdd096b257c14a31e719d21ff3fdd", size = 6262501, upload-time = "2025-08-14T12:05:01.39Z" }, + { url = "https://files.pythonhosted.org/packages/42/17/c2b050d3f5b71b6edd0d96ae16c990fdc42a5f1366464a5c2772146de33a/pyproj-3.7.2-cp314-cp314-macosx_13_0_x86_64.whl", hash = "sha256:2aaa328605ace41db050d06bac1adc11f01b71fe95c18661497763116c3a0f02", size = 6214541, upload-time = "2025-08-14T12:05:03.166Z" }, + { url = "https://files.pythonhosted.org/packages/03/68/68ada9c8aea96ded09a66cfd9bf87aa6db8c2edebe93f5bf9b66b0143fbc/pyproj-3.7.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:35dccbce8201313c596a970fde90e33605248b66272595c061b511c8100ccc08", size = 4617456, upload-time = "2025-08-14T12:05:04.563Z" }, + { url = "https://files.pythonhosted.org/packages/81/e4/4c50ceca7d0e937977866b02cb64e6ccf4df979a5871e521f9e255df6073/pyproj-3.7.2-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:25b0b7cb0042444c29a164b993c45c1b8013d6c48baa61dc1160d834a277e83b", size = 9615590, upload-time = "2025-08-14T12:05:06.094Z" }, + { url = "https://files.pythonhosted.org/packages/05/1e/ada6fb15a1d75b5bd9b554355a69a798c55a7dcc93b8d41596265c1772e3/pyproj-3.7.2-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:85def3a6388e9ba51f964619aa002a9d2098e77c6454ff47773bb68871024281", size = 9474960, upload-time = "2025-08-14T12:05:07.973Z" }, + { url = "https://files.pythonhosted.org/packages/51/07/9d48ad0a8db36e16f842f2c8a694c1d9d7dcf9137264846bef77585a71f3/pyproj-3.7.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b1bccefec3875ab81eabf49059e2b2ea77362c178b66fd3528c3e4df242f1516", size = 10799478, upload-time = "2025-08-14T12:05:14.102Z" }, + { url = "https://files.pythonhosted.org/packages/85/cf/2f812b529079f72f51ff2d6456b7fef06c01735e5cfd62d54ffb2b548028/pyproj-3.7.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d5371ca114d6990b675247355a801925814eca53e6c4b2f1b5c0a956336ee36e", size = 10710030, upload-time = "2025-08-14T12:05:16.317Z" }, + { url = "https://files.pythonhosted.org/packages/99/9b/4626a19e1f03eba4c0e77b91a6cf0f73aa9cb5d51a22ee385c22812bcc2c/pyproj-3.7.2-cp314-cp314-win32.whl", hash = "sha256:77f066626030f41be543274f5ac79f2a511fe89860ecd0914f22131b40a0ec25", size = 5991181, upload-time = "2025-08-14T12:05:19.492Z" }, + { url = "https://files.pythonhosted.org/packages/04/b2/5a6610554306a83a563080c2cf2c57565563eadd280e15388efa00fb5b33/pyproj-3.7.2-cp314-cp314-win_amd64.whl", hash = "sha256:5a964da1696b8522806f4276ab04ccfff8f9eb95133a92a25900697609d40112", size = 6434721, upload-time = "2025-08-14T12:05:21.022Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ce/6c910ea2e1c74ef673c5d48c482564b8a7824a44c4e35cca2e765b68cfcc/pyproj-3.7.2-cp314-cp314-win_arm64.whl", hash = "sha256:e258ab4dbd3cf627809067c0ba8f9884ea76c8e5999d039fb37a1619c6c3e1f6", size = 6363821, upload-time = "2025-08-14T12:05:22.627Z" }, + { url = "https://files.pythonhosted.org/packages/e4/e4/5532f6f7491812ba782a2177fe9de73fd8e2912b59f46a1d056b84b9b8f2/pyproj-3.7.2-cp314-cp314t-macosx_13_0_x86_64.whl", hash = "sha256:bbbac2f930c6d266f70ec75df35ef851d96fdb3701c674f42fd23a9314573b37", size = 6241773, upload-time = "2025-08-14T12:05:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/20/1f/0938c3f2bbbef1789132d1726d9b0e662f10cfc22522743937f421ad664e/pyproj-3.7.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:b7544e0a3d6339dc9151e9c8f3ea62a936ab7cc446a806ec448bbe86aebb979b", size = 4652537, upload-time = "2025-08-14T12:05:26.391Z" }, + { url = "https://files.pythonhosted.org/packages/c7/a8/488b1ed47d25972f33874f91f09ca8f2227902f05f63a2b80dc73e7b1c97/pyproj-3.7.2-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:f7f5133dca4c703e8acadf6f30bc567d39a42c6af321e7f81975c2518f3ed357", size = 9940864, upload-time = "2025-08-14T12:05:27.985Z" }, + { url = "https://files.pythonhosted.org/packages/c7/cc/7f4c895d0cb98e47b6a85a6d79eaca03eb266129eed2f845125c09cf31ff/pyproj-3.7.2-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:5aff3343038d7426aa5076f07feb88065f50e0502d1b0d7c22ddfdd2c75a3f81", size = 9688868, upload-time = "2025-08-14T12:05:30.425Z" }, + { url = "https://files.pythonhosted.org/packages/b2/b7/c7e306b8bb0f071d9825b753ee4920f066c40fbfcce9372c4f3cfb2fc4ed/pyproj-3.7.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b0552178c61f2ac1c820d087e8ba6e62b29442debddbb09d51c4bf8acc84d888", size = 11045910, upload-time = "2025-08-14T12:05:32.507Z" }, + { url = "https://files.pythonhosted.org/packages/42/fb/538a4d2df695980e2dde5c04d965fbdd1fe8c20a3194dc4aaa3952a4d1be/pyproj-3.7.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:47d87db2d2c436c5fd0409b34d70bb6cdb875cca2ebe7a9d1c442367b0ab8d59", size = 10895724, upload-time = "2025-08-14T12:05:35.465Z" }, + { url = "https://files.pythonhosted.org/packages/e8/8b/a3f0618b03957de9db5489a04558a8826f43906628bb0b766033aa3b5548/pyproj-3.7.2-cp314-cp314t-win32.whl", hash = "sha256:c9b6f1d8ad3e80a0ee0903a778b6ece7dca1d1d40f6d114ae01bc8ddbad971aa", size = 6056848, upload-time = "2025-08-14T12:05:37.553Z" }, + { url = "https://files.pythonhosted.org/packages/bc/56/413240dd5149dd3291eda55aa55a659da4431244a2fd1319d0ae89407cfb/pyproj-3.7.2-cp314-cp314t-win_amd64.whl", hash = "sha256:1914e29e27933ba6f9822663ee0600f169014a2859f851c054c88cf5ea8a333c", size = 6517676, upload-time = "2025-08-14T12:05:39.126Z" }, + { url = "https://files.pythonhosted.org/packages/15/73/a7141a1a0559bf1a7aa42a11c879ceb19f02f5c6c371c6d57fd86cefd4d1/pyproj-3.7.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d9d25bae416a24397e0d85739f84d323b55f6511e45a522dd7d7eae70d10c7e4", size = 6391844, upload-time = "2025-08-14T12:05:40.745Z" }, ] [[package]] name = "pytest" -version = "8.4.2" +version = "7.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, - { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116, upload-time = "2023-12-31T12:00:18.035Z" } 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/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287, upload-time = "2023-12-31T12:00:13.963Z" }, ] [[package]] @@ -1696,6 +1405,70 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, ] +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, + { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + [[package]] name = "requests" version = "2.32.5" @@ -1711,6 +1484,185 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] +[[package]] +name = "scikit-learn" +version = "1.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "joblib" }, + { name = "numpy" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "scipy", version = "1.16.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "threadpoolctl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/3e/daed796fd69cce768b8788401cc464ea90b306fb196ae1ffed0b98182859/scikit_learn-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b33579c10a3081d076ab403df4a4190da4f4432d443521674637677dc91e61f", size = 9336221, upload-time = "2025-09-09T08:20:19.328Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ce/af9d99533b24c55ff4e18d9b7b4d9919bbc6cd8f22fe7a7be01519a347d5/scikit_learn-1.7.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:36749fb62b3d961b1ce4fedf08fa57a1986cd409eff2d783bca5d4b9b5fce51c", size = 8653834, upload-time = "2025-09-09T08:20:22.073Z" }, + { url = "https://files.pythonhosted.org/packages/58/0e/8c2a03d518fb6bd0b6b0d4b114c63d5f1db01ff0f9925d8eb10960d01c01/scikit_learn-1.7.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7a58814265dfc52b3295b1900cfb5701589d30a8bb026c7540f1e9d3499d5ec8", size = 9660938, upload-time = "2025-09-09T08:20:24.327Z" }, + { url = "https://files.pythonhosted.org/packages/2b/75/4311605069b5d220e7cf5adabb38535bd96f0079313cdbb04b291479b22a/scikit_learn-1.7.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a847fea807e278f821a0406ca01e387f97653e284ecbd9750e3ee7c90347f18", size = 9477818, upload-time = "2025-09-09T08:20:26.845Z" }, + { url = "https://files.pythonhosted.org/packages/7f/9b/87961813c34adbca21a6b3f6b2bea344c43b30217a6d24cc437c6147f3e8/scikit_learn-1.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:ca250e6836d10e6f402436d6463d6c0e4d8e0234cfb6a9a47835bd392b852ce5", size = 8886969, upload-time = "2025-09-09T08:20:29.329Z" }, + { url = "https://files.pythonhosted.org/packages/43/83/564e141eef908a5863a54da8ca342a137f45a0bfb71d1d79704c9894c9d1/scikit_learn-1.7.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7509693451651cd7361d30ce4e86a1347493554f172b1c72a39300fa2aea79e", size = 9331967, upload-time = "2025-09-09T08:20:32.421Z" }, + { url = "https://files.pythonhosted.org/packages/18/d6/ba863a4171ac9d7314c4d3fc251f015704a2caeee41ced89f321c049ed83/scikit_learn-1.7.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:0486c8f827c2e7b64837c731c8feff72c0bd2b998067a8a9cbc10643c31f0fe1", size = 8648645, upload-time = "2025-09-09T08:20:34.436Z" }, + { url = "https://files.pythonhosted.org/packages/ef/0e/97dbca66347b8cf0ea8b529e6bb9367e337ba2e8be0ef5c1a545232abfde/scikit_learn-1.7.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89877e19a80c7b11a2891a27c21c4894fb18e2c2e077815bcade10d34287b20d", size = 9715424, upload-time = "2025-09-09T08:20:36.776Z" }, + { url = "https://files.pythonhosted.org/packages/f7/32/1f3b22e3207e1d2c883a7e09abb956362e7d1bd2f14458c7de258a26ac15/scikit_learn-1.7.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8da8bf89d4d79aaec192d2bda62f9b56ae4e5b4ef93b6a56b5de4977e375c1f1", size = 9509234, upload-time = "2025-09-09T08:20:38.957Z" }, + { url = "https://files.pythonhosted.org/packages/9f/71/34ddbd21f1da67c7a768146968b4d0220ee6831e4bcbad3e03dd3eae88b6/scikit_learn-1.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:9b7ed8d58725030568523e937c43e56bc01cadb478fc43c042a9aca1dacb3ba1", size = 8894244, upload-time = "2025-09-09T08:20:41.166Z" }, + { url = "https://files.pythonhosted.org/packages/a7/aa/3996e2196075689afb9fce0410ebdb4a09099d7964d061d7213700204409/scikit_learn-1.7.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8d91a97fa2b706943822398ab943cde71858a50245e31bc71dba62aab1d60a96", size = 9259818, upload-time = "2025-09-09T08:20:43.19Z" }, + { url = "https://files.pythonhosted.org/packages/43/5d/779320063e88af9c4a7c2cf463ff11c21ac9c8bd730c4a294b0000b666c9/scikit_learn-1.7.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:acbc0f5fd2edd3432a22c69bed78e837c70cf896cd7993d71d51ba6708507476", size = 8636997, upload-time = "2025-09-09T08:20:45.468Z" }, + { url = "https://files.pythonhosted.org/packages/5c/d0/0c577d9325b05594fdd33aa970bf53fb673f051a45496842caee13cfd7fe/scikit_learn-1.7.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b", size = 9478381, upload-time = "2025-09-09T08:20:47.982Z" }, + { url = "https://files.pythonhosted.org/packages/82/70/8bf44b933837ba8494ca0fc9a9ab60f1c13b062ad0197f60a56e2fc4c43e/scikit_learn-1.7.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d6e9deed1a47aca9fe2f267ab8e8fe82ee20b4526b2c0cd9e135cea10feb44", size = 9300296, upload-time = "2025-09-09T08:20:50.366Z" }, + { url = "https://files.pythonhosted.org/packages/c6/99/ed35197a158f1fdc2fe7c3680e9c70d0128f662e1fee4ed495f4b5e13db0/scikit_learn-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:6088aa475f0785e01bcf8529f55280a3d7d298679f50c0bb70a2364a82d0b290", size = 8731256, upload-time = "2025-09-09T08:20:52.627Z" }, + { url = "https://files.pythonhosted.org/packages/ae/93/a3038cb0293037fd335f77f31fe053b89c72f17b1c8908c576c29d953e84/scikit_learn-1.7.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b7dacaa05e5d76759fb071558a8b5130f4845166d88654a0f9bdf3eb57851b7", size = 9212382, upload-time = "2025-09-09T08:20:54.731Z" }, + { url = "https://files.pythonhosted.org/packages/40/dd/9a88879b0c1104259136146e4742026b52df8540c39fec21a6383f8292c7/scikit_learn-1.7.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:abebbd61ad9e1deed54cca45caea8ad5f79e1b93173dece40bb8e0c658dbe6fe", size = 8592042, upload-time = "2025-09-09T08:20:57.313Z" }, + { url = "https://files.pythonhosted.org/packages/46/af/c5e286471b7d10871b811b72ae794ac5fe2989c0a2df07f0ec723030f5f5/scikit_learn-1.7.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:502c18e39849c0ea1a5d681af1dbcf15f6cce601aebb657aabbfe84133c1907f", size = 9434180, upload-time = "2025-09-09T08:20:59.671Z" }, + { url = "https://files.pythonhosted.org/packages/f1/fd/df59faa53312d585023b2da27e866524ffb8faf87a68516c23896c718320/scikit_learn-1.7.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a4c328a71785382fe3fe676a9ecf2c86189249beff90bf85e22bdb7efaf9ae0", size = 9283660, upload-time = "2025-09-09T08:21:01.71Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c7/03000262759d7b6f38c836ff9d512f438a70d8a8ddae68ee80de72dcfb63/scikit_learn-1.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:63a9afd6f7b229aad94618c01c252ce9e6fa97918c5ca19c9a17a087d819440c", size = 8702057, upload-time = "2025-09-09T08:21:04.234Z" }, + { url = "https://files.pythonhosted.org/packages/55/87/ef5eb1f267084532c8e4aef98a28b6ffe7425acbfd64b5e2f2e066bc29b3/scikit_learn-1.7.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9acb6c5e867447b4e1390930e3944a005e2cb115922e693c08a323421a6966e8", size = 9558731, upload-time = "2025-09-09T08:21:06.381Z" }, + { url = "https://files.pythonhosted.org/packages/93/f8/6c1e3fc14b10118068d7938878a9f3f4e6d7b74a8ddb1e5bed65159ccda8/scikit_learn-1.7.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:2a41e2a0ef45063e654152ec9d8bcfc39f7afce35b08902bfe290c2498a67a6a", size = 9038852, upload-time = "2025-09-09T08:21:08.628Z" }, + { url = "https://files.pythonhosted.org/packages/83/87/066cafc896ee540c34becf95d30375fe5cbe93c3b75a0ee9aa852cd60021/scikit_learn-1.7.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98335fb98509b73385b3ab2bd0639b1f610541d3988ee675c670371d6a87aa7c", size = 9527094, upload-time = "2025-09-09T08:21:11.486Z" }, + { url = "https://files.pythonhosted.org/packages/9c/2b/4903e1ccafa1f6453b1ab78413938c8800633988c838aa0be386cbb33072/scikit_learn-1.7.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:191e5550980d45449126e23ed1d5e9e24b2c68329ee1f691a3987476e115e09c", size = 9367436, upload-time = "2025-09-09T08:21:13.602Z" }, + { url = "https://files.pythonhosted.org/packages/b5/aa/8444be3cfb10451617ff9d177b3c190288f4563e6c50ff02728be67ad094/scikit_learn-1.7.2-cp313-cp313t-win_amd64.whl", hash = "sha256:57dc4deb1d3762c75d685507fbd0bc17160144b2f2ba4ccea5dc285ab0d0e973", size = 9275749, upload-time = "2025-09-09T08:21:15.96Z" }, + { url = "https://files.pythonhosted.org/packages/d9/82/dee5acf66837852e8e68df6d8d3a6cb22d3df997b733b032f513d95205b7/scikit_learn-1.7.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fa8f63940e29c82d1e67a45d5297bdebbcb585f5a5a50c4914cc2e852ab77f33", size = 9208906, upload-time = "2025-09-09T08:21:18.557Z" }, + { url = "https://files.pythonhosted.org/packages/3c/30/9029e54e17b87cb7d50d51a5926429c683d5b4c1732f0507a6c3bed9bf65/scikit_learn-1.7.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:f95dc55b7902b91331fa4e5845dd5bde0580c9cd9612b1b2791b7e80c3d32615", size = 8627836, upload-time = "2025-09-09T08:21:20.695Z" }, + { url = "https://files.pythonhosted.org/packages/60/18/4a52c635c71b536879f4b971c2cedf32c35ee78f48367885ed8025d1f7ee/scikit_learn-1.7.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9656e4a53e54578ad10a434dc1f993330568cfee176dff07112b8785fb413106", size = 9426236, upload-time = "2025-09-09T08:21:22.645Z" }, + { url = "https://files.pythonhosted.org/packages/99/7e/290362f6ab582128c53445458a5befd471ed1ea37953d5bcf80604619250/scikit_learn-1.7.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96dc05a854add0e50d3f47a1ef21a10a595016da5b007c7d9cd9d0bffd1fcc61", size = 9312593, upload-time = "2025-09-09T08:21:24.65Z" }, + { url = "https://files.pythonhosted.org/packages/8e/87/24f541b6d62b1794939ae6422f8023703bbf6900378b2b34e0b4384dfefd/scikit_learn-1.7.2-cp314-cp314-win_amd64.whl", hash = "sha256:bb24510ed3f9f61476181e4db51ce801e2ba37541def12dc9333b946fc7a9cf8", size = 8820007, upload-time = "2025-09-09T08:21:26.713Z" }, +] + +[[package]] +name = "scipy" +version = "1.15.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +dependencies = [ + { name = "numpy", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/2f/4966032c5f8cc7e6a60f1b2e0ad686293b9474b65246b0c642e3ef3badd0/scipy-1.15.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c", size = 38702770, upload-time = "2025-05-08T16:04:20.849Z" }, + { url = "https://files.pythonhosted.org/packages/a0/6e/0c3bf90fae0e910c274db43304ebe25a6b391327f3f10b5dcc638c090795/scipy-1.15.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253", size = 30094511, upload-time = "2025-05-08T16:04:27.103Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b1/4deb37252311c1acff7f101f6453f0440794f51b6eacb1aad4459a134081/scipy-1.15.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f", size = 22368151, upload-time = "2025-05-08T16:04:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/f457626e3cd3c29b3a49ca115a304cebb8cc6f31b04678f03b216899d3c6/scipy-1.15.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92", size = 25121732, upload-time = "2025-05-08T16:04:36.596Z" }, + { url = "https://files.pythonhosted.org/packages/db/0a/92b1de4a7adc7a15dcf5bddc6e191f6f29ee663b30511ce20467ef9b82e4/scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82", size = 35547617, upload-time = "2025-05-08T16:04:43.546Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6d/41991e503e51fc1134502694c5fa7a1671501a17ffa12716a4a9151af3df/scipy-1.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40", size = 37662964, upload-time = "2025-05-08T16:04:49.431Z" }, + { url = "https://files.pythonhosted.org/packages/25/e1/3df8f83cb15f3500478c889be8fb18700813b95e9e087328230b98d547ff/scipy-1.15.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e", size = 37238749, upload-time = "2025-05-08T16:04:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/b3257cf446f2a3533ed7809757039016b74cd6f38271de91682aa844cfc5/scipy-1.15.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c", size = 40022383, upload-time = "2025-05-08T16:05:01.914Z" }, + { url = "https://files.pythonhosted.org/packages/d1/84/55bc4881973d3f79b479a5a2e2df61c8c9a04fcb986a213ac9c02cfb659b/scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13", size = 41259201, upload-time = "2025-05-08T16:05:08.166Z" }, + { url = "https://files.pythonhosted.org/packages/96/ab/5cc9f80f28f6a7dff646c5756e559823614a42b1939d86dd0ed550470210/scipy-1.15.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:993439ce220d25e3696d1b23b233dd010169b62f6456488567e830654ee37a6b", size = 38714255, upload-time = "2025-05-08T16:05:14.596Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4a/66ba30abe5ad1a3ad15bfb0b59d22174012e8056ff448cb1644deccbfed2/scipy-1.15.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:34716e281f181a02341ddeaad584205bd2fd3c242063bd3423d61ac259ca7eba", size = 30111035, upload-time = "2025-05-08T16:05:20.152Z" }, + { url = "https://files.pythonhosted.org/packages/4b/fa/a7e5b95afd80d24313307f03624acc65801846fa75599034f8ceb9e2cbf6/scipy-1.15.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3b0334816afb8b91dab859281b1b9786934392aa3d527cd847e41bb6f45bee65", size = 22384499, upload-time = "2025-05-08T16:05:24.494Z" }, + { url = "https://files.pythonhosted.org/packages/17/99/f3aaddccf3588bb4aea70ba35328c204cadd89517a1612ecfda5b2dd9d7a/scipy-1.15.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:6db907c7368e3092e24919b5e31c76998b0ce1684d51a90943cb0ed1b4ffd6c1", size = 25152602, upload-time = "2025-05-08T16:05:29.313Z" }, + { url = "https://files.pythonhosted.org/packages/56/c5/1032cdb565f146109212153339f9cb8b993701e9fe56b1c97699eee12586/scipy-1.15.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:721d6b4ef5dc82ca8968c25b111e307083d7ca9091bc38163fb89243e85e3889", size = 35503415, upload-time = "2025-05-08T16:05:34.699Z" }, + { url = "https://files.pythonhosted.org/packages/bd/37/89f19c8c05505d0601ed5650156e50eb881ae3918786c8fd7262b4ee66d3/scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39cb9c62e471b1bb3750066ecc3a3f3052b37751c7c3dfd0fd7e48900ed52982", size = 37652622, upload-time = "2025-05-08T16:05:40.762Z" }, + { url = "https://files.pythonhosted.org/packages/7e/31/be59513aa9695519b18e1851bb9e487de66f2d31f835201f1b42f5d4d475/scipy-1.15.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:795c46999bae845966368a3c013e0e00947932d68e235702b5c3f6ea799aa8c9", size = 37244796, upload-time = "2025-05-08T16:05:48.119Z" }, + { url = "https://files.pythonhosted.org/packages/10/c0/4f5f3eeccc235632aab79b27a74a9130c6c35df358129f7ac8b29f562ac7/scipy-1.15.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:18aaacb735ab38b38db42cb01f6b92a2d0d4b6aabefeb07f02849e47f8fb3594", size = 40047684, upload-time = "2025-05-08T16:05:54.22Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a7/0ddaf514ce8a8714f6ed243a2b391b41dbb65251affe21ee3077ec45ea9a/scipy-1.15.3-cp311-cp311-win_amd64.whl", hash = "sha256:ae48a786a28412d744c62fd7816a4118ef97e5be0bee968ce8f0a2fba7acf3bb", size = 41246504, upload-time = "2025-05-08T16:06:00.437Z" }, + { url = "https://files.pythonhosted.org/packages/37/4b/683aa044c4162e10ed7a7ea30527f2cbd92e6999c10a8ed8edb253836e9c/scipy-1.15.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6ac6310fdbfb7aa6612408bd2f07295bcbd3fda00d2d702178434751fe48e019", size = 38766735, upload-time = "2025-05-08T16:06:06.471Z" }, + { url = "https://files.pythonhosted.org/packages/7b/7e/f30be3d03de07f25dc0ec926d1681fed5c732d759ac8f51079708c79e680/scipy-1.15.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:185cd3d6d05ca4b44a8f1595af87f9c372bb6acf9c808e99aa3e9aa03bd98cf6", size = 30173284, upload-time = "2025-05-08T16:06:11.686Z" }, + { url = "https://files.pythonhosted.org/packages/07/9c/0ddb0d0abdabe0d181c1793db51f02cd59e4901da6f9f7848e1f96759f0d/scipy-1.15.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:05dc6abcd105e1a29f95eada46d4a3f251743cfd7d3ae8ddb4088047f24ea477", size = 22446958, upload-time = "2025-05-08T16:06:15.97Z" }, + { url = "https://files.pythonhosted.org/packages/af/43/0bce905a965f36c58ff80d8bea33f1f9351b05fad4beaad4eae34699b7a1/scipy-1.15.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:06efcba926324df1696931a57a176c80848ccd67ce6ad020c810736bfd58eb1c", size = 25242454, upload-time = "2025-05-08T16:06:20.394Z" }, + { url = "https://files.pythonhosted.org/packages/56/30/a6f08f84ee5b7b28b4c597aca4cbe545535c39fe911845a96414700b64ba/scipy-1.15.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05045d8b9bfd807ee1b9f38761993297b10b245f012b11b13b91ba8945f7e45", size = 35210199, upload-time = "2025-05-08T16:06:26.159Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1f/03f52c282437a168ee2c7c14a1a0d0781a9a4a8962d84ac05c06b4c5b555/scipy-1.15.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271e3713e645149ea5ea3e97b57fdab61ce61333f97cfae392c28ba786f9bb49", size = 37309455, upload-time = "2025-05-08T16:06:32.778Z" }, + { url = "https://files.pythonhosted.org/packages/89/b1/fbb53137f42c4bf630b1ffdfc2151a62d1d1b903b249f030d2b1c0280af8/scipy-1.15.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cfd56fc1a8e53f6e89ba3a7a7251f7396412d655bca2aa5611c8ec9a6784a1e", size = 36885140, upload-time = "2025-05-08T16:06:39.249Z" }, + { url = "https://files.pythonhosted.org/packages/2e/2e/025e39e339f5090df1ff266d021892694dbb7e63568edcfe43f892fa381d/scipy-1.15.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ff17c0bb1cb32952c09217d8d1eed9b53d1463e5f1dd6052c7857f83127d539", size = 39710549, upload-time = "2025-05-08T16:06:45.729Z" }, + { url = "https://files.pythonhosted.org/packages/e6/eb/3bf6ea8ab7f1503dca3a10df2e4b9c3f6b3316df07f6c0ded94b281c7101/scipy-1.15.3-cp312-cp312-win_amd64.whl", hash = "sha256:52092bc0472cfd17df49ff17e70624345efece4e1a12b23783a1ac59a1b728ed", size = 40966184, upload-time = "2025-05-08T16:06:52.623Z" }, + { url = "https://files.pythonhosted.org/packages/73/18/ec27848c9baae6e0d6573eda6e01a602e5649ee72c27c3a8aad673ebecfd/scipy-1.15.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c620736bcc334782e24d173c0fdbb7590a0a436d2fdf39310a8902505008759", size = 38728256, upload-time = "2025-05-08T16:06:58.696Z" }, + { url = "https://files.pythonhosted.org/packages/74/cd/1aef2184948728b4b6e21267d53b3339762c285a46a274ebb7863c9e4742/scipy-1.15.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:7e11270a000969409d37ed399585ee530b9ef6aa99d50c019de4cb01e8e54e62", size = 30109540, upload-time = "2025-05-08T16:07:04.209Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d8/59e452c0a255ec352bd0a833537a3bc1bfb679944c4938ab375b0a6b3a3e/scipy-1.15.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8c9ed3ba2c8a2ce098163a9bdb26f891746d02136995df25227a20e71c396ebb", size = 22383115, upload-time = "2025-05-08T16:07:08.998Z" }, + { url = "https://files.pythonhosted.org/packages/08/f5/456f56bbbfccf696263b47095291040655e3cbaf05d063bdc7c7517f32ac/scipy-1.15.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0bdd905264c0c9cfa74a4772cdb2070171790381a5c4d312c973382fc6eaf730", size = 25163884, upload-time = "2025-05-08T16:07:14.091Z" }, + { url = "https://files.pythonhosted.org/packages/a2/66/a9618b6a435a0f0c0b8a6d0a2efb32d4ec5a85f023c2b79d39512040355b/scipy-1.15.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79167bba085c31f38603e11a267d862957cbb3ce018d8b38f79ac043bc92d825", size = 35174018, upload-time = "2025-05-08T16:07:19.427Z" }, + { url = "https://files.pythonhosted.org/packages/b5/09/c5b6734a50ad4882432b6bb7c02baf757f5b2f256041da5df242e2d7e6b6/scipy-1.15.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9deabd6d547aee2c9a81dee6cc96c6d7e9a9b1953f74850c179f91fdc729cb7", size = 37269716, upload-time = "2025-05-08T16:07:25.712Z" }, + { url = "https://files.pythonhosted.org/packages/77/0a/eac00ff741f23bcabd352731ed9b8995a0a60ef57f5fd788d611d43d69a1/scipy-1.15.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dde4fc32993071ac0c7dd2d82569e544f0bdaff66269cb475e0f369adad13f11", size = 36872342, upload-time = "2025-05-08T16:07:31.468Z" }, + { url = "https://files.pythonhosted.org/packages/fe/54/4379be86dd74b6ad81551689107360d9a3e18f24d20767a2d5b9253a3f0a/scipy-1.15.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f77f853d584e72e874d87357ad70f44b437331507d1c311457bed8ed2b956126", size = 39670869, upload-time = "2025-05-08T16:07:38.002Z" }, + { url = "https://files.pythonhosted.org/packages/87/2e/892ad2862ba54f084ffe8cc4a22667eaf9c2bcec6d2bff1d15713c6c0703/scipy-1.15.3-cp313-cp313-win_amd64.whl", hash = "sha256:b90ab29d0c37ec9bf55424c064312930ca5f4bde15ee8619ee44e69319aab163", size = 40988851, upload-time = "2025-05-08T16:08:33.671Z" }, + { url = "https://files.pythonhosted.org/packages/1b/e9/7a879c137f7e55b30d75d90ce3eb468197646bc7b443ac036ae3fe109055/scipy-1.15.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3ac07623267feb3ae308487c260ac684b32ea35fd81e12845039952f558047b8", size = 38863011, upload-time = "2025-05-08T16:07:44.039Z" }, + { url = "https://files.pythonhosted.org/packages/51/d1/226a806bbd69f62ce5ef5f3ffadc35286e9fbc802f606a07eb83bf2359de/scipy-1.15.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6487aa99c2a3d509a5227d9a5e889ff05830a06b2ce08ec30df6d79db5fcd5c5", size = 30266407, upload-time = "2025-05-08T16:07:49.891Z" }, + { url = "https://files.pythonhosted.org/packages/e5/9b/f32d1d6093ab9eeabbd839b0f7619c62e46cc4b7b6dbf05b6e615bbd4400/scipy-1.15.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:50f9e62461c95d933d5c5ef4a1f2ebf9a2b4e83b0db374cb3f1de104d935922e", size = 22540030, upload-time = "2025-05-08T16:07:54.121Z" }, + { url = "https://files.pythonhosted.org/packages/e7/29/c278f699b095c1a884f29fda126340fcc201461ee8bfea5c8bdb1c7c958b/scipy-1.15.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14ed70039d182f411ffc74789a16df3835e05dc469b898233a245cdfd7f162cb", size = 25218709, upload-time = "2025-05-08T16:07:58.506Z" }, + { url = "https://files.pythonhosted.org/packages/24/18/9e5374b617aba742a990581373cd6b68a2945d65cc588482749ef2e64467/scipy-1.15.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a769105537aa07a69468a0eefcd121be52006db61cdd8cac8a0e68980bbb723", size = 34809045, upload-time = "2025-05-08T16:08:03.929Z" }, + { url = "https://files.pythonhosted.org/packages/e1/fe/9c4361e7ba2927074360856db6135ef4904d505e9b3afbbcb073c4008328/scipy-1.15.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db984639887e3dffb3928d118145ffe40eff2fa40cb241a306ec57c219ebbbb", size = 36703062, upload-time = "2025-05-08T16:08:09.558Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8e/038ccfe29d272b30086b25a4960f757f97122cb2ec42e62b460d02fe98e9/scipy-1.15.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:40e54d5c7e7ebf1aa596c374c49fa3135f04648a0caabcb66c52884b943f02b4", size = 36393132, upload-time = "2025-05-08T16:08:15.34Z" }, + { url = "https://files.pythonhosted.org/packages/10/7e/5c12285452970be5bdbe8352c619250b97ebf7917d7a9a9e96b8a8140f17/scipy-1.15.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5e721fed53187e71d0ccf382b6bf977644c533e506c4d33c3fb24de89f5c3ed5", size = 38979503, upload-time = "2025-05-08T16:08:21.513Z" }, + { url = "https://files.pythonhosted.org/packages/81/06/0a5e5349474e1cbc5757975b21bd4fad0e72ebf138c5592f191646154e06/scipy-1.15.3-cp313-cp313t-win_amd64.whl", hash = "sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca", size = 40308097, upload-time = "2025-05-08T16:08:27.627Z" }, +] + +[[package]] +name = "scipy" +version = "1.16.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", +] +dependencies = [ + { name = "numpy", marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/3b/546a6f0bfe791bbb7f8d591613454d15097e53f906308ec6f7c1ce588e8e/scipy-1.16.2.tar.gz", hash = "sha256:af029b153d243a80afb6eabe40b0a07f8e35c9adc269c019f364ad747f826a6b", size = 30580599, upload-time = "2025-09-11T17:48:08.271Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/ef/37ed4b213d64b48422df92560af7300e10fe30b5d665dd79932baebee0c6/scipy-1.16.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:6ab88ea43a57da1af33292ebd04b417e8e2eaf9d5aa05700be8d6e1b6501cd92", size = 36619956, upload-time = "2025-09-11T17:39:20.5Z" }, + { url = "https://files.pythonhosted.org/packages/85/ab/5c2eba89b9416961a982346a4d6a647d78c91ec96ab94ed522b3b6baf444/scipy-1.16.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c95e96c7305c96ede73a7389f46ccd6c659c4da5ef1b2789466baeaed3622b6e", size = 28931117, upload-time = "2025-09-11T17:39:29.06Z" }, + { url = "https://files.pythonhosted.org/packages/80/d1/eed51ab64d227fe60229a2d57fb60ca5898cfa50ba27d4f573e9e5f0b430/scipy-1.16.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:87eb178db04ece7c698220d523c170125dbffebb7af0345e66c3554f6f60c173", size = 20921997, upload-time = "2025-09-11T17:39:34.892Z" }, + { url = "https://files.pythonhosted.org/packages/be/7c/33ea3e23bbadde96726edba6bf9111fb1969d14d9d477ffa202c67bec9da/scipy-1.16.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:4e409eac067dcee96a57fbcf424c13f428037827ec7ee3cb671ff525ca4fc34d", size = 23523374, upload-time = "2025-09-11T17:39:40.846Z" }, + { url = "https://files.pythonhosted.org/packages/96/0b/7399dc96e1e3f9a05e258c98d716196a34f528eef2ec55aad651ed136d03/scipy-1.16.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e574be127bb760f0dad24ff6e217c80213d153058372362ccb9555a10fc5e8d2", size = 33583702, upload-time = "2025-09-11T17:39:49.011Z" }, + { url = "https://files.pythonhosted.org/packages/1a/bc/a5c75095089b96ea72c1bd37a4497c24b581ec73db4ef58ebee142ad2d14/scipy-1.16.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f5db5ba6188d698ba7abab982ad6973265b74bb40a1efe1821b58c87f73892b9", size = 35883427, upload-time = "2025-09-11T17:39:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/ab/66/e25705ca3d2b87b97fe0a278a24b7f477b4023a926847935a1a71488a6a6/scipy-1.16.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec6e74c4e884104ae006d34110677bfe0098203a3fec2f3faf349f4cb05165e3", size = 36212940, upload-time = "2025-09-11T17:40:06.013Z" }, + { url = "https://files.pythonhosted.org/packages/d6/fd/0bb911585e12f3abdd603d721d83fc1c7492835e1401a0e6d498d7822b4b/scipy-1.16.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:912f46667d2d3834bc3d57361f854226475f695eb08c08a904aadb1c936b6a88", size = 38865092, upload-time = "2025-09-11T17:40:15.143Z" }, + { url = "https://files.pythonhosted.org/packages/d6/73/c449a7d56ba6e6f874183759f8483cde21f900a8be117d67ffbb670c2958/scipy-1.16.2-cp311-cp311-win_amd64.whl", hash = "sha256:91e9e8a37befa5a69e9cacbe0bcb79ae5afb4a0b130fd6db6ee6cc0d491695fa", size = 38687626, upload-time = "2025-09-11T17:40:24.041Z" }, + { url = "https://files.pythonhosted.org/packages/68/72/02f37316adf95307f5d9e579023c6899f89ff3a051fa079dbd6faafc48e5/scipy-1.16.2-cp311-cp311-win_arm64.whl", hash = "sha256:f3bf75a6dcecab62afde4d1f973f1692be013110cad5338007927db8da73249c", size = 25503506, upload-time = "2025-09-11T17:40:30.703Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8d/6396e00db1282279a4ddd507c5f5e11f606812b608ee58517ce8abbf883f/scipy-1.16.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:89d6c100fa5c48472047632e06f0876b3c4931aac1f4291afc81a3644316bb0d", size = 36646259, upload-time = "2025-09-11T17:40:39.329Z" }, + { url = "https://files.pythonhosted.org/packages/3b/93/ea9edd7e193fceb8eef149804491890bde73fb169c896b61aa3e2d1e4e77/scipy-1.16.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ca748936cd579d3f01928b30a17dc474550b01272d8046e3e1ee593f23620371", size = 28888976, upload-time = "2025-09-11T17:40:46.82Z" }, + { url = "https://files.pythonhosted.org/packages/91/4d/281fddc3d80fd738ba86fd3aed9202331180b01e2c78eaae0642f22f7e83/scipy-1.16.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:fac4f8ce2ddb40e2e3d0f7ec36d2a1e7f92559a2471e59aec37bd8d9de01fec0", size = 20879905, upload-time = "2025-09-11T17:40:52.545Z" }, + { url = "https://files.pythonhosted.org/packages/69/40/b33b74c84606fd301b2915f0062e45733c6ff5708d121dd0deaa8871e2d0/scipy-1.16.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:033570f1dcefd79547a88e18bccacff025c8c647a330381064f561d43b821232", size = 23553066, upload-time = "2025-09-11T17:40:59.014Z" }, + { url = "https://files.pythonhosted.org/packages/55/a7/22c739e2f21a42cc8f16bc76b47cff4ed54fbe0962832c589591c2abec34/scipy-1.16.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ea3421209bf00c8a5ef2227de496601087d8f638a2363ee09af059bd70976dc1", size = 33336407, upload-time = "2025-09-11T17:41:06.796Z" }, + { url = "https://files.pythonhosted.org/packages/53/11/a0160990b82999b45874dc60c0c183d3a3a969a563fffc476d5a9995c407/scipy-1.16.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f66bd07ba6f84cd4a380b41d1bf3c59ea488b590a2ff96744845163309ee8e2f", size = 35673281, upload-time = "2025-09-11T17:41:15.055Z" }, + { url = "https://files.pythonhosted.org/packages/96/53/7ef48a4cfcf243c3d0f1643f5887c81f29fdf76911c4e49331828e19fc0a/scipy-1.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e9feab931bd2aea4a23388c962df6468af3d808ddf2d40f94a81c5dc38f32ef", size = 36004222, upload-time = "2025-09-11T17:41:23.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7f/71a69e0afd460049d41c65c630c919c537815277dfea214031005f474d78/scipy-1.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03dfc75e52f72cf23ec2ced468645321407faad8f0fe7b1f5b49264adbc29cb1", size = 38664586, upload-time = "2025-09-11T17:41:31.021Z" }, + { url = "https://files.pythonhosted.org/packages/34/95/20e02ca66fb495a95fba0642fd48e0c390d0ece9b9b14c6e931a60a12dea/scipy-1.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:0ce54e07bbb394b417457409a64fd015be623f36e330ac49306433ffe04bc97e", size = 38550641, upload-time = "2025-09-11T17:41:36.61Z" }, + { url = "https://files.pythonhosted.org/packages/92/ad/13646b9beb0a95528ca46d52b7babafbe115017814a611f2065ee4e61d20/scipy-1.16.2-cp312-cp312-win_arm64.whl", hash = "sha256:2a8ffaa4ac0df81a0b94577b18ee079f13fecdb924df3328fc44a7dc5ac46851", size = 25456070, upload-time = "2025-09-11T17:41:41.3Z" }, + { url = "https://files.pythonhosted.org/packages/c1/27/c5b52f1ee81727a9fc457f5ac1e9bf3d6eab311805ea615c83c27ba06400/scipy-1.16.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:84f7bf944b43e20b8a894f5fe593976926744f6c185bacfcbdfbb62736b5cc70", size = 36604856, upload-time = "2025-09-11T17:41:47.695Z" }, + { url = "https://files.pythonhosted.org/packages/32/a9/15c20d08e950b540184caa8ced675ba1128accb0e09c653780ba023a4110/scipy-1.16.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5c39026d12edc826a1ef2ad35ad1e6d7f087f934bb868fc43fa3049c8b8508f9", size = 28864626, upload-time = "2025-09-11T17:41:52.642Z" }, + { url = "https://files.pythonhosted.org/packages/4c/fc/ea36098df653cca26062a627c1a94b0de659e97127c8491e18713ca0e3b9/scipy-1.16.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e52729ffd45b68777c5319560014d6fd251294200625d9d70fd8626516fc49f5", size = 20855689, upload-time = "2025-09-11T17:41:57.886Z" }, + { url = "https://files.pythonhosted.org/packages/dc/6f/d0b53be55727f3e6d7c72687ec18ea6d0047cf95f1f77488b99a2bafaee1/scipy-1.16.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:024dd4a118cccec09ca3209b7e8e614931a6ffb804b2a601839499cb88bdf925", size = 23512151, upload-time = "2025-09-11T17:42:02.303Z" }, + { url = "https://files.pythonhosted.org/packages/11/85/bf7dab56e5c4b1d3d8eef92ca8ede788418ad38a7dc3ff50262f00808760/scipy-1.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7a5dc7ee9c33019973a470556081b0fd3c9f4c44019191039f9769183141a4d9", size = 33329824, upload-time = "2025-09-11T17:42:07.549Z" }, + { url = "https://files.pythonhosted.org/packages/da/6a/1a927b14ddc7714111ea51f4e568203b2bb6ed59bdd036d62127c1a360c8/scipy-1.16.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c2275ff105e508942f99d4e3bc56b6ef5e4b3c0af970386ca56b777608ce95b7", size = 35681881, upload-time = "2025-09-11T17:42:13.255Z" }, + { url = "https://files.pythonhosted.org/packages/c1/5f/331148ea5780b4fcc7007a4a6a6ee0a0c1507a796365cc642d4d226e1c3a/scipy-1.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:af80196eaa84f033e48444d2e0786ec47d328ba00c71e4299b602235ffef9acb", size = 36006219, upload-time = "2025-09-11T17:42:18.765Z" }, + { url = "https://files.pythonhosted.org/packages/46/3a/e991aa9d2aec723b4a8dcfbfc8365edec5d5e5f9f133888067f1cbb7dfc1/scipy-1.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9fb1eb735fe3d6ed1f89918224e3385fbf6f9e23757cacc35f9c78d3b712dd6e", size = 38682147, upload-time = "2025-09-11T17:42:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/a1/57/0f38e396ad19e41b4c5db66130167eef8ee620a49bc7d0512e3bb67e0cab/scipy-1.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:fda714cf45ba43c9d3bae8f2585c777f64e3f89a2e073b668b32ede412d8f52c", size = 38520766, upload-time = "2025-09-11T17:43:25.342Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a5/85d3e867b6822d331e26c862a91375bb7746a0b458db5effa093d34cdb89/scipy-1.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:2f5350da923ccfd0b00e07c3e5cfb316c1c0d6c1d864c07a72d092e9f20db104", size = 25451169, upload-time = "2025-09-11T17:43:30.198Z" }, + { url = "https://files.pythonhosted.org/packages/09/d9/60679189bcebda55992d1a45498de6d080dcaf21ce0c8f24f888117e0c2d/scipy-1.16.2-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:53d8d2ee29b925344c13bda64ab51785f016b1b9617849dac10897f0701b20c1", size = 37012682, upload-time = "2025-09-11T17:42:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/83/be/a99d13ee4d3b7887a96f8c71361b9659ba4ef34da0338f14891e102a127f/scipy-1.16.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:9e05e33657efb4c6a9d23bd8300101536abd99c85cca82da0bffff8d8764d08a", size = 29389926, upload-time = "2025-09-11T17:42:35.845Z" }, + { url = "https://files.pythonhosted.org/packages/bf/0a/130164a4881cec6ca8c00faf3b57926f28ed429cd6001a673f83c7c2a579/scipy-1.16.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:7fe65b36036357003b3ef9d37547abeefaa353b237e989c21027b8ed62b12d4f", size = 21381152, upload-time = "2025-09-11T17:42:40.07Z" }, + { url = "https://files.pythonhosted.org/packages/47/a6/503ffb0310ae77fba874e10cddfc4a1280bdcca1d13c3751b8c3c2996cf8/scipy-1.16.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6406d2ac6d40b861cccf57f49592f9779071655e9f75cd4f977fa0bdd09cb2e4", size = 23914410, upload-time = "2025-09-11T17:42:44.313Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c7/1147774bcea50d00c02600aadaa919facbd8537997a62496270133536ed6/scipy-1.16.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff4dc42bd321991fbf611c23fc35912d690f731c9914bf3af8f417e64aca0f21", size = 33481880, upload-time = "2025-09-11T17:42:49.325Z" }, + { url = "https://files.pythonhosted.org/packages/6a/74/99d5415e4c3e46b2586f30cdbecb95e101c7192628a484a40dd0d163811a/scipy-1.16.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:654324826654d4d9133e10675325708fb954bc84dae6e9ad0a52e75c6b1a01d7", size = 35791425, upload-time = "2025-09-11T17:42:54.711Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ee/a6559de7c1cc710e938c0355d9d4fbcd732dac4d0d131959d1f3b63eb29c/scipy-1.16.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63870a84cd15c44e65220eaed2dac0e8f8b26bbb991456a033c1d9abfe8a94f8", size = 36178622, upload-time = "2025-09-11T17:43:00.375Z" }, + { url = "https://files.pythonhosted.org/packages/4e/7b/f127a5795d5ba8ece4e0dce7d4a9fb7cb9e4f4757137757d7a69ab7d4f1a/scipy-1.16.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fa01f0f6a3050fa6a9771a95d5faccc8e2f5a92b4a2e5440a0fa7264a2398472", size = 38783985, upload-time = "2025-09-11T17:43:06.661Z" }, + { url = "https://files.pythonhosted.org/packages/3e/9f/bc81c1d1e033951eb5912cd3750cc005943afa3e65a725d2443a3b3c4347/scipy-1.16.2-cp313-cp313t-win_amd64.whl", hash = "sha256:116296e89fba96f76353a8579820c2512f6e55835d3fad7780fece04367de351", size = 38631367, upload-time = "2025-09-11T17:43:14.44Z" }, + { url = "https://files.pythonhosted.org/packages/d6/5e/2cc7555fd81d01814271412a1d59a289d25f8b63208a0a16c21069d55d3e/scipy-1.16.2-cp313-cp313t-win_arm64.whl", hash = "sha256:98e22834650be81d42982360382b43b17f7ba95e0e6993e2a4f5b9ad9283a94d", size = 25787992, upload-time = "2025-09-11T17:43:19.745Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ac/ad8951250516db71619f0bd3b2eb2448db04b720a003dd98619b78b692c0/scipy-1.16.2-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:567e77755019bb7461513c87f02bb73fb65b11f049aaaa8ca17cfaa5a5c45d77", size = 36595109, upload-time = "2025-09-11T17:43:35.713Z" }, + { url = "https://files.pythonhosted.org/packages/ff/f6/5779049ed119c5b503b0f3dc6d6f3f68eefc3a9190d4ad4c276f854f051b/scipy-1.16.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:17d9bb346194e8967296621208fcdfd39b55498ef7d2f376884d5ac47cec1a70", size = 28859110, upload-time = "2025-09-11T17:43:40.814Z" }, + { url = "https://files.pythonhosted.org/packages/82/09/9986e410ae38bf0a0c737ff8189ac81a93b8e42349aac009891c054403d7/scipy-1.16.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:0a17541827a9b78b777d33b623a6dcfe2ef4a25806204d08ead0768f4e529a88", size = 20850110, upload-time = "2025-09-11T17:43:44.981Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ad/485cdef2d9215e2a7df6d61b81d2ac073dfacf6ae24b9ae87274c4e936ae/scipy-1.16.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:d7d4c6ba016ffc0f9568d012f5f1eb77ddd99412aea121e6fa8b4c3b7cbad91f", size = 23497014, upload-time = "2025-09-11T17:43:49.074Z" }, + { url = "https://files.pythonhosted.org/packages/a7/74/f6a852e5d581122b8f0f831f1d1e32fb8987776ed3658e95c377d308ed86/scipy-1.16.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9702c4c023227785c779cba2e1d6f7635dbb5b2e0936cdd3a4ecb98d78fd41eb", size = 33401155, upload-time = "2025-09-11T17:43:54.661Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f5/61d243bbc7c6e5e4e13dde9887e84a5cbe9e0f75fd09843044af1590844e/scipy-1.16.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d1cdf0ac28948d225decdefcc45ad7dd91716c29ab56ef32f8e0d50657dffcc7", size = 35691174, upload-time = "2025-09-11T17:44:00.101Z" }, + { url = "https://files.pythonhosted.org/packages/03/99/59933956331f8cc57e406cdb7a483906c74706b156998f322913e789c7e1/scipy-1.16.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:70327d6aa572a17c2941cdfb20673f82e536e91850a2e4cb0c5b858b690e1548", size = 36070752, upload-time = "2025-09-11T17:44:05.619Z" }, + { url = "https://files.pythonhosted.org/packages/c6/7d/00f825cfb47ee19ef74ecf01244b43e95eae74e7e0ff796026ea7cd98456/scipy-1.16.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5221c0b2a4b58aa7c4ed0387d360fd90ee9086d383bb34d9f2789fafddc8a936", size = 38701010, upload-time = "2025-09-11T17:44:11.322Z" }, + { url = "https://files.pythonhosted.org/packages/e4/9f/b62587029980378304ba5a8563d376c96f40b1e133daacee76efdcae32de/scipy-1.16.2-cp314-cp314-win_amd64.whl", hash = "sha256:f5a85d7b2b708025af08f060a496dd261055b617d776fc05a1a1cc69e09fe9ff", size = 39360061, upload-time = "2025-09-11T17:45:09.814Z" }, + { url = "https://files.pythonhosted.org/packages/82/04/7a2f1609921352c7fbee0815811b5050582f67f19983096c4769867ca45f/scipy-1.16.2-cp314-cp314-win_arm64.whl", hash = "sha256:2cc73a33305b4b24556957d5857d6253ce1e2dcd67fa0ff46d87d1670b3e1e1d", size = 26126914, upload-time = "2025-09-11T17:45:14.73Z" }, + { url = "https://files.pythonhosted.org/packages/51/b9/60929ce350c16b221928725d2d1d7f86cf96b8bc07415547057d1196dc92/scipy-1.16.2-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:9ea2a3fed83065d77367775d689401a703d0f697420719ee10c0780bcab594d8", size = 37013193, upload-time = "2025-09-11T17:44:16.757Z" }, + { url = "https://files.pythonhosted.org/packages/2a/41/ed80e67782d4bc5fc85a966bc356c601afddd175856ba7c7bb6d9490607e/scipy-1.16.2-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7280d926f11ca945c3ef92ba960fa924e1465f8d07ce3a9923080363390624c4", size = 29390172, upload-time = "2025-09-11T17:44:21.783Z" }, + { url = "https://files.pythonhosted.org/packages/c4/a3/2f673ace4090452696ccded5f5f8efffb353b8f3628f823a110e0170b605/scipy-1.16.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:8afae1756f6a1fe04636407ef7dbece33d826a5d462b74f3d0eb82deabefd831", size = 21381326, upload-time = "2025-09-11T17:44:25.982Z" }, + { url = "https://files.pythonhosted.org/packages/42/bf/59df61c5d51395066c35836b78136accf506197617c8662e60ea209881e1/scipy-1.16.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:5c66511f29aa8d233388e7416a3f20d5cae7a2744d5cee2ecd38c081f4e861b3", size = 23915036, upload-time = "2025-09-11T17:44:30.527Z" }, + { url = "https://files.pythonhosted.org/packages/91/c3/edc7b300dc16847ad3672f1a6f3f7c5d13522b21b84b81c265f4f2760d4a/scipy-1.16.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efe6305aeaa0e96b0ccca5ff647a43737d9a092064a3894e46c414db84bc54ac", size = 33484341, upload-time = "2025-09-11T17:44:35.981Z" }, + { url = "https://files.pythonhosted.org/packages/26/c7/24d1524e72f06ff141e8d04b833c20db3021020563272ccb1b83860082a9/scipy-1.16.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f3a337d9ae06a1e8d655ee9d8ecb835ea5ddcdcbd8d23012afa055ab014f374", size = 35790840, upload-time = "2025-09-11T17:44:41.76Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b7/5aaad984eeedd56858dc33d75efa59e8ce798d918e1033ef62d2708f2c3d/scipy-1.16.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bab3605795d269067d8ce78a910220262711b753de8913d3deeaedb5dded3bb6", size = 36174716, upload-time = "2025-09-11T17:44:47.316Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c2/e276a237acb09824822b0ada11b028ed4067fdc367a946730979feacb870/scipy-1.16.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b0348d8ddb55be2a844c518cd8cc8deeeb8aeba707cf834db5758fc89b476a2c", size = 38790088, upload-time = "2025-09-11T17:44:53.011Z" }, + { url = "https://files.pythonhosted.org/packages/c6/b4/5c18a766e8353015439f3780f5fc473f36f9762edc1a2e45da3ff5a31b21/scipy-1.16.2-cp314-cp314t-win_amd64.whl", hash = "sha256:26284797e38b8a75e14ea6631d29bda11e76ceaa6ddb6fdebbfe4c4d90faf2f9", size = 39457455, upload-time = "2025-09-11T17:44:58.899Z" }, + { url = "https://files.pythonhosted.org/packages/97/30/2f9a5243008f76dfc5dee9a53dfb939d9b31e16ce4bd4f2e628bfc5d89d2/scipy-1.16.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d2a4472c231328d4de38d5f1f68fdd6d28a615138f842580a8a321b5845cf779", size = 26448374, upload-time = "2025-09-11T17:45:03.45Z" }, +] + [[package]] name = "setuptools" version = "80.9.0" @@ -1720,6 +1672,73 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, ] +[[package]] +name = "shapely" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/bc/0989043118a27cccb4e906a46b7565ce36ca7b57f5a18b78f4f1b0f72d9d/shapely-2.1.2.tar.gz", hash = "sha256:2ed4ecb28320a433db18a5bf029986aa8afcfd740745e78847e330d5d94922a9", size = 315489, upload-time = "2025-09-24T13:51:41.432Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/89/c3548aa9b9812a5d143986764dededfa48d817714e947398bdda87c77a72/shapely-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7ae48c236c0324b4e139bea88a306a04ca630f49be66741b340729d380d8f52f", size = 1825959, upload-time = "2025-09-24T13:50:00.682Z" }, + { url = "https://files.pythonhosted.org/packages/ce/8a/7ebc947080442edd614ceebe0ce2cdbd00c25e832c240e1d1de61d0e6b38/shapely-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eba6710407f1daa8e7602c347dfc94adc02205ec27ed956346190d66579eb9ea", size = 1629196, upload-time = "2025-09-24T13:50:03.447Z" }, + { url = "https://files.pythonhosted.org/packages/c8/86/c9c27881c20d00fc409e7e059de569d5ed0abfcec9c49548b124ebddea51/shapely-2.1.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ef4a456cc8b7b3d50ccec29642aa4aeda959e9da2fe9540a92754770d5f0cf1f", size = 2951065, upload-time = "2025-09-24T13:50:05.266Z" }, + { url = "https://files.pythonhosted.org/packages/50/8a/0ab1f7433a2a85d9e9aea5b1fbb333f3b09b309e7817309250b4b7b2cc7a/shapely-2.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e38a190442aacc67ff9f75ce60aec04893041f16f97d242209106d502486a142", size = 3058666, upload-time = "2025-09-24T13:50:06.872Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c6/5a30ffac9c4f3ffd5b7113a7f5299ccec4713acd5ee44039778a7698224e/shapely-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:40d784101f5d06a1fd30b55fc11ea58a61be23f930d934d86f19a180909908a4", size = 3966905, upload-time = "2025-09-24T13:50:09.417Z" }, + { url = "https://files.pythonhosted.org/packages/9c/72/e92f3035ba43e53959007f928315a68fbcf2eeb4e5ededb6f0dc7ff1ecc3/shapely-2.1.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f6f6cd5819c50d9bcf921882784586aab34a4bd53e7553e175dece6db513a6f0", size = 4129260, upload-time = "2025-09-24T13:50:11.183Z" }, + { url = "https://files.pythonhosted.org/packages/42/24/605901b73a3d9f65fa958e63c9211f4be23d584da8a1a7487382fac7fdc5/shapely-2.1.2-cp310-cp310-win32.whl", hash = "sha256:fe9627c39c59e553c90f5bc3128252cb85dc3b3be8189710666d2f8bc3a5503e", size = 1544301, upload-time = "2025-09-24T13:50:12.521Z" }, + { url = "https://files.pythonhosted.org/packages/e1/89/6db795b8dd3919851856bd2ddd13ce434a748072f6fdee42ff30cbd3afa3/shapely-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:1d0bfb4b8f661b3b4ec3565fa36c340bfb1cda82087199711f86a88647d26b2f", size = 1722074, upload-time = "2025-09-24T13:50:13.909Z" }, + { url = "https://files.pythonhosted.org/packages/8f/8d/1ff672dea9ec6a7b5d422eb6d095ed886e2e523733329f75fdcb14ee1149/shapely-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:91121757b0a36c9aac3427a651a7e6567110a4a67c97edf04f8d55d4765f6618", size = 1820038, upload-time = "2025-09-24T13:50:15.628Z" }, + { url = "https://files.pythonhosted.org/packages/4f/ce/28fab8c772ce5db23a0d86bf0adaee0c4c79d5ad1db766055fa3dab442e2/shapely-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:16a9c722ba774cf50b5d4541242b4cce05aafd44a015290c82ba8a16931ff63d", size = 1626039, upload-time = "2025-09-24T13:50:16.881Z" }, + { url = "https://files.pythonhosted.org/packages/70/8b/868b7e3f4982f5006e9395c1e12343c66a8155c0374fdc07c0e6a1ab547d/shapely-2.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cc4f7397459b12c0b196c9efe1f9d7e92463cbba142632b4cc6d8bbbbd3e2b09", size = 3001519, upload-time = "2025-09-24T13:50:18.606Z" }, + { url = "https://files.pythonhosted.org/packages/13/02/58b0b8d9c17c93ab6340edd8b7308c0c5a5b81f94ce65705819b7416dba5/shapely-2.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:136ab87b17e733e22f0961504d05e77e7be8c9b5a8184f685b4a91a84efe3c26", size = 3110842, upload-time = "2025-09-24T13:50:21.77Z" }, + { url = "https://files.pythonhosted.org/packages/af/61/8e389c97994d5f331dcffb25e2fa761aeedfb52b3ad9bcdd7b8671f4810a/shapely-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:16c5d0fc45d3aa0a69074979f4f1928ca2734fb2e0dde8af9611e134e46774e7", size = 4021316, upload-time = "2025-09-24T13:50:23.626Z" }, + { url = "https://files.pythonhosted.org/packages/d3/d4/9b2a9fe6039f9e42ccf2cb3e84f219fd8364b0c3b8e7bbc857b5fbe9c14c/shapely-2.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6ddc759f72b5b2b0f54a7e7cde44acef680a55019eb52ac63a7af2cf17cb9cd2", size = 4178586, upload-time = "2025-09-24T13:50:25.443Z" }, + { url = "https://files.pythonhosted.org/packages/16/f6/9840f6963ed4decf76b08fd6d7fed14f8779fb7a62cb45c5617fa8ac6eab/shapely-2.1.2-cp311-cp311-win32.whl", hash = "sha256:2fa78b49485391224755a856ed3b3bd91c8455f6121fee0db0e71cefb07d0ef6", size = 1543961, upload-time = "2025-09-24T13:50:26.968Z" }, + { url = "https://files.pythonhosted.org/packages/38/1e/3f8ea46353c2a33c1669eb7327f9665103aa3a8dfe7f2e4ef714c210b2c2/shapely-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:c64d5c97b2f47e3cd9b712eaced3b061f2b71234b3fc263e0fcf7d889c6559dc", size = 1722856, upload-time = "2025-09-24T13:50:28.497Z" }, + { url = "https://files.pythonhosted.org/packages/24/c0/f3b6453cf2dfa99adc0ba6675f9aaff9e526d2224cbd7ff9c1a879238693/shapely-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fe2533caae6a91a543dec62e8360fe86ffcdc42a7c55f9dfd0128a977a896b94", size = 1833550, upload-time = "2025-09-24T13:50:30.019Z" }, + { url = "https://files.pythonhosted.org/packages/86/07/59dee0bc4b913b7ab59ab1086225baca5b8f19865e6101db9ebb7243e132/shapely-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ba4d1333cc0bc94381d6d4308d2e4e008e0bd128bdcff5573199742ee3634359", size = 1643556, upload-time = "2025-09-24T13:50:32.291Z" }, + { url = "https://files.pythonhosted.org/packages/26/29/a5397e75b435b9895cd53e165083faed5d12fd9626eadec15a83a2411f0f/shapely-2.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0bd308103340030feef6c111d3eb98d50dc13feea33affc8a6f9fa549e9458a3", size = 2988308, upload-time = "2025-09-24T13:50:33.862Z" }, + { url = "https://files.pythonhosted.org/packages/b9/37/e781683abac55dde9771e086b790e554811a71ed0b2b8a1e789b7430dd44/shapely-2.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1e7d4d7ad262a48bb44277ca12c7c78cb1b0f56b32c10734ec9a1d30c0b0c54b", size = 3099844, upload-time = "2025-09-24T13:50:35.459Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f3/9876b64d4a5a321b9dc482c92bb6f061f2fa42131cba643c699f39317cb9/shapely-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e9eddfe513096a71896441a7c37db72da0687b34752c4e193577a145c71736fc", size = 3988842, upload-time = "2025-09-24T13:50:37.478Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a0/704c7292f7014c7e74ec84eddb7b109e1fbae74a16deae9c1504b1d15565/shapely-2.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:980c777c612514c0cf99bc8a9de6d286f5e186dcaf9091252fcd444e5638193d", size = 4152714, upload-time = "2025-09-24T13:50:39.9Z" }, + { url = "https://files.pythonhosted.org/packages/53/46/319c9dc788884ad0785242543cdffac0e6530e4d0deb6c4862bc4143dcf3/shapely-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9111274b88e4d7b54a95218e243282709b330ef52b7b86bc6aaf4f805306f454", size = 1542745, upload-time = "2025-09-24T13:50:41.414Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bf/cb6c1c505cb31e818e900b9312d514f381fbfa5c4363edfce0fcc4f8c1a4/shapely-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:743044b4cfb34f9a67205cee9279feaf60ba7d02e69febc2afc609047cb49179", size = 1722861, upload-time = "2025-09-24T13:50:43.35Z" }, + { url = "https://files.pythonhosted.org/packages/c3/90/98ef257c23c46425dc4d1d31005ad7c8d649fe423a38b917db02c30f1f5a/shapely-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b510dda1a3672d6879beb319bc7c5fd302c6c354584690973c838f46ec3e0fa8", size = 1832644, upload-time = "2025-09-24T13:50:44.886Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ab/0bee5a830d209adcd3a01f2d4b70e587cdd9fd7380d5198c064091005af8/shapely-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8cff473e81017594d20ec55d86b54bc635544897e13a7cfc12e36909c5309a2a", size = 1642887, upload-time = "2025-09-24T13:50:46.735Z" }, + { url = "https://files.pythonhosted.org/packages/2d/5e/7d7f54ba960c13302584c73704d8c4d15404a51024631adb60b126a4ae88/shapely-2.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe7b77dc63d707c09726b7908f575fc04ff1d1ad0f3fb92aec212396bc6cfe5e", size = 2970931, upload-time = "2025-09-24T13:50:48.374Z" }, + { url = "https://files.pythonhosted.org/packages/f2/a2/83fc37e2a58090e3d2ff79175a95493c664bcd0b653dd75cb9134645a4e5/shapely-2.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ed1a5bbfb386ee8332713bf7508bc24e32d24b74fc9a7b9f8529a55db9f4ee6", size = 3082855, upload-time = "2025-09-24T13:50:50.037Z" }, + { url = "https://files.pythonhosted.org/packages/44/2b/578faf235a5b09f16b5f02833c53822294d7f21b242f8e2d0cf03fb64321/shapely-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a84e0582858d841d54355246ddfcbd1fce3179f185da7470f41ce39d001ee1af", size = 3979960, upload-time = "2025-09-24T13:50:51.74Z" }, + { url = "https://files.pythonhosted.org/packages/4d/04/167f096386120f692cc4ca02f75a17b961858997a95e67a3cb6a7bbd6b53/shapely-2.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc3487447a43d42adcdf52d7ac73804f2312cbfa5d433a7d2c506dcab0033dfd", size = 4142851, upload-time = "2025-09-24T13:50:53.49Z" }, + { url = "https://files.pythonhosted.org/packages/48/74/fb402c5a6235d1c65a97348b48cdedb75fb19eca2b1d66d04969fc1c6091/shapely-2.1.2-cp313-cp313-win32.whl", hash = "sha256:9c3a3c648aedc9f99c09263b39f2d8252f199cb3ac154fadc173283d7d111350", size = 1541890, upload-time = "2025-09-24T13:50:55.337Z" }, + { url = "https://files.pythonhosted.org/packages/41/47/3647fe7ad990af60ad98b889657a976042c9988c2807cf322a9d6685f462/shapely-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:ca2591bff6645c216695bdf1614fca9c82ea1144d4a7591a466fef64f28f0715", size = 1722151, upload-time = "2025-09-24T13:50:57.153Z" }, + { url = "https://files.pythonhosted.org/packages/3c/49/63953754faa51ffe7d8189bfbe9ca34def29f8c0e34c67cbe2a2795f269d/shapely-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2d93d23bdd2ed9dc157b46bc2f19b7da143ca8714464249bef6771c679d5ff40", size = 1834130, upload-time = "2025-09-24T13:50:58.49Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ee/dce001c1984052970ff60eb4727164892fb2d08052c575042a47f5a9e88f/shapely-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:01d0d304b25634d60bd7cf291828119ab55a3bab87dc4af1e44b07fb225f188b", size = 1642802, upload-time = "2025-09-24T13:50:59.871Z" }, + { url = "https://files.pythonhosted.org/packages/da/e7/fc4e9a19929522877fa602f705706b96e78376afb7fad09cad5b9af1553c/shapely-2.1.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8d8382dd120d64b03698b7298b89611a6ea6f55ada9d39942838b79c9bc89801", size = 3018460, upload-time = "2025-09-24T13:51:02.08Z" }, + { url = "https://files.pythonhosted.org/packages/a1/18/7519a25db21847b525696883ddc8e6a0ecaa36159ea88e0fef11466384d0/shapely-2.1.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:19efa3611eef966e776183e338b2d7ea43569ae99ab34f8d17c2c054d3205cc0", size = 3095223, upload-time = "2025-09-24T13:51:04.472Z" }, + { url = "https://files.pythonhosted.org/packages/48/de/b59a620b1f3a129c3fecc2737104a0a7e04e79335bd3b0a1f1609744cf17/shapely-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:346ec0c1a0fcd32f57f00e4134d1200e14bf3f5ae12af87ba83ca275c502498c", size = 4030760, upload-time = "2025-09-24T13:51:06.455Z" }, + { url = "https://files.pythonhosted.org/packages/96/b3/c6655ee7232b417562bae192ae0d3ceaadb1cc0ffc2088a2ddf415456cc2/shapely-2.1.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6305993a35989391bd3476ee538a5c9a845861462327efe00dd11a5c8c709a99", size = 4170078, upload-time = "2025-09-24T13:51:08.584Z" }, + { url = "https://files.pythonhosted.org/packages/a0/8e/605c76808d73503c9333af8f6cbe7e1354d2d238bda5f88eea36bfe0f42a/shapely-2.1.2-cp313-cp313t-win32.whl", hash = "sha256:c8876673449f3401f278c86eb33224c5764582f72b653a415d0e6672fde887bf", size = 1559178, upload-time = "2025-09-24T13:51:10.73Z" }, + { url = "https://files.pythonhosted.org/packages/36/f7/d317eb232352a1f1444d11002d477e54514a4a6045536d49d0c59783c0da/shapely-2.1.2-cp313-cp313t-win_amd64.whl", hash = "sha256:4a44bc62a10d84c11a7a3d7c1c4fe857f7477c3506e24c9062da0db0ae0c449c", size = 1739756, upload-time = "2025-09-24T13:51:12.105Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c4/3ce4c2d9b6aabd27d26ec988f08cb877ba9e6e96086eff81bfea93e688c7/shapely-2.1.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:9a522f460d28e2bf4e12396240a5fc1518788b2fcd73535166d748399ef0c223", size = 1831290, upload-time = "2025-09-24T13:51:13.56Z" }, + { url = "https://files.pythonhosted.org/packages/17/b9/f6ab8918fc15429f79cb04afa9f9913546212d7fb5e5196132a2af46676b/shapely-2.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1ff629e00818033b8d71139565527ced7d776c269a49bd78c9df84e8f852190c", size = 1641463, upload-time = "2025-09-24T13:51:14.972Z" }, + { url = "https://files.pythonhosted.org/packages/a5/57/91d59ae525ca641e7ac5551c04c9503aee6f29b92b392f31790fcb1a4358/shapely-2.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f67b34271dedc3c653eba4e3d7111aa421d5be9b4c4c7d38d30907f796cb30df", size = 2970145, upload-time = "2025-09-24T13:51:16.961Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cb/4948be52ee1da6927831ab59e10d4c29baa2a714f599f1f0d1bc747f5777/shapely-2.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21952dc00df38a2c28375659b07a3979d22641aeb104751e769c3ee825aadecf", size = 3073806, upload-time = "2025-09-24T13:51:18.712Z" }, + { url = "https://files.pythonhosted.org/packages/03/83/f768a54af775eb41ef2e7bec8a0a0dbe7d2431c3e78c0a8bdba7ab17e446/shapely-2.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1f2f33f486777456586948e333a56ae21f35ae273be99255a191f5c1fa302eb4", size = 3980803, upload-time = "2025-09-24T13:51:20.37Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/559c7c195807c91c79d38a1f6901384a2878a76fbdf3f1048893a9b7534d/shapely-2.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cf831a13e0d5a7eb519e96f58ec26e049b1fad411fc6fc23b162a7ce04d9cffc", size = 4133301, upload-time = "2025-09-24T13:51:21.887Z" }, + { url = "https://files.pythonhosted.org/packages/80/cd/60d5ae203241c53ef3abd2ef27c6800e21afd6c94e39db5315ea0cbafb4a/shapely-2.1.2-cp314-cp314-win32.whl", hash = "sha256:61edcd8d0d17dd99075d320a1dd39c0cb9616f7572f10ef91b4b5b00c4aeb566", size = 1583247, upload-time = "2025-09-24T13:51:23.401Z" }, + { url = "https://files.pythonhosted.org/packages/74/d4/135684f342e909330e50d31d441ace06bf83c7dc0777e11043f99167b123/shapely-2.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:a444e7afccdb0999e203b976adb37ea633725333e5b119ad40b1ca291ecf311c", size = 1773019, upload-time = "2025-09-24T13:51:24.873Z" }, + { url = "https://files.pythonhosted.org/packages/a3/05/a44f3f9f695fa3ada22786dc9da33c933da1cbc4bfe876fe3a100bafe263/shapely-2.1.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:5ebe3f84c6112ad3d4632b1fd2290665aa75d4cef5f6c5d77c4c95b324527c6a", size = 1834137, upload-time = "2025-09-24T13:51:26.665Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/4d57db45bf314573427b0a70dfca15d912d108e6023f623947fa69f39b72/shapely-2.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5860eb9f00a1d49ebb14e881f5caf6c2cf472c7fd38bd7f253bbd34f934eb076", size = 1642884, upload-time = "2025-09-24T13:51:28.029Z" }, + { url = "https://files.pythonhosted.org/packages/5a/27/4e29c0a55d6d14ad7422bf86995d7ff3f54af0eba59617eb95caf84b9680/shapely-2.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b705c99c76695702656327b819c9660768ec33f5ce01fa32b2af62b56ba400a1", size = 3018320, upload-time = "2025-09-24T13:51:29.903Z" }, + { url = "https://files.pythonhosted.org/packages/9f/bb/992e6a3c463f4d29d4cd6ab8963b75b1b1040199edbd72beada4af46bde5/shapely-2.1.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a1fd0ea855b2cf7c9cddaf25543e914dd75af9de08785f20ca3085f2c9ca60b0", size = 3094931, upload-time = "2025-09-24T13:51:32.699Z" }, + { url = "https://files.pythonhosted.org/packages/9c/16/82e65e21070e473f0ed6451224ed9fa0be85033d17e0c6e7213a12f59d12/shapely-2.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:df90e2db118c3671a0754f38e36802db75fe0920d211a27481daf50a711fdf26", size = 4030406, upload-time = "2025-09-24T13:51:34.189Z" }, + { url = "https://files.pythonhosted.org/packages/7c/75/c24ed871c576d7e2b64b04b1fe3d075157f6eb54e59670d3f5ffb36e25c7/shapely-2.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:361b6d45030b4ac64ddd0a26046906c8202eb60d0f9f53085f5179f1d23021a0", size = 4169511, upload-time = "2025-09-24T13:51:36.297Z" }, + { url = "https://files.pythonhosted.org/packages/b1/f7/b3d1d6d18ebf55236eec1c681ce5e665742aab3c0b7b232720a7d43df7b6/shapely-2.1.2-cp314-cp314t-win32.whl", hash = "sha256:b54df60f1fbdecc8ebc2c5b11870461a6417b3d617f555e5033f1505d36e5735", size = 1602607, upload-time = "2025-09-24T13:51:37.757Z" }, + { url = "https://files.pythonhosted.org/packages/9a/f6/f09272a71976dfc138129b8faf435d064a811ae2f708cb147dccdf7aacdb/shapely-2.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:0036ac886e0923417932c2e6369b6c52e38e0ff5d9120b90eef5cd9a5fc5cae9", size = 1796682, upload-time = "2025-09-24T13:51:39.233Z" }, +] + [[package]] name = "six" version = "1.17.0" @@ -1738,6 +1757,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415, upload-time = "2024-12-10T12:05:27.824Z" }, ] +[[package]] +name = "threadpoolctl" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, +] + [[package]] name = "tomli" version = "2.3.0" @@ -1788,12 +1816,15 @@ wheels = [ ] [[package]] -name = "typing" -version = "3.10.0.0" +name = "tqdm" +version = "4.67.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/1b/835d4431805939d2996f8772aca1d2313a57e8860fec0e48e8e7dfe3a477/typing-3.10.0.0.tar.gz", hash = "sha256:13b4ad211f54ddbf93e5901a9967b1e07720c1d1b78d596ac6a439641aa1b130", size = 78962, upload-time = "2021-05-01T18:03:58.186Z" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/5d/865e17349564eb1772688d8afc5e3081a5964c640d64d1d2880ebaed002d/typing-3.10.0.0-py3-none-any.whl", hash = "sha256:12fbdfbe7d6cca1a42e485229afcb0b0c8259258cfb919b8a5e2a5c953742f89", size = 26320, upload-time = "2021-05-01T18:03:56.398Z" }, + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, ] [[package]] @@ -1832,6 +1863,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/03/ff/7c0c86c43b3cbb927e0ccc0255cb4057ceba4799cd44ae95174ce8e8b5b2/vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc", size = 9636, upload-time = "2023-11-05T08:46:51.205Z" }, ] +[[package]] +name = "virtualenv" +version = "20.35.3" +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/a4/d5/b0ccd381d55c8f45d46f77df6ae59fbc23d19e901e2d523395598e5f4c93/virtualenv-20.35.3.tar.gz", hash = "sha256:4f1a845d131133bdff10590489610c98c168ff99dc75d6c96853801f7f67af44", size = 6002907, upload-time = "2025-10-10T21:23:33.178Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/73/d9a94da0e9d470a543c1b9d3ccbceb0f59455983088e727b8a1824ed90fb/virtualenv-20.35.3-py3-none-any.whl", hash = "sha256:63d106565078d8c8d0b206d48080f938a8b25361e19432d2c9db40d2899c810a", size = 5981061, upload-time = "2025-10-10T21:23:30.433Z" }, +] + [[package]] name = "wcwidth" version = "0.2.14" @@ -1840,50 +1886,3 @@ sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc7 wheels = [ { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, ] - -[[package]] -name = "zipp" -version = "3.23.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, -] - -[[package]] -name = "zope-interface" -version = "8.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/3a/7fcf02178b8fad0a51e67e32765cd039ae505d054d744d76b8c2bbcba5ba/zope_interface-8.0.1.tar.gz", hash = "sha256:eba5610d042c3704a48222f7f7c6ab5b243ed26f917e2bc69379456b115e02d1", size = 253746, upload-time = "2025-09-25T05:55:51.285Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/75/e5/ffef169d17b92c6236b3b18b890c0ce73502f3cbd5b6532ff20d412d94a3/zope_interface-8.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fd7195081b8637eeed8d73e4d183b07199a1dc738fb28b3de6666b1b55662570", size = 207364, upload-time = "2025-09-25T05:58:50.262Z" }, - { url = "https://files.pythonhosted.org/packages/35/b6/87aca626c09af829d3a32011599d6e18864bc8daa0ad3a7e258f3d7f8bcf/zope_interface-8.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f7c4bc4021108847bce763673ce70d0716b08dfc2ba9889e7bad46ac2b3bb924", size = 207901, upload-time = "2025-09-25T05:58:51.74Z" }, - { url = "https://files.pythonhosted.org/packages/d8/c1/eec33cc9f847ebeb0bc6234d7d45fe3fc0a6fe8fc5b5e6be0442bd2c684d/zope_interface-8.0.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:758803806b962f32c87b31bb18c298b022965ba34fe532163831cc39118c24ab", size = 249358, upload-time = "2025-09-25T05:58:16.979Z" }, - { url = "https://files.pythonhosted.org/packages/58/7d/1e3476a1ef0175559bd8492dc7bb921ad0df5b73861d764b1f824ad5484a/zope_interface-8.0.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f8e88f35f86bbe8243cad4b2972deef0fdfca0a0723455abbebdc83bbab96b69", size = 254475, upload-time = "2025-09-25T05:58:10.032Z" }, - { url = "https://files.pythonhosted.org/packages/bc/67/ba5ea98ff23f723c5cbe7db7409f2e43c9fe2df1ced67881443c01e64478/zope_interface-8.0.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7844765695937d9b0d83211220b72e2cf6ac81a08608ad2b58f2c094af498d83", size = 254913, upload-time = "2025-09-25T06:26:22.263Z" }, - { url = "https://files.pythonhosted.org/packages/2b/a7/b1b8b6c13fba955c043cdee409953ee85f652b106493e2e931a84f95c1aa/zope_interface-8.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:64fa7b206dd9669f29d5c1241a768bebe8ab1e8a4b63ee16491f041e058c09d0", size = 211753, upload-time = "2025-09-25T05:59:00.561Z" }, - { url = "https://files.pythonhosted.org/packages/f2/2f/c10c739bcb9b072090c97c2e08533777497190daa19d190d72b4cce9c7cb/zope_interface-8.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4bd01022d2e1bce4a4a4ed9549edb25393c92e607d7daa6deff843f1f68b479d", size = 207903, upload-time = "2025-09-25T05:58:21.671Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e1/9845ac3697f108d9a1af6912170c59a23732090bbfb35955fe77e5544955/zope_interface-8.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:29be8db8b712d94f1c05e24ea230a879271d787205ba1c9a6100d1d81f06c69a", size = 208345, upload-time = "2025-09-25T05:58:24.217Z" }, - { url = "https://files.pythonhosted.org/packages/f2/49/6573bc8b841cfab18e80c8e8259f1abdbbf716140011370de30231be79ad/zope_interface-8.0.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:51ae1b856565b30455b7879fdf0a56a88763b401d3f814fa9f9542d7410dbd7e", size = 255027, upload-time = "2025-09-25T05:58:19.975Z" }, - { url = "https://files.pythonhosted.org/packages/e2/fd/908b0fd4b1ab6e412dfac9bd2b606f2893ef9ba3dd36d643f5e5b94c57b3/zope_interface-8.0.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d2e7596149cb1acd1d4d41b9f8fe2ffc0e9e29e2e91d026311814181d0d9efaf", size = 259800, upload-time = "2025-09-25T05:58:11.487Z" }, - { url = "https://files.pythonhosted.org/packages/dc/78/8419a2b4e88410520ed4b7f93bbd25a6d4ae66c4e2b131320f2b90f43077/zope_interface-8.0.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b2737c11c34fb9128816759864752d007ec4f987b571c934c30723ed881a7a4f", size = 260978, upload-time = "2025-09-25T06:26:24.483Z" }, - { url = "https://files.pythonhosted.org/packages/e5/90/caf68152c292f1810e2bd3acd2177badf08a740aa8a348714617d6c9ad0b/zope_interface-8.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:cf66e4bf731aa7e0ced855bb3670e8cda772f6515a475c6a107bad5cb6604103", size = 212155, upload-time = "2025-09-25T05:59:40.318Z" }, - { url = "https://files.pythonhosted.org/packages/dc/a6/0f08713ddda834c428ebf97b2a7fd8dea50c0100065a8955924dbd94dae8/zope_interface-8.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:115f27c1cc95ce7a517d960ef381beedb0a7ce9489645e80b9ab3cbf8a78799c", size = 208609, upload-time = "2025-09-25T05:58:53.698Z" }, - { url = "https://files.pythonhosted.org/packages/e9/5e/d423045f54dc81e0991ec655041e7a0eccf6b2642535839dd364b35f4d7f/zope_interface-8.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af655c573b84e3cb6a4f6fd3fbe04e4dc91c63c6b6f99019b3713ef964e589bc", size = 208797, upload-time = "2025-09-25T05:58:56.258Z" }, - { url = "https://files.pythonhosted.org/packages/c6/43/39d4bb3f7a80ebd261446792493cfa4e198badd47107224f5b6fe1997ad9/zope_interface-8.0.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:23f82ef9b2d5370750cc1bf883c3b94c33d098ce08557922a3fbc7ff3b63dfe1", size = 259242, upload-time = "2025-09-25T05:58:21.602Z" }, - { url = "https://files.pythonhosted.org/packages/da/29/49effcff64ef30731e35520a152a9dfcafec86cf114b4c2aff942e8264ba/zope_interface-8.0.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:35a1565d5244997f2e629c5c68715b3d9d9036e8df23c4068b08d9316dcb2822", size = 264696, upload-time = "2025-09-25T05:58:13.351Z" }, - { url = "https://files.pythonhosted.org/packages/c7/39/b947673ec9a258eeaa20208dd2f6127d9fbb3e5071272a674ebe02063a78/zope_interface-8.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:029ea1db7e855a475bf88d9910baab4e94d007a054810e9007ac037a91c67c6f", size = 264229, upload-time = "2025-09-25T06:26:26.226Z" }, - { url = "https://files.pythonhosted.org/packages/8f/ee/eed6efd1fc3788d1bef7a814e0592d8173b7fe601c699b935009df035fc2/zope_interface-8.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0beb3e7f7dc153944076fcaf717a935f68d39efa9fce96ec97bafcc0c2ea6cab", size = 212270, upload-time = "2025-09-25T05:58:53.584Z" }, - { url = "https://files.pythonhosted.org/packages/5f/dc/3c12fca01c910c793d636ffe9c0984e0646abaf804e44552070228ed0ede/zope_interface-8.0.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:c7cc027fc5c61c5d69e5080c30b66382f454f43dc379c463a38e78a9c6bab71a", size = 208992, upload-time = "2025-09-25T05:58:40.712Z" }, - { url = "https://files.pythonhosted.org/packages/46/71/6127b7282a3e380ca927ab2b40778a9c97935a4a57a2656dadc312db5f30/zope_interface-8.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fcf9097ff3003b7662299f1c25145e15260ec2a27f9a9e69461a585d79ca8552", size = 209051, upload-time = "2025-09-25T05:58:42.182Z" }, - { url = "https://files.pythonhosted.org/packages/56/86/4387a9f951ee18b0e41fda77da77d59c33e59f04660578e2bad688703e64/zope_interface-8.0.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6d965347dd1fb9e9a53aa852d4ded46b41ca670d517fd54e733a6b6a4d0561c2", size = 259223, upload-time = "2025-09-25T05:58:23.191Z" }, - { url = "https://files.pythonhosted.org/packages/61/08/ce60a114466abc067c68ed41e2550c655f551468ae17b4b17ea360090146/zope_interface-8.0.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9a3b8bb77a4b89427a87d1e9eb969ab05e38e6b4a338a9de10f6df23c33ec3c2", size = 264690, upload-time = "2025-09-25T05:58:15.052Z" }, - { url = "https://files.pythonhosted.org/packages/36/9a/62a9ba3a919594605a07c34eee3068659bbd648e2fa0c4a86d876810b674/zope_interface-8.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:87e6b089002c43231fb9afec89268391bcc7a3b66e76e269ffde19a8112fb8d5", size = 264201, upload-time = "2025-09-25T06:26:27.797Z" }, - { url = "https://files.pythonhosted.org/packages/da/06/8fe88bd7edef60566d21ef5caca1034e10f6b87441ea85de4bbf9ea74768/zope_interface-8.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:64a43f5280aa770cbafd0307cb3d1ff430e2a1001774e8ceb40787abe4bb6658", size = 212273, upload-time = "2025-09-25T06:00:25.398Z" }, - { url = "https://files.pythonhosted.org/packages/e5/24/d5c5e7936e014276b7a98a076de4f5dc2587100fea95779c1e36650b8770/zope_interface-8.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b84464a9fcf801289fa8b15bfc0829e7855d47fb4a8059555effc6f2d1d9a613", size = 207443, upload-time = "2025-09-25T05:59:34.299Z" }, - { url = "https://files.pythonhosted.org/packages/8a/76/565cf6db478ba344b27cfd6828f17da2888cf1beb521bce31142b3041fb5/zope_interface-8.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7b915cf7e747b5356d741be79a153aa9107e8923bc93bcd65fc873caf0fb5c50", size = 207928, upload-time = "2025-09-25T05:59:35.524Z" }, - { url = "https://files.pythonhosted.org/packages/65/03/9780355205c3b3f55e9ce700e52846b40d0bab99c078e102c0d7e2f3e022/zope_interface-8.0.1-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:110c73ddf974b369ef3c6e7b0d87d44673cf4914eba3fe8a33bfb21c6c606ad8", size = 248605, upload-time = "2025-09-25T05:58:25.586Z" }, - { url = "https://files.pythonhosted.org/packages/44/09/b10eda92f1373cd8e4e9dd376559414d1759a8b54e98eeef0d81844f0638/zope_interface-8.0.1-cp39-cp39-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9e9bdca901c1bcc34e438001718512c65b3b8924aabcd732b6e7a7f0cd715f17", size = 253793, upload-time = "2025-09-25T05:58:16.92Z" }, - { url = "https://files.pythonhosted.org/packages/62/37/3529065a2b6b7dc8f287ff3c8d1e8b7d8c4681c069e520bd3c4ac995a95c/zope_interface-8.0.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bbd22d4801ad3e8ec704ba9e3e6a4ac2e875e4d77e363051ccb76153d24c5519", size = 254263, upload-time = "2025-09-25T06:26:29.371Z" }, - { url = "https://files.pythonhosted.org/packages/c3/31/42588bea7ddad3abd2d4987ec3b767bd09394cc091a4918b1cf7b9de07ae/zope_interface-8.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:a0016ca85f93b938824e2f9a43534446e95134a2945b084944786e1ace2020bc", size = 211780, upload-time = "2025-09-25T05:59:50.015Z" }, -] From e6faf4af0855bd51368c1e13c73e7e76a5503c95 Mon Sep 17 00:00:00 2001 From: Jae Date: Sun, 26 Oct 2025 10:58:40 -0600 Subject: [PATCH 2/6] feat: second version of the dataset builder + build django command using VP data only, as well as first sample dataset. TODO: fix weather features. --- .../feature_engineering/dataset_builder.py | 624 +++++++++--------- .../gtfs-rt-pipeline/eta_vp_sample.parquet | Bin 0 -> 820078 bytes .../management/commands/build_eta_sample.py | 166 ++++- 3 files changed, 452 insertions(+), 338 deletions(-) create mode 100644 eta_prediction/gtfs-rt-pipeline/eta_vp_sample.parquet diff --git a/eta_prediction/feature_engineering/dataset_builder.py b/eta_prediction/feature_engineering/dataset_builder.py index b9987b6..a788556 100644 --- a/eta_prediction/feature_engineering/dataset_builder.py +++ b/eta_prediction/feature_engineering/dataset_builder.py @@ -2,331 +2,373 @@ from datetime import datetime, date, time, timedelta from typing import Optional, List - import numpy as np import pandas as pd +from math import radians, cos, sin, asin, sqrt -from django.db.models import F, Q, OuterRef, Subquery, Exists, Prefetch -from django.db.models.functions import Coalesce - +from django.db.models import F, Q from sch_pipeline.models import StopTime, Stop, Route, Trip -from rt_pipeline.models import VehiclePosition, TripUpdate -from sch_pipeline.utils import top_routes_by_scheduled_trips - +from rt_pipeline.models import VehiclePosition from feature_engineering.temporal import extract_temporal_features from feature_engineering.operational import calculate_headway, detect_congestion_proxy from feature_engineering.weather import fetch_weather -def _parse_sched_time(val) -> Optional[int]: +def haversine_distance(lat1, lon1, lat2, lon2): + """ + Calculate the great circle distance in meters between two points + on the earth (specified in decimal degrees) """ - Normalize schedule arrival_time to seconds since midnight. - Accepts 'HH:MM:SS', integer seconds, or time object. + # Convert decimal degrees to radians + lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) + + # Haversine formula + dlon = lon2 - lon1 + dlat = lat2 - lat1 + a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 + c = 2 * asin(sqrt(a)) + r = 6371000 # Radius of earth in meters + return c * r + + +def find_actual_arrival_time(vp_df_for_trip, stop_lat, stop_lon, distance_threshold=50): """ - if val is None or pd.isna(val): + Find the ts when a vehicle arrived at a stop. + + Strategy: + 1. Calculate distance from each VP to the stop + 2. Find the first VP within distance_threshold meters + 3. Return its ts as arrival time + + Args: + vp_df_for_trip: DataFrame of VehiclePositions for a specific trip, sorted by ts + stop_lat: Stop lat + stop_lon: Stop lon + distance_threshold: Distance in meters to consider "arrived" (default 50m) + + Returns: + datetime or None if vehicle never arrived + """ + if vp_df_for_trip.empty: return None - # If it's already an integer (seconds), return it - if isinstance(val, int): - return val + # Calculate distances to stop + distances = vp_df_for_trip.apply( + lambda row: haversine_distance(row['lat'], row['lon'], stop_lat, stop_lon), + axis=1 + ) - # If it's a time object - if isinstance(val, time): - return val.hour * 3600 + val.minute * 60 + val.second + # Find first position within threshold + arrived_mask = distances <= distance_threshold + if arrived_mask.any(): + first_arrival_idx = arrived_mask.idxmax() # First True index + return vp_df_for_trip.loc[first_arrival_idx, 'ts'] - # If it's a timedelta (from GTFS sometimes) - if isinstance(val, timedelta): - return int(val.total_seconds()) + # Alternative: If never within threshold, find closest approach + closest_idx = distances.idxmin() + min_distance = distances.min() - # If it's a string - if isinstance(val, str): - try: - parts = val.split(":") - hh, mm, ss = int(parts[0]), int(parts[1]), int(parts[2]) - return hh * 3600 + mm * 60 + ss - except Exception: - return None + # Only use closest approach if reasonably close (e.g., within 200m) + if min_distance <= 200: + return vp_df_for_trip.loc[closest_idx, 'ts'] return None -def _yyyymmdd_to_date(s: Optional[str]) -> Optional[date]: - """Convert YYYYMMDD string or date object to date object.""" - if not s or pd.isna(s): - return None - - # If it's already a date object, return it - if isinstance(s, date): - return s - - # If it's a datetime, extract the date - if isinstance(s, datetime): - return s.date() - - try: - s = str(s) - return date(int(s[0:4]), int(s[4:6]), int(s[6:8])) - except Exception: - return None - - -def _mk_dt(d: Optional[date], seconds_since_midnight: Optional[int]) -> Optional[datetime]: - """Combine date and seconds to create datetime.""" - if d is None or seconds_since_midnight is None: - return None - return datetime.combine(d, time(0, 0)) + timedelta(seconds=int(seconds_since_midnight)) - - -def build_training_dataset( - provider_id: Optional[int] = None, +def build_vp_training_dataset( route_ids: Optional[List[str]] = None, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None, - min_observations_per_stop: int = 30, + distance_threshold: float = 50.0, + max_stops_ahead: int = 5, attach_weather: bool = True, tz_for_temporal: str = "America/Costa_Rica", ) -> pd.DataFrame: """ - Optimized pipeline using direct database join via raw SQL or simplified ORM. - - Strategy: - 1. Filter TripUpdates by date range FIRST (reduce dataset) - 2. Get matching trip_ids for routes - 3. Use a single query with proper joins instead of subqueries - 4. Process in pandas for complex computations + Build training dataset from VehiclePosition data only. + + For each VehiclePosition: + - Identify current trip and route + - Find remaining stops in trip + - Calculate distance to each remaining stop (up to max_stops_ahead) + - Find actual arrival times from subsequent VehiclePositions + - Extract temporal, operational, and weather features + + Args: + route_ids: List of route IDs to include (None = all routes) + start_date: Start of date range + end_date: End of date range + distance_threshold: Distance in meters to consider "arrived at stop" + max_stops_ahead: Maximum number of future stops to include per VP + attach_weather: Whether to fetch weather data + tz_for_temporal: Timezone for temporal features + + Returns: + DataFrame with columns: + - trip_id, route_id, vehicle_id + - vp_ts, vp_lat, vp_lon + - stop_id, stop_sequence, stop_lat, stop_lon + - distance_to_stop (meters) + - scheduled_arrival, actual_arrival, delay_seconds + - temporal features (hour, day_of_week, etc.) + - operational features (headway, avg_speed) + - weather features (temperature, precipitation, wind_speed) """ - + print("=" * 70) - print("OPTIMIZED DATASET BUILDER") + print("VP-BASED DATASET BUILDER") print("=" * 70) # ============================================================ - # STEP 1: Filter TripUpdates first (reduce data volume) + # STEP 1: Fetch VehiclePositions # ============================================================ - print("\nStep 1: Building TripUpdate filter...") + print("\nStep 1: Fetching VehiclePositions...") - tu_qs = TripUpdate.objects.all() + vp_qs = VehiclePosition.objects.exclude( + Q(trip_id__isnull=True) | + Q(lat__isnull=True) | + Q(lon__isnull=True) + ) - # Date range filter if start_date: print(f" Filtering start_date >= {start_date}") - tu_qs = tu_qs.filter(ts__gte=start_date) + vp_qs = vp_qs.filter(ts__gte=start_date) if end_date: print(f" Filtering end_date < {end_date}") - tu_qs = tu_qs.filter(ts__lt=end_date) - - # Must have essential fields - tu_qs = tu_qs.exclude( - Q(trip_id__isnull=True) | - Q(stop_sequence__isnull=True) | - Q(start_date__isnull=True) - ) + vp_qs = vp_qs.filter(ts__lt=end_date) - print(f" TripUpdates matching date range: {tu_qs.count():,}") - - # ============================================================ - # STEP 2: Get trip_ids for specified routes - # ============================================================ + # Filter by route if specified if route_ids: - print(f"\nStep 2: Filtering for routes: {route_ids}") + print(f" Filtering for routes: {route_ids}") trip_ids_for_routes = list( Trip.objects.filter(route_id__in=route_ids) .values_list("trip_id", flat=True) ) - print(f" Found {len(trip_ids_for_routes):,} trips for these routes") - - # Filter TripUpdates to only these trips - tu_qs = tu_qs.filter(trip_id__in=trip_ids_for_routes) - print(f" TripUpdates for these routes: {tu_qs.count():,}") + vp_qs = vp_qs.filter(trip_id__in=trip_ids_for_routes) - # ============================================================ - # STEP 3: Get TripUpdate data (deduplicated) - # ============================================================ - print("\nStep 3: Fetching TripUpdate data...") - - # Get latest update per (trip_id, stop_sequence) - # We'll deduplicate in pandas since Django ORM doesn't have good window functions - tu_data = tu_qs.values( + print(f" Fetching VehiclePosition records...") + vp_data = vp_qs.values( 'trip_id', - 'stop_sequence', - 'arrival_time', - 'departure_time', + 'vehicle_id', 'ts', - 'start_date', - 'stop_id', - ).order_by('trip_id', 'stop_sequence', '-ts') + 'lat', + 'lon', + 'bearing', + 'speed', + ).order_by('trip_id', 'ts') - print(f" Fetching TripUpdate records...") - tu_df = pd.DataFrame.from_records(tu_data) - print(f" Retrieved {len(tu_df):,} TripUpdate records") + vp_df = pd.DataFrame.from_records(vp_data) + print(f" Retrieved {len(vp_df):,} VehiclePosition records") - if tu_df.empty: - print("\nWARNING: No TripUpdate data found!") + if vp_df.empty: + print("\nWARNING: No VehiclePosition data found!") return pd.DataFrame() - # Deduplicate: keep latest update per (trip_id, stop_sequence) - print(" Deduplicating TripUpdates (keeping latest per trip/stop)...") - tu_df = tu_df.drop_duplicates(subset=['trip_id', 'stop_sequence'], keep='first') - print(f" After deduplication: {len(tu_df):,} records") - - # Rename for clarity - tu_df = tu_df.rename(columns={ - 'arrival_time': 'tu_arrival', - 'departure_time': 'tu_departure', - 'ts': 'tu_ts', - 'start_date': 'tu_start_date', - 'stop_id': 'tu_stop_id', - }) - # ============================================================ - # STEP 4: Get StopTime data for matching trips + # STEP 2: Get trip metadata # ============================================================ - print("\nStep 4: Fetching StopTime schedule data...") + print("\nStep 2: Getting trip metadata...") - # Get unique trip_ids from TripUpdates - trip_ids = tu_df['trip_id'].unique() - print(f" Unique trips to fetch: {len(trip_ids):,}") + trip_ids = vp_df['trip_id'].unique() + trips_data = Trip.objects.filter(trip_id__in=trip_ids).values( + 'trip_id', 'route_id', 'direction_id', 'trip_headsign', 'service_id' + ) + trips_df = pd.DataFrame.from_records(trips_data) - # Fetch StopTimes for these trips - st_qs = StopTime.objects.filter(trip_id__in=trip_ids) + vp_df = vp_df.merge(trips_df, on='trip_id', how='left') + print(f" Added route info for {len(vp_df):,} records") - st_data = st_qs.values( + # Drop VPs without route info + initial_count = len(vp_df) + vp_df = vp_df.dropna(subset=['route_id']) + print(f" Dropped {initial_count - len(vp_df):,} VPs without route info") + + # ============================================================ + # STEP 3: Get stop sequences for each trip + # ============================================================ + print("\nStep 3: Loading stop sequences for trips...") + + stoptimes_data = StopTime.objects.filter( + trip_id__in=trip_ids + ).values( 'trip_id', 'stop_sequence', 'stop_id', 'arrival_time', - 'departure_time', - ) + ).order_by('trip_id', 'stop_sequence') - print(f" Fetching StopTime records...") - st_df = pd.DataFrame.from_records(st_data) + st_df = pd.DataFrame.from_records(stoptimes_data) print(f" Retrieved {len(st_df):,} StopTime records") if st_df.empty: print("\nWARNING: No StopTime data found!") return pd.DataFrame() + # # Get stop coordinates + # stop_ids = st_df['stop_id'].unique() + # stops_data = Stop.objects.filter(id__in=stop_ids).values( + # 'id', 'stop_lat', 'stop_lon', 'stop_name' + # ) + # stops_df = pd.DataFrame.from_records(stops_data).rename( + # columns={'id': 'stop_id'} + # ) + + # st_df = st_df.merge(stops_df, on='stop_id', how='left') + # print(f" Added coordinates for {st_df['stop_lat'].notna().sum():,} stops") + + # Get stop coordinates + stop_ids = st_df['stop_id'].unique() + # remove any NaN / None values and coerce to list for ORM filter + stop_ids = [s for s in stop_ids if pd.notna(s)] + stops_data = Stop.objects.filter(id__in=stop_ids).values( + 'id', 'stop_lat', 'stop_lon', 'stop_name' + ) + stops_df = pd.DataFrame.from_records(stops_data).rename( + columns={'id': 'stop_id'} + ) + # use the model column that stores GTFS stop id (stop_id) so values() returns 'stop_id' + stops_data = Stop.objects.filter(stop_id__in=stop_ids).values( + 'stop_id', 'stop_lat', 'stop_lon', 'stop_name' + ) + stops_df = pd.DataFrame.from_records(stops_data) + + st_df = st_df.merge(stops_df, on='stop_id', how='left') + print(f" Added coordinates for {st_df['stop_lat'].notna().sum():,} stops") + # st_df = st_df.merge(stops_df, on='stop_id', how='left') + # print(f" Added coordinates for {st_df['stop_lat'].notna().sum():,} stops") +# ...existing code... + + # ============================================================ - # STEP 5: Join StopTime + TripUpdate + # STEP 4: For each VP, find remaining stops and distances # ============================================================ - print("\nStep 5: Joining schedule and realtime data...") + print(f"\nStep 4: Calculating distances to remaining stops (max {max_stops_ahead})...") - df = st_df.merge( - tu_df, - on=['trip_id', 'stop_sequence'], - how='inner', # Only keep records with both schedule and realtime data - suffixes=('_sched', '_tu') - ) + training_rows = [] + total_vps = len(vp_df) - print(f" After join: {len(df):,} records") + # Group VPs by trip for efficient processing + vp_grouped = vp_df.groupby('trip_id') + st_grouped = st_df.groupby('trip_id') - if df.empty: - print("\nWARNING: No matching records after join!") + processed_trips = 0 + for trip_id, trip_vps in vp_grouped: + processed_trips += 1 + if processed_trips % 100 == 0: + print(f" Processing trip {processed_trips}/{len(vp_grouped)} ({len(training_rows):,} rows generated)") + + # Get stop sequence for this trip + if trip_id not in st_grouped.groups: + continue + + trip_stops = st_grouped.get_group(trip_id).sort_values('stop_sequence') + + # For each VP in this trip + for vp_idx, vp_row in trip_vps.iterrows(): + vp_lat = vp_row['lat'] + vp_lon = vp_row['lon'] + vp_ts = vp_row['ts'] + + # Find which stops are ahead of this VP + # Strategy: Calculate distance to all stops, take the closest N + distances_to_stops = trip_stops.apply( + lambda stop: haversine_distance(vp_lat, vp_lon, stop['stop_lat'], stop['stop_lon']), + axis=1 + ) + + trip_stops_with_dist = trip_stops.copy() + trip_stops_with_dist['distance_to_stop'] = distances_to_stops + + # Sort by stop_sequence and take upcoming stops + # A stop is "upcoming" if it hasn't been passed yet + # Simple heuristic: stops that are ahead in sequence from the closest stop + closest_stop_idx = distances_to_stops.idxmin() + closest_stop_seq = trip_stops.loc[closest_stop_idx, 'stop_sequence'] + + # Get stops with sequence >= closest (upcoming stops) + upcoming_stops = trip_stops_with_dist[ + trip_stops_with_dist['stop_sequence'] >= closest_stop_seq + ].head(max_stops_ahead) + + # For each upcoming stop, find actual arrival time + for stop_idx, stop_row in upcoming_stops.iterrows(): + # Find actual arrival from future VPs + future_vps = trip_vps[trip_vps['ts'] > vp_ts] + + actual_arrival = find_actual_arrival_time( + future_vps, + stop_row['stop_lat'], + stop_row['stop_lon'], + distance_threshold=distance_threshold + ) + + # Only include if we found an actual arrival + if actual_arrival is not None: + training_rows.append({ + 'trip_id': trip_id, + 'route_id': vp_row['route_id'], + 'vehicle_id': vp_row['vehicle_id'], + 'vp_ts': vp_ts, + 'vp_lat': vp_lat, + 'vp_lon': vp_lon, + 'vp_bearing': vp_row.get('bearing'), + 'vp_speed': vp_row.get('speed'), + 'stop_id': stop_row['stop_id'], + 'stop_sequence': stop_row['stop_sequence'], + 'stop_lat': stop_row['stop_lat'], + 'stop_lon': stop_row['stop_lon'], + 'distance_to_stop': stop_row['distance_to_stop'], + 'scheduled_arrival': stop_row['arrival_time'], + 'actual_arrival': actual_arrival, + }) + + print(f" Generated {len(training_rows):,} training samples") + + if not training_rows: + print("\nWARNING: No training rows generated!") return pd.DataFrame() - # ============================================================ - # STEP 6: Get Trip/Route metadata - # ============================================================ - print("\nStep 6: Adding route information...") - - trip_ids = df['trip_id'].unique() - trips_data = Trip.objects.filter(trip_id__in=trip_ids).values( - 'trip_id', 'route_id', 'direction_id', 'trip_headsign' - ) - trips_df = pd.DataFrame.from_records(trips_data) - - df = df.merge(trips_df, on='trip_id', how='left') - print(f" Added route_id for {len(df):,} records") + df = pd.DataFrame(training_rows) # ============================================================ - # STEP 7: Compute scheduled and actual arrival times + # STEP 5: Compute delay_seconds # ============================================================ - print("\nStep 7: Computing scheduled_arrival...") - - # Debug: Check what we have - print(f" Sample arrival_time values: {df['arrival_time'].head().tolist()}") - print(f" Sample arrival_time types: {[type(x) for x in df['arrival_time'].head().tolist()]}") - print(f" Sample tu_start_date values: {df['tu_start_date'].head().tolist()}") - print(f" Sample tu_start_date types: {[type(x) for x in df['tu_start_date'].head().tolist()]}") + print("\nStep 5: Computing delay_seconds...") - df["sched_secs"] = df["arrival_time"].apply(_parse_sched_time) - df["start_date_obj"] = df["tu_start_date"].apply(_yyyymmdd_to_date) + # Convert tss to datetime + df['vp_ts'] = pd.to_datetime(df['vp_ts'], utc=True) + df['actual_arrival'] = pd.to_datetime(df['actual_arrival'], utc=True) - print(f" Parsed sched_secs (non-null): {df['sched_secs'].notna().sum()}/{len(df)}") - print(f" Parsed start_date_obj (non-null): {df['start_date_obj'].notna().sum()}/{len(df)}") - print(f" Sample sched_secs: {df['sched_secs'].head().tolist()}") - print(f" Sample start_date_obj: {df['start_date_obj'].head().tolist()}") - - # Check if both are present before combining - both_valid = (df['sched_secs'].notna() & df['start_date_obj'].notna()).sum() - print(f" Rows with BOTH sched_secs AND start_date_obj: {both_valid}/{len(df)}") - - df["scheduled_arrival"] = df.apply( - lambda row: _mk_dt(row["start_date_obj"], row["sched_secs"]), - axis=1 - ) - - print(f" Scheduled arrivals (non-null): {df['scheduled_arrival'].notna().sum()}/{len(df)}") - print(f" Sample scheduled_arrival: {df['scheduled_arrival'].head().tolist()}") - - print("\nStep 8: Computing actual_arrival...") - print(f" Sample tu_arrival: {df['tu_arrival'].head().tolist()}") - print(f" Sample tu_departure: {df['tu_departure'].head().tolist()}") - print(f" Sample tu_ts: {df['tu_ts'].head().tolist()}") - print(f" tu_arrival (non-null): {df['tu_arrival'].notna().sum()}/{len(df)}") - print(f" tu_departure (non-null): {df['tu_departure'].notna().sum()}/{len(df)}") - print(f" tu_ts (non-null): {df['tu_ts'].notna().sum()}/{len(df)}") - - df["actual_arrival"] = df["tu_arrival"].combine_first( - df["tu_departure"] - ).combine_first(df["tu_ts"]) - - print(f" Actual arrivals (non-null): {df['actual_arrival'].notna().sum()}/{len(df)}") - print(f" Sample actual_arrival: {df['actual_arrival'].head().tolist()}") - - # Ensure datetime dtype - for col in ["scheduled_arrival", "actual_arrival"]: - df[col] = pd.to_datetime(df[col], utc=True, errors="coerce") - - print(f"\n After pd.to_datetime conversion:") - print(f" Scheduled arrivals (non-null): {df['scheduled_arrival'].notna().sum()}/{len(df)}") - print(f" Actual arrivals (non-null): {df['actual_arrival'].notna().sum()}/{len(df)}") - - # ============================================================ - # STEP 9: Compute delay - # ============================================================ - print("\nStep 9: Computing delay_seconds...") - df["delay_seconds"] = ( - df["actual_arrival"] - df["scheduled_arrival"] + # Parse scheduled arrival time (may need date context) + # For now, compute time_to_arrival (prediction target) + df['time_to_arrival_seconds'] = ( + df['actual_arrival'] - df['vp_ts'] ).dt.total_seconds() - # Drop rows with missing critical data + # Filter out negative or unrealistic values initial_count = len(df) - df = df.dropna(subset=["scheduled_arrival", "actual_arrival", "delay_seconds"]) - print(f" Dropped {initial_count - len(df):,} rows with missing critical data") + df = df[ + (df['time_to_arrival_seconds'] >= 0) & + (df['time_to_arrival_seconds'] <= 7200) # Max 2 hours ahead + ] + print(f" Dropped {initial_count - len(df):,} rows with invalid time_to_arrival") print(f" Remaining: {len(df):,} rows") - if df.empty: - print("\nWARNING: All rows dropped due to missing data") - return df - # ============================================================ - # STEP 10: Temporal features + # STEP 6: Temporal features # ============================================================ - print("\nStep 10: Extracting temporal features...") + print("\nStep 6: Extracting temporal features...") + temporal_data = [] - for idx, ts in enumerate(df["actual_arrival"]): + for idx, ts in enumerate(df['vp_ts']): if idx % 10000 == 0 and idx > 0: print(f" Processed {idx:,}/{len(df):,} temporal features") - if pd.notna(ts): - try: - feats = extract_temporal_features(ts, tz=tz_for_temporal, region="CR") - temporal_data.append(feats) - except Exception as e: - temporal_data.append({}) - else: + try: + feats = extract_temporal_features(ts, tz=tz_for_temporal, region="CR") + temporal_data.append(feats) + except Exception: temporal_data.append({}) tf = pd.DataFrame(temporal_data) @@ -338,78 +380,54 @@ def build_training_dataset( df[k] = np.nan # ============================================================ - # STEP 11: Operational features + # STEP 7: Operational features # ============================================================ - print("\nStep 11: Computing operational features...") + print("\nStep 7: Computing operational features...") - def _safe_headway(route_id, timestamp): + def _safe_headway(route_id, ts, vehicle_id): try: return calculate_headway( route_id=route_id, - timestamp=timestamp, - vehicle_id=None + ts=ts, + vehicle_id=vehicle_id ) except Exception: return np.nan - def _safe_congestion(route_id, stop_sequence, timestamp): - try: - result = detect_congestion_proxy( - route_id=route_id, - stop_sequence=stop_sequence, - timestamp=timestamp, - ) - return result.get("avg_speed_last_10min", np.nan) if result else np.nan - except Exception: - return np.nan - headways = [] - speeds = [] for idx, row in df.iterrows(): - if idx % 50 == 0: - print(f" Processing operational features: {idx:,}/{len(df):,}") - headways.append(_safe_headway(row["route_id"], row["actual_arrival"])) - speeds.append(_safe_congestion(row["route_id"], row["stop_sequence"], row["actual_arrival"])) + if idx % 1000 == 0: + print(f" Processing headway: {idx:,}/{len(df):,}") + headways.append(_safe_headway( + row['route_id'], + row['vp_ts'], + row['vehicle_id'] + )) - df["headway_seconds"] = headways - df["avg_speed_last_10min"] = speeds + df['headway_seconds'] = headways + # Use VP speed directly if available + df['current_speed_kmh'] = df['vp_speed'] * 3.6 # m/s to km/h # ============================================================ - # STEP 12: Weather features + # STEP 8: Weather features # ============================================================ if attach_weather: - print("\nStep 12: Fetching weather data...") - - # Use tu_stop_id (from realtime) or stop_id (from schedule) - df['final_stop_id'] = df['tu_stop_id'].combine_first(df['stop_id']) - - stop_ids = df["final_stop_id"].unique() - stop_meta = Stop.objects.filter( - id__in=stop_ids - ).values("id", "stop_lat", "stop_lon") - stop_df = pd.DataFrame.from_records(stop_meta).rename( - columns={"id": "final_stop_id"} - ) - - df = df.merge(stop_df, on="final_stop_id", how="left") + print("\nStep 8: Fetching weather data...") weather_data = [] for idx, row in df.iterrows(): if idx % 5000 == 0: print(f" Fetching weather: {idx:,}/{len(df):,}") - if pd.notna(row.get("stop_lat")) and pd.notna(row.get("stop_lon")) and pd.notna(row.get("actual_arrival")): - try: - w = fetch_weather( - float(row["stop_lat"]), - float(row["stop_lon"]), - pd.Timestamp(row["actual_arrival"]).to_pydatetime() - ) - weather_data.append(w or {}) - except Exception: - weather_data.append({}) - else: + try: + w = fetch_weather( + float(row['vp_lat']), + float(row['vp_lon']), + row['vp_ts'].to_pydatetime() + ) + weather_data.append(w or {}) + except Exception: weather_data.append({}) wx_df = pd.DataFrame(weather_data) @@ -424,41 +442,17 @@ def _safe_congestion(route_id, stop_sequence, timestamp): df["wind_speed_kmh"] = np.nan # ============================================================ - # STEP 13: Outlier filtering - # ============================================================ - # print("\nStep 13: Filtering outliers...") - # initial_count = len(df) - - # # Clip extreme delays (±2 hours) - # df = df[(df["delay_seconds"] >= -7200) & (df["delay_seconds"] <= 7200)] - # print(f" Dropped {initial_count - len(df):,} outlier rows") - - # ============================================================ - # STEP 14: Minimum observations per stop + # STEP 9: Final column selection # ============================================================ - print(f"\nStep 14: Filtering stops with < {min_observations_per_stop} observations...") - - df['final_stop_id'] = df['tu_stop_id'].combine_first(df['stop_id']) - counts = df.groupby("final_stop_id").size() - keep_stops = set(counts[counts >= min_observations_per_stop].index) - - initial_count = len(df) - df = df[df["final_stop_id"].isin(keep_stops)] - print(f" Kept {len(keep_stops)} stops, dropped {initial_count - len(df):,} rows") - - # ============================================================ - # STEP 15: Final column selection - # ============================================================ - print("\nStep 15: Preparing final dataset...") - - # Use tu_stop_id preferentially, fallback to schedule stop_id - df['stop_id'] = df['tu_stop_id'].combine_first(df['stop_id']) + print("\nStep 9: Preparing final dataset...") wanted_cols = [ - "trip_id", "route_id", "stop_id", "stop_sequence", - "scheduled_arrival", "actual_arrival", "delay_seconds", + "trip_id", "route_id", "vehicle_id", "stop_id", "stop_sequence", + "vp_ts", "vp_lat", "vp_lon", "vp_bearing", + "stop_lat", "stop_lon", "distance_to_stop", + "actual_arrival", "time_to_arrival_seconds", "hour", "day_of_week", "is_weekend", "is_holiday", "is_peak_hour", - "headway_seconds", "avg_speed_last_10min", + "headway_seconds", "current_speed_kmh", "temperature_c", "precipitation_mm", "wind_speed_kmh", ] @@ -470,6 +464,10 @@ def _safe_congestion(route_id, stop_sequence, timestamp): print("\n" + "=" * 70) print(f"✓ Final dataset: {len(result):,} rows × {len(wanted_cols)} columns") + print(f" Unique trips: {result['trip_id'].nunique():,}") + print(f" Unique routes: {result['route_id'].nunique():,}") + print(f" Unique stops: {result['stop_id'].nunique():,}") + print(f" Avg time_to_arrival: {result['time_to_arrival_seconds'].mean():.1f}s ({result['time_to_arrival_seconds'].mean()/60:.1f} min)") print("=" * 70) return result diff --git a/eta_prediction/gtfs-rt-pipeline/eta_vp_sample.parquet b/eta_prediction/gtfs-rt-pipeline/eta_vp_sample.parquet new file mode 100644 index 0000000000000000000000000000000000000000..ebd8d88b4685c259b2f3282bab6f835086edd780 GIT binary patch literal 820078 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�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áUWE)@v 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 literal 0 HcmV?d00001 diff --git a/eta_prediction/gtfs-rt-pipeline/rt_pipeline/management/commands/build_eta_sample.py b/eta_prediction/gtfs-rt-pipeline/rt_pipeline/management/commands/build_eta_sample.py index da1ea37..9d07df1 100644 --- a/eta_prediction/gtfs-rt-pipeline/rt_pipeline/management/commands/build_eta_sample.py +++ b/eta_prediction/gtfs-rt-pipeline/rt_pipeline/management/commands/build_eta_sample.py @@ -17,7 +17,7 @@ sys.path.insert(0, str(ETA_PREDICTION_ROOT)) try: - from feature_engineering.dataset_builder import build_training_dataset, save_dataset + from feature_engineering.dataset_builder import build_vp_training_dataset, save_dataset from sch_pipeline.utils import top_routes_by_scheduled_trips except ImportError as e: print(f"ERROR: Failed to import required modules: {e}") @@ -28,7 +28,7 @@ class Command(BaseCommand): - help = "Build a small ETA training dataset for the top-N busiest routes (by scheduled trips)." + help = "Build ETA training dataset from VehiclePosition data for the top-N busiest routes." def add_arguments(self, parser): parser.add_argument( @@ -49,10 +49,28 @@ def add_arguments(self, parser): default=10, help="Min observations per stop" ) + parser.add_argument( + "--distance-threshold", + type=float, + default=50.0, + help="Distance threshold (meters) to consider vehicle 'arrived' at stop" + ) + parser.add_argument( + "--max-stops-ahead", + type=int, + default=5, + help="Maximum number of upcoming stops to include per VP" + ) + parser.add_argument( + "--vp-sample-interval", + type=int, + default=30, + help="Sample VPs every N seconds per vehicle (0=no sampling, use all VPs)" + ) parser.add_argument( "--out", type=str, - default="eta_sample.parquet", + default="eta_vp_sample.parquet", help="Output parquet path" ) parser.add_argument( @@ -65,18 +83,49 @@ def add_arguments(self, parser): type=str, help="Comma-separated route IDs (overrides --top-routes)" ) + parser.add_argument( + "--start-date", + type=str, + help="Start date (YYYY-MM-DD format, overrides --days)" + ) + parser.add_argument( + "--end-date", + type=str, + help="End date (YYYY-MM-DD format, overrides --days)" + ) def handle(self, *args, **opts): n = opts["top_routes"] days = opts["days"] min_obs = opts["min_observations"] + distance_threshold = opts["distance_threshold"] + max_stops_ahead = opts["max_stops_ahead"] + # vp_sample_interval = opts["vp_sample_interval"] out = opts["out"] attach_weather = not opts["no_weather"] manual_routes = opts.get("route_ids") + start_date_str = opts.get("start_date") + end_date_str = opts.get("end_date") - # or for a fixed day window matching your data: - start = timezone.datetime(2025, 10, 8, 0, 0, tzinfo=UTC) - end = timezone.datetime(2025, 10, 9, 0, 0, tzinfo=UTC) + # Determine date range + if start_date_str and end_date_str: + try: + start = timezone.datetime.strptime(start_date_str, "%Y-%m-%d").replace(tzinfo=UTC) + end = timezone.datetime.strptime(end_date_str, "%Y-%m-%d").replace(tzinfo=UTC) + except ValueError as e: + self.stdout.write( + self.style.ERROR(f"Invalid date format: {e}. Use YYYY-MM-DD") + ) + return + else: + # Default: use fixed date range or calculate from --days + # For testing, using fixed dates: + start = timezone.datetime(2025, 10, 8, 0, 0, tzinfo=UTC) + end = timezone.datetime(2025, 10, 9, 0, 0, tzinfo=UTC) + # Or calculate from days: + # end = timezone.now() + # start = end - timedelta(days=days) + # Determine which routes to use if manual_routes: route_ids = [r.strip() for r in manual_routes.split(",")] @@ -112,21 +161,49 @@ def handle(self, *args, **opts): self.stdout.write("\n" + "="*60) self.stdout.write(self.style.NOTICE("Configuration:")) self.stdout.write(f" Routes: {', '.join(route_ids)}") - self.stdout.write(f" Date range: {start.date()} to {end.date()} ({days} days)") + self.stdout.write(f" Date range: {start.date()} to {end.date()}") + self.stdout.write(f" Distance threshold: {distance_threshold}m") + self.stdout.write(f" Max stops ahead: {max_stops_ahead}") + # # self.stdout.write(f" VP sample interval: {vp_sample_interval}s ({'all VPs' if vp_sample_interval == 0 else 'sampled'})") self.stdout.write(f" Min observations/stop: {min_obs}") self.stdout.write(f" Weather features: {'enabled' if attach_weather else 'disabled'}") self.stdout.write(f" Output: {out}") self.stdout.write("="*60 + "\n") + # Check for VehiclePosition data + from rt_pipeline.models import VehiclePosition + vp_count = VehiclePosition.objects.filter( + ts__gte=start, + ts__lt=end + ).count() + + if vp_count == 0: + self.stdout.write( + self.style.WARNING( + f"No VehiclePosition data found in date range {start.date()} to {end.date()}\n" + "Check data availability:\n" + " python manage.py shell -c 'from rt_pipeline.models import VehiclePosition; " + "from django.db.models import Min, Max; " + "print(VehiclePosition.objects.aggregate(min=Min(\"ts\"), max=Max(\"ts\")))'" + ) + ) + return + else: + self.stdout.write( + self.style.SUCCESS(f"Found {vp_count:,} VehiclePosition records in date range") + ) + # Build dataset try: - self.stdout.write(self.style.NOTICE("Building dataset...")) - df = build_training_dataset( - provider_id=None, + self.stdout.write(self.style.NOTICE("\nBuilding dataset...")) + df = build_vp_training_dataset( route_ids=route_ids, start_date=start, end_date=end, - min_observations_per_stop=min_obs, + distance_threshold=distance_threshold, + max_stops_ahead=max_stops_ahead, + # min_observations_per_stop=min_obs, + # vp_sample_interval_seconds=vp_sample_interval, attach_weather=attach_weather, ) except Exception as e: @@ -141,12 +218,22 @@ def handle(self, *args, **opts): self.stdout.write( self.style.WARNING( "Resulting dataset is empty. Possible issues:\n" - " 1. No TripUpdate data in the date range\n" - " 2. No matching stop_sequences between StopTime and TripUpdate\n" - " 3. All data filtered out by min_observations threshold\n" + " 1. No VehiclePosition data in the date range\n" + " 2. VPs not matching any trips with stop sequences\n" + " 3. Vehicles never came close enough to stops (try increasing --distance-threshold)\n" + " 4. All data filtered out by --min-observations threshold\n" + " 5. No future VPs available to detect arrivals (incomplete trips)\n" "\nDebug queries:\n" - " - Check TripUpdate count: python manage.py shell -c 'from rt_pipeline.models import TripUpdate; print(TripUpdate.objects.count())'\n" - " - Check date range: python manage.py shell -c 'from rt_pipeline.models import TripUpdate; print(TripUpdate.objects.aggregate(min=Min(\"ts\"), max=Max(\"ts\")))'" + " - Check VP count: python manage.py shell -c 'from rt_pipeline.models import VehiclePosition; print(VehiclePosition.objects.count())'\n" + " - Check date range: python manage.py shell -c 'from rt_pipeline.models import VehiclePosition; from django.db.models import Min, Max; print(VehiclePosition.objects.aggregate(min=Min(\"ts\"), max=Max(\"ts\")))'\n" + " - Check StopTime data: python manage.py shell -c 'from sch_pipeline.models import StopTime, Stop; print(f\"StopTimes: {StopTime.objects.count()}, Stops with coords: {Stop.objects.exclude(stop_lat__isnull=True).count()}\")'\n" + "\nTry adjusting parameters:\n" + " - Increase --distance-threshold (current: {})m\n" + " - Reduce --min-observations (current: {})\n" + " - Increase --max-stops-ahead (current: {})\n" + " - Set --vp-sample-interval to 0 to use all VPs".format( + distance_threshold, min_obs, max_stops_ahead + ) ) ) return @@ -156,17 +243,33 @@ def handle(self, *args, **opts): self.stdout.write(self.style.SUCCESS("Dataset Summary:")) self.stdout.write(f" Total rows: {len(df):,}") self.stdout.write(f" Unique trips: {df['trip_id'].nunique():,}") + self.stdout.write(f" Unique routes: {df['route_id'].nunique()}") + self.stdout.write(f" Unique vehicles: {df['vehicle_id'].nunique():,}") self.stdout.write(f" Unique stops: {df['stop_id'].nunique():,}") - self.stdout.write(f" Routes: {df['route_id'].nunique()}") - if "delay_seconds" in df.columns: - delay_stats = df["delay_seconds"].describe() - self.stdout.write(f"\n Delay statistics (seconds):") - self.stdout.write(f" Mean: {delay_stats['mean']:.1f}") - self.stdout.write(f" Median: {delay_stats['50%']:.1f}") - self.stdout.write(f" Std: {delay_stats['std']:.1f}") - self.stdout.write(f" Min: {delay_stats['min']:.1f}") - self.stdout.write(f" Max: {delay_stats['max']:.1f}") + if "time_to_arrival_seconds" in df.columns: + tta_stats = df["time_to_arrival_seconds"].describe() + self.stdout.write(f"\n Time-to-arrival statistics:") + self.stdout.write(f" Mean: {tta_stats['mean']:.1f}s ({tta_stats['mean']/60:.1f} min)") + self.stdout.write(f" Median: {tta_stats['50%']:.1f}s ({tta_stats['50%']/60:.1f} min)") + self.stdout.write(f" Std: {tta_stats['std']:.1f}s") + self.stdout.write(f" Min: {tta_stats['min']:.1f}s") + self.stdout.write(f" Max: {tta_stats['max']:.1f}s ({tta_stats['max']/60:.1f} min)") + + if "distance_to_stop" in df.columns: + dist_stats = df["distance_to_stop"].describe() + self.stdout.write(f"\n Distance-to-stop statistics:") + self.stdout.write(f" Mean: {dist_stats['mean']:.1f}m") + self.stdout.write(f" Median: {dist_stats['50%']:.1f}m") + self.stdout.write(f" Min: {dist_stats['min']:.1f}m") + self.stdout.write(f" Max: {dist_stats['max']:.1f}m") + + if "current_speed_kmh" in df.columns: + speed_stats = df[df["current_speed_kmh"] > 0]["current_speed_kmh"].describe() + if not speed_stats.empty: + self.stdout.write(f"\n Speed statistics (km/h):") + self.stdout.write(f" Mean: {speed_stats['mean']:.1f}") + self.stdout.write(f" Median: {speed_stats['50%']:.1f}") missing = df.isnull().sum() if missing.any(): @@ -183,6 +286,19 @@ def handle(self, *args, **opts): self.stdout.write( self.style.SUCCESS(f"✓ Successfully saved to {out}") ) + + # Provide guidance on next steps + self.stdout.write("\n" + self.style.NOTICE("Next steps:")) + self.stdout.write(" 1. Inspect the dataset: ") + self.stdout.write(f" import pandas as pd; df = pd.read_parquet('{out}'); df.head()") + self.stdout.write(" 2. Check feature distributions and correlations") + self.stdout.write(" 3. Train a model predicting 'time_to_arrival_seconds' from:") + self.stdout.write(" - distance_to_stop") + self.stdout.write(" - current_speed_kmh") + self.stdout.write(" - temporal features (hour, is_peak_hour, etc.)") + self.stdout.write(" - operational features (headway_seconds)") + self.stdout.write(" - weather features (if enabled)") + except Exception as e: self.stdout.write( self.style.ERROR(f"Failed to save dataset: {e}") From 3693d3e0fd31a3ad212b4ef9ec4597c747ff269d Mon Sep 17 00:00:00 2001 From: Jae Date: Mon, 27 Oct 2025 18:19:36 -0600 Subject: [PATCH 3/6] feat: added first batch of baseline models: historical mean, ewma, distance and time based polyregs. consult README for details. --- eta_prediction/models/common/data.py | 230 +++++++++ eta_prediction/models/common/keys.py | 193 ++++++++ eta_prediction/models/common/metrics.py | 245 ++++++++++ eta_prediction/models/common/registry.py | 260 ++++++++++ eta_prediction/models/common/utils.py | 276 +++++++++++ .../models/evaluation/leaderboard.py | 229 +++++++++ .../models/evaluation/roll_validate.py | 260 ++++++++++ eta_prediction/models/ewma/predict.py | 155 ++++++ eta_prediction/models/ewma/train.py | 299 ++++++++++++ .../models/historical_mean/predict.py | 136 ++++++ .../models/historical_mean/train.py | 218 +++++++++ .../models/polyreg_distance/predict.py | 112 +++++ .../models/polyreg_distance/train.py | 292 +++++++++++ eta_prediction/models/polyreg_time/predict.py | 96 ++++ eta_prediction/models/polyreg_time/train.py | 462 ++++++++++++++++++ eta_prediction/models/train_all_models.py | 375 ++++++++++++++ ...ute-temporal_20251027_161343_alpha=0_3.pkl | Bin 0 -> 3759 bytes ...mporal_20251027_161343_alpha=0_3_meta.json | 50 ++ ...ute-temporal_20251027_161350_alpha=0_3.pkl | Bin 0 -> 21100 bytes ...mporal_20251027_161350_alpha=0_3_meta.json | 51 ++ ...ute-temporal_20251027_153126_alpha=0_3.pkl | Bin 0 -> 1831 bytes ...mporal_20251027_153126_alpha=0_3_meta.json | 50 ++ ...ute-temporal_20251027_153130_alpha=0_3.pkl | Bin 0 -> 9735 bytes ...mporal_20251027_153130_alpha=0_3_meta.json | 51 ++ ...dataset_route-temporal_20251027_161336.pkl | Bin 0 -> 26490 bytes ...t_route-temporal_20251027_161336_meta.json | 49 ++ ...dataset_route-temporal_20251027_153123.pkl | Bin 0 -> 12916 bytes ...t_route-temporal_20251027_153123_meta.json | 49 ++ ...1027_161336_degree=2_route_specific=no.pkl | Bin 0 -> 937 bytes ...61336_degree=2_route_specific=no_meta.json | 45 ++ ...027_161343_degree=2_route_specific=yes.pkl | Bin 0 -> 1188 bytes ...1343_degree=2_route_specific=yes_meta.json | 45 ++ ...1027_161343_degree=3_route_specific=no.pkl | Bin 0 -> 945 bytes ...61343_degree=3_route_specific=no_meta.json | 45 ++ ...1027_153123_degree=2_route_specific=no.pkl | Bin 0 -> 937 bytes ...53123_degree=2_route_specific=no_meta.json | 45 ++ ...027_153126_degree=2_route_specific=yes.pkl | Bin 0 -> 949 bytes ...3126_degree=2_route_specific=yes_meta.json | 45 ++ ...1027_153126_degree=3_route_specific=no.pkl | Bin 0 -> 945 bytes ...53126_degree=3_route_specific=no_meta.json | 45 ++ ...251027_161336_degree=2_handle_nan=drop.pkl | Bin 0 -> 2109 bytes ..._161336_degree=2_handle_nan=drop_meta.json | 56 +++ ...251027_161343_degree=2_handle_nan=drop.pkl | Bin 0 -> 2109 bytes ..._161343_degree=2_handle_nan=drop_meta.json | 56 +++ ...251027_153123_degree=2_handle_nan=drop.pkl | Bin 0 -> 2109 bytes ..._153123_degree=2_handle_nan=drop_meta.json | 56 +++ ...251027_153127_degree=2_handle_nan=drop.pkl | Bin 0 -> 2109 bytes ..._153127_degree=2_handle_nan=drop_meta.json | 56 +++ eta_prediction/models/trained/registry.json | 98 ++++ 49 files changed, 4730 insertions(+) create mode 100644 eta_prediction/models/common/data.py create mode 100644 eta_prediction/models/common/keys.py create mode 100644 eta_prediction/models/common/metrics.py create mode 100644 eta_prediction/models/common/registry.py create mode 100644 eta_prediction/models/common/utils.py create mode 100644 eta_prediction/models/evaluation/leaderboard.py create mode 100644 eta_prediction/models/evaluation/roll_validate.py create mode 100644 eta_prediction/models/ewma/predict.py create mode 100644 eta_prediction/models/ewma/train.py create mode 100644 eta_prediction/models/historical_mean/predict.py create mode 100644 eta_prediction/models/historical_mean/train.py create mode 100644 eta_prediction/models/polyreg_distance/predict.py create mode 100644 eta_prediction/models/polyreg_distance/train.py create mode 100644 eta_prediction/models/polyreg_time/predict.py create mode 100644 eta_prediction/models/polyreg_time/train.py create mode 100644 eta_prediction/models/train_all_models.py create mode 100644 eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3.pkl create mode 100644 eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3_meta.json create mode 100644 eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161350_alpha=0_3.pkl create mode 100644 eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161350_alpha=0_3_meta.json create mode 100644 eta_prediction/models/trained/ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3.pkl create mode 100644 eta_prediction/models/trained/ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3_meta.json create mode 100644 eta_prediction/models/trained/ewma_Green-E_dataset_route-temporal_20251027_153130_alpha=0_3.pkl create mode 100644 eta_prediction/models/trained/ewma_Green-E_dataset_route-temporal_20251027_153130_alpha=0_3_meta.json create mode 100644 eta_prediction/models/trained/historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336.pkl create mode 100644 eta_prediction/models/trained/historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336_meta.json create mode 100644 eta_prediction/models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123.pkl create mode 100644 eta_prediction/models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123_meta.json create mode 100644 eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no.pkl create mode 100644 eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no_meta.json create mode 100644 eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=2_route_specific=yes.pkl create mode 100644 eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=2_route_specific=yes_meta.json create mode 100644 eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no.pkl create mode 100644 eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no_meta.json create mode 100644 eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153123_degree=2_route_specific=no.pkl create mode 100644 eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153123_degree=2_route_specific=no_meta.json create mode 100644 eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=2_route_specific=yes.pkl create mode 100644 eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=2_route_specific=yes_meta.json create mode 100644 eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no.pkl create mode 100644 eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no_meta.json create mode 100644 eta_prediction/models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161336_degree=2_handle_nan=drop.pkl create mode 100644 eta_prediction/models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161336_degree=2_handle_nan=drop_meta.json create mode 100644 eta_prediction/models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop.pkl create mode 100644 eta_prediction/models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop_meta.json create mode 100644 eta_prediction/models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153123_degree=2_handle_nan=drop.pkl create mode 100644 eta_prediction/models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153123_degree=2_handle_nan=drop_meta.json create mode 100644 eta_prediction/models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop.pkl create mode 100644 eta_prediction/models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop_meta.json create mode 100644 eta_prediction/models/trained/registry.json diff --git a/eta_prediction/models/common/data.py b/eta_prediction/models/common/data.py new file mode 100644 index 0000000..a6a3788 --- /dev/null +++ b/eta_prediction/models/common/data.py @@ -0,0 +1,230 @@ +""" +Data loading and preprocessing utilities for ETA prediction models. +Handles dataset splitting, feature engineering, and train/test preparation. +""" + +import pandas as pd +import numpy as np +from pathlib import Path +from typing import Tuple, List, Optional, Dict +from datetime import datetime, timedelta + + +class ETADataset: + """ + Manages ETA prediction datasets with consistent preprocessing and splitting. + + Expected columns from VP dataset builder: + - Identifiers: trip_id, route_id, vehicle_id, stop_id, stop_sequence + - Position: vp_ts, vp_lat, vp_lon, vp_bearing + - Stop: stop_lat, stop_lon, distance_to_stop + - Target: actual_arrival, time_to_arrival_seconds + - Temporal: hour, day_of_week, is_weekend, is_holiday, is_peak_hour + - Operational: headway_seconds, current_speed_kmh + - Weather (optional): temperature_c, precipitation_mm, wind_speed_kmh + """ + + FEATURE_GROUPS = { + 'identifiers': ['trip_id', 'route_id', 'vehicle_id', 'stop_id', 'stop_sequence'], + 'position': ['vp_lat', 'vp_lon', 'vp_bearing', 'distance_to_stop'], + 'temporal': ['hour', 'day_of_week', 'is_weekend', 'is_holiday', 'is_peak_hour'], + 'operational': ['headway_seconds', 'current_speed_kmh'], + 'weather': ['temperature_c', 'precipitation_mm', 'wind_speed_kmh'], + 'target': ['time_to_arrival_seconds'] + } + + def __init__(self, data_path: str): + """ + Initialize dataset from parquet file. + + Args: + data_path: Path to parquet file from VP dataset builder + """ + self.data_path = Path(data_path) + self.df = pd.read_parquet(data_path) + self.df['vp_ts'] = pd.to_datetime(self.df['vp_ts']) + + # Store original size + self.original_size = len(self.df) + + def clean_data(self, + drop_missing_target: bool = True, + max_eta_seconds: float = 3600 * 2, # 2 hours + min_distance: float = 10.0) -> 'ETADataset': + """ + Clean dataset by removing invalid rows. + + Args: + drop_missing_target: Remove rows without valid ETA target + max_eta_seconds: Maximum reasonable ETA (filter outliers) + min_distance: Minimum distance to stop (meters) to keep + + Returns: + Self for chaining + """ + initial_rows = len(self.df) + + if drop_missing_target: + self.df = self.df.dropna(subset=['time_to_arrival_seconds']) + + # Filter outliers + self.df = self.df[ + (self.df['time_to_arrival_seconds'] >= 0) & + (self.df['time_to_arrival_seconds'] <= max_eta_seconds) + ] + + # Filter too-close stops (likely already passed) + if 'distance_to_stop' in self.df.columns: + self.df = self.df[self.df['distance_to_stop'] >= min_distance] + + print(f"Cleaned: {initial_rows} → {len(self.df)} rows " + f"({100 * len(self.df) / initial_rows:.1f}% retained)") + + return self + + def get_features(self, feature_groups: List[str]) -> List[str]: + """ + Get list of feature columns from specified groups. + + Args: + feature_groups: List of group names (e.g., ['temporal', 'position']) + + Returns: + List of column names that exist in the dataset + """ + features = [] + for group in feature_groups: + if group in self.FEATURE_GROUPS: + features.extend(self.FEATURE_GROUPS[group]) + + # Return only columns that exist + return [f for f in features if f in self.df.columns] + + def temporal_split(self, + train_frac: float = 0.7, + val_frac: float = 0.15) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: + """ + Split dataset by time (avoids data leakage). + + Args: + train_frac: Fraction for training + val_frac: Fraction for validation (remainder goes to test) + + Returns: + train_df, val_df, test_df + """ + # Sort by timestamp + df_sorted = self.df.sort_values('vp_ts').reset_index(drop=True) + + n = len(df_sorted) + train_end = int(n * train_frac) + val_end = int(n * (train_frac + val_frac)) + + train_df = df_sorted.iloc[:train_end].copy() + val_df = df_sorted.iloc[train_end:val_end].copy() + test_df = df_sorted.iloc[val_end:].copy() + + print(f"Temporal split: train={len(train_df)}, val={len(val_df)}, test={len(test_df)}") + + return train_df, val_df, test_df + + def route_split(self, + test_routes: Optional[List[str]] = None, + test_frac: float = 0.2) -> Tuple[pd.DataFrame, pd.DataFrame]: + """ + Split by route for cross-route generalization testing. + + Args: + test_routes: Specific routes for test set, or None to sample + test_frac: Fraction of routes for testing if test_routes is None + + Returns: + train_df, test_df + """ + if test_routes is None: + routes = self.df['route_id'].unique() + n_test = max(1, int(len(routes) * test_frac)) + test_routes = np.random.choice(routes, size=n_test, replace=False) + + test_df = self.df[self.df['route_id'].isin(test_routes)].copy() + train_df = self.df[~self.df['route_id'].isin(test_routes)].copy() + + print(f"Route split: {len(test_routes)} test routes") + print(f" Train: {len(train_df)} samples") + print(f" Test: {len(test_df)} samples") + + return train_df, test_df + + def get_route_stats(self) -> pd.DataFrame: + """Get statistics per route.""" + return self.df.groupby('route_id').agg({ + 'time_to_arrival_seconds': ['count', 'mean', 'std'], + 'distance_to_stop': ['mean', 'std'], + 'trip_id': 'nunique' + }).round(2) + + def summary(self) -> Dict: + """Get dataset summary statistics.""" + return { + 'total_samples': len(self.df), + 'date_range': (self.df['vp_ts'].min(), self.df['vp_ts'].max()), + 'routes': self.df['route_id'].nunique(), + 'trips': self.df['trip_id'].nunique(), + 'vehicles': self.df['vehicle_id'].nunique(), + 'stops': self.df['stop_id'].nunique(), + 'eta_mean_minutes': self.df['time_to_arrival_seconds'].mean() / 60, + 'eta_std_minutes': self.df['time_to_arrival_seconds'].std() / 60, + 'missing_weather': self.df['temperature_c'].isna().sum() if 'temperature_c' in self.df.columns else 'N/A' + } + + +def load_dataset(dataset_name: str = "sample_dataset") -> ETADataset: + """ + Load dataset from datasets directory. + + Args: + dataset_name: Name of dataset (without .parquet extension) + + Returns: + ETADataset instance + """ + datasets_dir = Path(__file__).parent.parent.parent / "datasets" + data_path = datasets_dir / f"{dataset_name}.parquet" + + if not data_path.exists(): + raise FileNotFoundError(f"Dataset not found: {data_path}") + + return ETADataset(str(data_path)) + + +def prepare_features_target(df: pd.DataFrame, + feature_cols: List[str], + target_col: str = 'time_to_arrival_seconds', + fill_na: bool = True) -> Tuple[pd.DataFrame, pd.Series]: + """ + Extract features and target, handle missing values. + + Args: + df: DataFrame with features and target + feature_cols: List of feature column names + target_col: Name of target column + fill_na: Whether to fill NaN values + + Returns: + X (features), y (target) + """ + # Get features that exist + available_features = [f for f in feature_cols if f in df.columns] + + X = df[available_features].copy() + y = df[target_col].copy() + + if fill_na: + # Fill numeric features with median, boolean with False + for col in X.columns: + if X[col].dtype == 'bool': + X[col] = X[col].fillna(False) + elif X[col].dtype in ['int64', 'float64']: + X[col] = X[col].fillna(X[col].median()) + + return X, y \ No newline at end of file diff --git a/eta_prediction/models/common/keys.py b/eta_prediction/models/common/keys.py new file mode 100644 index 0000000..074f301 --- /dev/null +++ b/eta_prediction/models/common/keys.py @@ -0,0 +1,193 @@ +""" +Model key generation and identification utilities. +Ensures consistent naming and versioning across the modeling pipeline. +""" + +from typing import Dict, Optional +from datetime import datetime + + +class ModelKey: + """ + Generates unique, descriptive keys for trained models. + + Format: {model_type}_{dataset}_{features}_{timestamp} + Example: polyreg_distance_sample_temporal-position_20250126_143022 + """ + + @staticmethod + def generate(model_type: str, + dataset_name: str, + feature_groups: list, + version: Optional[str] = None, + **kwargs) -> str: + """ + Generate a unique model key. + + Args: + model_type: Type of model (e.g., 'polyreg_distance', 'ewma') + dataset_name: Name of training dataset + feature_groups: List of feature group names used + version: Optional version string, defaults to timestamp + **kwargs: Additional metadata to include in key + + Returns: + Unique model key string + """ + # Create features string + features_str = '-'.join(sorted(feature_groups)) + + # Create version string + if version is None: + version = datetime.now().strftime("%Y%m%d_%H%M%S") + + # Base key + key_parts = [ + model_type, + dataset_name, + features_str, + version + ] + + # Add optional kwargs + for k, v in sorted(kwargs.items()): + if v is not None: + key_parts.append(f"{k}={v}") + + return '_'.join(key_parts) + + @staticmethod + def parse(key: str) -> Dict[str, str]: + """ + Parse a model key back into components. + + Args: + key: Model key string + + Returns: + Dictionary with parsed components + """ + parts = key.split('_') + + if len(parts) < 4: + raise ValueError(f"Invalid model key format: {key}") + + parsed = { + 'model_type': parts[0], + 'dataset': parts[1], + 'features': parts[2], + 'version': '_'.join(parts[3:5]) if len(parts) >= 5 else parts[3] + } + + # Parse additional kwargs (key=value format) + if len(parts) > 5: + for part in parts[5:]: + if '=' in part: + k, v = part.split('=', 1) + parsed[k] = v + + return parsed + + +class PredictionKey: + """ + Generates keys for prediction requests to enable caching and deduplication. + + Format: {route_id}_{stop_id}_{vp_hash} + """ + + @staticmethod + def generate(route_id: str, + stop_id: str, + vehicle_lat: float, + vehicle_lon: float, + timestamp: datetime, + stop_sequence: Optional[int] = None) -> str: + """ + Generate prediction key for a vehicle-stop pair. + + Args: + route_id: Route identifier + stop_id: Stop identifier + vehicle_lat: Vehicle latitude + vehicle_lon: Vehicle longitude + timestamp: Timestamp of vehicle position + stop_sequence: Optional stop sequence number + + Returns: + Prediction key string + """ + # Round coordinates to ~10m precision for caching + lat_rounded = round(vehicle_lat, 4) + lon_rounded = round(vehicle_lon, 4) + + # Create position hash + vp_hash = f"{lat_rounded},{lon_rounded}" + + # Build key + if stop_sequence is not None: + return f"{route_id}_{stop_id}_{stop_sequence}_{vp_hash}" + else: + return f"{route_id}_{stop_id}_{vp_hash}" + + +class ExperimentKey: + """ + Generates keys for experiments and model comparisons. + """ + + @staticmethod + def generate(experiment_name: str, + models: list, + dataset: str, + timestamp: Optional[str] = None) -> str: + """ + Generate experiment key. + + Args: + experiment_name: Name of experiment + models: List of model types being compared + dataset: Dataset name + timestamp: Optional timestamp, defaults to now + + Returns: + Experiment key string + """ + if timestamp is None: + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + + models_str = '-'.join(sorted(models)) + + return f"exp_{experiment_name}_{models_str}_{dataset}_{timestamp}" + + +def model_filename(model_key: str, extension: str = "pkl") -> str: + """ + Generate consistent filename for model artifacts. + + Args: + model_key: Model key from ModelKey.generate() + extension: File extension (pkl, joblib, json, etc.) + + Returns: + Filename string + """ + return f"{model_key}.{extension}" + + +def validate_model_key(key: str) -> bool: + """ + Validate that a string is a properly formatted model key. + + Args: + key: String to validate + + Returns: + True if valid, False otherwise + """ + try: + parsed = ModelKey.parse(key) + required = ['model_type', 'dataset', 'features', 'version'] + return all(k in parsed for k in required) + except (ValueError, IndexError): + return False \ No newline at end of file diff --git a/eta_prediction/models/common/metrics.py b/eta_prediction/models/common/metrics.py new file mode 100644 index 0000000..70814de --- /dev/null +++ b/eta_prediction/models/common/metrics.py @@ -0,0 +1,245 @@ +""" +Evaluation metrics for ETA prediction models. +Provides domain-specific metrics beyond standard regression metrics. +""" + +import numpy as np +import pandas as pd +from typing import Dict, Optional, Tuple +from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score + + +def mae_seconds(y_true: np.ndarray, y_pred: np.ndarray) -> float: + """Mean Absolute Error in seconds.""" + return mean_absolute_error(y_true, y_pred) + + +def mae_minutes(y_true: np.ndarray, y_pred: np.ndarray) -> float: + """Mean Absolute Error in minutes.""" + return mean_absolute_error(y_true, y_pred) / 60 + + +def rmse_seconds(y_true: np.ndarray, y_pred: np.ndarray) -> float: + """Root Mean Squared Error in seconds.""" + return np.sqrt(mean_squared_error(y_true, y_pred)) + + +def rmse_minutes(y_true: np.ndarray, y_pred: np.ndarray) -> float: + """Root Mean Squared Error in minutes.""" + return np.sqrt(mean_squared_error(y_true, y_pred)) / 60 + + +def mape(y_true: np.ndarray, y_pred: np.ndarray, epsilon: float = 1.0) -> float: + """ + Mean Absolute Percentage Error. + + Args: + y_true: True values + y_pred: Predicted values + epsilon: Small value to avoid division by zero + + Returns: + MAPE as percentage + """ + return 100 * np.mean(np.abs((y_true - y_pred) / (y_true + epsilon))) + + +def median_ae(y_true: np.ndarray, y_pred: np.ndarray) -> float: + """Median Absolute Error in seconds (robust to outliers).""" + return np.median(np.abs(y_true - y_pred)) + + +def within_threshold(y_true: np.ndarray, + y_pred: np.ndarray, + threshold_seconds: float = 60) -> float: + """ + Fraction of predictions within threshold. + + Args: + y_true: True values in seconds + y_pred: Predicted values in seconds + threshold_seconds: Acceptable error threshold + + Returns: + Fraction of predictions within threshold (0-1) + """ + errors = np.abs(y_true - y_pred) + return np.mean(errors <= threshold_seconds) + + +def late_penalty_mae(y_true: np.ndarray, + y_pred: np.ndarray, + late_multiplier: float = 2.0) -> float: + """ + MAE with higher penalty for late predictions (user-centric). + + Args: + y_true: True values + y_pred: Predicted values + late_multiplier: Multiplier for underprediction errors + + Returns: + Weighted MAE + """ + errors = y_pred - y_true + weights = np.where(errors < 0, late_multiplier, 1.0) + return np.mean(np.abs(errors) * weights) + + +def quantile_error(y_true: np.ndarray, + y_pred: np.ndarray, + quantiles: list = [0.5, 0.9, 0.95]) -> Dict[str, float]: + """ + Absolute errors at different quantiles. + + Args: + y_true: True values + y_pred: Predicted values + quantiles: List of quantiles to compute + + Returns: + Dictionary mapping quantile to error + """ + errors = np.abs(y_true - y_pred) + return {f"q{int(q*100)}": np.quantile(errors, q) for q in quantiles} + + +def bias(y_true: np.ndarray, y_pred: np.ndarray) -> float: + """ + Mean bias (positive = overprediction, negative = underprediction). + + Returns: + Mean bias in seconds + """ + return np.mean(y_pred - y_true) + + +def compute_all_metrics(y_true: np.ndarray, + y_pred: np.ndarray, + prefix: str = "") -> Dict[str, float]: + """ + Compute comprehensive set of metrics. + + Args: + y_true: True values in seconds + y_pred: Predicted values in seconds + prefix: Optional prefix for metric names (e.g., "val_") + + Returns: + Dictionary of all metrics + """ + metrics = { + f"{prefix}mae_seconds": mae_seconds(y_true, y_pred), + f"{prefix}mae_minutes": mae_minutes(y_true, y_pred), + f"{prefix}rmse_seconds": rmse_seconds(y_true, y_pred), + f"{prefix}rmse_minutes": rmse_minutes(y_true, y_pred), + f"{prefix}mape": mape(y_true, y_pred), + f"{prefix}median_ae": median_ae(y_true, y_pred), + f"{prefix}bias_seconds": bias(y_true, y_pred), + f"{prefix}r2": r2_score(y_true, y_pred), + f"{prefix}within_60s": within_threshold(y_true, y_pred, 60), + f"{prefix}within_120s": within_threshold(y_true, y_pred, 120), + f"{prefix}within_300s": within_threshold(y_true, y_pred, 300), + f"{prefix}late_penalty_mae": late_penalty_mae(y_true, y_pred), + } + + # Add quantile errors + quantile_errs = quantile_error(y_true, y_pred) + for k, v in quantile_errs.items(): + metrics[f"{prefix}error_{k}"] = v + + return metrics + + +def compare_models(results: Dict[str, Dict[str, float]], + metric: str = "mae_seconds") -> pd.DataFrame: + """ + Compare multiple models on a metric. + + Args: + results: Dict mapping model_name -> metrics_dict + metric: Metric to compare (or 'all' for all metrics) + + Returns: + DataFrame with comparison + """ + if metric == 'all': + df = pd.DataFrame(results).T + else: + df = pd.DataFrame({ + 'model': list(results.keys()), + metric: [results[m].get(metric, np.nan) for m in results.keys()] + }) + df = df.sort_values(metric) + + return df + + +def error_analysis(y_true: np.ndarray, + y_pred: np.ndarray, + feature_df: Optional[pd.DataFrame] = None, + group_by: Optional[str] = None) -> pd.DataFrame: + """ + Analyze errors by different segments. + + Args: + y_true: True values + y_pred: Predicted values + feature_df: DataFrame with features for grouping + group_by: Column name to group by + + Returns: + DataFrame with error statistics per group + """ + errors = np.abs(y_true - y_pred) + + if feature_df is None or group_by is None: + # Overall statistics + return pd.DataFrame({ + 'count': [len(errors)], + 'mae': [np.mean(errors)], + 'median_ae': [np.median(errors)], + 'rmse': [np.sqrt(np.mean(errors**2))], + 'max_error': [np.max(errors)], + }) + + # Group-wise statistics + df = feature_df.copy() + df['error'] = errors + + stats = df.groupby(group_by)['error'].agg([ + ('count', 'count'), + ('mae', 'mean'), + ('median_ae', 'median'), + ('std', 'std'), + ('max', 'max') + ]).round(2) + + return stats.sort_values('mae', ascending=False) + + +def prediction_intervals(y_pred: np.ndarray, + residuals: np.ndarray, + confidence: float = 0.95) -> Tuple[np.ndarray, np.ndarray]: + """ + Compute prediction intervals based on residual distribution. + + Args: + y_pred: Point predictions + residuals: Training residuals (y_true - y_pred) + confidence: Confidence level (e.g., 0.95 for 95% interval) + + Returns: + lower_bound, upper_bound arrays + """ + alpha = 1 - confidence + lower_q = alpha / 2 + upper_q = 1 - alpha / 2 + + lower_percentile = np.percentile(residuals, lower_q * 100) + upper_percentile = np.percentile(residuals, upper_q * 100) + + lower_bound = y_pred + lower_percentile + upper_bound = y_pred + upper_percentile + + return lower_bound, upper_bound \ No newline at end of file diff --git a/eta_prediction/models/common/registry.py b/eta_prediction/models/common/registry.py new file mode 100644 index 0000000..a248206 --- /dev/null +++ b/eta_prediction/models/common/registry.py @@ -0,0 +1,260 @@ +""" +Model registry for managing trained models and their metadata. +Provides save/load functionality with consistent structure. +""" + +import json +import pickle +from pathlib import Path +from typing import Dict, Any, Optional, List +from datetime import datetime +import pandas as pd + + +class ModelRegistry: + """ + Manages model artifacts and metadata in a structured directory. + + Structure: + models/ + ├── trained/ + │ ├── {model_key}.pkl # Serialized model + │ └── {model_key}_meta.json # Model metadata + └── registry.json # Index of all models + """ + + def __init__(self, base_dir: str = "models/trained"): + """ + Initialize registry. + + Args: + base_dir: Base directory for model storage + """ + self.base_dir = Path(base_dir) + self.base_dir.mkdir(parents=True, exist_ok=True) + + self.registry_file = self.base_dir / "registry.json" + self._load_registry() + + def _load_registry(self): + """Load registry index from disk.""" + if self.registry_file.exists(): + with open(self.registry_file, 'r') as f: + self.registry = json.load(f) + else: + self.registry = {} + + def _save_registry(self): + """Save registry index to disk.""" + with open(self.registry_file, 'w') as f: + json.dump(self.registry, f, indent=2) + + def save_model(self, + model_key: str, + model: Any, + metadata: Dict[str, Any], + overwrite: bool = False) -> Path: + """ + Save model and metadata to registry. + + Args: + model_key: Unique model identifier + model: Trained model object (must be picklable) + metadata: Model metadata (training metrics, config, etc.) + overwrite: Whether to overwrite existing model + + Returns: + Path to saved model file + """ + model_path = self.base_dir / f"{model_key}.pkl" + meta_path = self.base_dir / f"{model_key}_meta.json" + + if model_path.exists() and not overwrite: + raise FileExistsError(f"Model {model_key} already exists. Set overwrite=True to replace.") + + # Save model artifact + with open(model_path, 'wb') as f: + pickle.dump(model, f) + + # Enrich metadata + metadata['model_key'] = model_key + metadata['saved_at'] = datetime.now().isoformat() + metadata['model_path'] = str(model_path) + + # Save metadata + with open(meta_path, 'w') as f: + json.dump(metadata, f, indent=2) + + # Update registry + self.registry[model_key] = { + 'model_path': str(model_path), + 'meta_path': str(meta_path), + 'saved_at': metadata['saved_at'], + 'model_type': metadata.get('model_type', 'unknown') + } + self._save_registry() + + print(f"✓ Saved model: {model_key}") + return model_path + + def load_model(self, model_key: str) -> Any: + """ + Load model from registry. + + Args: + model_key: Unique model identifier + + Returns: + Loaded model object + """ + if model_key not in self.registry: + raise KeyError(f"Model {model_key} not found in registry") + + model_path = Path(self.registry[model_key]['model_path']) + + with open(model_path, 'rb') as f: + model = pickle.load(f) + + return model + + def load_metadata(self, model_key: str) -> Dict[str, Any]: + """ + Load model metadata. + + Args: + model_key: Unique model identifier + + Returns: + Metadata dictionary + """ + if model_key not in self.registry: + raise KeyError(f"Model {model_key} not found in registry") + + meta_path = Path(self.registry[model_key]['meta_path']) + + with open(meta_path, 'r') as f: + metadata = json.load(f) + + return metadata + + def list_models(self, + model_type: Optional[str] = None, + sort_by: str = 'saved_at') -> pd.DataFrame: + """ + List all models in registry. + + Args: + model_type: Filter by model type (e.g., 'polyreg_distance') + sort_by: Column to sort by + + Returns: + DataFrame with model information + """ + models = [] + + for key, info in self.registry.items(): + if model_type and info.get('model_type') != model_type: + continue + + # Load metadata for richer info + try: + meta = self.load_metadata(key) + models.append({ + 'model_key': key, + 'model_type': info.get('model_type', 'unknown'), + 'saved_at': info['saved_at'], + 'dataset': meta.get('dataset', 'unknown'), + 'mae_seconds': meta.get('metrics', {}).get('test_mae_seconds', None), + 'rmse_seconds': meta.get('metrics', {}).get('test_rmse_seconds', None), + 'r2': meta.get('metrics', {}).get('test_r2', None), + }) + except Exception as e: + print(f"Warning: Could not load metadata for {key}: {e}") + models.append({ + 'model_key': key, + 'model_type': info.get('model_type', 'unknown'), + 'saved_at': info['saved_at'], + }) + + df = pd.DataFrame(models) + if not df.empty and sort_by in df.columns: + df = df.sort_values(sort_by, ascending=False) + + return df + + def delete_model(self, model_key: str) -> bool: + """ + Delete model and metadata from registry. + + Args: + model_key: Unique model identifier + + Returns: + True if deleted successfully + """ + if model_key not in self.registry: + raise KeyError(f"Model {model_key} not found in registry") + + # Delete files + model_path = Path(self.registry[model_key]['model_path']) + meta_path = Path(self.registry[model_key]['meta_path']) + + if model_path.exists(): + model_path.unlink() + if meta_path.exists(): + meta_path.unlink() + + # Remove from registry + del self.registry[model_key] + self._save_registry() + + print(f"✓ Deleted model: {model_key}") + return True + + def get_best_model(self, + model_type: Optional[str] = None, + metric: str = 'test_mae_seconds', + minimize: bool = True) -> str: + """ + Get best model by metric. + + Args: + model_type: Filter by model type + metric: Metric to optimize + minimize: Whether to minimize (True) or maximize (False) metric + + Returns: + Model key of best model + """ + candidates = [] + + for key in self.registry.keys(): + if model_type and self.registry[key].get('model_type') != model_type: + continue + + try: + meta = self.load_metadata(key) + metric_value = meta.get('metrics', {}).get(metric) + + if metric_value is not None: + candidates.append((key, metric_value)) + except Exception: + continue + + if not candidates: + raise ValueError(f"No models found with metric {metric}") + + # Sort and return best + candidates.sort(key=lambda x: x[1], reverse=not minimize) + return candidates[0][0] + + +# Global registry instance +_registry = None + +def get_registry() -> ModelRegistry: + """Get or create global registry instance.""" + global _registry + if _registry is None: + _registry = ModelRegistry() + return _registry \ No newline at end of file diff --git a/eta_prediction/models/common/utils.py b/eta_prediction/models/common/utils.py new file mode 100644 index 0000000..0f1566a --- /dev/null +++ b/eta_prediction/models/common/utils.py @@ -0,0 +1,276 @@ +""" +Utility functions for models package. +""" + +import numpy as np +import pandas as pd +from typing import Any, Dict, List, Optional +from datetime import datetime +import logging + + +def setup_logging(name: str = "eta_models", level: str = "INFO") -> logging.Logger: + """ + Setup consistent logging for models. + + Args: + name: Logger name + level: Logging level + + Returns: + Configured logger + """ + logger = logging.getLogger(name) + logger.setLevel(getattr(logging, level)) + + if not logger.handlers: + handler = logging.StreamHandler() + formatter = logging.Formatter( + '%(asctime)s - %(name)s - %(levelname)s - %(message)s' + ) + handler.setFormatter(formatter) + logger.addHandler(handler) + + return logger + + +def safe_divide(numerator: np.ndarray, + denominator: np.ndarray, + fill_value: float = 0.0) -> np.ndarray: + """ + Safe division that handles division by zero. + + Args: + numerator: Numerator array + denominator: Denominator array + fill_value: Value to use when denominator is zero + + Returns: + Result array + """ + result = np.full_like(numerator, fill_value, dtype=float) + mask = denominator != 0 + result[mask] = numerator[mask] / denominator[mask] + return result + + +def clip_predictions(predictions: np.ndarray, + min_value: float = 0.0, + max_value: float = 7200.0) -> np.ndarray: + """ + Clip predictions to reasonable range. + + Args: + predictions: Raw predictions + min_value: Minimum ETA (seconds) + max_value: Maximum ETA (seconds, default 2 hours) + + Returns: + Clipped predictions + """ + return np.clip(predictions, min_value, max_value) + + +def add_lag_features(df: pd.DataFrame, + columns: List[str], + lags: List[int], + group_by: Optional[str] = None) -> pd.DataFrame: + """ + Add lagged features to dataframe. + + Args: + df: Input dataframe + columns: Columns to lag + lags: List of lag values (e.g., [1, 2, 3]) + group_by: Optional column to group by before lagging + + Returns: + DataFrame with lag features added + """ + df_copy = df.copy() + + for col in columns: + for lag in lags: + lag_col_name = f"{col}_lag{lag}" + + if group_by: + df_copy[lag_col_name] = df_copy.groupby(group_by)[col].shift(lag) + else: + df_copy[lag_col_name] = df_copy[col].shift(lag) + + return df_copy + + +def smooth_predictions(predictions: np.ndarray, + window_size: int = 3, + method: str = 'ewma', + alpha: float = 0.3) -> np.ndarray: + """ + Smooth predictions using moving average. + + Args: + predictions: Array of predictions + window_size: Window size for smoothing + method: 'mean', 'median', or 'ewma' + alpha: Alpha parameter for EWMA + + Returns: + Smoothed predictions + """ + if len(predictions) < window_size: + return predictions + + if method == 'mean': + return pd.Series(predictions).rolling(window_size, min_periods=1).mean().values + elif method == 'median': + return pd.Series(predictions).rolling(window_size, min_periods=1).median().values + elif method == 'ewma': + return pd.Series(predictions).ewm(alpha=alpha).mean().values + else: + raise ValueError(f"Unknown smoothing method: {method}") + + +def calculate_speed_kmh(distance_m: float, time_s: float) -> float: + """ + Calculate speed in km/h from distance and time. + + Args: + distance_m: Distance in meters + time_s: Time in seconds + + Returns: + Speed in km/h + """ + if time_s <= 0: + return 0.0 + return (distance_m / 1000) / (time_s / 3600) + + +def haversine_distance(lat1: float, lon1: float, + lat2: float, lon2: float) -> float: + """ + Calculate great-circle distance between two points. + + Args: + lat1, lon1: First point coordinates + lat2, lon2: Second point coordinates + + Returns: + Distance in meters + """ + R = 6371000 # Earth radius in meters + + phi1 = np.radians(lat1) + phi2 = np.radians(lat2) + delta_phi = np.radians(lat2 - lat1) + delta_lambda = np.radians(lon2 - lon1) + + a = np.sin(delta_phi / 2) ** 2 + \ + np.cos(phi1) * np.cos(phi2) * np.sin(delta_lambda / 2) ** 2 + c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a)) + + return R * c + + +def format_seconds(seconds: float) -> str: + """ + Format seconds as human-readable string. + + Args: + seconds: Time in seconds + + Returns: + Formatted string (e.g., "2m 30s", "1h 15m") + """ + if seconds < 60: + return f"{int(seconds)}s" + elif seconds < 3600: + minutes = int(seconds / 60) + secs = int(seconds % 60) + return f"{minutes}m {secs}s" + else: + hours = int(seconds / 3600) + minutes = int((seconds % 3600) / 60) + return f"{hours}h {minutes}m" + + +def print_metrics_table(metrics: Dict[str, float], title: str = "Metrics"): + """ + Pretty print metrics as a table. + + Args: + metrics: Dictionary of metric names to values + title: Table title + """ + print(f"\n{'='*50}") + print(f"{title:^50}") + print(f"{'='*50}") + + for name, value in metrics.items(): + if isinstance(value, float): + print(f"{name:.<40} {value:.4f}") + else: + print(f"{name:.<40} {value}") + + print(f"{'='*50}\n") + + +def train_test_summary(train_df: pd.DataFrame, + test_df: pd.DataFrame, + val_df: Optional[pd.DataFrame] = None): + """ + Print summary of train/test split. + + Args: + train_df: Training dataframe + test_df: Test dataframe + val_df: Optional validation dataframe + """ + print("\n" + "="*60) + print("DATASET SPLIT SUMMARY".center(60)) + print("="*60) + + print(f"\nTrain: {len(train_df):,} samples") + print(f" Date range: {train_df['vp_ts'].min()} to {train_df['vp_ts'].max()}") + print(f" Routes: {train_df['route_id'].nunique()}") + print(f" Mean ETA: {train_df['time_to_arrival_seconds'].mean()/60:.1f} min") + + if val_df is not None: + print(f"\nValidation: {len(val_df):,} samples") + print(f" Date range: {val_df['vp_ts'].min()} to {val_df['vp_ts'].max()}") + print(f" Routes: {val_df['route_id'].nunique()}") + print(f" Mean ETA: {val_df['time_to_arrival_seconds'].mean()/60:.1f} min") + + print(f"\nTest: {len(test_df):,} samples") + print(f" Date range: {test_df['vp_ts'].min()} to {test_df['vp_ts'].max()}") + print(f" Routes: {test_df['route_id'].nunique()}") + print(f" Mean ETA: {test_df['time_to_arrival_seconds'].mean()/60:.1f} min") + + print("="*60 + "\n") + + +def create_feature_importance_df(feature_names: List[str], + importances: np.ndarray, + top_n: int = 20) -> pd.DataFrame: + """ + Create sorted feature importance dataframe. + + Args: + feature_names: List of feature names + importances: Array of importance values + top_n: Number of top features to return + + Returns: + DataFrame sorted by importance + """ + df = pd.DataFrame({ + 'feature': feature_names, + 'importance': importances + }) + + df = df.sort_values('importance', ascending=False) + + if top_n: + df = df.head(top_n) + + return df \ No newline at end of file diff --git a/eta_prediction/models/evaluation/leaderboard.py b/eta_prediction/models/evaluation/leaderboard.py new file mode 100644 index 0000000..292a9f4 --- /dev/null +++ b/eta_prediction/models/evaluation/leaderboard.py @@ -0,0 +1,229 @@ +""" +Model leaderboard for comparing performance across models. +""" + +import pandas as pd +import numpy as np +from typing import List, Optional, Dict +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) + +from common.registry import get_registry +from common.data import load_dataset +from common.metrics import compute_all_metrics + + +class ModelLeaderboard: + """ + Compare multiple models on standardized test sets. + """ + + def __init__(self): + self.registry = get_registry() + self.results = [] + + def evaluate_model(self, + model_key: str, + test_df: pd.DataFrame, + target_col: str = 'time_to_arrival_seconds') -> Dict: + """ + Evaluate single model on test set. + + Args: + model_key: Model identifier + test_df: Test dataframe + target_col: Target column name + + Returns: + Dictionary with metrics + """ + print(f"Evaluating {model_key}...") + + # Load model and metadata + model = self.registry.load_model(model_key) + metadata = self.registry.load_metadata(model_key) + + # Predict + y_true = test_df[target_col].values + y_pred = model.predict(test_df) + + # Compute metrics + metrics = compute_all_metrics(y_true, y_pred) + + # Add model info + result = { + 'model_key': model_key, + 'model_type': metadata.get('model_type', 'unknown'), + 'dataset': metadata.get('dataset', 'unknown'), + **metrics + } + + return result + + def compare_models(self, + model_keys: List[str], + dataset_name: str = "sample_dataset", + test_routes: Optional[List[str]] = None) -> pd.DataFrame: + """ + Compare multiple models on same test set. + + Args: + model_keys: List of model keys to compare + dataset_name: Dataset to evaluate on + test_routes: Specific routes for testing + + Returns: + DataFrame with comparison results + """ + print(f"\n{'='*60}") + print(f"MODEL LEADERBOARD".center(60)) + print(f"{'='*60}\n") + print(f"Dataset: {dataset_name}") + print(f"Models: {len(model_keys)}\n") + + # Load dataset + dataset = load_dataset(dataset_name) + dataset.clean_data() + + # Get test set + if test_routes: + _, test_df = dataset.route_split(test_routes=test_routes) + else: + _, _, test_df = dataset.temporal_split(train_frac=0.7, val_frac=0.15) + + print(f"Test set: {len(test_df)} samples\n") + + # Evaluate each model + results = [] + for model_key in model_keys: + try: + result = self.evaluate_model(model_key, test_df) + results.append(result) + except Exception as e: + print(f" Error evaluating {model_key}: {e}") + + # Create comparison dataframe + df = pd.DataFrame(results) + + # Sort by MAE (primary metric) + if 'mae_seconds' in df.columns: + df = df.sort_values('mae_seconds') + + self.results = results + + return df + + def print_leaderboard(self, + df: pd.DataFrame, + metrics: List[str] = ['mae_minutes', 'rmse_minutes', 'r2', + 'within_60s', 'bias_seconds']): + """ + Pretty print leaderboard. + + Args: + df: Results dataframe + metrics: Metrics to display + """ + print(f"\n{'='*80}") + print(f"LEADERBOARD RESULTS".center(80)) + print(f"{'='*80}\n") + + # Select columns + display_cols = ['model_type'] + [m for m in metrics if m in df.columns] + display_df = df[display_cols].copy() + + # Format numbers + for col in metrics: + if col in display_df.columns: + if col.startswith('within_'): + display_df[col] = (display_df[col] * 100).round(1).astype(str) + '%' + else: + display_df[col] = display_df[col].round(3) + + # Add rank + display_df.insert(0, 'rank', range(1, len(display_df) + 1)) + + print(display_df.to_string(index=False)) + print(f"\n{'='*80}\n") + + # Highlight winner + winner = df.iloc[0] + print(f"🏆 Best Model: {winner['model_type']}") + print(f" MAE: {winner['mae_minutes']:.3f} minutes") + print(f" RMSE: {winner['rmse_minutes']:.3f} minutes") + print(f" R²: {winner['r2']:.3f}") + + def model_comparison_summary(self, df: pd.DataFrame) -> str: + """ + Generate text summary of model comparison. + + Args: + df: Results dataframe + + Returns: + Summary string + """ + best = df.iloc[0] + worst = df.iloc[-1] + + improvement = (worst['mae_seconds'] - best['mae_seconds']) / worst['mae_seconds'] * 100 + + summary = f""" +Model Comparison Summary +======================== + +Total Models Evaluated: {len(df)} +Test Samples: {df.iloc[0].get('test_samples', 'N/A')} + +Best Model: {best['model_type']} + - MAE: {best['mae_minutes']:.2f} minutes + - RMSE: {best['rmse_minutes']:.2f} minutes + - R²: {best['r2']:.3f} + - Within 60s: {best['within_60s']*100:.1f}% + +Baseline (Worst): {worst['model_type']} + - MAE: {worst['mae_minutes']:.2f} minutes + +Improvement: {improvement:.1f}% reduction in MAE from baseline to best model. +""" + return summary + + +def quick_compare(model_keys: List[str], + dataset_name: str = "sample_dataset") -> pd.DataFrame: + """ + Quick comparison function. + + Args: + model_keys: List of model keys + dataset_name: Dataset name + + Returns: + Comparison dataframe + """ + leaderboard = ModelLeaderboard() + df = leaderboard.compare_models(model_keys, dataset_name) + leaderboard.print_leaderboard(df) + + return df + + +if __name__ == "__main__": + # Example: Compare all model types + + # You would need to train these first + model_keys = [ + "historical_mean_sample_dataset_temporal-route_20250126_143022", + "polyreg_distance_sample_dataset_distance_20250126_143022_degree=2", + "polyreg_time_sample_dataset_distance-operational-temporal_20250126_143022_degree=2", + "ewma_sample_dataset_temporal-route_20250126_143022_alpha=0_3" + ] + + # Run comparison + results_df = quick_compare(model_keys) + + # Save results + results_df.to_csv("models/leaderboard_results.csv", index=False) + print("\nResults saved to models/leaderboard_results.csv") \ No newline at end of file diff --git a/eta_prediction/models/evaluation/roll_validate.py b/eta_prediction/models/evaluation/roll_validate.py new file mode 100644 index 0000000..4df4837 --- /dev/null +++ b/eta_prediction/models/evaluation/roll_validate.py @@ -0,0 +1,260 @@ +""" +Rolling window (walk-forward) validation for time series models. +Evaluates model performance over time with realistic train/test splits. +""" + +import pandas as pd +import numpy as np +from typing import Dict, List, Callable, Optional +from datetime import timedelta +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) + +from common.data import load_dataset +from common.metrics import compute_all_metrics +from common.utils import print_metrics_table + + +class RollingValidator: + """ + Perform rolling window validation on time series data. + """ + + def __init__(self, + train_window_days: int = 7, + test_window_days: int = 1, + step_days: int = 1): + """ + Initialize validator. + + Args: + train_window_days: Size of training window in days + test_window_days: Size of test window in days + step_days: Step size between windows + """ + self.train_window = timedelta(days=train_window_days) + self.test_window = timedelta(days=test_window_days) + self.step = timedelta(days=step_days) + + self.results = [] + + def validate(self, + dataset_name: str, + train_fn: Callable, + predict_fn: Callable, + target_col: str = 'time_to_arrival_seconds') -> pd.DataFrame: + """ + Perform rolling window validation. + + Args: + dataset_name: Dataset to validate on + train_fn: Function(train_df) -> model + predict_fn: Function(model, test_df) -> predictions + target_col: Target column name + + Returns: + DataFrame with results per window + """ + print(f"\n{'='*60}") + print(f"ROLLING WINDOW VALIDATION".center(60)) + print(f"{'='*60}\n") + print(f"Train window: {self.train_window.days} days") + print(f"Test window: {self.test_window.days} days") + print(f"Step size: {self.step.days} days\n") + + # Load dataset + dataset = load_dataset(dataset_name) + dataset.clean_data() + + df = dataset.df.sort_values('vp_ts').reset_index(drop=True) + + # Get date range + start_date = df['vp_ts'].min() + end_date = df['vp_ts'].max() + + print(f"Data range: {start_date} to {end_date}") + print(f"Total duration: {(end_date - start_date).days} days\n") + + # Generate windows + current_start = start_date + window_num = 1 + results = [] + + while current_start + self.train_window + self.test_window <= end_date: + train_end = current_start + self.train_window + test_start = train_end + test_end = test_start + self.test_window + + print(f"Window {window_num}:") + print(f" Train: {current_start.date()} to {train_end.date()}") + print(f" Test: {test_start.date()} to {test_end.date()}") + + # Split data + train_df = df[(df['vp_ts'] >= current_start) & (df['vp_ts'] < train_end)] + test_df = df[(df['vp_ts'] >= test_start) & (df['vp_ts'] < test_end)] + + print(f" Train samples: {len(train_df)}, Test samples: {len(test_df)}") + + if len(train_df) == 0 or len(test_df) == 0: + print(f" Skipping (insufficient data)\n") + current_start += self.step + window_num += 1 + continue + + try: + # Train model + model = train_fn(train_df) + + # Predict + y_true = test_df[target_col].values + y_pred = predict_fn(model, test_df) + + # Compute metrics + metrics = compute_all_metrics(y_true, y_pred) + + # Store results + result = { + 'window': window_num, + 'train_start': current_start, + 'train_end': train_end, + 'test_start': test_start, + 'test_end': test_end, + 'train_samples': len(train_df), + 'test_samples': len(test_df), + **metrics + } + results.append(result) + + print(f" MAE: {metrics['mae_minutes']:.2f} min, RMSE: {metrics['rmse_minutes']:.2f} min") + print() + + except Exception as e: + print(f" Error: {e}\n") + + # Move to next window + current_start += self.step + window_num += 1 + + # Create results dataframe + results_df = pd.DataFrame(results) + + if not results_df.empty: + self._print_summary(results_df) + + self.results = results_df + return results_df + + def _print_summary(self, results_df: pd.DataFrame): + """Print summary statistics.""" + print(f"\n{'='*60}") + print(f"VALIDATION SUMMARY".center(60)) + print(f"{'='*60}\n") + + print(f"Total windows: {len(results_df)}") + print(f"\nAverage Metrics:") + print(f" MAE: {results_df['mae_minutes'].mean():.3f} ± {results_df['mae_minutes'].std():.3f} minutes") + print(f" RMSE: {results_df['rmse_minutes'].mean():.3f} ± {results_df['rmse_minutes'].std():.3f} minutes") + print(f" R²: {results_df['r2'].mean():.3f} ± {results_df['r2'].std():.3f}") + print(f" Within 60s: {results_df['within_60s'].mean()*100:.1f}%") + + print(f"\nBest Window: {results_df.loc[results_df['mae_minutes'].idxmin(), 'window']}") + print(f" MAE: {results_df['mae_minutes'].min():.3f} minutes") + + print(f"\nWorst Window: {results_df.loc[results_df['mae_minutes'].idxmax(), 'window']}") + print(f" MAE: {results_df['mae_minutes'].max():.3f} minutes") + + print(f"\n{'='*60}\n") + + def plot_results(self, results_df: Optional[pd.DataFrame] = None, + metric: str = 'mae_minutes'): + """ + Plot metric over time (requires matplotlib). + + Args: + results_df: Results dataframe (uses self.results if None) + metric: Metric to plot + """ + if results_df is None: + results_df = self.results + + if results_df.empty: + print("No results to plot") + return + + try: + import matplotlib.pyplot as plt + + fig, ax = plt.subplots(figsize=(12, 6)) + + ax.plot(results_df['window'], results_df[metric], marker='o') + ax.set_xlabel('Window Number') + ax.set_ylabel(metric.replace('_', ' ').title()) + ax.set_title(f'Rolling Window Validation: {metric}') + ax.grid(True, alpha=0.3) + + # Add mean line + mean_val = results_df[metric].mean() + ax.axhline(mean_val, color='r', linestyle='--', + label=f'Mean: {mean_val:.3f}') + ax.legend() + + plt.tight_layout() + plt.savefig(f'rolling_validation_{metric}.png', dpi=150) + print(f"Plot saved to rolling_validation_{metric}.png") + + except ImportError: + print("matplotlib not available for plotting") + + +def quick_rolling_validate(model_class, + model_params: Dict, + dataset_name: str = "sample_dataset", + train_window_days: int = 7) -> pd.DataFrame: + """ + Quick rolling validation for a model class. + + Args: + model_class: Model class to instantiate + model_params: Parameters for model initialization + dataset_name: Dataset name + train_window_days: Training window size + + Returns: + Results dataframe + """ + def train_fn(train_df): + model = model_class(**model_params) + model.fit(train_df) + return model + + def predict_fn(model, test_df): + return model.predict(test_df) + + validator = RollingValidator( + train_window_days=train_window_days, + test_window_days=1, + step_days=1 + ) + + results_df = validator.validate(dataset_name, train_fn, predict_fn) + + return results_df + + +if __name__ == "__main__": + # Example: Rolling validation for EWMA model + import sys + sys.path.append(str(Path(__file__).parent.parent)) + from ewma.train import EWMAModel + + results = quick_rolling_validate( + model_class=EWMAModel, + model_params={'alpha': 0.3, 'group_by': ['route_id', 'stop_sequence']}, + train_window_days=7 + ) + + # Save results + results.to_csv("models/rolling_validation_results.csv", index=False) + print("Results saved to models/rolling_validation_results.csv") \ No newline at end of file diff --git a/eta_prediction/models/ewma/predict.py b/eta_prediction/models/ewma/predict.py new file mode 100644 index 0000000..14ba453 --- /dev/null +++ b/eta_prediction/models/ewma/predict.py @@ -0,0 +1,155 @@ +""" +Prediction interface for EWMA model. +""" + +import pandas as pd +import numpy as np +from typing import Dict, Optional +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) + +from common.registry import get_registry +from common.utils import format_seconds + + +def predict_eta(model_key: str, + route_id: str, + stop_sequence: int, + hour: Optional[int] = None) -> Dict: + """ + Predict ETA using EWMA model. + + Args: + model_key: Model identifier + route_id: Route ID + stop_sequence: Stop sequence number + hour: Hour of day (if model uses hourly grouping) + + Returns: + Dictionary with prediction and metadata + """ + # Load model + registry = get_registry() + model = registry.load_model(model_key) + metadata = registry.load_metadata(model_key) + + # Prepare input + input_data = { + 'route_id': [route_id], + 'stop_sequence': [stop_sequence] + } + + if hour is not None and 'hour' in model.group_by: + input_data['hour'] = [hour] + + input_df = pd.DataFrame(input_data) + + # Predict + eta_seconds = model.predict(input_df)[0] + + # Check if EWMA value exists + key = tuple(input_df.iloc[0][col] for col in model.group_by) + has_ewma = key in model.ewma_values + n_observations = model.observation_counts.get(key, 0) if has_ewma else 0 + + return { + 'eta_seconds': float(eta_seconds), + 'eta_minutes': float(eta_seconds / 60), + 'eta_formatted': format_seconds(eta_seconds), + 'model_key': model_key, + 'model_type': 'ewma', + 'alpha': metadata.get('alpha'), + 'has_ewma_value': has_ewma, + 'n_observations': n_observations, + 'using_global_mean': not has_ewma or n_observations < model.min_observations + } + + +def predict_and_update(model_key: str, + route_id: str, + stop_sequence: int, + observed_eta: float, + hour: Optional[int] = None, + save_updated: bool = False) -> Dict: + """ + Predict ETA and update model with observed value (online learning). + + Args: + model_key: Model identifier + route_id: Route ID + stop_sequence: Stop sequence + observed_eta: Actual observed ETA in seconds + hour: Hour of day + save_updated: Whether to save updated model back to registry + + Returns: + Dictionary with prediction, error, and updated EWMA + """ + # Get prediction first + result = predict_eta(model_key, route_id, stop_sequence, hour) + prediction = result['eta_seconds'] + + # Load model for update + registry = get_registry() + model = registry.load_model(model_key) + + # Prepare input for update + input_data = { + 'route_id': [route_id], + 'stop_sequence': [stop_sequence] + } + if hour is not None and 'hour' in model.group_by: + input_data['hour'] = [hour] + + input_df = pd.DataFrame(input_data) + + # Update model + model.update(input_df, np.array([observed_eta])) + + # Get new EWMA value + key = tuple(input_df.iloc[0][col] for col in model.group_by) + new_ewma = model.ewma_values.get(key) + + # Save if requested + if save_updated: + metadata = registry.load_metadata(model_key) + registry.save_model(model_key, model, metadata, overwrite=True) + + return { + **result, + 'observed_eta_seconds': observed_eta, + 'error_seconds': observed_eta - prediction, + 'updated_ewma_seconds': new_ewma, + 'model_updated': True + } + + +def batch_predict(model_key: str, input_df: pd.DataFrame) -> pd.DataFrame: + """Batch prediction.""" + registry = get_registry() + model = registry.load_model(model_key) + + result_df = input_df.copy() + result_df['predicted_eta_seconds'] = model.predict(input_df) + result_df['predicted_eta_minutes'] = result_df['predicted_eta_seconds'] / 60 + + return result_df + + +if __name__ == "__main__": + # Example: predict and update + result = predict_and_update( + model_key="ewma_sample_dataset_temporal-route_20250126_143022_alpha=0_3", + route_id="1", + stop_sequence=5, + observed_eta=180.0, # 3 minutes + hour=8 + ) + + print("Prediction and Update:") + print(f" Predicted: {result['eta_formatted']}") + print(f" Observed: {format_seconds(result['observed_eta_seconds'])}") + print(f" Error: {result['error_seconds']:.1f} seconds") + print(f" Updated EWMA: {result['updated_ewma_seconds']/60:.2f} minutes") \ No newline at end of file diff --git a/eta_prediction/models/ewma/train.py b/eta_prediction/models/ewma/train.py new file mode 100644 index 0000000..af6abb8 --- /dev/null +++ b/eta_prediction/models/ewma/train.py @@ -0,0 +1,299 @@ +""" +Exponentially Weighted Moving Average (EWMA) Model +Adapts predictions based on recent observations with exponential decay. +""" + +import pandas as pd +import numpy as np +from typing import Dict, Optional +from collections import defaultdict +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) + +from common.data import load_dataset +from common.metrics import compute_all_metrics +from common.keys import ModelKey +from common.registry import get_registry +from common.utils import print_metrics_table, train_test_summary, clip_predictions + + +class EWMAModel: + """ + EWMA-based ETA prediction. + + Maintains exponentially weighted moving averages for each (route, stop) pair. + Updates incrementally as new observations arrive. + + ETA_new = alpha * observed + (1 - alpha) * ETA_old + """ + + def __init__(self, + alpha: float = 0.3, + group_by: list = ['route_id', 'stop_sequence'], + min_observations: int = 3): + """ + Initialize EWMA model. + + Args: + alpha: Smoothing parameter (0-1, higher = more weight on recent) + group_by: Features to group by + min_observations: Min observations before using EWMA + """ + self.alpha = alpha + self.group_by = group_by + self.min_observations = min_observations + + self.ewma_values = {} # (route, stop, ...) -> current EWMA + self.observation_counts = {} # (route, stop, ...) -> count + self.global_mean = None + + def _make_key(self, row: pd.Series) -> tuple: + """Create lookup key from row.""" + return tuple(row[col] for col in self.group_by) + + def fit(self, train_df: pd.DataFrame, target_col: str = 'time_to_arrival_seconds'): + """ + Train EWMA model by processing observations in time order. + + Args: + train_df: Training dataframe (should be time-sorted) + target_col: Target column name + """ + # Sort by timestamp + df_sorted = train_df.sort_values('vp_ts').reset_index(drop=True) + + self.global_mean = df_sorted[target_col].mean() + + # Process observations sequentially + for _, row in df_sorted.iterrows(): + key = self._make_key(row) + observed = row[target_col] + + if key not in self.ewma_values: + # Initialize with first observation + self.ewma_values[key] = observed + self.observation_counts[key] = 1 + else: + # Update EWMA + old_ewma = self.ewma_values[key] + new_ewma = self.alpha * observed + (1 - self.alpha) * old_ewma + self.ewma_values[key] = new_ewma + self.observation_counts[key] += 1 + + print(f"Trained EWMA model (alpha={self.alpha})") + print(f" Unique groups: {len(self.ewma_values)}") + print(f" Total observations: {len(df_sorted)}") + print(f" Global mean: {self.global_mean/60:.2f} minutes") + + def predict(self, X: pd.DataFrame) -> np.ndarray: + """ + Predict ETAs using current EWMA values. + + Args: + X: DataFrame with group_by columns + + Returns: + Array of predicted ETAs + """ + predictions = [] + + for _, row in X.iterrows(): + key = self._make_key(row) + + if key in self.ewma_values: + count = self.observation_counts[key] + if count >= self.min_observations: + predictions.append(self.ewma_values[key]) + else: + # Not enough observations, use global mean + predictions.append(self.global_mean) + else: + # New group, use global mean + predictions.append(self.global_mean) + + return clip_predictions(np.array(predictions)) + + def update(self, X: pd.DataFrame, y: np.ndarray): + """ + Update EWMA values with new observations (online learning). + + Args: + X: Features + y: Observed values + """ + for (_, row), observed in zip(X.iterrows(), y): + key = self._make_key(row) + + if key not in self.ewma_values: + self.ewma_values[key] = observed + self.observation_counts[key] = 1 + else: + old_ewma = self.ewma_values[key] + new_ewma = self.alpha * observed + (1 - self.alpha) * old_ewma + self.ewma_values[key] = new_ewma + self.observation_counts[key] += 1 + + def get_coverage(self, X: pd.DataFrame) -> float: + """Get fraction of predictions with EWMA values.""" + covered = 0 + for _, row in X.iterrows(): + key = self._make_key(row) + if key in self.ewma_values and self.observation_counts[key] >= self.min_observations: + covered += 1 + return covered / len(X) + + def get_group_stats(self) -> pd.DataFrame: + """Get statistics about learned groups.""" + stats = [] + for key, ewma in self.ewma_values.items(): + count = self.observation_counts[key] + stats.append({ + **{col: val for col, val in zip(self.group_by, key)}, + 'ewma_eta_minutes': ewma / 60, + 'n_observations': count + }) + + return pd.DataFrame(stats).sort_values('n_observations', ascending=False) + + +def train_ewma(dataset_name: str = "sample_dataset", + alpha: float = 0.3, + group_by: list = ['route_id', 'stop_sequence'], + min_observations: int = 3, + test_size: float = 0.2, + save_model: bool = True) -> Dict: + """ + Train and evaluate EWMA model. + + Args: + dataset_name: Name of dataset + alpha: EWMA smoothing parameter + group_by: Grouping columns + min_observations: Minimum observations threshold + test_size: Test fraction + save_model: Whether to save + + Returns: + Dictionary with model, metrics, metadata + """ + print(f"\n{'='*60}") + print(f"Training EWMA Model".center(60)) + print(f"{'='*60}\n") + print(f"Config: alpha={alpha}, group_by={group_by}, min_obs={min_observations}") + + # Load dataset + print(f"\nLoading dataset: {dataset_name}") + dataset = load_dataset(dataset_name) + dataset.clean_data() + + # Split data temporally (important for time series) + train_df, val_df, test_df = dataset.temporal_split( + train_frac=1-test_size-0.1, + val_frac=0.1 + ) + + train_test_summary(train_df, test_df, val_df) + + # Train model + print("Training model...") + model = EWMAModel( + alpha=alpha, + group_by=group_by, + min_observations=min_observations + ) + model.fit(train_df) + + # Evaluate on validation (with optional online updates) + print("\nValidation Performance:") + y_val = val_df['time_to_arrival_seconds'].values + val_preds = model.predict(val_df) + val_metrics = compute_all_metrics(y_val, val_preds, prefix="val_") + print_metrics_table(val_metrics, "Validation Metrics") + + val_coverage = model.get_coverage(val_df) + print(f"Validation coverage: {val_coverage*100:.1f}%") + + # Optionally update model with validation data + print("\nUpdating model with validation data...") + model.update(val_df, y_val) + + # Evaluate on test set + print("\nTest Performance:") + y_test = test_df['time_to_arrival_seconds'].values + test_preds = model.predict(test_df) + test_metrics = compute_all_metrics(y_test, test_preds, prefix="test_") + print_metrics_table(test_metrics, "Test Metrics") + + test_coverage = model.get_coverage(test_df) + print(f"Test coverage: {test_coverage*100:.1f}%") + + # Show some group stats + group_stats = model.get_group_stats() + print(f"\nTop 10 groups by observation count:") + print(group_stats.head(10)) + + # Prepare metadata + metadata = { + 'model_type': 'ewma', + 'dataset': dataset_name, + 'alpha': alpha, + 'group_by': group_by, + 'min_observations': min_observations, + 'n_groups': len(model.ewma_values), + 'train_samples': len(train_df), + 'test_samples': len(test_df), + 'test_coverage': float(test_coverage), + 'global_mean_eta': float(model.global_mean), + 'metrics': {**val_metrics, **test_metrics} + } + + # Save model + if save_model: + model_key = ModelKey.generate( + model_type='ewma', + dataset_name=dataset_name, + feature_groups=['temporal', 'route'], + alpha=str(alpha).replace('.', '_') + ) + + registry = get_registry() + registry.save_model(model_key, model, metadata) + metadata['model_key'] = model_key + + return { + 'model': model, + 'metrics': metadata['metrics'], + 'metadata': metadata + } + + +if __name__ == "__main__": + # Train with different alpha values + + # Conservative (slow adaptation) + result1 = train_ewma(alpha=0.1) + + # Balanced + result2 = train_ewma(alpha=0.3) + + # Aggressive (fast adaptation) + result3 = train_ewma(alpha=0.5) + + # With hourly grouping + result4 = train_ewma( + alpha=0.3, + group_by=['route_id', 'stop_sequence', 'hour'] + ) + + # Compare + print("\n" + "="*60) + print("Model Comparison (Test MAE)") + print("="*60) + results = [result1, result2, result3, result4] + labels = ["alpha=0.1", "alpha=0.3", "alpha=0.5", "alpha=0.3+hour"] + + for label, result in zip(labels, results): + mae_min = result['metrics']['test_mae_minutes'] + print(f"{label:20s}: {mae_min:.3f} minutes") \ No newline at end of file diff --git a/eta_prediction/models/historical_mean/predict.py b/eta_prediction/models/historical_mean/predict.py new file mode 100644 index 0000000..ff5ce67 --- /dev/null +++ b/eta_prediction/models/historical_mean/predict.py @@ -0,0 +1,136 @@ +""" +Prediction interface for Historical Mean model. +""" + +import pandas as pd +import numpy as np +from typing import Dict, Optional +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) + +from common.registry import get_registry +from common.utils import format_seconds + + +def predict_eta(model_key: str, + route_id: str, + stop_sequence: int, + hour: int, + day_of_week: Optional[int] = None, + is_peak_hour: Optional[bool] = None) -> Dict: + """ + Predict ETA using historical mean model. + + Args: + model_key: Model identifier in registry + route_id: Route ID + stop_sequence: Stop sequence number + hour: Hour of day (0-23) + day_of_week: Day of week (0=Monday, optional) + is_peak_hour: Peak hour flag (optional) + + Returns: + Dictionary with prediction and metadata + """ + # Load model + registry = get_registry() + model = registry.load_model(model_key) + metadata = registry.load_metadata(model_key) + + # Prepare input dataframe + input_data = { + 'route_id': [route_id], + 'stop_sequence': [stop_sequence], + 'hour': [hour] + } + + if day_of_week is not None and 'day_of_week' in model.group_by: + input_data['day_of_week'] = [day_of_week] + + if is_peak_hour is not None and 'is_peak_hour' in model.group_by: + input_data['is_peak_hour'] = [is_peak_hour] + + input_df = pd.DataFrame(input_data) + + # Predict + eta_seconds = model.predict(input_df)[0] + + # Check if prediction came from historical data or fallback + coverage = model.get_coverage(input_df) + has_historical_data = coverage > 0 + + return { + 'eta_seconds': float(eta_seconds), + 'eta_minutes': float(eta_seconds / 60), + 'eta_formatted': format_seconds(eta_seconds), + 'model_key': model_key, + 'model_type': 'historical_mean', + 'has_historical_data': has_historical_data, + 'global_mean_eta': metadata.get('global_mean_eta'), + 'group_by': metadata.get('group_by') + } + + +def batch_predict(model_key: str, input_df: pd.DataFrame) -> pd.DataFrame: + """ + Batch prediction for multiple inputs. + + Args: + model_key: Model identifier in registry + input_df: DataFrame with features + + Returns: + DataFrame with predictions added + """ + registry = get_registry() + model = registry.load_model(model_key) + + result_df = input_df.copy() + result_df['predicted_eta_seconds'] = model.predict(input_df) + result_df['predicted_eta_minutes'] = result_df['predicted_eta_seconds'] / 60 + + # Add coverage information + result_df['has_historical_data'] = False + merged = input_df[model.group_by].merge( + model.lookup_table, + on=model.group_by, + how='left', + indicator=True + ) + result_df.loc[merged['_merge'] == 'both', 'has_historical_data'] = True + + return result_df + + +if __name__ == "__main__": + # Example usage + + # Single prediction + result = predict_eta( + model_key="historical_mean_sample_dataset_temporal-route_20250126_143022", + route_id="1", + stop_sequence=5, + hour=8, + day_of_week=0 # Monday + ) + + print("Single Prediction:") + print(f" ETA: {result['eta_formatted']}") + print(f" Has historical data: {result['has_historical_data']}") + + # Batch prediction example + test_data = pd.DataFrame({ + 'route_id': ['1', '1', '2'], + 'stop_sequence': [5, 10, 3], + 'hour': [8, 17, 12] + }) + + predictions = batch_predict( + model_key="historical_mean_sample_dataset_temporal-route_20250126_143022", + input_df=test_data + ) + + print("\nBatch Predictions:") + print(predictions[['route_id', 'stop_sequence', 'predicted_eta_minutes', 'has_historical_data']]) \ No newline at end of file diff --git a/eta_prediction/models/historical_mean/train.py b/eta_prediction/models/historical_mean/train.py new file mode 100644 index 0000000..77f552d --- /dev/null +++ b/eta_prediction/models/historical_mean/train.py @@ -0,0 +1,218 @@ +""" +Historical Mean Baseline Model +Predicts ETA based on historical average travel times grouped by route, stop, and time features. +""" + +import pandas as pd +import numpy as np +from typing import Dict, List, Optional +import sys +from pathlib import Path + +# Add parent directory to path for imports +sys.path.append(str(Path(__file__).parent.parent)) + +from common.data import load_dataset, prepare_features_target +from common.metrics import compute_all_metrics +from common.keys import ModelKey +from common.registry import get_registry +from common.utils import print_metrics_table, train_test_summary + + +class HistoricalMeanModel: + """ + Baseline model using historical mean ETAs. + + Groups data by route, stop, and temporal features, then computes + mean ETA for each group. At prediction time, looks up the appropriate group mean. + """ + + def __init__(self, group_by: List[str] = ['route_id', 'stop_sequence', 'hour']): + """ + Initialize model. + + Args: + group_by: List of columns to group by for computing means + """ + self.group_by = group_by + self.lookup_table = None + self.global_mean = None + self.feature_cols = None + + def fit(self, train_df: pd.DataFrame, target_col: str = 'time_to_arrival_seconds'): + """ + Train model by computing historical means. + + Args: + train_df: Training dataframe with features and target + target_col: Name of target column + """ + # Store feature columns for later + self.feature_cols = self.group_by + + # Compute global mean as fallback + self.global_mean = train_df[target_col].mean() + + # Compute group means + self.lookup_table = train_df.groupby(self.group_by)[target_col].agg([ + ('mean', 'mean'), + ('std', 'std'), + ('count', 'count') + ]).reset_index() + + print(f"Trained on {len(train_df)} samples") + print(f"Created {len(self.lookup_table)} unique groups") + print(f"Global mean ETA: {self.global_mean/60:.2f} minutes") + + def predict(self, X: pd.DataFrame) -> np.ndarray: + """ + Predict ETAs for input data. + + Args: + X: DataFrame with features matching group_by columns + + Returns: + Array of predicted ETAs in seconds + """ + if self.lookup_table is None: + raise ValueError("Model not trained. Call fit() first.") + + # Merge with lookup table + merged = X[self.group_by].merge( + self.lookup_table, + on=self.group_by, + how='left' + ) + + # Use group mean, fallback to global mean + predictions = merged['mean'].fillna(self.global_mean).values + + return predictions + + def get_coverage(self, X: pd.DataFrame) -> float: + """ + Get fraction of predictions with matching historical data. + + Args: + X: DataFrame with features + + Returns: + Coverage ratio (0-1) + """ + merged = X[self.group_by].merge( + self.lookup_table, + on=self.group_by, + how='left', + indicator=True + ) + + return (merged['_merge'] == 'both').mean() + + +def train_historical_mean(dataset_name: str = "sample_dataset", + group_by: List[str] = ['route_id', 'stop_sequence', 'hour'], + test_size: float = 0.2, + save_model: bool = True) -> Dict: + """ + Train and evaluate historical mean model. + + Args: + dataset_name: Name of dataset in datasets/ directory + group_by: List of columns to group by + test_size: Fraction of data for testing + save_model: Whether to save to registry + + Returns: + Dictionary with model, metrics, and metadata + """ + print(f"\n{'='*60}") + print(f"Training Historical Mean Model".center(60)) + print(f"{'='*60}\n") + + # Load dataset + print(f"Loading dataset: {dataset_name}") + dataset = load_dataset(dataset_name) + dataset.clean_data() + + # Split data temporally + train_df, val_df, test_df = dataset.temporal_split( + train_frac=1-test_size-0.1, + val_frac=0.1 + ) + + train_test_summary(train_df, test_df, val_df) + + # Train model + print("Training model...") + model = HistoricalMeanModel(group_by=group_by) + model.fit(train_df) + + # Evaluate on validation set + print("\nValidation Performance:") + y_val = val_df['time_to_arrival_seconds'].values + val_preds = model.predict(val_df) + val_metrics = compute_all_metrics(y_val, val_preds, prefix="val_") + print_metrics_table(val_metrics, "Validation Metrics") + + val_coverage = model.get_coverage(val_df) + print(f"Validation coverage: {val_coverage*100:.1f}%") + + # Evaluate on test set + print("\nTest Performance:") + y_test = test_df['time_to_arrival_seconds'].values + test_preds = model.predict(test_df) + test_metrics = compute_all_metrics(y_test, test_preds, prefix="test_") + print_metrics_table(test_metrics, "Test Metrics") + + test_coverage = model.get_coverage(test_df) + print(f"Test coverage: {test_coverage*100:.1f}%") + + # Prepare metadata + metadata = { + 'model_type': 'historical_mean', + 'dataset': dataset_name, + 'group_by': group_by, + 'train_samples': len(train_df), + 'test_samples': len(test_df), + 'unique_groups': len(model.lookup_table), + 'global_mean_eta': float(model.global_mean), + 'test_coverage': float(test_coverage), + 'metrics': {**val_metrics, **test_metrics} + } + + # Save model + if save_model: + model_key = ModelKey.generate( + model_type='historical_mean', + dataset_name=dataset_name, + feature_groups=['temporal', 'route'] + ) + + registry = get_registry() + registry.save_model(model_key, model, metadata) + metadata['model_key'] = model_key + + return { + 'model': model, + 'metrics': metadata['metrics'], + 'metadata': metadata + } + + +if __name__ == "__main__": + # Train with different grouping strategies + + # Basic: route + stop + hour + result1 = train_historical_mean( + group_by=['route_id', 'stop_sequence', 'hour'] + ) + + # With day of week + result2 = train_historical_mean( + group_by=['route_id', 'stop_sequence', 'hour', 'day_of_week'] + ) + + # With peak hour indicator + result3 = train_historical_mean( + group_by=['route_id', 'stop_sequence', 'is_peak_hour'] + ) \ No newline at end of file diff --git a/eta_prediction/models/polyreg_distance/predict.py b/eta_prediction/models/polyreg_distance/predict.py new file mode 100644 index 0000000..2fa1ddd --- /dev/null +++ b/eta_prediction/models/polyreg_distance/predict.py @@ -0,0 +1,112 @@ +""" +Prediction interface for Polynomial Regression Distance model. +""" + +import pandas as pd +import numpy as np +from typing import Dict, Optional +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) + +from common.registry import get_registry +from common.utils import format_seconds + + +def predict_eta(model_key: str, + distance_to_stop: float, + route_id: Optional[str] = None) -> Dict: + """ + Predict ETA using polynomial regression distance model. + + Args: + model_key: Model identifier in registry + distance_to_stop: Distance to stop in meters + route_id: Route ID (required for route-specific models) + + Returns: + Dictionary with prediction and metadata + """ + # Load model + registry = get_registry() + model = registry.load_model(model_key) + metadata = registry.load_metadata(model_key) + + # Prepare input + input_data = {'distance_to_stop': [distance_to_stop]} + if model.route_specific: + if route_id is None: + raise ValueError("route_id required for route-specific model") + input_data['route_id'] = [route_id] + + input_df = pd.DataFrame(input_data) + + # Predict + eta_seconds = model.predict(input_df)[0] + + # Get coefficients for this route + coefs = model.get_coefficients(route_id if model.route_specific else None) + + return { + 'eta_seconds': float(eta_seconds), + 'eta_minutes': float(eta_seconds / 60), + 'eta_formatted': format_seconds(eta_seconds), + 'model_key': model_key, + 'model_type': 'polyreg_distance', + 'distance_to_stop_m': distance_to_stop, + 'route_specific': metadata.get('route_specific', False), + 'degree': metadata.get('degree'), + 'coefficients': coefs + } + + +def batch_predict(model_key: str, input_df: pd.DataFrame) -> pd.DataFrame: + """ + Batch prediction for multiple inputs. + + Args: + model_key: Model identifier in registry + input_df: DataFrame with distance_to_stop (and route_id if needed) + + Returns: + DataFrame with predictions added + """ + registry = get_registry() + model = registry.load_model(model_key) + + result_df = input_df.copy() + result_df['predicted_eta_seconds'] = model.predict(input_df) + result_df['predicted_eta_minutes'] = result_df['predicted_eta_seconds'] / 60 + + return result_df + + +if __name__ == "__main__": + # Example usage + + # Single prediction + result = predict_eta( + model_key="polyreg_distance_sample_dataset_distance_20250126_143022_degree=2", + distance_to_stop=1500.0, # 1.5 km + route_id="1" + ) + + print("Single Prediction:") + print(f" Distance: {result['distance_to_stop_m']} meters") + print(f" ETA: {result['eta_formatted']}") + print(f" Degree: {result['degree']}") + + # Batch prediction + test_data = pd.DataFrame({ + 'route_id': ['1', '1', '2'], + 'distance_to_stop': [500.0, 1500.0, 3000.0] + }) + + predictions = batch_predict( + model_key="polyreg_distance_sample_dataset_distance_20250126_143022_degree=2", + input_df=test_data + ) + + print("\nBatch Predictions:") + print(predictions[['route_id', 'distance_to_stop', 'predicted_eta_minutes']]) \ No newline at end of file diff --git a/eta_prediction/models/polyreg_distance/train.py b/eta_prediction/models/polyreg_distance/train.py new file mode 100644 index 0000000..2a5611c --- /dev/null +++ b/eta_prediction/models/polyreg_distance/train.py @@ -0,0 +1,292 @@ +""" +Polynomial Regression Model - Distance-based +Fits polynomial features on distance_to_stop with optional route-specific models. +""" + +import pandas as pd +import numpy as np +from typing import Dict, Optional +from sklearn.preprocessing import PolynomialFeatures +from sklearn.linear_model import Ridge +from sklearn.pipeline import Pipeline +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) + +from common.data import load_dataset, prepare_features_target +from common.metrics import compute_all_metrics +from common.keys import ModelKey +from common.registry import get_registry +from common.utils import print_metrics_table, train_test_summary, clip_predictions + + +class PolyRegDistanceModel: + """ + Polynomial regression on distance with optional route-specific models. + + Features: distance_to_stop, (distance)^2, (distance)^3, ... + Can fit separate models per route for better performance. + """ + + def __init__(self, + degree: int = 2, + alpha: float = 1.0, + route_specific: bool = False): + """ + Initialize model. + + Args: + degree: Polynomial degree (2 or 3 recommended) + alpha: Ridge regression alpha (regularization strength) + route_specific: Whether to fit separate model per route + """ + self.degree = degree + self.alpha = alpha + self.route_specific = route_specific + self.models = {} # route_id -> model mapping + self.global_model = None + self.feature_cols = ['distance_to_stop'] + + def _create_pipeline(self) -> Pipeline: + """Create sklearn pipeline with polynomial features and ridge regression.""" + return Pipeline([ + ('poly', PolynomialFeatures(degree=self.degree, include_bias=True)), + ('ridge', Ridge(alpha=self.alpha)) + ]) + + def fit(self, train_df: pd.DataFrame, target_col: str = 'time_to_arrival_seconds'): + """ + Train model(s). + + Args: + train_df: Training dataframe with distance_to_stop and target + target_col: Name of target column + """ + if 'distance_to_stop' not in train_df.columns: + raise ValueError("distance_to_stop column required") + + if self.route_specific: + # Fit separate model per route + for route_id, route_df in train_df.groupby('route_id'): + X = route_df[['distance_to_stop']].values + y = route_df[target_col].values + + model = self._create_pipeline() + model.fit(X, y) + self.models[route_id] = model + + print(f"Trained {len(self.models)} route-specific models (degree={self.degree})") + else: + # Fit single global model + X = train_df[['distance_to_stop']].values + y = train_df[target_col].values + + self.global_model = self._create_pipeline() + self.global_model.fit(X, y) + + print(f"Trained global model (degree={self.degree}, alpha={self.alpha})") + + def predict(self, X: pd.DataFrame) -> np.ndarray: + """ + Predict ETAs. + + Args: + X: DataFrame with distance_to_stop (and route_id if route_specific) + + Returns: + Array of predicted ETAs in seconds + """ + if self.route_specific: + if 'route_id' not in X.columns: + raise ValueError("route_id required for route-specific model") + + # Create predictions array matching input length + predictions = np.zeros(len(X)) + + # Reset index to get positional indices + X_reset = X.reset_index(drop=True) + + for route_id, route_df in X_reset.groupby('route_id'): + # Get positional indices (0-based from reset_index) + pos_indices = route_df.index.values + X_route = route_df[['distance_to_stop']].values + + if route_id in self.models: + predictions[pos_indices] = self.models[route_id].predict(X_route) + elif self.global_model is not None: + # Fallback to global model + predictions[pos_indices] = self.global_model.predict(X_route) + else: + # No model available - use simple linear estimate (30 km/h avg) + predictions[pos_indices] = X_route.flatten() / 30000 * 3600 + else: + if self.global_model is None: + raise ValueError("Model not trained") + + X_dist = X[['distance_to_stop']].values + predictions = self.global_model.predict(X_dist) + + # Clip to reasonable range + return clip_predictions(predictions) + + def get_coefficients(self, route_id: Optional[str] = None) -> Dict: + """ + Get model coefficients. + + Args: + route_id: Route ID for route-specific model, None for global + + Returns: + Dictionary with coefficients + """ + if route_id and route_id in self.models: + model = self.models[route_id] + elif self.global_model: + model = self.global_model + else: + return {} + + coefs = model.named_steps['ridge'].coef_ + intercept = model.named_steps['ridge'].intercept_ + + return { + 'intercept': float(intercept), + 'coefficients': coefs.tolist(), + 'degree': self.degree + } + + +def train_polyreg_distance(dataset_name: str = "sample_dataset", + degree: int = 2, + alpha: float = 1.0, + route_specific: bool = False, + test_size: float = 0.2, + save_model: bool = True) -> Dict: + """ + Train and evaluate polynomial regression distance model. + + Args: + dataset_name: Name of dataset in datasets/ directory + degree: Polynomial degree + alpha: Ridge regularization strength + route_specific: Whether to fit per-route models + test_size: Fraction of data for testing + save_model: Whether to save to registry + + Returns: + Dictionary with model, metrics, and metadata + """ + print(f"\n{'='*60}") + print(f"Training Polynomial Regression Distance Model".center(60)) + print(f"{'='*60}\n") + print(f"Config: degree={degree}, alpha={alpha}, route_specific={route_specific}") + + # Load dataset + print(f"\nLoading dataset: {dataset_name}") + dataset = load_dataset(dataset_name) + dataset.clean_data() + + # Split data temporally + train_df, val_df, test_df = dataset.temporal_split( + train_frac=1-test_size-0.1, + val_frac=0.1 + ) + + train_test_summary(train_df, test_df, val_df) + + # Train model + print("Training model...") + model = PolyRegDistanceModel( + degree=degree, + alpha=alpha, + route_specific=route_specific + ) + model.fit(train_df) + + # Evaluate on validation set + print("\nValidation Performance:") + y_val = val_df['time_to_arrival_seconds'].values + val_preds = model.predict(val_df) + val_metrics = compute_all_metrics(y_val, val_preds, prefix="val_") + print_metrics_table(val_metrics, "Validation Metrics") + + # Evaluate on test set + print("\nTest Performance:") + y_test = test_df['time_to_arrival_seconds'].values + test_preds = model.predict(test_df) + test_metrics = compute_all_metrics(y_test, test_preds, prefix="test_") + print_metrics_table(test_metrics, "Test Metrics") + + # Get sample coefficients + sample_coefs = model.get_coefficients() + if sample_coefs: + print(f"\nModel coefficients (sample):") + print(f" Intercept: {sample_coefs['intercept']:.2f}") + print(f" Coefficients: {[f'{c:.6f}' for c in sample_coefs['coefficients'][:5]]}") + + # Prepare metadata + metadata = { + 'model_type': 'polyreg_distance', + 'dataset': dataset_name, + 'degree': degree, + 'alpha': alpha, + 'route_specific': route_specific, + 'n_models': len(model.models) if route_specific else 1, + 'train_samples': len(train_df), + 'test_samples': len(test_df), + 'metrics': {**val_metrics, **test_metrics} + } + + # Save model + if save_model: + model_key = ModelKey.generate( + model_type='polyreg_distance', + dataset_name=dataset_name, + feature_groups=['distance'], + degree=degree, + route_specific='yes' if route_specific else 'no' + ) + + registry = get_registry() + registry.save_model(model_key, model, metadata) + metadata['model_key'] = model_key + + return { + 'model': model, + 'metrics': metadata['metrics'], + 'metadata': metadata + } + + +if __name__ == "__main__": + # Train different configurations + + # Degree 2, global model + result1 = train_polyreg_distance( + degree=2, + alpha=1.0, + route_specific=False + ) + + # Degree 3, global model + result2 = train_polyreg_distance( + degree=3, + alpha=1.0, + route_specific=False + ) + + # Degree 2, route-specific + result3 = train_polyreg_distance( + degree=2, + alpha=1.0, + route_specific=True + ) + + # Compare results + print("\n" + "="*60) + print("Model Comparison (Test MAE)") + print("="*60) + for i, result in enumerate([result1, result2, result3], 1): + mae_min = result['metrics']['test_mae_minutes'] + print(f"Model {i}: {mae_min:.3f} minutes") \ No newline at end of file diff --git a/eta_prediction/models/polyreg_time/predict.py b/eta_prediction/models/polyreg_time/predict.py new file mode 100644 index 0000000..aefeecb --- /dev/null +++ b/eta_prediction/models/polyreg_time/predict.py @@ -0,0 +1,96 @@ +""" +Prediction interface for Polynomial Regression Time model. +""" + +import pandas as pd +from typing import Dict, Optional +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) + +from common.registry import get_registry +from common.utils import format_seconds + + +def predict_eta(model_key: str, + distance_to_stop: float, + hour: Optional[int] = None, + day_of_week: Optional[int] = None, + is_peak_hour: Optional[bool] = None, + is_weekend: Optional[bool] = None, + is_holiday: Optional[bool] = None, + headway_seconds: Optional[float] = None, + current_speed_kmh: Optional[float] = None, + temperature_c: Optional[float] = None, + precipitation_mm: Optional[float] = None) -> Dict: + """ + Predict ETA using polynomial regression time model. + + Args: + model_key: Model identifier + distance_to_stop: Distance in meters + hour: Hour of day (0-23) + day_of_week: Day of week (0=Monday) + is_peak_hour: Peak hour flag + is_weekend: Weekend flag + is_holiday: Holiday flag + headway_seconds: Time since last vehicle + current_speed_kmh: Current vehicle speed + temperature_c: Temperature + precipitation_mm: Precipitation + + Returns: + Dictionary with prediction and metadata + """ + # Load model + registry = get_registry() + model = registry.load_model(model_key) + metadata = registry.load_metadata(model_key) + + # Prepare input + input_data = {'distance_to_stop': [distance_to_stop]} + + # Add optional features + optional_features = { + 'hour': hour, + 'day_of_week': day_of_week, + 'is_peak_hour': is_peak_hour, + 'is_weekend': is_weekend, + 'is_holiday': is_holiday, + 'headway_seconds': headway_seconds, + 'current_speed_kmh': current_speed_kmh, + 'temperature_c': temperature_c, + 'precipitation_mm': precipitation_mm + } + + for key, value in optional_features.items(): + if value is not None: + input_data[key] = [value] + + input_df = pd.DataFrame(input_data) + + # Predict + eta_seconds = model.predict(input_df)[0] + + return { + 'eta_seconds': float(eta_seconds), + 'eta_minutes': float(eta_seconds / 60), + 'eta_formatted': format_seconds(eta_seconds), + 'model_key': model_key, + 'model_type': 'polyreg_time', + 'distance_to_stop_m': distance_to_stop, + 'features_used': list(input_data.keys()) + } + + +def batch_predict(model_key: str, input_df: pd.DataFrame) -> pd.DataFrame: + """Batch prediction.""" + registry = get_registry() + model = registry.load_model(model_key) + + result_df = input_df.copy() + result_df['predicted_eta_seconds'] = model.predict(input_df) + result_df['predicted_eta_minutes'] = result_df['predicted_eta_seconds'] / 60 + + return result_df \ No newline at end of file diff --git a/eta_prediction/models/polyreg_time/train.py b/eta_prediction/models/polyreg_time/train.py new file mode 100644 index 0000000..0865fa8 --- /dev/null +++ b/eta_prediction/models/polyreg_time/train.py @@ -0,0 +1,462 @@ +""" +Polynomial Regression Model - Time Enhanced +Fits polynomial features with temporal, operational, and optional weather features. +""" + +import pandas as pd +import numpy as np +from typing import Dict, List, Optional +from sklearn.preprocessing import PolynomialFeatures, StandardScaler +from sklearn.linear_model import Ridge +from sklearn.pipeline import Pipeline +from sklearn.compose import ColumnTransformer +import sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent.parent)) + +from common.data import load_dataset +from common.metrics import compute_all_metrics +from common.keys import ModelKey +from common.registry import get_registry +from common.utils import print_metrics_table, train_test_summary, clip_predictions + + +class PolyRegTimeModel: + """ + Enhanced polynomial regression with temporal/operational features. + + Features: + - Core: distance_to_stop (polynomialized) + - Temporal: hour, day_of_week, is_weekend, is_peak_hour + - Operational: headway_seconds, current_speed_kmh + - Weather: temperature_c, precipitation_mm, wind_speed_kmh + """ + + def __init__(self, + poly_degree: int = 2, + alpha: float = 1.0, + include_temporal: bool = True, + include_operational: bool = True, + include_weather: bool = False, + handle_nan: str = 'drop'): # 'drop', 'impute', or 'error' + """ + Initialize model. + + Args: + poly_degree: Polynomial degree for distance + alpha: Ridge regularization strength + include_temporal: Include time-of-day features + include_operational: Include headway/speed features + include_weather: Include weather features + handle_nan: How to handle NaN - 'drop', 'impute', or 'error' + """ + self.poly_degree = poly_degree + self.alpha = alpha + self.include_temporal = include_temporal + self.include_operational = include_operational + self.include_weather = include_weather + self.handle_nan = handle_nan + self.model = None + self.feature_cols = None + self.available_features = None + + def _get_feature_groups(self) -> Dict[str, List[str]]: + """Define feature groups.""" + return { + 'core': ['distance_to_stop'], + 'temporal': ['hour', 'day_of_week', 'is_weekend', 'is_peak_hour'] + if self.include_temporal else [], + 'operational': ['headway_seconds', 'current_speed_kmh'] + if self.include_operational else [], + 'weather': ['temperature_c', 'precipitation_mm', 'wind_speed_kmh'] + if self.include_weather else [] + } + + def _clean_data(self, df: pd.DataFrame, + target_col: str = 'time_to_arrival_seconds') -> pd.DataFrame: + """ + Clean data and handle NaN values. + + Args: + df: Input dataframe + target_col: Target column name + + Returns: + Cleaned dataframe + """ + print(f"\n{'='*60}") + print("Data Cleaning") + print(f"{'='*60}") + print(f"Initial rows: {len(df):,}") + + # Get all potential features + feature_groups = self._get_feature_groups() + all_features = [] + for group_features in feature_groups.values(): + all_features.extend(group_features) + + # Check which features are available and have acceptable NaN levels + available = [] + missing = [] + high_nan = [] + + for feat in all_features: + if feat not in df.columns: + missing.append(feat) + continue + + nan_ratio = df[feat].isna().sum() / len(df) + + if nan_ratio > 0.3: # More than 30% NaN + high_nan.append((feat, f"{nan_ratio*100:.1f}%")) + else: + available.append(feat) + + # Print feature availability + if missing: + print(f"\n⚠️ Missing features: {', '.join(missing)}") + if high_nan: + print(f"⚠️ High NaN features (>30%):") + for feat, ratio in high_nan: + print(f" - {feat}: {ratio} NaN") + + print(f"\n✓ Available features ({len(available)}):") + for feat in available: + nan_count = df[feat].isna().sum() + if nan_count > 0: + print(f" - {feat} ({nan_count:,} NaN)") + else: + print(f" - {feat}") + + # Store available features + self.available_features = available + + # Handle NaN based on strategy + if self.handle_nan == 'error': + # Check for any NaN in available features + target + check_cols = available + [target_col] + nan_counts = df[check_cols].isna().sum() + if nan_counts.sum() > 0: + print("\nNaN values found:") + for col, count in nan_counts[nan_counts > 0].items(): + print(f" {col}: {count}") + raise ValueError("NaN values found and handle_nan='error'") + df_clean = df + + elif self.handle_nan == 'drop': + # Drop rows with NaN in available features or target + check_cols = available + [target_col] + initial_len = len(df) + df_clean = df.dropna(subset=check_cols) + dropped = initial_len - len(df_clean) + + if dropped > 0: + pct = (dropped / initial_len) * 100 + print(f"\n✓ Dropped {dropped:,} rows ({pct:.2f}%) with NaN values") + + elif self.handle_nan == 'impute': + # Impute NaN values + df_clean = df.copy() + imputed = [] + + for feat in available: + nan_count = df_clean[feat].isna().sum() + if nan_count > 0: + if pd.api.types.is_numeric_dtype(df_clean[feat]): + fill_val = df_clean[feat].median() + df_clean[feat] = df_clean[feat].fillna(fill_val) + imputed.append(f"{feat} (median={fill_val:.2f})") + else: + mode_val = df_clean[feat].mode()[0] + df_clean[feat] = df_clean[feat].fillna(mode_val) + imputed.append(f"{feat} (mode={mode_val})") + + if imputed: + print(f"\n✓ Imputed features:") + for imp in imputed: + print(f" - {imp}") + + # Still drop rows with target NaN + target_nan = df_clean[target_col].isna().sum() + if target_nan > 0: + df_clean = df_clean.dropna(subset=[target_col]) + print(f"\n✓ Dropped {target_nan:,} rows with target NaN") + + else: + raise ValueError(f"Invalid handle_nan: {self.handle_nan}") + + print(f"\nFinal rows: {len(df_clean):,}") + + # Validate no NaN remains + remaining_nan = df_clean[available + [target_col]].isna().sum().sum() + if remaining_nan > 0: + raise ValueError(f"ERROR: {remaining_nan} NaN values remain after cleaning!") + + print("✓ No NaN values in features or target") + + return df_clean + + def _create_pipeline(self) -> Pipeline: + """Create sklearn pipeline.""" + # Separate polynomial features for distance and scaling for others + return Pipeline([ + ('features', ColumnTransformer([ + ('poly_distance', PolynomialFeatures( + degree=self.poly_degree, + include_bias=False + ), [0]), # First column is distance + ('scale_others', StandardScaler(), slice(1, None)) # Rest of features + ])), + ('ridge', Ridge(alpha=self.alpha)) + ]) + + def fit(self, train_df: pd.DataFrame, + target_col: str = 'time_to_arrival_seconds'): + """ + Train model. + + Args: + train_df: Training dataframe + target_col: Target column name + """ + # Clean data + train_clean = self._clean_data(train_df, target_col) + + # Build feature list from available features + feature_groups = self._get_feature_groups() + self.feature_cols = [] + + # Always include core (distance) + for feat in feature_groups['core']: + if feat in self.available_features: + self.feature_cols.append(feat) + + # Add other available features + for group in ['temporal', 'operational', 'weather']: + for feat in feature_groups[group]: + if feat in self.available_features: + self.feature_cols.append(feat) + + if not self.feature_cols: + raise ValueError("No features available after cleaning!") + + print(f"\n{'='*60}") + print("Model Training") + print(f"{'='*60}") + print(f"Features ({len(self.feature_cols)}): {', '.join(self.feature_cols)}") + + # Prepare data + X = train_clean[self.feature_cols].values + y = train_clean[target_col].values + + # Create and fit model + self.model = self._create_pipeline() + self.model.fit(X, y) + + print(f"✓ Model trained (poly_degree={self.poly_degree}, alpha={self.alpha})") + + def predict(self, X: pd.DataFrame) -> np.ndarray: + """ + Predict ETAs. + + Args: + X: DataFrame with features + + Returns: + Array of predicted ETAs in seconds + """ + if self.model is None: + raise ValueError("Model not trained") + + if self.feature_cols is None: + raise ValueError("Feature columns not set") + + # Check for missing features + missing = [f for f in self.feature_cols if f not in X.columns] + if missing: + raise ValueError(f"Missing features in input: {missing}") + + # Handle NaN in prediction data + X_pred = X[self.feature_cols].copy() + + if self.handle_nan == 'impute': + # Impute with median/mode + for col in self.feature_cols: + if X_pred[col].isna().any(): + if pd.api.types.is_numeric_dtype(X_pred[col]): + X_pred[col] = X_pred[col].fillna(X_pred[col].median()) + else: + X_pred[col] = X_pred[col].fillna(X_pred[col].mode()[0]) + elif self.handle_nan == 'drop': + # For prediction, we can't drop - impute instead + for col in self.feature_cols: + if X_pred[col].isna().any(): + if pd.api.types.is_numeric_dtype(X_pred[col]): + X_pred[col] = X_pred[col].fillna(0) # Safe default + + X_array = X_pred.values + predictions = self.model.predict(X_array) + + return clip_predictions(predictions) + + def get_feature_importance(self) -> Dict[str, float]: + """Get feature coefficients (approximate importance).""" + if self.model is None: + return {} + + coefs = self.model.named_steps['ridge'].coef_ + + importance = {} + for i, feat in enumerate(self.feature_cols): + importance[feat] = abs(coefs[i]) + + # Sort by importance + return dict(sorted(importance.items(), key=lambda x: x[1], reverse=True)) + + +def train_polyreg_time(dataset_name: str = "sample_dataset", + poly_degree: int = 2, + alpha: float = 1.0, + include_temporal: bool = True, + include_operational: bool = True, + include_weather: bool = False, + handle_nan: str = 'drop', + test_size: float = 0.2, + save_model: bool = True) -> Dict: + """ + Train and evaluate polynomial regression time model. + + Args: + dataset_name: Dataset name + poly_degree: Polynomial degree for distance + alpha: Ridge regularization + include_temporal: Include temporal features + include_operational: Include operational features + include_weather: Include weather features + handle_nan: 'drop', 'impute', or 'error' + test_size: Test set fraction + save_model: Save to registry + + Returns: + Dictionary with model, metrics, metadata + """ + print(f"\n{'='*60}") + print(f"Polynomial Regression Time Model".center(60)) + print(f"{'='*60}\n") + print(f"Config:") + print(f" poly_degree={poly_degree}, alpha={alpha}") + print(f" temporal={include_temporal}, operational={include_operational}") + print(f" weather={include_weather}, handle_nan='{handle_nan}'") + + # Load dataset + print(f"\nLoading dataset: {dataset_name}") + dataset = load_dataset(dataset_name) + dataset.clean_data() + + # Split data + train_df, val_df, test_df = dataset.temporal_split( + train_frac=1-test_size-0.1, + val_frac=0.1 + ) + + train_test_summary(train_df, test_df, val_df) + + # Train model + print("\n" + "="*60) + print("Training") + print("="*60) + model = PolyRegTimeModel( + poly_degree=poly_degree, + alpha=alpha, + include_temporal=include_temporal, + include_operational=include_operational, + include_weather=include_weather, + handle_nan=handle_nan + ) + model.fit(train_df) + + # Validation + print(f"\n{'='*60}") + print("Validation Performance") + print("="*60) + y_val = val_df['time_to_arrival_seconds'].values + val_preds = model.predict(val_df) + val_metrics = compute_all_metrics(y_val, val_preds, prefix="val_") + print_metrics_table(val_metrics, "Validation") + + # Test + print(f"\n{'='*60}") + print("Test Performance") + print("="*60) + y_test = test_df['time_to_arrival_seconds'].values + test_preds = model.predict(test_df) + test_metrics = compute_all_metrics(y_test, test_preds, prefix="test_") + print_metrics_table(test_metrics, "Test") + + # Feature importance + importance = model.get_feature_importance() + if importance: + print(f"\nTop 5 Features by Coefficient:") + for i, (feat, coef) in enumerate(list(importance.items())[:5], 1): + print(f" {i}. {feat}: {coef:.6f}") + + # Metadata + metadata = { + 'model_type': 'polyreg_time', + 'dataset': dataset_name, + 'poly_degree': poly_degree, + 'alpha': alpha, + 'include_temporal': include_temporal, + 'include_operational': include_operational, + 'include_weather': include_weather, + 'handle_nan': handle_nan, + 'n_features': len(model.feature_cols) if model.feature_cols else 0, + 'features': model.feature_cols, + 'train_samples': len(train_df), + 'test_samples': len(test_df), + 'metrics': {**val_metrics, **test_metrics} + } + + # Save + if save_model: + model_key = ModelKey.generate( + model_type='polyreg_time', + dataset_name=dataset_name, + feature_groups=['temporal', 'operational'] if include_temporal else ['operational'], + degree=poly_degree, + handle_nan=handle_nan + ) + + registry = get_registry() + registry.save_model(model_key, model, metadata) + metadata['model_key'] = model_key + print(f"\n✓ Model saved: {model_key}") + + return { + 'model': model, + 'metrics': metadata['metrics'], + 'metadata': metadata + } + + +if __name__ == "__main__": + # Example: Train with different configurations + + # Basic model - drop NaN + result1 = train_polyreg_time( + poly_degree=2, + include_temporal=True, + include_operational=True, + include_weather=False, + handle_nan='drop' + ) + + # With imputation + result2 = train_polyreg_time( + poly_degree=2, + include_temporal=True, + include_operational=True, + include_weather=False, + handle_nan='impute' + ) \ No newline at end of file diff --git a/eta_prediction/models/train_all_models.py b/eta_prediction/models/train_all_models.py new file mode 100644 index 0000000..db5d690 --- /dev/null +++ b/eta_prediction/models/train_all_models.py @@ -0,0 +1,375 @@ +""" +Main training script for all ETA prediction models. +Trains multiple model types and compares performance. +Updated with robust NaN handling. +""" + +import argparse +import sys +from pathlib import Path + +# Add models directory to path +sys.path.append(str(Path(__file__).parent)) + +from historical_mean.train import train_historical_mean +from polyreg_distance.train import train_polyreg_distance +from polyreg_time.train import train_polyreg_time +from ewma.train import train_ewma +from evaluation.leaderboard import quick_compare +from common.registry import get_registry + + +def train_all_baselines(dataset_name: str = "sample_dataset", + save_models: bool = True, + handle_nan: str = 'drop'): + """ + Train all baseline models with robust NaN handling. + + Args: + dataset_name: Dataset to train on + save_models: Whether to save models to registry + handle_nan: How to handle NaN - 'drop' or 'impute' + + Returns: + Dictionary of trained models and their keys + """ + print("\n" + "="*80) + print("TRAINING ALL BASELINE MODELS".center(80)) + print("="*80 + "\n") + print(f"NaN Handling Strategy: {handle_nan}") + + models = {} + + # 1. Historical Mean (simplest baseline) + print("\n[1/4] Historical Mean Model") + print("-" * 80) + try: + result = train_historical_mean( + dataset_name=dataset_name, + group_by=['route_id', 'stop_sequence', 'hour'], + save_model=save_models + ) + models['historical_mean'] = result + print("✓ Historical Mean trained successfully") + except Exception as e: + print(f"✗ Historical Mean failed: {e}") + + # 2. Polynomial Regression - Distance Only + print("\n[2/4] Polynomial Regression Distance Model") + print("-" * 80) + try: + result = train_polyreg_distance( + dataset_name=dataset_name, + degree=2, + alpha=1.0, + route_specific=False, + save_model=save_models + ) + models['polyreg_distance'] = result + print("✓ Polynomial Regression Distance trained successfully") + if save_models and 'model_key' in result.get('metadata', {}): + print(f" Saved as: {result['metadata']['model_key']}") + except Exception as e: + print(f"✗ Polynomial Regression Distance failed: {e}") + import traceback + traceback.print_exc() + + # 3. Polynomial Regression - Time Enhanced + print("\n[3/4] Polynomial Regression Time Model") + print("-" * 80) + try: + result = train_polyreg_time( + dataset_name=dataset_name, + poly_degree=2, + alpha=1.0, + include_temporal=True, + include_operational=True, + include_weather=False, + handle_nan=handle_nan, # Use configurable NaN handling + save_model=save_models + ) + models['polyreg_time'] = result + print("✓ Polynomial Regression Time trained successfully") + except Exception as e: + print(f"✗ Polynomial Regression Time failed: {e}") + import traceback + traceback.print_exc() + + # 4. EWMA (adaptive baseline) + print("\n[4/4] EWMA Model") + print("-" * 80) + try: + result = train_ewma( + dataset_name=dataset_name, + alpha=0.3, + group_by=['route_id', 'stop_sequence'], + save_model=save_models + ) + models['ewma'] = result + print("✓ EWMA trained successfully") + except Exception as e: + print(f"✗ EWMA failed: {e}") + + # Summary + print("\n" + "="*80) + print(f"Training Summary: {len(models)}/4 models trained successfully") + print("="*80) + + return models + + +def compare_all_models(models: dict): + """ + Compare all trained models. + + Args: + models: Dictionary of model results + """ + if not models: + print("\n⚠️ No models to compare") + return None + + print("\n" + "="*80) + print("MODEL COMPARISON".center(80)) + print("="*80 + "\n") + + # Extract metrics + comparison = [] + for model_type, result in models.items(): + metrics = result['metrics'] + comparison.append({ + 'model': model_type, + 'test_mae_min': metrics.get('test_mae_minutes', 0), + 'test_rmse_min': metrics.get('test_rmse_minutes', 0), + 'test_r2': metrics.get('test_r2', 0), + 'test_within_60s': metrics.get('test_within_60s', 0) * 100, + 'test_bias_sec': metrics.get('test_bias_seconds', 0) + }) + + import pandas as pd + df = pd.DataFrame(comparison) + df = df.sort_values('test_mae_min') + + print("\nRanking by Test MAE:") + print("-" * 80) + print(df.to_string(index=False)) + + # Highlight best + best = df.iloc[0] + print(f"\n🏆 Winner: {best['model']}") + print(f" MAE: {best['test_mae_min']:.3f} minutes") + print(f" RMSE: {best['test_rmse_min']:.3f} minutes") + print(f" R²: {best['test_r2']:.3f}") + print(f" Within 60s: {best['test_within_60s']:.1f}%") + + # Calculate improvements + if len(df) > 1: + worst = df.iloc[-1] + improvement = (worst['test_mae_min'] - best['test_mae_min']) / worst['test_mae_min'] * 100 + print(f"\n📈 Improvement from baseline: {improvement:.1f}% reduction in MAE") + + return df + + +def train_advanced_configurations(dataset_name: str = "sample_dataset", + handle_nan: str = 'drop'): + """ + Train advanced model configurations. + + Args: + dataset_name: Dataset to train on + handle_nan: NaN handling strategy + + Returns: + Dictionary of results + """ + print("\n" + "="*80) + print("TRAINING ADVANCED CONFIGURATIONS".center(80)) + print("="*80 + "\n") + + advanced = {} + + # Route-specific polynomial regression + print("[1/4] Route-Specific Polynomial Regression") + print("-" * 80) + try: + result = train_polyreg_distance( + dataset_name=dataset_name, + degree=2, + route_specific=True, + save_model=True + ) + advanced['polyreg_route_specific'] = result + print("✓ Route-specific model trained successfully") + except Exception as e: + print(f"✗ Route-specific model failed: {e}") + + # Higher degree polynomial + print("\n[2/4] Degree-3 Polynomial Regression") + print("-" * 80) + try: + result = train_polyreg_distance( + dataset_name=dataset_name, + degree=3, + route_specific=False, + save_model=True + ) + advanced['polyreg_degree3'] = result + print("✓ Degree-3 model trained successfully") + except Exception as e: + print(f"✗ Degree-3 model failed: {e}") + + # Polynomial with weather (if available) + print("\n[3/4] Polynomial Regression with Weather") + print("-" * 80) + try: + result = train_polyreg_time( + dataset_name=dataset_name, + poly_degree=2, + include_temporal=True, + include_operational=True, + include_weather=True, + handle_nan=handle_nan, + save_model=True + ) + advanced['polyreg_with_weather'] = result + print("✓ Weather-enhanced model trained successfully") + except Exception as e: + print(f"✗ Weather-enhanced model failed: {e}") + print(" (Weather features may not be available in dataset)") + + # EWMA with hourly grouping + print("\n[4/4] EWMA with Hourly Grouping") + print("-" * 80) + try: + result = train_ewma( + dataset_name=dataset_name, + alpha=0.3, + group_by=['route_id', 'stop_sequence', 'hour'], + save_model=True + ) + advanced['ewma_hourly'] = result + print("✓ Hourly EWMA trained successfully") + except Exception as e: + print(f"✗ Hourly EWMA failed: {e}") + + print("\n" + "="*80) + print(f"Advanced Training Summary: {len(advanced)}/4 models trained") + print("="*80) + + return advanced + + +def main(): + """Main training pipeline.""" + parser = argparse.ArgumentParser( + description="Train ETA prediction models with robust NaN handling" + ) + parser.add_argument( + '--dataset', + type=str, + default='sample_dataset', + help='Dataset name (without .parquet extension)' + ) + parser.add_argument( + '--mode', + type=str, + choices=['baseline', 'advanced', 'all'], + default='baseline', + help='Training mode: baseline, advanced, or all' + ) + parser.add_argument( + '--handle-nan', + type=str, + choices=['drop', 'impute'], + default='drop', + help='How to handle NaN values: drop rows or impute' + ) + parser.add_argument( + '--no-save', + action='store_true', + help='Do not save models to registry' + ) + parser.add_argument( + '--compare-only', + action='store_true', + help='Only compare existing models in registry' + ) + + args = parser.parse_args() + + if args.compare_only: + # Compare existing models + registry = get_registry() + models_df = registry.list_models() + + if models_df.empty: + print("No models found in registry. Train some models first.") + return + + print("\nModels in Registry:") + print(models_df) + + # Get model keys + model_keys = models_df['model_key'].tolist() + + # Run comparison + quick_compare(model_keys, args.dataset) + + return + + save_models = not args.no_save + + # Train models based on mode + if args.mode == 'baseline': + models = train_all_baselines( + args.dataset, + save_models, + handle_nan=args.handle_nan + ) + compare_all_models(models) + + elif args.mode == 'advanced': + models = train_advanced_configurations( + args.dataset, + handle_nan=args.handle_nan + ) + compare_all_models(models) + + elif args.mode == 'all': + print("\n" + "="*80) + print("COMPREHENSIVE MODEL TRAINING".center(80)) + print("="*80) + + baseline_models = train_all_baselines( + args.dataset, + save_models, + handle_nan=args.handle_nan + ) + advanced_models = train_advanced_configurations( + args.dataset, + handle_nan=args.handle_nan + ) + + all_models = {**baseline_models, **advanced_models} + compare_all_models(all_models) + + # Print registry summary + print("\n" + "="*80) + print("MODEL REGISTRY SUMMARY".center(80)) + print("="*80 + "\n") + + registry = get_registry() + models_df = registry.list_models() + print(f"Total models in registry: {len(models_df)}") + + if not models_df.empty: + print(f"\nRecent models:") + print(models_df.head(10)) + print(f"\nModels saved to: {registry.base_dir}") + + print("\n✅ Training complete!") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3.pkl b/eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3.pkl new file mode 100644 index 0000000000000000000000000000000000000000..5b6deaf3540a2fd066950c14b2d7e30504e364e5 GIT binary patch literal 3759 zcmZXXdsGxv9LJf*ZU{(9Qlz9sWUHx#oDGBPq||BIi&AC@4mlJ{_MpMUkrFP0>wDAkyg zHMg^|TR0rv@^En4cRz=Z{}wPrE+u^DRu_Elf0`ktQsTCgt>5M>PiKhvl-T@E`&}u1 zi6LruHIA?A${XgqVPyz~5(gVrMZxXM7^0FAU9}&Lo3lSNkeH!>3`*>nFAqsElrTgZ zCHyUyYf}5m86uAoheI}YZD}oHh((kr?>gV{&^;c8a8M$yG^)rk(-%nKaj2jb+tXfI zaqWmVkeH!Zg4KeVzRb;j@xlWPU{rx(YvmvBZ8S5$4Ju&zRSG*DXJG(?3It`BzjxPL z4>5qK0?QLhZM9Fu>jCfzO%&8EzVb?wZg_A@w8qE8zID`8ts4zYXlux$C5J_eA*m-Z#(cg1{!0t0vB`X-h=0Y^D4v@Z?2L z>ET-#A6k^|^f8UD?{)peE|OFWnWu6W{1l?wQVh^a{dM@-qQCc71eOw~p)J_2TjLhJ zc1pL#n9$a^zxS&H`!<&{HncUK({}5LiPxMAp&chNe}DMEKs(cO@ClvF)d&(&TR>!NTki=%d7|J2oHhSf;zru#MA{IG@?`L9@&x0uEE6|MJeEi`G1* z4-}lF#N$(Z%!w_0a#N+R0KfkAtAtGo?ZqBUi8GE*jA+*srl$CI6_tq?i_=mZ=8$e8G_v*@qgcUoNG3$6;#U7phPJiD;UAA}tA&n#D z<%p5J1I)n#+?1$2`iCj=Ztv0i>>J{TJ`(m_D=h8=6t4e z?UXQY=*~GkAuo`?ajc_p+-pA*ndo;jgf^$+!GhAxE@o%JR_etw?~0}GCB}w!Db4B` z3cntq8$uk0cDH_BSY>ir*v4s}Oij^OTDsTh77E+YMm^Vd(=&71*v7TcWa~%GvmDva zp4ZySHT{z|YG597F@ZK}qw%EqQtCG5d*-^!?bNz4D{d5K1(p;q!(M8m^*6(rm75X* z34HZnz?{$r1)9f_@H82Jt+M z2bX!6gun1$DtLm2>EHwpEx;zgN5EMgE&#^_m<>uqXa&Yyu}Z*bEj3@Ks>p;1&?X!`DGM58nXE9DEye z^6*`Je!+csY2k;!z`=tcgo8)GFC07uYB~57dHoIy=U@*==ioW;83%s>4~p=2aJvXE zf%Qgs1$<H*ts@%7 zp$$aSIMhP)5{I@CO%zev;5(0Y6RqLVUZPWZ)PdEq19cLKL7x&a`sC08hbzzKuog)+ V=l}nOy_8&4oICyh;r8WC`VX&pV$=Wt literal 0 HcmV?d00001 diff --git a/eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3_meta.json b/eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3_meta.json new file mode 100644 index 0000000..b9371d0 --- /dev/null +++ b/eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3_meta.json @@ -0,0 +1,50 @@ +{ + "model_type": "ewma", + "dataset": "GreeD_GreenE_dataset", + "alpha": 0.3, + "group_by": [ + "route_id", + "stop_sequence" + ], + "min_observations": 3, + "n_groups": 87, + "train_samples": 55776, + "test_samples": 15937, + "test_coverage": 1.0, + "global_mean_eta": 339.58555651176135, + "metrics": { + "val_mae_seconds": 211.49454665725085, + "val_mae_minutes": 3.524909110954181, + "val_rmse_seconds": 262.5054034097363, + "val_rmse_minutes": 4.375090056828938, + "val_mape": 260.52255013629735, + "val_median_ae": 180.3349818574003, + "val_bias_seconds": 13.029060142569517, + "val_r2": -0.493944103622439, + "val_within_60s": 0.17670682730923695, + "val_within_120s": 0.3468875502008032, + "val_within_300s": 0.7344377510040161, + "val_late_penalty_mae": 310.72728991459155, + "val_error_q50": 180.3349818574003, + "val_error_q90": 437.2813132681595, + "val_error_q95": 512.7054372777407, + "test_mae_seconds": 201.65004332816596, + "test_mae_minutes": 3.3608340554694327, + "test_rmse_seconds": 283.57128315570293, + "test_rmse_minutes": 4.726188052595049, + "test_mape": 232.35584499599972, + "test_median_ae": 159.391001673946, + "test_bias_seconds": -29.697829288611917, + "test_r2": -0.15778218178753667, + "test_within_60s": 0.20330049570182593, + "test_within_120s": 0.3838865533036331, + "test_within_300s": 0.7896718328418146, + "test_late_penalty_mae": 317.3239796365549, + "test_error_q50": 159.391001673946, + "test_error_q90": 393.32199239850286, + "test_error_q95": 497.0474372662015 + }, + "model_key": "ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3", + "saved_at": "2025-10-27T16:13:43.294001", + "model_path": "models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3.pkl" +} \ No newline at end of file diff --git a/eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161350_alpha=0_3.pkl b/eta_prediction/models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161350_alpha=0_3.pkl new file mode 100644 index 0000000000000000000000000000000000000000..b6c7dbdb3395a5403cdb8cc5cec56027a5bf3c32 GIT binary patch literal 21100 zcmZvk2Ut|e(uQ|b1k4H;)`&S_&VZr_2**)D6fv;~$f3wELlgxOF`yVQ=bUqn7#4F} zbCz|@dR=vm82+k0(`VY5f1k(u-I=$mI-KgNI^*4&USd|D&u{FXoKhi)k%29Aae-k` zc{$c@e%kKZ=-`luyqS4TGV;>$8s}I9M#RX0c^=)av}OO~ScS$#>tg~&Bl*?Ar=zAthL3hQ*uF%mBW@i;qq!{vp`1Tx$} zp!AA2o6Fo2NCyK+oT)6|=*`zadaaxIu;=_qg3Y92$_i3D-mBT~TN{Do8Aw){VUyQu zY6&FWK=c*=ENYw;$BA2>wvU0twv!el>BkDBr-8^l?oF}plO>Q529osAr4ih#ERaD4 zl6Zdom>S>O2_(Wm`nYemdpWuoCwQWx3_DHpKUJpFlKPyuWR%KzQ2}>&V$Z z1z@XyQ8pK5B%QStfVBd=rQ!F7%})_PEd|7$jn7Sb70v-3WUvDCkBcp-ysd@+1}h+K zUrOxN{1XD`r+_h5PW#`^5zi}10l@`b9?f=o#Vv3jjSa4jO>K3d+9xB>9y2`O*!Gu; zJuSY$NTjifNkZF8m8VAv;VLB=z`NV|10xm-7KYj7CkfRSKBy@GC&fay?9c3a-Cqm9 zu*1Z}YUTfncQ*np4@h0{$Msv*Qx63Ll81MK%YBFWch?CvYIrw2ve@>quod+hrNy+K z>bXSSK3=dBJdO$nO?8sT3*KrNNL=o&{qlh#fiyIbAY3 zGLWQfeY^X&D{z8O-|%D-+GJaJ#^1?uZnyp?eXE+Pwp@D?!D%`lz zaJoRw8Hmrh6*o#b#|Y%QfdrJXa=iIpU4f`arq7?hWbHVCR5Bb{RK~oM;|_?|l|Pzz ze~+s2Y^KwF~X;ID#XL1`1HNI1QV&y%y zx915&Hq4Wl6qn`oL(Oq$6K5b}y{)G9-Tt3o!%s9dvU~s9H5~-P*VeaNm1=IMe-jAb zk6Y@fnpd-D31pgK9$kz7;udeEg*^yiPJZZEhEUW4t1(}`al zFv|I(P9O&jBzb;=#KfY_oZwF98|I0>QP%n0o&96t-)LRUyp3R z{{4{?Oi+d-nDo4Ky;(PJ8-Z5M&G{eOdp8vCJ1>Ew%5Q%dcKeoK!$W6e?&6h`s;M^t z7roN3=uwHuiT{2RkD7;Qxc#|JwPqa_ylpnvBsM6&^l{X4PH;OsdG|C|-bUV}{+ zL$73L9nc2Dz=B$o{@br_d~tH3(MBq%0DWtxA0DrSXCPTBAn9%D!bKO6 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 NqZd!#nqe|n`VVoguh9Si literal 0 HcmV?d00001 diff --git a/eta_prediction/models/trained/ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3_meta.json b/eta_prediction/models/trained/ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3_meta.json new file mode 100644 index 0000000..f1dc3a5 --- /dev/null +++ b/eta_prediction/models/trained/ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3_meta.json @@ -0,0 +1,50 @@ +{ + "model_type": "ewma", + "dataset": "Green-E_dataset", + "alpha": 0.3, + "group_by": [ + "route_id", + "stop_sequence" + ], + "min_observations": 3, + "n_groups": 40, + "train_samples": 28376, + "test_samples": 8108, + "test_coverage": 1.0, + "global_mean_eta": 302.06773329574287, + "metrics": { + "val_mae_seconds": 203.3557201448098, + "val_mae_minutes": 3.3892620024134965, + "val_rmse_seconds": 252.15700487536375, + "val_rmse_minutes": 4.202616747922729, + "val_mape": 270.5165428169176, + "val_median_ae": 173.24044944586387, + "val_bias_seconds": 16.80370434601153, + "val_r2": -0.2716530493586409, + "val_within_60s": 0.17710902812037493, + "val_within_120s": 0.3569314257523434, + "val_within_300s": 0.7594967932905772, + "val_late_penalty_mae": 296.6317280442089, + "val_error_q50": 173.24044944586387, + "val_error_q90": 418.9661530715284, + "val_error_q95": 491.8442652015592, + "test_mae_seconds": 178.3380760765118, + "test_mae_minutes": 2.9723012679418637, + "test_rmse_seconds": 228.86587837061023, + "test_rmse_minutes": 3.814431306176837, + "test_mape": 232.26256482909068, + "test_median_ae": 149.84818262916514, + "test_bias_seconds": -18.859752436068646, + "test_r2": -0.13991825614647024, + "test_within_60s": 0.22459299457326098, + "test_within_120s": 0.4135421805624075, + "test_within_300s": 0.8210409472126295, + "test_late_penalty_mae": 276.936990332802, + "test_error_q50": 149.84818262916514, + "test_error_q90": 354.4112797755112, + "test_error_q95": 420.82779801475175 + }, + "model_key": "ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3", + "saved_at": "2025-10-27T15:31:26.702546", + "model_path": "models/trained/ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3.pkl" +} \ No newline at end of file diff --git a/eta_prediction/models/trained/ewma_Green-E_dataset_route-temporal_20251027_153130_alpha=0_3.pkl b/eta_prediction/models/trained/ewma_Green-E_dataset_route-temporal_20251027_153130_alpha=0_3.pkl new file mode 100644 index 0000000000000000000000000000000000000000..b8546895685b6b7739c6653dba3e2e74886d589c GIT binary patch literal 9735 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 RG;^JD7{Tlj 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 literal 0 HcmV?d00001 diff --git a/eta_prediction/models/trained/historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336_meta.json b/eta_prediction/models/trained/historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336_meta.json new file mode 100644 index 0000000..d87cb5c --- /dev/null +++ b/eta_prediction/models/trained/historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336_meta.json @@ -0,0 +1,49 @@ +{ + "model_type": "historical_mean", + "dataset": "GreeD_GreenE_dataset", + "group_by": [ + "route_id", + "stop_sequence", + "hour" + ], + "train_samples": 55776, + "test_samples": 15937, + "unique_groups": 603, + "global_mean_eta": 339.58555651176135, + "test_coverage": 0.07033946163016878, + "metrics": { + "val_mae_seconds": 188.48621053687847, + "val_mae_minutes": 3.141436842281308, + "val_rmse_seconds": 231.27304306809742, + "val_rmse_minutes": 3.8545507178016236, + "val_mape": 251.58293756565487, + "val_median_ae": 170.12708719851577, + "val_bias_seconds": 18.80827793184968, + "val_r2": -0.15959913704745587, + "val_within_60s": 0.18812751004016065, + "val_within_120s": 0.35993975903614456, + "val_within_300s": 0.8103664658634538, + "val_late_penalty_mae": 273.32517683939284, + "val_error_q50": 170.12708719851577, + "val_error_q90": 368.41025641025647, + "val_error_q95": 432.7021464646463, + "test_mae_seconds": 203.6471012061657, + "test_mae_minutes": 3.394118353436095, + "test_rmse_seconds": 268.5121730883911, + "test_rmse_minutes": 4.475202884806518, + "test_mape": 332.0206534150948, + "test_median_ae": 190.58555651176135, + "test_bias_seconds": 47.89990676147698, + "test_r2": -0.0380788039777038, + "test_within_60s": 0.1540440484407354, + "test_within_120s": 0.31254313860827004, + "test_within_300s": 0.8064252996172429, + "test_late_penalty_mae": 281.5206984285102, + "test_error_q50": 190.58555651176135, + "test_error_q90": 325.58555651176135, + "test_error_q95": 378.41444348823865 + }, + "model_key": "historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336", + "saved_at": "2025-10-27T16:13:36.193921", + "model_path": "models/trained/historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336.pkl" +} \ No newline at end of file diff --git a/eta_prediction/models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123.pkl b/eta_prediction/models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123.pkl new file mode 100644 index 0000000000000000000000000000000000000000..7da5329c6d614f3be070591a4cf7f8c86655676e GIT binary patch literal 12916 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 HalQTvGNc}g literal 0 HcmV?d00001 diff --git a/eta_prediction/models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123_meta.json b/eta_prediction/models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123_meta.json new file mode 100644 index 0000000..0929151 --- /dev/null +++ b/eta_prediction/models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123_meta.json @@ -0,0 +1,49 @@ +{ + "model_type": "historical_mean", + "dataset": "Green-E_dataset", + "group_by": [ + "route_id", + "stop_sequence", + "hour" + ], + "train_samples": 28376, + "test_samples": 8108, + "unique_groups": 280, + "global_mean_eta": 302.06773329574287, + "test_coverage": 0.07153428712382832, + "metrics": { + "val_mae_seconds": 177.28030378599385, + "val_mae_minutes": 2.9546717297665643, + "val_rmse_seconds": 216.85589155545463, + "val_rmse_minutes": 3.614264859257577, + "val_mape": 247.95922400016696, + "val_median_ae": 162.66558139534885, + "val_bias_seconds": 0.667498968482134, + "val_r2": 0.059477881060912674, + "val_within_60s": 0.2035027133695116, + "val_within_120s": 0.38085841144548593, + "val_within_300s": 0.8428712382831771, + "val_late_penalty_mae": 265.5867061947497, + "val_error_q50": 162.66558139534885, + "val_error_q90": 349.1961672473869, + "val_error_q95": 416.48636363636354, + "test_mae_seconds": 180.46420470592372, + "test_mae_minutes": 3.0077367450987285, + "test_rmse_seconds": 218.0821128743672, + "test_rmse_minutes": 3.634701881239453, + "test_mape": 322.95492475881525, + "test_median_ae": 177.06773329574287, + "test_bias_seconds": 40.155552937287396, + "test_r2": -0.03502706026023983, + "test_within_60s": 0.16884558460779478, + "test_within_120s": 0.3444745929945733, + "test_within_300s": 0.9284657128761716, + "test_late_penalty_mae": 250.61853059024185, + "test_error_q50": 177.06773329574287, + "test_error_q90": 291.06773329574287, + "test_error_q95": 343.93226670425713 + }, + "model_key": "historical_mean_Green-E_dataset_route-temporal_20251027_153123", + "saved_at": "2025-10-27T15:31:23.198816", + "model_path": "models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123.pkl" +} \ No newline at end of file diff --git a/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no.pkl b/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no.pkl new file mode 100644 index 0000000000000000000000000000000000000000..3b09f4b9db78971520635d20f5e86cae06d8669e GIT binary patch literal 937 zcmYLIJ#Q015Vhl+V}S`F0)!w(LP%7!Fz2saaoXAWdhgB7`}t3wYn9O#F6TxKEc96-o#$FW z>@AlX!^ItP>_Y$P<@jv#&!py}HH8P}auBj7 z1r9?!E3+MChGt)xE>~=HgJH?-E8tegxy(UH4Hz0b)8njLjgwf91LU`J7IZQWIl*@2 z5L?wQe#Bi|YggN~Lrgb9l=wjoWy)Od0S=GH-dd5 zc>VV8S2wrhUr~WL2$(_HBXltLm4$3YhV%Ip5ZJZFAlV`+) Vp{;mBYcO3u<_$?|a^yuf{ts)5aS{Lk literal 0 HcmV?d00001 diff --git a/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no_meta.json b/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no_meta.json new file mode 100644 index 0000000..9ceff47 --- /dev/null +++ b/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no_meta.json @@ -0,0 +1,45 @@ +{ + "model_type": "polyreg_distance", + "dataset": "GreeD_GreenE_dataset", + "degree": 2, + "alpha": 1.0, + "route_specific": false, + "n_models": 1, + "train_samples": 55776, + "test_samples": 15937, + "metrics": { + "val_mae_seconds": 118.33522017386228, + "val_mae_minutes": 1.9722536695643713, + "val_rmse_seconds": 147.4320048885588, + "val_rmse_minutes": 2.45720008147598, + "val_mape": 93.43295610102453, + "val_median_ae": 97.47945470527691, + "val_bias_seconds": 30.394819330767035, + "val_r2": 0.5287608144870035, + "val_within_60s": 0.31187248995983935, + "val_within_120s": 0.5769327309236948, + "val_within_300s": 0.9673694779116466, + "val_late_penalty_mae": 162.30542059540986, + "val_error_q50": 97.47945470527691, + "val_error_q90": 238.62670606391822, + "val_error_q95": 279.2548974659458, + "test_mae_seconds": 123.5511068583619, + "test_mae_minutes": 2.0591851143060316, + "test_rmse_seconds": 203.81529586421217, + "test_rmse_minutes": 3.3969215977368696, + "test_mape": 104.74742241391077, + "test_median_ae": 88.93672551283461, + "test_bias_seconds": 21.426761865595083, + "test_r2": 0.4018970945475846, + "test_within_60s": 0.3289201229842505, + "test_within_120s": 0.6077680868419402, + "test_within_300s": 0.9589006713936123, + "test_late_penalty_mae": 174.6132793547453, + "test_error_q50": 88.93672551283461, + "test_error_q90": 235.554625621601, + "test_error_q95": 284.2655008122929 + }, + "model_key": "polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no", + "saved_at": "2025-10-27T16:13:36.371801", + "model_path": "models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no.pkl" +} \ No newline at end of file diff --git a/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=2_route_specific=yes.pkl b/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=2_route_specific=yes.pkl new file mode 100644 index 0000000000000000000000000000000000000000..173578462af19364101b6aae26c3c3838494a13d GIT binary patch literal 1188 zcmZ8hO^g&p6rS0co}I|BZZ=|&9~DF5B5dVmuUe0tfHe$qLnOm+R;akI{Lif^ja_orFR=s~s$0ET8cTOe%&!)9qm?t>#2DN}JzV*h_AW z5*Icr>~16mEjm{1vtf}WrM=4Pe%Nhca)N`-JMEwI&tNgQPirIN5m9q+-gU_oH>{%6 zXSLVcsZPyVgU+rTdxz2zWa>5&nJv|bbT($6(yChmmgK?EwX9A^!~a1yP@ zjEJ<#ttlc)QaGR1U#%~w=e}8ZNym|NG%CE=w{PQD{o2pg)GHQ5v)*)f; zMxYas-y)bVEQn$VZxagX2Z`Gz91a@r zD($`&wBU96)s^8WyjjQW$_;N#;P?bigs`y?6MQ%cr>1bak_yhiJ8-__8s2@L>C4Y? z_wClxZtux2n~&ameE8y{_D>~uupPoj@G)G0t0ftyez^A4`q%IOj|{jG!cGXE)ZG@Y kH%jz?C$n)SK6>>nVv(i?;U>KT^OuKNO%tUvW}TTW<{+rh z+TehPK964g4+L*LdH14!fF8a0AL!eBbq~wDd0)TZ@6CH%{rI_38h!q3rscpupT)vD zt|ADX;XPjF!sah$cEvAH;oN1pJIus(mBL2%td~n! z*iAO!!?wX#f`dM|8r}%6Vcy-Pvk`Hhq&YujT`0xPSj3P`yurpOYN}dNI~>W0o^S-2 z*hY{!qE(A@HegTbR4)Jv@?ghToR&1mb1T38EVi!rn$?o~uPh{?Rx3wM!1W!`6lI zODvUsKKXs=)7p>KuOI5)z8su7c>h8_-+X)LE>akE9r0#Fd~VE?u-BtROR!r6_t;D@ zhRJnOBjS=90+HNn)xXn+a literal 0 HcmV?d00001 diff --git a/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no_meta.json b/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no_meta.json new file mode 100644 index 0000000..05d6c71 --- /dev/null +++ b/eta_prediction/models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no_meta.json @@ -0,0 +1,45 @@ +{ + "model_type": "polyreg_distance", + "dataset": "GreeD_GreenE_dataset", + "degree": 3, + "alpha": 1.0, + "route_specific": false, + "n_models": 1, + "train_samples": 55776, + "test_samples": 15937, + "metrics": { + "val_mae_seconds": 115.07092762128921, + "val_mae_minutes": 1.9178487936881536, + "val_rmse_seconds": 144.6602968203363, + "val_rmse_minutes": 2.411004947005605, + "val_mape": 79.64604331765742, + "val_median_ae": 94.68512674528748, + "val_bias_seconds": 30.508160726403148, + "val_r2": 0.5463127676307029, + "val_within_60s": 0.35956325301204817, + "val_within_120s": 0.5739206827309237, + "val_within_300s": 0.9717620481927711, + "val_late_penalty_mae": 157.35231106873226, + "val_error_q50": 94.68512674528748, + "val_error_q90": 235.59755671317495, + "val_error_q95": 270.4510296183838, + "test_mae_seconds": 119.9525494391816, + "test_mae_minutes": 1.9992091573196933, + "test_rmse_seconds": 202.0064219057079, + "test_rmse_minutes": 3.366773698428465, + "test_mape": 88.59479884687285, + "test_median_ae": 83.96342677401618, + "test_bias_seconds": 21.404002989225067, + "test_r2": 0.4124663879991807, + "test_within_60s": 0.3936750956892765, + "test_within_120s": 0.6196272824245467, + "test_within_300s": 0.9632302189872624, + "test_late_penalty_mae": 169.2268226641599, + "test_error_q50": 83.96342677401618, + "test_error_q90": 234.33307725852058, + "test_error_q95": 274.8348733878997 + }, + "model_key": "polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no", + "saved_at": "2025-10-27T16:13:43.662321", + "model_path": "models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no.pkl" +} \ No newline at end of file diff --git a/eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153123_degree=2_route_specific=no.pkl b/eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153123_degree=2_route_specific=no.pkl new file mode 100644 index 0000000000000000000000000000000000000000..90e9535be2711af406e1351f127bc534c311ad30 GIT binary patch literal 937 zcmYLIO=}cE5Z%r0Y!+Q(2r8nvL_EZU11gCTg{UhEE-oP;cnM910l?mZ54bEcj<2@=OlvL~T{>X4fLNp= z#*uI3Rko!}-x)|9ammIv=$Gxj1a4GVhytWgfWEymJI=cW)e8E{5zKo!S*(K_2Y;hSQP;d1Ld}@73;I-?CZ~9`sFKI!%))v=vSqK&6x6D$zNk zSK|Qt*($LJVht%ne^r%vF$`mEAk0hY1UH7$&^pXOtd(`9j2(@_2jf8Wiz=CfoM5kZ zh~0XGUvL-Kd-Y!95VK7mByLzhm9mg-;plkcZTR{V?DzYx|Is)8^=b~IQTO`fCDv*i zZ#Vis{(j%q>4&q&-2>fMQ8)Z{%a*~5fhPjEp& z4~Yr%EtNkZ{)hYr&tCNE#iKW^*{{rD=<51<^{1&CDyD!l%+C2%}sIU+PNTC3IdwY7EH43bQ!s0IVY*tv&ugvlc6h_Bj ztx$uIRbHiY!6o{o3jNr41>BVe>mr92g!up%v4L>K^-!P_Zl%V12p(Jv^LP6{!h7)Et}k>zxn@=&X6{(ff9`6Vh`x}tRFnHV)FY;@1kQp(C+WRrQ= zJ{U`I&XoqOmV|TjD~FD4R%IRQ`WN9xf+*J;RrHK8$;nL zF=AZ|**iM5E5L$0*z*miC24qL{nzj1?p@!qS`r@gO=>{GjjlB(De}cVU@AW_WM!%@$uz%dWK7NF?+S=Q- z-jBcEH+A~q?D4ne8Iqg2jpk)E@cei}!rYECEy3;)%nLK37-kQMg_uijsCo9h+urCs z`g!~G*;70ufZ0lRs}czOW!e~JQ*CmhndGM0tsHV~hE*3Lv9B%BHcqgOm{mdZ`CjRH!0i!T13NL#-DP$}rh|$qt>JS!QO7K??QI z+Q8_g&#OoO4Mn{A4-~w3?M08C^liSnhh^Tpuix+Y=IvBJey)^;pFf{z**DN*v9OM- z2tsGLQ0ULDkz*Zt56AbhE#QS)+3Y%w`aY zu845pYiW^fDbqK4Qg^sy!yEK-c2fd3D$GO%QYb)QUz;4K-2&?%v$#Qxs|8^6i_<&< znb8qgD^xFJg;(iRaEX4tpfEBX19!OrJ0*|=gnUjY2Zl#ZXvMUmx&z-3Dw25&tRuL^ zeIIBOgF#Cxj126D8!TK<2qFPcr9?9vha0Hpy zMvyt8Rf}}iXD{hgF8~YjVB1%mmNdu+wG_S=o|i8C5N3s^YZ8= zmP+6MWZy2m`nh_z{pjfM&6O`d{(fq|zx(1oQW$j|@@7PQX2g`R*P}#Bu$u(;!WN}o0R0Hu~Y3@3aK{zq6>-H g(U#;JCHThpIk8C7c5Ki(OxBP&P15QNdEN>C1A};Xr~m)} literal 0 HcmV?d00001 diff --git a/eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no_meta.json b/eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no_meta.json new file mode 100644 index 0000000..94d9035 --- /dev/null +++ b/eta_prediction/models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no_meta.json @@ -0,0 +1,45 @@ +{ + "model_type": "polyreg_distance", + "dataset": "Green-E_dataset", + "degree": 3, + "alpha": 1.0, + "route_specific": false, + "n_models": 1, + "train_samples": 28376, + "test_samples": 8108, + "metrics": { + "val_mae_seconds": 98.57279939330748, + "val_mae_minutes": 1.6428799898884578, + "val_rmse_seconds": 131.11172761535084, + "val_rmse_minutes": 2.1851954602558474, + "val_mape": 61.77629325039929, + "val_median_ae": 68.74423966997944, + "val_bias_seconds": -7.017570892080588, + "val_r2": 0.6561970154992272, + "val_within_60s": 0.4506660088801184, + "val_within_120s": 0.6783423778983719, + "val_within_300s": 0.9708929452392698, + "val_late_penalty_mae": 151.3679845360015, + "val_error_q50": 68.74423966997944, + "val_error_q90": 226.55861935066076, + "val_error_q95": 266.4160591589552, + "test_mae_seconds": 99.21758512007604, + "test_mae_minutes": 1.653626418667934, + "test_rmse_seconds": 141.96946540818053, + "test_rmse_minutes": 2.3661577568030085, + "test_mape": 74.76037404420727, + "test_median_ae": 66.85534777451522, + "test_bias_seconds": 12.61711757659896, + "test_r2": 0.5613667941019505, + "test_within_60s": 0.46090281203749384, + "test_within_120s": 0.6906758756783424, + "test_within_300s": 0.9750863344844598, + "test_late_penalty_mae": 142.51781889181456, + "test_error_q50": 66.85534777451522, + "test_error_q90": 220.92219925564422, + "test_error_q95": 255.99641825336954 + }, + "model_key": "polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no", + "saved_at": "2025-10-27T15:31:26.914035", + "model_path": "models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no.pkl" +} \ No newline at end of file diff --git a/eta_prediction/models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161336_degree=2_handle_nan=drop.pkl b/eta_prediction/models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161336_degree=2_handle_nan=drop.pkl new file mode 100644 index 0000000000000000000000000000000000000000..9f9bd870ede304b10fd2ca0c19beb3ad6d79ab17 GIT binary patch literal 2109 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 Lhx8*7HEVwZucJ5F literal 0 HcmV?d00001 diff --git a/eta_prediction/models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop_meta.json b/eta_prediction/models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop_meta.json new file mode 100644 index 0000000..9ed8816 --- /dev/null +++ b/eta_prediction/models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop_meta.json @@ -0,0 +1,56 @@ +{ + "model_type": "polyreg_time", + "dataset": "GreeD_GreenE_dataset", + "poly_degree": 2, + "alpha": 1.0, + "include_temporal": true, + "include_operational": true, + "include_weather": true, + "handle_nan": "drop", + "n_features": 6, + "features": [ + "distance_to_stop", + "hour", + "day_of_week", + "is_weekend", + "is_peak_hour", + "current_speed_kmh" + ], + "train_samples": 55776, + "test_samples": 15937, + "metrics": { + "val_mae_seconds": 107.41798854915723, + "val_mae_minutes": 1.7902998091526205, + "val_rmse_seconds": 134.24933419909556, + "val_rmse_minutes": 2.2374889033182592, + "val_mape": 85.30883232489415, + "val_median_ae": 89.35690898715825, + "val_bias_seconds": 42.06393495865259, + "val_r2": 0.609265161884355, + "val_within_60s": 0.32831325301204817, + "val_within_120s": 0.6307730923694779, + "val_within_300s": 0.9723895582329317, + "val_late_penalty_mae": 140.09501534440955, + "val_error_q50": 89.35690898715825, + "val_error_q90": 217.41537149012277, + "val_error_q95": 259.4290028938885, + "test_mae_seconds": 118.05428080457894, + "test_mae_minutes": 1.9675713467429823, + "test_rmse_seconds": 193.7685262911181, + "test_rmse_minutes": 3.2294754381853017, + "test_mape": 101.54860891798711, + "test_median_ae": 91.21456355930684, + "test_bias_seconds": 38.65748686057865, + "test_r2": 0.45940896745373916, + "test_within_60s": 0.3226454163267867, + "test_within_120s": 0.6295413189433394, + "test_within_300s": 0.9630419777875384, + "test_late_penalty_mae": 157.75267777657905, + "test_error_q50": 91.21456355930684, + "test_error_q90": 220.5362925685771, + "test_error_q95": 275.7262612358998 + }, + "model_key": "polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop", + "saved_at": "2025-10-27T16:13:43.927828", + "model_path": "models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop.pkl" +} \ No newline at end of file diff --git a/eta_prediction/models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153123_degree=2_handle_nan=drop.pkl b/eta_prediction/models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153123_degree=2_handle_nan=drop.pkl new file mode 100644 index 0000000000000000000000000000000000000000..9984f555cdca60372aa2be54f2ee6a97aa13fc97 GIT binary patch literal 2109 zcmaJ?ONbmr7@nETE4!0@1wq%uV4`M2aAY^QE7&ZY7x)wFvHCvtS?rN*5 zHx8nhLo%~aAS9)N@gUwrl*A}{(hxj}=phP%U`#xz2oVoKFZx$MW(R!qp}VX4@Bi`r z-~ZK1#aCvkx%g5OA@e$%EFt}F^72itlo7}zo4hou(3xD zS>}XjtDs8Q3n|tI=WnDA$K1g7B8MPJ{E%_%>7Lr0?Xi$>EL|4F+oRd`34$dhT(7Ai ziUY?ZD8P_L(cvuAs^rHhs4=nP5zK>n=!V2|1EN*+aQ50yup}f2g-((@SSIc_B~Z9R;=qPv?#yC@oP?a& zLFyDom)r3JdSscic>xU?>!wM)$fXX&lAr^QYz^0bL)pD_bb%}AuWSwt7 z$50v^tr9NaCxC6b{y=?3N3A7o<#1Q4ny@iI%M8>2$?gA`y}Bs>@JIjgOFv)R>)x~qxW z$cYbJGX>CLXl;nO0M1b87G<6Tgu1dPzEn9t$5~70rrJEv0(647%T$`}3Y6S}o&qGd zrLQRMJn+aT0o&)s!xALAI$G>jzN9Vk|qS)p5E26w2gH8A7OposAL7b8r4UoWo=mEBZ5Wq;?5=4I3 zsoRW`x*tL3G3U6WRoRdZ8~&(LYywY5c0$7kRdDC@TF+2o%G#jv59(&KdFU^=;+vI| zy49$D8zjo2PlFwZ0Wc3~dQ8;-L7N3a^2nCpjXtd^hOs6ra4mOAH}WmunsJ`DN~bh^ zMitrv0cq=>;no^c3*F;#V|Q|Y5;d1SbK4G87Orjme*X6hwENx6%zh2osp2Z;kc~@M zOhD=nh7;gy=3#pH+{JY#sngu%XWw3U^T)5|pSbzPtJfdliL)3h@_+8mJ^$9Vg*$G} zCvI-^pC6w&_U9MBU7a5p`Kfw-ayoXGc5%*3+i2SLl$|J{C!Mu&Rv{iqX!I;Fw300L z#$R&rB1-(62I#r#EQ8MVg~Mntlpo7;9i?AOi?LNEYP7t5G;C_SWs z0yitFWHZwKHxMh(An3{5uV)tYi?3gq|NQ66f4qFE`03SeJ{sTm+V*~~Al3$D zBr7Hn5x7&ZY7x)wFvHCvtS?rN*5 zHx8nhLo%~aAS9)N@gUwrl*A}{(hxj}=phP%U`#xz2oVoKFZx$MW(R!qp}VX4@Bi`r z-~ZK1#aCvkx%g5OA@e$%EFt}F^72itlo7}zo4hou(3xD zS>}XjtDs8Q3n|tI=WnDA$K1g7B8MPJ{E%_%>7Lr0?Xi$>EL|4F+oRd`34$dh94v<@ z4jhl507Du@hqF+tk{_p_#>9$8Fc0dX8xqeAh*s6Z*=s++l8_`6dI@r^w!v@2iO_0C z_OHz#D?#eWW?tk62r3Rln{gk)tMNv>d30c}@3%H!nYiDSK;a6B0~?aLGm8;&5^`n} zA>3fOj*MBrd>3j~69(C2aUe^sAELYtE1)O=D%)U%Sm1T^nyO`RwOlMJtAq>q31FM9KTx01QEN$CIo#E%CTtAQG6OY0a{GUz>tKns8aV=0IhZ>~%ujrs z02@!Zk|Li#gL)Ye#0wuSgrvS-q z=_^V*4?OaTKrE7w;H}VRn;<|I^@AH4K#D^Sbd1G62Z|MDR_K-(dAb|8XyvVfwZSS{B|`Tu=|~N&=b-6cI!qsh4vnNR zK)%Ko6troeWPuE;=@z;znMJzYD$pHk^sY5}H@$~GWaZT`@*(4lMme*_&-K>@H34Kw zd}pHpNew~?nlsh%sK98RW_u72G+!)-#ltvNovvgSy#l9{LNe_-5s# zZZ)dk28puh(_jZ;0L(+09#b_y&}M;NL0c*|!(o{PC;#CvLv+>h(u>;w;9B{GYpX&%bqT;f|a0 ziJKe!=f`J`{rSajSLa7YeyX0IoQ~b4U7R!1Hkx)lWhYALNoTE`RftCt8a)dPtt5-R z@t0h@h!Q`i0ebE_%b;_8;V>Eu<;U_|N9otnVr-R(8ZECM4V&7o84wUQn}lW}%SJNL zlSW7kPhI!|^SnVa59WVz_WCbd8utQ&mzM`p;_FxDKmYmiA1|LOetPwrkH+`Cw!PoztVcT*hY!wv zvh&j8m%se%zON5liW^=D;xv)bog^_Jf7J%fB4P#jKGd%dQh17rM)ikxPrj$$xqpAm z-waG>Nq@2v6S^uRHiBcwSXiGI5CY<~+SX-=`Pp L2lPV{wd#KZ8?!fd literal 0 HcmV?d00001 diff --git a/eta_prediction/models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop_meta.json b/eta_prediction/models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop_meta.json new file mode 100644 index 0000000..3a08e28 --- /dev/null +++ b/eta_prediction/models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop_meta.json @@ -0,0 +1,56 @@ +{ + "model_type": "polyreg_time", + "dataset": "Green-E_dataset", + "poly_degree": 2, + "alpha": 1.0, + "include_temporal": true, + "include_operational": true, + "include_weather": true, + "handle_nan": "drop", + "n_features": 6, + "features": [ + "distance_to_stop", + "hour", + "day_of_week", + "is_weekend", + "is_peak_hour", + "current_speed_kmh" + ], + "train_samples": 28376, + "test_samples": 8108, + "metrics": { + "val_mae_seconds": 100.71320949864169, + "val_mae_minutes": 1.6785534916440281, + "val_rmse_seconds": 129.2578899932698, + "val_rmse_minutes": 2.1542981665544967, + "val_mape": 92.54489955096588, + "val_median_ae": 77.32605733049868, + "val_bias_seconds": 28.070838007683715, + "val_r2": 0.665850599040172, + "val_within_60s": 0.37469166255550074, + "val_within_120s": 0.6877158362111495, + "val_within_300s": 0.9733596447952639, + "val_late_penalty_mae": 137.03439524412067, + "val_error_q50": 77.32605733049868, + "val_error_q90": 219.9602711693123, + "val_error_q95": 269.51804611951917, + "test_mae_seconds": 113.21111443177227, + "test_mae_minutes": 1.8868519071962047, + "test_rmse_seconds": 146.6391273815427, + "test_rmse_minutes": 2.443985456359045, + "test_mape": 123.17577609080617, + "test_median_ae": 91.57208077001115, + "test_bias_seconds": 58.8425310468469, + "test_r2": 0.5320371823959318, + "test_within_60s": 0.302910705476073, + "test_within_120s": 0.6466452886038481, + "test_within_300s": 0.9649728663048841, + "test_late_penalty_mae": 140.39540612423497, + "test_error_q50": 91.57208077001115, + "test_error_q90": 228.6687863181721, + "test_error_q95": 274.2806521166451 + }, + "model_key": "polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop", + "saved_at": "2025-10-27T15:31:27.071084", + "model_path": "models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop.pkl" +} \ No newline at end of file diff --git a/eta_prediction/models/trained/registry.json b/eta_prediction/models/trained/registry.json new file mode 100644 index 0000000..aad90f0 --- /dev/null +++ b/eta_prediction/models/trained/registry.json @@ -0,0 +1,98 @@ +{ + "historical_mean_Green-E_dataset_route-temporal_20251027_153123": { + "model_path": "models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123.pkl", + "meta_path": "models/trained/historical_mean_Green-E_dataset_route-temporal_20251027_153123_meta.json", + "saved_at": "2025-10-27T15:31:23.198816", + "model_type": "historical_mean" + }, + "polyreg_distance_Green-E_dataset_distance_20251027_153123_degree=2_route_specific=no": { + "model_path": "models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153123_degree=2_route_specific=no.pkl", + "meta_path": "models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153123_degree=2_route_specific=no_meta.json", + "saved_at": "2025-10-27T15:31:23.308570", + "model_type": "polyreg_distance" + }, + "polyreg_time_Green-E_dataset_operational-temporal_20251027_153123_degree=2_handle_nan=drop": { + "model_path": "models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153123_degree=2_handle_nan=drop.pkl", + "meta_path": "models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153123_degree=2_handle_nan=drop_meta.json", + "saved_at": "2025-10-27T15:31:23.464266", + "model_type": "polyreg_time" + }, + "ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3": { + "model_path": "models/trained/ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3.pkl", + "meta_path": "models/trained/ewma_Green-E_dataset_route-temporal_20251027_153126_alpha=0_3_meta.json", + "saved_at": "2025-10-27T15:31:26.702546", + "model_type": "ewma" + }, + "polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=2_route_specific=yes": { + "model_path": "models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=2_route_specific=yes.pkl", + "meta_path": "models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=2_route_specific=yes_meta.json", + "saved_at": "2025-10-27T15:31:26.813864", + "model_type": "polyreg_distance" + }, + "polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no": { + "model_path": "models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no.pkl", + "meta_path": "models/trained/polyreg_distance_Green-E_dataset_distance_20251027_153126_degree=3_route_specific=no_meta.json", + "saved_at": "2025-10-27T15:31:26.914035", + "model_type": "polyreg_distance" + }, + "polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop": { + "model_path": "models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop.pkl", + "meta_path": "models/trained/polyreg_time_Green-E_dataset_operational-temporal_20251027_153127_degree=2_handle_nan=drop_meta.json", + "saved_at": "2025-10-27T15:31:27.071084", + "model_type": "polyreg_time" + }, + "ewma_Green-E_dataset_route-temporal_20251027_153130_alpha=0_3": { + "model_path": "models/trained/ewma_Green-E_dataset_route-temporal_20251027_153130_alpha=0_3.pkl", + "meta_path": "models/trained/ewma_Green-E_dataset_route-temporal_20251027_153130_alpha=0_3_meta.json", + "saved_at": "2025-10-27T15:31:30.568347", + "model_type": "ewma" + }, + "historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336": { + "model_path": "models/trained/historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336.pkl", + "meta_path": "models/trained/historical_mean_GreeD_GreenE_dataset_route-temporal_20251027_161336_meta.json", + "saved_at": "2025-10-27T16:13:36.193921", + "model_type": "historical_mean" + }, + "polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no": { + "model_path": "models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no.pkl", + "meta_path": "models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161336_degree=2_route_specific=no_meta.json", + "saved_at": "2025-10-27T16:13:36.371801", + "model_type": "polyreg_distance" + }, + "polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161336_degree=2_handle_nan=drop": { + "model_path": "models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161336_degree=2_handle_nan=drop.pkl", + "meta_path": "models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161336_degree=2_handle_nan=drop_meta.json", + "saved_at": "2025-10-27T16:13:36.628321", + "model_type": "polyreg_time" + }, + "ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3": { + "model_path": "models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3.pkl", + "meta_path": "models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161343_alpha=0_3_meta.json", + "saved_at": "2025-10-27T16:13:43.294001", + "model_type": "ewma" + }, + "polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=2_route_specific=yes": { + "model_path": "models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=2_route_specific=yes.pkl", + "meta_path": "models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=2_route_specific=yes_meta.json", + "saved_at": "2025-10-27T16:13:43.488583", + "model_type": "polyreg_distance" + }, + "polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no": { + "model_path": "models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no.pkl", + "meta_path": "models/trained/polyreg_distance_GreeD_GreenE_dataset_distance_20251027_161343_degree=3_route_specific=no_meta.json", + "saved_at": "2025-10-27T16:13:43.662321", + "model_type": "polyreg_distance" + }, + "polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop": { + "model_path": "models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop.pkl", + "meta_path": "models/trained/polyreg_time_GreeD_GreenE_dataset_operational-temporal_20251027_161343_degree=2_handle_nan=drop_meta.json", + "saved_at": "2025-10-27T16:13:43.927828", + "model_type": "polyreg_time" + }, + "ewma_GreeD_GreenE_dataset_route-temporal_20251027_161350_alpha=0_3": { + "model_path": "models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161350_alpha=0_3.pkl", + "meta_path": "models/trained/ewma_GreeD_GreenE_dataset_route-temporal_20251027_161350_alpha=0_3_meta.json", + "saved_at": "2025-10-27T16:13:50.951525", + "model_type": "ewma" + } +} \ No newline at end of file From a3ede10dfd0f7231b342a9e1ffa303d331f2af85 Mon Sep 17 00:00:00 2001 From: Jae Date: Tue, 28 Oct 2025 13:18:10 -0600 Subject: [PATCH 4/6] docs: models directory README --- eta_prediction/models/README.md | 263 ++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 eta_prediction/models/README.md diff --git a/eta_prediction/models/README.md b/eta_prediction/models/README.md new file mode 100644 index 0000000..d23fa20 --- /dev/null +++ b/eta_prediction/models/README.md @@ -0,0 +1,263 @@ +# ETA Prediction Models + +Complete modeling framework for transit ETA prediction using GTFS-RT data. + +## Directory Structure + +``` +models/ +├── README.md # This file +├── train_all_models.py # Main training script +├── common/ # Shared utilities +│ ├── data.py # Dataset loading and preprocessing +│ ├── keys.py # Model key generation +│ ├── metrics.py # Evaluation metrics +│ ├── registry.py # Model storage and retrieval +│ └── utils.py # Helper functions +├── evaluation/ # Model evaluation tools +│ ├── leaderboard.py # Model comparison +│ └── roll_validate.py # Rolling window validation +├── historical_mean/ # Historical mean baseline +│ ├── train.py +│ └── predict.py +├── polyreg_distance/ # Polynomial regression (distance) +│ ├── train.py +│ └── predict.py +├── polyreg_time/ # Polynomial regression (time) +│ ├── train.py +│ └── predict.py +├── ewma/ # Exponential weighted moving average +│ ├── train.py +│ └── predict.py +└── trained/ # Saved models (created automatically) + ├── {model_key}.pkl + ├── {model_key}_meta.json + └── registry.json +``` + +## Usage + +### 1. Train All Baseline Models + +```bash +# Train all baseline models on sample dataset +python train_all_models.py --dataset sample_dataset --mode baseline + +# Train baseline + advanced configurations +python train_all_models.py --dataset sample_dataset --mode all + +# Train without saving (dry run) +python train_all_models.py --dataset sample_dataset --no-save +``` + +### 2. Train Individual Models + +```python +from models.polyreg_time.train import train_polyreg_time + +# Train polynomial regression with time features +result = train_polyreg_time( + dataset_name="sample_dataset", + poly_degree=2, + include_temporal=True, + include_operational=True +) + +print(f"Test MAE: {result['metrics']['test_mae_minutes']:.2f} minutes") +``` + +### 3. Make Predictions + +```python +from models.polyreg_time.predict import predict_eta + +# Single prediction +prediction = predict_eta( + model_key=f'{MODEL_KEY}', + distance_to_stop=1500.0, # meters + hour=8, + is_peak_hour=True, + current_speed_kmh=25.0 +) + +print(f"ETA: {prediction['eta_formatted']}") +``` + +### 4. Compare Models + +```python +from models.evaluation.leaderboard import quick_compare + +model_keys = [ + "historical_mean_...", + "polyreg_distance_...", + "polyreg_time_...", + "ewma_..." +] + +results = quick_compare(model_keys, "sample_dataset") +``` + +## Model Types + +### 1. Historical Mean (`historical_mean/`) + +**Description**: Baseline model using historical average ETAs grouped by route, stop, and time features. + +**Example**: +```python +from models.historical_mean.train import train_historical_mean + +result = train_historical_mean( + group_by=['route_id', 'stop_sequence', 'hour', 'day_of_week'] +) +``` + +--- + +### 2. Polynomial Regression - Distance (`polyreg_distance/`) + +**Description**: Polynomial regression on distance to stop with optional route-specific models. + +**Example**: +```python +from models.polyreg_distance.train import train_polyreg_distance + +result = train_polyreg_distance( + degree=2, + route_specific=True +) +``` + +--- + +### 3. Polynomial Regression - Time (`polyreg_time/`) + +**Description**: Enhanced polynomial regression combining distance with temporal and operational features. + +**Example**: +```python +from models.polyreg_time.train import train_polyreg_time + +result = train_polyreg_time( + poly_degree=2, + include_temporal=True, + include_operational=True, + include_weather=False +) +``` + +--- + +### 4. EWMA (`ewma/`) + +**Description**: Exponentially weighted moving average that adapts predictions based on recent observations. + +**Example**: +```python +from models.ewma.train import train_ewma + +result = train_ewma( + alpha=0.3, # Higher = faster adaptation + group_by=['route_id', 'stop_sequence', 'hour'] +) +``` + +## Evaluation + +### Metrics + +All models are evaluated on: + +- **MAE (Mean Absolute Error)**: Primary metric, in seconds and minutes +- **RMSE (Root Mean Squared Error)**: Penalizes large errors +- **R²**: Goodness of fit +- **Within Threshold**: % predictions within 60s, 120s, 300s +- **Bias**: Over/under-prediction tendency +- **Quantile Errors**: 50th, 90th, 95th percentile errors + +### Rolling Window Validation + +Test models on sequential time windows: + +```python +from models.evaluation.roll_validate import quick_rolling_validate +from models.ewma.train import EWMAModel + +results = quick_rolling_validate( + model_class=EWMAModel, + model_params={'alpha': 0.3}, + train_window_days=7 +) +``` + +### Leaderboard + +Compare multiple models: + +```python +from models.evaluation.leaderboard import ModelLeaderboard + +leaderboard = ModelLeaderboard() +df = leaderboard.compare_models( + model_keys=['model1', 'model2', 'model3'], + dataset_name="sample_dataset" +) +leaderboard.print_leaderboard(df) +``` + +## Model Registry + +All trained models are stored in the registry with metadata: + +```python +from models.common.registry import get_registry + +registry = get_registry() + +# List all models +models = registry.list_models() + +# Load a model +model = registry.load_model("polyreg_time_...") + +# Get metadata +metadata = registry.load_metadata("polyreg_time_...") + +# Get best model by metric +best_key = registry.get_best_model(metric='test_mae_seconds') +``` + +## Feature Engineering Integration + +Models use features from the `feature_engineering` module: + +**Temporal features** (`temporal.py`): +- hour, day_of_week, is_weekend, is_holiday, is_peak_hour + +**Spatial features** (`spatial.py`): +- distance_to_stop, bearing_to_stop, progress_on_segment + +**Operational features** (`operational.py`): +- headway_seconds, avg_speed_last_10min, vehicles_on_route + +**Weather features** (`weather.py`): +- temperature_c, precipitation_mm, wind_speed_kmh + +See `feature_engineering/README.md` for details. + +## Dataset Requirements + +Models expect datasets built with `dataset_builder.py` script through the `build_eta_sample` Django command: + +**Minimum Required Columns**: +- `trip_id`, `route_id`, `vehicle_id`, `stop_id`, `stop_sequence` +- `vp_ts`, `vp_lat`, `vp_lon` +- `stop_lat`, `stop_lon`, `distance_to_stop` +- `time_to_arrival_seconds` (target) + +**Recommended Columns**: +- `hour`, `day_of_week`, `is_peak_hour` +- `headway_seconds`, `current_speed_kmh` + + From 600dcde3733d6c0b687a603195e3edea6e9a3b89 Mon Sep 17 00:00:00 2001 From: Jae Date: Tue, 28 Oct 2025 13:19:37 -0600 Subject: [PATCH 5/6] chore: models directory __init__.py file for it to work as an importable module --- eta_prediction/models/__init__.py | 194 ++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 eta_prediction/models/__init__.py diff --git a/eta_prediction/models/__init__.py b/eta_prediction/models/__init__.py new file mode 100644 index 0000000..25e59d6 --- /dev/null +++ b/eta_prediction/models/__init__.py @@ -0,0 +1,194 @@ +""" +ETA Prediction Models Package + +Comprehensive modeling framework for transit ETA prediction. + +Example usage: + >>> from models import train_all_baselines, get_registry + >>> models = train_all_baselines("sample_dataset") + >>> registry = get_registry() + >>> best_key = registry.get_best_model() +""" + +__version__ = "1.0.0" +__author__ = "SIMOVI Team" + +# Core utilities +from .common.data import load_dataset, ETADataset, prepare_features_target +from .common.registry import get_registry, ModelRegistry +from .common.keys import ModelKey, PredictionKey +from .common.metrics import ( + compute_all_metrics, + mae_minutes, + rmse_minutes, + within_threshold +) +from .common.utils import ( + format_seconds, + haversine_distance, + clip_predictions, + setup_logging +) + +# Training functions +from .historical_mean.train import train_historical_mean, HistoricalMeanModel +from .polyreg_distance.train import train_polyreg_distance, PolyRegDistanceModel +from .polyreg_time.train import train_polyreg_time, PolyRegTimeModel +from .ewma.train import train_ewma, EWMAModel + +# Prediction functions +from .historical_mean.predict import predict_eta as predict_historical_mean +from .polyreg_distance.predict import predict_eta as predict_polyreg_distance +from .polyreg_time.predict import predict_eta as predict_polyreg_time +from .ewma.predict import predict_eta as predict_ewma + +# Evaluation +from .evaluation.leaderboard import ModelLeaderboard, quick_compare +from .evaluation.roll_validate import RollingValidator, quick_rolling_validate + +# Main training pipeline +from .train_all_models import train_all_baselines, train_advanced_configurations + + +__all__ = [ + # Core utilities + 'load_dataset', + 'ETADataset', + 'prepare_features_target', + 'get_registry', + 'ModelRegistry', + 'ModelKey', + 'PredictionKey', + 'compute_all_metrics', + 'mae_minutes', + 'rmse_minutes', + 'within_threshold', + 'format_seconds', + 'haversine_distance', + 'clip_predictions', + 'setup_logging', + + # Models + 'HistoricalMeanModel', + 'PolyRegDistanceModel', + 'PolyRegTimeModel', + 'EWMAModel', + + # Training + 'train_historical_mean', + 'train_polyreg_distance', + 'train_polyreg_time', + 'train_ewma', + 'train_all_baselines', + 'train_advanced_configurations', + + # Prediction + 'predict_historical_mean', + 'predict_polyreg_distance', + 'predict_polyreg_time', + 'predict_ewma', + + # Evaluation + 'ModelLeaderboard', + 'quick_compare', + 'RollingValidator', + 'quick_rolling_validate', +] + + +# Package info +MODELS = { + 'historical_mean': { + 'description': 'Historical average baseline', + 'typical_mae': '2-4 minutes', + 'features': ['route_id', 'stop_sequence', 'temporal'] + }, + 'polyreg_distance': { + 'description': 'Polynomial regression on distance', + 'typical_mae': '1.5-3 minutes', + 'features': ['distance_to_stop'] + }, + 'polyreg_time': { + 'description': 'Polynomial regression with time features', + 'typical_mae': '1-2.5 minutes', + 'features': ['distance_to_stop', 'temporal', 'operational'] + }, + 'ewma': { + 'description': 'Exponentially weighted moving average', + 'typical_mae': '1.5-3 minutes', + 'features': ['route_id', 'stop_sequence', 'temporal'], + 'online_learning': True + } +} + + +def list_models(): + """List available model types.""" + print("\nAvailable Model Types:") + print("=" * 70) + for name, info in MODELS.items(): + print(f"\n{name}:") + print(f" Description: {info['description']}") + print(f" Typical MAE: {info['typical_mae']}") + print(f" Features: {', '.join(info['features'])}") + if info.get('online_learning'): + print(f" Online Learning: Yes") + print("\n" + "=" * 70) + + +def quick_start_guide(): + """Print quick start guide.""" + guide = """ + ETA Prediction Models - Quick Start + ==================================== + + 1. Train all baselines: + >>> from models import train_all_baselines + >>> results = train_all_baselines("sample_dataset") + + 2. Compare models: + >>> from models import quick_compare, get_registry + >>> registry = get_registry() + >>> model_keys = registry.list_models()['model_key'].tolist() + >>> comparison = quick_compare(model_keys) + + 3. Load and use best model: + >>> best_key = registry.get_best_model(metric='test_mae_seconds') + >>> model = registry.load_model(best_key) + >>> predictions = model.predict(your_data) + + 4. Make single prediction: + >>> from models import predict_polyreg_time + >>> result = predict_polyreg_time( + ... model_key=best_key, + ... distance_to_stop=1500.0, + ... hour=8, + ... is_peak_hour=True + ... ) + >>> print(f"ETA: {result['eta_formatted']}") + + For more details, see models/README.md + """ + print(guide) + + +# Auto-create directories +def _setup_directories(): + """Create necessary directories if they don't exist.""" + from pathlib import Path + base_dir = Path(__file__).parent + + dirs = [ + base_dir / 'trained', + base_dir.parent / 'datasets', + base_dir.parent / 'datasets' / 'metadata', + base_dir.parent / 'datasets' / 'production', + base_dir.parent / 'datasets' / 'experimental' + ] + + for dir_path in dirs: + dir_path.mkdir(parents=True, exist_ok=True) + + +# Run setup on import +_setup_directories() \ No newline at end of file From 4601cd494d8ff86f51df9c265f60b500eebe19e2 Mon Sep 17 00:00:00 2001 From: Jae Date: Wed, 29 Oct 2025 01:31:27 -0600 Subject: [PATCH 6/6] chore: deleted initial GTFS testing scripts --- eta_prediction/gtfs_rt_bindings_SA.py | 73 --------------------------- eta_prediction/gtfs_rt_bindings_TU.py | 18 ------- eta_prediction/gtfs_rt_bindings_VP.py | 40 --------------- 3 files changed, 131 deletions(-) delete mode 100644 eta_prediction/gtfs_rt_bindings_SA.py delete mode 100644 eta_prediction/gtfs_rt_bindings_TU.py delete mode 100644 eta_prediction/gtfs_rt_bindings_VP.py diff --git a/eta_prediction/gtfs_rt_bindings_SA.py b/eta_prediction/gtfs_rt_bindings_SA.py deleted file mode 100644 index 66810b2..0000000 --- a/eta_prediction/gtfs_rt_bindings_SA.py +++ /dev/null @@ -1,73 +0,0 @@ -from google.transit import gtfs_realtime_pb2 -import requests -from datetime import datetime, timezone - -""" -This script takes a GTFS-RT Service Alerts feed and prints out the first N alerts. -""" -N = 10 -URL = "https://cdn.mbta.com/realtime/Alerts.pb" # MBTA Service Alerts feed - -def ts_to_iso(ts): - return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat() if ts else None - -def get_text(translated_string): - """Return the first non-empty translation (common case).""" - if not translated_string or not translated_string.translation: - return None - for t in translated_string.translation: - if t.text: - return t.text - return None - -def fmt_period(active_period): - start = ts_to_iso(active_period.start) if active_period.HasField("start") else None - end = ts_to_iso(active_period.end) if active_period.HasField("end") else None - return f"{start or '—'} → {end or '—'}" - -def describe_informed_entity(ie): - parts = [] - if ie.route_id: - parts.append(f"route={ie.route_id}") - if ie.stop_id: - parts.append(f"stop={ie.stop_id}") - if ie.trip and ie.trip.trip_id: - parts.append(f"trip={ie.trip.trip_id}") - if not parts: - parts.append("system-wide") - return ", ".join(parts) - -feed = gtfs_realtime_pb2.FeedMessage() -resp = requests.get(URL, timeout=15) -resp.raise_for_status() -feed.ParseFromString(resp.content) - -shown = 0 -for entity in feed.entity: - if not entity.HasField("alert"): - continue - alert = entity.alert - - header = get_text(alert.header_text) or "(no header)" - desc = get_text(alert.description_text) or "" - cause = gtfs_realtime_pb2.Alert.Cause.Name(alert.cause) if alert.HasField("cause") else "CAUSE_UNSPECIFIED" - effect = gtfs_realtime_pb2.Alert.Effect.Name(alert.effect) if alert.HasField("effect") else "EFFECT_UNSPECIFIED" - - periods = [fmt_period(p) for p in alert.active_period] - applies = [describe_informed_entity(ie) for ie in alert.informed_entity] - - print(f"ALERT: {header}") - if desc: - print(f" desc: {desc}") - print(f" cause: {cause} | effect: {effect}") - if periods: - for i, p in enumerate(periods, 1): - print(f" active[{i}]: {p}") - if applies: - for i, a in enumerate(applies, 1): - print(f" applies_to[{i}]: {a}") - print("-" * 80) - - count += 1 - if count >= N: # show first N alerts - break diff --git a/eta_prediction/gtfs_rt_bindings_TU.py b/eta_prediction/gtfs_rt_bindings_TU.py deleted file mode 100644 index 07a78de..0000000 --- a/eta_prediction/gtfs_rt_bindings_TU.py +++ /dev/null @@ -1,18 +0,0 @@ -from google.transit import gtfs_realtime_pb2 -import requests -from datetime import datetime, timezone - -""" -This script takes a GTFS-RT Trip Updates feed and prints out the first N trip updates. -""" -N = 10 -# URL = "https://cdn.mbta.com/realtime/TripUpdates.pb" -URL = "https://databus.bucr.digital/feed/realtime/trip_updates.pb" # bUCR Realtime Trip Updates feed - -feed = gtfs_realtime_pb2.FeedMessage() -response = requests.get(URL) -feed.ParseFromString(response.content) - -for entity in feed.entity[:N]: # show first N trip updates - if entity.HasField('trip_update'): - print(entity.trip_update) diff --git a/eta_prediction/gtfs_rt_bindings_VP.py b/eta_prediction/gtfs_rt_bindings_VP.py deleted file mode 100644 index 3ff79b5..0000000 --- a/eta_prediction/gtfs_rt_bindings_VP.py +++ /dev/null @@ -1,40 +0,0 @@ -from google.transit import gtfs_realtime_pb2 -import requests -from datetime import datetime, timezone - -""" -This script takes a GTFS-RT Vehicle Positions feed and prints out the first N vehicle positions. -""" -N = 10 -# URL = "https://cdn.mbta.com/realtime/VehiclePositions.pb" -URL = "https://databus.bucr.digital/feed/realtime/vehicle_positions.pb" # bUCR Realtime Vehicle Positions feed - -feed = gtfs_realtime_pb2.FeedMessage() -resp = requests.get(URL, timeout=15) -resp.raise_for_status() -feed.ParseFromString(resp.content) - -def ts_to_iso(ts): - return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat() if ts else None - -count = 0 -for entity in feed.entity: - if entity.HasField("vehicle"): - v = entity.vehicle - pos = v.position # lat, lon, speed (m/s), bearing (deg) - trip = v.trip # trip_id, route_id, start_time/date - veh = v.vehicle # id, label - - print( - f"veh_id={veh.id or '—'} route={trip.route_id or '—'} trip={trip.trip_id or '—'}\n" - f" lat={pos.latitude:.6f} lon={pos.longitude:.6f} " - f"speed_mps={pos.speed if pos.HasField('speed') else '—'} " - f"bearing={pos.bearing if pos.HasField('bearing') else '—'}\n" - f" current_stop_seq={v.current_stop_sequence if v.HasField('current_stop_sequence') else '—'} " - f"status={v.current_status if v.HasField('current_status') else '—'} " - f"timestamp={ts_to_iso(v.timestamp)}" - ) - print("-" * 80) - count += 1 - if count >= 10: # show first N vehicle positions - break