diff --git a/.gitignore b/.gitignore index d290cdb..2a6c60f 100644 --- a/.gitignore +++ b/.gitignore @@ -186,3 +186,4 @@ docs/_build docs/source/api/generated docs/source/api/api/* docs/zz/* +ARCHITECTURE.md diff --git a/AUTHORS.md b/AUTHORS.md index 7a85e03..ed93389 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -7,4 +7,4 @@ order by last name) and are considered "The gSolve Developers": * Alison Kirkby - Earth Sciences New Zealand, New Zealand * Craig Miller - Earth Sciences New Zealand, New Zealand * Vaughan Stagpoole - Earth Sciences New Zealand, New Zealand -* Aleksandr Spesivtsev - Earth Sciences New Zealand, New Zealand \ No newline at end of file +* Aleksandr Spesivtsev - Earth Sciences New Zealand, New Zealand diff --git a/CHANGELOG.md b/CHANGELOG.md index 527cb43..8e2bca4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,6 @@ New features: * Added GPLv3 licence * PyGTide added for ETERNA tide correction -Maintenance: +Maintenance: * Bug fix for terrain corrections - diff --git a/README.md b/README.md index 78fd941..b77f2e8 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,15 @@ ![gSolve logo](docs/source/_static/gsolve_logo.png) - + [![codecov](https://codecov.io/gh/GNS-Science/gsolve/branch/main/graph/badge.svg)](https://codecov.io/gh/GNS-Science/gsolve) [![GitHub License](https://img.shields.io/github/license/GNS-Science/gsolve)](https://github.com/GNS-Science/gsolve/blob/main/LICENSE) ![Publish to PyPI](https://github.com/GNS-Science/gsolve/actions/workflows/publish.yml/badge.svg) [![Pypi version](https://img.shields.io/pypi/v/gsolve)](https://pypi.org/project/gsolve/) - - # gSolve -gSolve, a Python computer library by Earth Sciences New Zealand (formerly GNS Science) to transform relative gravity survey measurements to absolute gravity values and gravity anomalies and disturbances. +gSolve, a Python computer library by Earth Sciences New Zealand (formerly GNS Science) to transform relative gravity survey measurements to absolute gravity values and gravity anomalies and disturbances. -It is suitable for time varying gravity as well as Bouguer gravity. +It is suitable for time varying gravity as well as Bouguer gravity. This version is a substantial re-write of the previous python version to remove the limitation of a graphical user interface and to update to python 3 with modern software management. @@ -30,8 +28,10 @@ Process gravity data for time change microgravity and Bouguer surveys. * option to correct for ocean loading using [pyhardisp](https://github.com/craigmillernz/pyhardisp). * correct for drift across loops or whole survey. * network adjustment with three different network adjustment algorithms depending on user requirements. -# calibrate meters to absolute values. -* residuals can be filtered using a percentile cut filter. + +# calibrate meters to absolute values + +* residuals can be filtered using a percentile cut filter. ## Corrections @@ -42,7 +42,7 @@ Process gravity data for time change microgravity and Bouguer surveys. ## Plotting * plot raw observations -* residual cumuluative probability density functions, CDF. +* residual cumulative probability density functions, CDF. * drift curve * network map @@ -65,14 +65,14 @@ Full documentation is available here. [gSolve](https://gns-science.github.io/gso # Authors and acknowledgment -gSolve builds on many previous authors. +gSolve builds on many previous authors. The current author team is Adrian Benson, Alison Kirkby, Craig Miller, Aleksandr Spesivtsev, Vaughan Stagpoole. This version supersedes previous Gsolve versions e.g. -McCubbine, J., Tontini, F. C., Stagpoole, V., Smith, E., & O’Brien, G. (2018). Gsolve, a Python computer program with a graphical user interface to transform relative gravity survey measurements to absolute gravity values and gravity anomalies. SoftwareX, 7, 129–137. +McCubbine, J., Tontini, F. C., Stagpoole, V., Smith, E., & O’Brien, G. (2018). Gsolve, a Python computer program with a graphical user interface to transform relative gravity survey measurements to absolute gravity values and gravity anomalies. SoftwareX, 7, 129–137. -# How to cite gSolve +# How to cite gSolve Link to JOSS paper here when it is ready. @@ -82,4 +82,4 @@ Python 3.12+ # License -Licenced with GPLv3. +Licensed with GPLv3. diff --git a/cspell.json b/cspell.json index 491a245..39f0a1f 100644 --- a/cspell.json +++ b/cspell.json @@ -15,5 +15,9 @@ "data-science-tools", "git", "en-au" + ], + "ignorePaths": [ + ".git/**", + ".gitignore" ] } \ No newline at end of file diff --git a/examples/ocean_load/quicktide/okataina_qtp_input.csv b/examples/ocean_load/quicktide/okataina_qtp_input.csv index 60ccaba..cb9cade 100644 --- a/examples/ocean_load/quicktide/okataina_qtp_input.csv +++ b/examples/ocean_load/quicktide/okataina_qtp_input.csv @@ -1,613 +1,613 @@ -ACNN,03/16/2020 21:08,-38.512209,176.331926,297.958 -ACNN,03/16/2020 21:12,-38.512209,176.331926,297.958 -ACNN,03/16/2020 21:13,-38.512209,176.331926,297.958 -WP93,03/16/2020 22:29,-38.265116,176.564573,467.265 -WP93,03/16/2020 22:30,-38.265116,176.564573,467.265 -WP146,03/16/2020 22:44,-38.268071,176.572404,446.828 -WP146,03/16/2020 22:45,-38.268071,176.572404,446.828 -WP140,03/16/2020 22:56,-38.269557,176.577605,434.051 -WP140,03/16/2020 22:59,-38.269557,176.577605,434.051 -WP140,03/16/2020 23:00,-38.269557,176.577605,434.051 -WP143,03/16/2020 23:24,-38.275345,176.584047,479.006 -WP143,03/16/2020 23:25,-38.275345,176.584047,479.006 -WP143,03/16/2020 23:26,-38.275345,176.584047,479.006 -WP144,03/16/2020 23:55,-38.274621,176.568323,448.606 -WP144,03/16/2020 23:57,-38.274621,176.568323,448.606 -WP144,03/16/2020 23:58,-38.274621,176.568323,448.606 -WP93,03/17/2020 00:13,-38.265116,176.564573,467.265 -WP93,03/17/2020 00:14,-38.265116,176.564573,467.265 -WP98,03/17/2020 00:28,-38.256793,176.571165,457.455 -WP139,03/17/2020 01:04,-38.262333,176.556635,494.174 -WP139,03/17/2020 01:06,-38.262333,176.556635,494.174 -WP139,03/17/2020 01:07,-38.262333,176.556635,494.174 -WP138,03/17/2020 01:15,-38.255525,176.560111,495.930 -WP138,03/17/2020 01:18,-38.255525,176.560111,495.930 -WP138,03/17/2020 01:19,-38.255525,176.560111,495.930 -WP96,03/17/2020 02:16,-38.262988,176.543263,514.214 -WP96,03/17/2020 02:17,-38.262988,176.543263,514.214 -WP93,03/17/2020 02:36,-38.265116,176.564573,467.265 -WP93,03/17/2020 02:37,-38.265116,176.564573,467.265 -ACNN,03/17/2020 03:39,-38.512209,176.331926,297.958 -ACNN,03/17/2020 03:41,-38.512209,176.331926,297.958 -ACNN,03/17/2020 03:42,-38.512209,176.331926,297.958 -ACNN,03/17/2020 20:44,-38.512209,176.331926,297.958 -ACNN,03/17/2020 20:46,-38.512209,176.331926,297.958 -ACNN,03/17/2020 20:47,-38.512209,176.331926,297.958 -WP93,03/17/2020 21:40,-38.265116,176.564573,467.265 -WP93,03/17/2020 21:42,-38.265116,176.564573,467.265 -WP93,03/17/2020 21:43,-38.265116,176.564573,467.265 -WP148,03/17/2020 22:01,-38.290511,176.575760,471.560 -WP148,03/17/2020 22:06,-38.290511,176.575760,471.560 -WP148,03/17/2020 22:07,-38.290511,176.575760,471.560 -WP141,03/17/2020 22:28,-38.281541,176.576093,453.541 -WP141,03/17/2020 22:29,-38.281541,176.576093,453.541 -WP141,03/17/2020 22:30,-38.281541,176.576093,453.541 -WP142,03/17/2020 22:52,-38.281560,176.566694,474.395 -WP142,03/17/2020 22:53,-38.281560,176.566694,474.395 -WP142,03/17/2020 22:54,-38.281560,176.566694,474.395 -WP147,03/17/2020 23:14,-38.293007,176.555309,449.272 -WP147,03/17/2020 23:17,-38.293007,176.555309,449.272 -WP139,03/17/2020 23:39,-38.262333,176.556635,494.174 -WP139,03/17/2020 23:40,-38.262333,176.556635,494.174 -WP93,03/17/2020 23:52,-38.265116,176.564573,467.265 -WP93,03/17/2020 23:54,-38.265116,176.564573,467.265 -WP93,03/17/2020 23:55,-38.265116,176.564573,467.265 -WP99,03/18/2020 00:17,-38.269413,176.550480,475.842 -WP99,03/18/2020 00:20,-38.269413,176.550480,475.842 -WP136,03/18/2020 00:39,-38.274086,176.545530,473.901 -WP136,03/18/2020 00:44,-38.274086,176.545530,473.901 -WP95,03/18/2020 00:58,-38.272596,176.535114,486.335 -WP95,03/18/2020 01:03,-38.272596,176.535114,486.335 -WP95,03/18/2020 01:04,-38.272596,176.535114,486.335 -WP145,03/18/2020 01:43,-38.281429,176.543511,458.052 -WP145,03/18/2020 01:45,-38.281429,176.543511,458.052 -WP145,03/18/2020 01:46,-38.281429,176.543511,458.052 -WP93,03/18/2020 02:03,-38.265116,176.564573,467.265 -WP93,03/18/2020 02:07,-38.265116,176.564573,467.265 -WP93,03/18/2020 02:08,-38.265116,176.564573,467.265 -WP149,03/18/2020 02:26,-38.307750,176.558839,445.231 -WP149,03/18/2020 02:29,-38.307750,176.558839,445.231 -WP149,03/18/2020 02:30,-38.307750,176.558839,445.231 -ACNN,03/18/2020 03:10,-38.512209,176.331926,297.958 -ACNN,03/18/2020 03:15,-38.512209,176.331926,297.958 -AGUP,06/10/2020 23:48,-38.054648,176.441513,284.462 -AGUP,06/10/2020 23:50,-38.054648,176.441513,284.462 -OG32,06/11/2020 00:56,-38.122774,176.475586,820.424 -OG32,06/11/2020 00:57,-38.122774,176.475586,820.424 -OG36,06/11/2020 01:55,-38.138471,176.467108,926.489 -OG36,06/11/2020 01:57,-38.138471,176.467108,926.489 -OG37,06/11/2020 02:23,-38.138224,176.459507,854.027 -OG37,06/11/2020 02:24,-38.138224,176.459507,854.027 -OG38,06/11/2020 02:44,-38.134208,176.461352,851.227 -OG38,06/11/2020 02:45,-38.134208,176.461352,851.227 -OG34,06/11/2020 03:12,-38.131201,176.474881,800.569 -OG34,06/11/2020 03:13,-38.131201,176.474881,800.569 -OG34,06/11/2020 03:14,-38.131201,176.474881,800.569 -OG33,06/11/2020 03:32,-38.128162,176.479851,837.787 -OG33,06/11/2020 03:33,-38.128162,176.479851,837.787 -OG32,06/11/2020 03:43,-38.122774,176.475586,820.424 -OG32,06/11/2020 03:44,-38.122774,176.475586,820.424 -AGUP,06/11/2020 04:35,-38.054648,176.441513,284.462 -AGUP,06/11/2020 04:36,-38.054648,176.441513,284.462 -AGUP,06/11/2020 23:06,-38.054648,176.441513,284.462 -AGUP,06/11/2020 23:08,-38.054648,176.441513,284.462 -AGUP,06/11/2020 23:10,-38.054648,176.441513,284.462 -OG29,06/12/2020 00:36,-38.090789,176.456845,591.652 -OG29,06/12/2020 00:37,-38.090789,176.456845,591.652 -OG29,06/12/2020 00:38,-38.090789,176.456845,591.652 -OG16,06/12/2020 00:51,-38.096062,176.456555,620.377 -OG16,06/12/2020 00:53,-38.096062,176.456555,620.377 -OG16,06/12/2020 00:54,-38.096062,176.456555,620.377 -OG09,06/12/2020 01:05,-38.094752,176.447202,646.313 -OG09,06/12/2020 01:06,-38.094752,176.447202,646.313 -OG07,06/12/2020 01:21,-38.086364,176.446698,592.772 -OG05,06/12/2020 01:34,-38.083088,176.456330,545.289 -OG05,06/12/2020 01:35,-38.083088,176.456330,545.289 -OG05,06/12/2020 01:36,-38.083088,176.456330,545.289 -OG29,06/12/2020 01:52,-38.090789,176.456845,591.652 -OG29,06/12/2020 01:53,-38.090789,176.456845,591.652 -OG32,06/12/2020 02:32,-38.122774,176.475586,820.424 -OG32,06/12/2020 02:33,-38.122774,176.475586,820.424 -OG31,06/12/2020 02:45,-38.117953,176.479049,756.718 -OG31,06/12/2020 02:46,-38.117953,176.479049,756.718 -OG20,06/12/2020 03:03,-38.115873,176.472735,673.949 -OG20,06/12/2020 03:04,-38.115873,176.472735,673.949 -OG20,06/12/2020 03:05,-38.115873,176.472735,673.949 -OG28,06/12/2020 03:20,-38.105198,176.474171,662.676 -OG28,06/12/2020 03:21,-38.105198,176.474171,662.676 -OG27,06/12/2020 03:34,-38.099356,176.468858,628.158 -OG27,06/12/2020 03:35,-38.099356,176.468858,628.158 -OG27,06/12/2020 03:36,-38.099356,176.468858,628.158 -OG05,06/12/2020 03:54,-38.083088,176.456330,545.289 -OG05,06/12/2020 03:55,-38.083088,176.456330,545.289 -OG05,06/12/2020 03:56,-38.083088,176.456330,545.289 -AGUP,06/12/2020 04:16,-38.054648,176.441513,284.462 -AGUP,06/12/2020 04:18,-38.054648,176.441513,284.462 -AGUP,06/12/2020 04:19,-38.054648,176.441513,284.462 -AGUP,06/15/2020 20:18,-38.054648,176.441513,284.462 -AGUP,06/15/2020 20:20,-38.054648,176.441513,284.462 -AGUP,06/15/2020 20:21,-38.054648,176.441513,284.462 -AGUP,06/15/2020 20:22,-38.054648,176.441513,284.462 -OK100,06/15/2020 21:02,-38.085725,176.461508,571.934 -OK100,06/15/2020 21:03,-38.085725,176.461508,571.934 -OK100,06/15/2020 21:04,-38.085725,176.461508,571.934 -OK100,06/15/2020 21:05,-38.085725,176.461508,571.934 -OK101,06/15/2020 21:29,-38.095606,176.464133,611.804 -OK101,06/15/2020 21:30,-38.095606,176.464133,611.804 -OK101,06/15/2020 21:31,-38.095606,176.464133,611.804 -OK101,06/15/2020 21:32,-38.095606,176.464133,611.804 -OK103,06/15/2020 22:13,-38.126974,176.457878,817.623 -OK103,06/15/2020 22:14,-38.126974,176.457878,817.623 -OK103,06/15/2020 22:16,-38.126974,176.457878,817.623 -OK103,06/15/2020 22:17,-38.126974,176.457878,817.623 -OK102,06/15/2020 22:55,-38.116363,176.464753,653.245 -OK102,06/15/2020 22:56,-38.116363,176.464753,653.245 -OK102,06/15/2020 22:57,-38.116363,176.464753,653.245 -OK104,06/15/2020 23:08,-38.116836,176.459708,653.269 -OK104,06/15/2020 23:09,-38.116836,176.459708,653.269 -OK104,06/15/2020 23:10,-38.116836,176.459708,653.269 -OK105,06/15/2020 23:22,-38.113316,176.450891,624.164 -OK105,06/15/2020 23:23,-38.113316,176.450891,624.164 -OK105,06/15/2020 23:24,-38.113316,176.450891,624.164 -OK105,06/15/2020 23:25,-38.113316,176.450891,624.164 -OK106,06/15/2020 23:45,-38.109690,176.447081,595.380 -OK106,06/15/2020 23:46,-38.109690,176.447081,595.380 -OK106,06/15/2020 23:47,-38.109690,176.447081,595.380 -OK107,06/15/2020 23:59,-38.105259,176.443636,569.412 -OK107,06/16/2020 00:00,-38.105259,176.443636,569.412 -OK107,06/16/2020 00:01,-38.105259,176.443636,569.412 -OK101,06/16/2020 00:19,-38.095606,176.464133,611.804 -OK101,06/16/2020 00:20,-38.095606,176.464133,611.804 -OK101,06/16/2020 00:21,-38.095606,176.464133,611.804 -OK108,06/16/2020 00:35,-38.089592,176.462151,570.424 -OK108,06/16/2020 00:36,-38.089592,176.462151,570.424 -OK108,06/16/2020 00:37,-38.089592,176.462151,570.424 -OK100,06/16/2020 00:47,-38.085725,176.461508,571.934 -OK100,06/16/2020 00:48,-38.085725,176.461508,571.934 -OK100,06/16/2020 00:49,-38.085725,176.461508,571.934 -OK109,06/16/2020 01:01,-38.090300,176.473812,574.586 -OK109,06/16/2020 01:02,-38.090300,176.473812,574.586 -OK109,06/16/2020 01:03,-38.090300,176.473812,574.586 -OK110,06/16/2020 01:27,-38.089956,176.509779,724.067 -OK110,06/16/2020 01:28,-38.089956,176.509779,724.067 -OK110,06/16/2020 01:29,-38.089956,176.509779,724.067 -OK111,06/16/2020 01:44,-38.092895,176.507268,766.928 -OK111,06/16/2020 01:45,-38.092895,176.507268,766.928 -OK111,06/16/2020 01:46,-38.092895,176.507268,766.928 -OK112,06/16/2020 01:57,-38.098088,176.503781,745.889 -OK112,06/16/2020 01:58,-38.098088,176.503781,745.889 -OK112,06/16/2020 01:59,-38.098088,176.503781,745.889 -OK113,06/16/2020 02:10,-38.101380,176.501816,699.390 -OK113,06/16/2020 02:11,-38.101380,176.501816,699.390 -OK113,06/16/2020 02:12,-38.101380,176.501816,699.390 -OK110,06/16/2020 02:33,-38.089956,176.509779,724.067 -OK110,06/16/2020 02:34,-38.089956,176.509779,724.067 -OK110,06/16/2020 02:35,-38.089956,176.509779,724.067 -OK110,06/16/2020 02:36,-38.089956,176.509779,724.067 -OK114,06/16/2020 02:49,-38.095670,176.514649,676.003 -OK114,06/16/2020 02:51,-38.095670,176.514649,676.003 -OK114,06/16/2020 02:52,-38.095670,176.514649,676.003 -OK100,06/16/2020 03:17,-38.085725,176.461508,571.934 -OK100,06/16/2020 03:18,-38.085725,176.461508,571.934 -OK100,06/16/2020 03:19,-38.085725,176.461508,571.934 -OK115,06/16/2020 03:48,-38.072775,176.445752,531.606 -OK115,06/16/2020 03:49,-38.072775,176.445752,531.606 -OK115,06/16/2020 03:50,-38.072775,176.445752,531.606 -AGUP,06/16/2020 04:13,-38.054648,176.441513,284.462 -AGUP,06/16/2020 04:14,-38.054648,176.441513,284.462 -AGUP,06/16/2020 04:15,-38.054648,176.441513,284.462 -AGUP,06/16/2020 04:16,-38.054648,176.441513,284.462 -AGUP,06/16/2020 20:24,-38.054648,176.441513,284.462 -AGUP,06/16/2020 20:25,-38.054648,176.441513,284.462 -AGUP,06/16/2020 20:26,-38.054648,176.441513,284.462 -AGUP,06/16/2020 20:27,-38.054648,176.441513,284.462 -AGUP,06/16/2020 20:28,-38.054648,176.441513,284.462 -OK116,06/16/2020 20:47,-38.058756,176.439179,358.501 -OK116,06/16/2020 20:48,-38.058756,176.439179,358.501 -OK116,06/16/2020 20:49,-38.058756,176.439179,358.501 -OK117,06/16/2020 21:03,-38.068929,176.437052,483.316 -OK117,06/16/2020 21:04,-38.068929,176.437052,483.316 -OK117,06/16/2020 21:05,-38.068929,176.437052,483.316 -OK118,06/16/2020 21:16,-38.073657,176.441712,522.573 -OK118,06/16/2020 21:17,-38.073657,176.441712,522.573 -OK118,06/16/2020 21:18,-38.073657,176.441712,522.573 -OK115,06/16/2020 21:24,-38.072775,176.445752,531.606 -OK115,06/16/2020 21:26,-38.072775,176.445752,531.606 -OK115,06/16/2020 21:27,-38.072775,176.445752,531.606 -OK120,06/16/2020 21:58,-38.082193,176.443110,557.141 -OK120,06/16/2020 21:59,-38.082193,176.443110,557.141 -OK120,06/16/2020 22:00,-38.082193,176.443110,557.141 -OK121,06/16/2020 22:22,-38.081916,176.450346,560.335 -OK121,06/16/2020 22:23,-38.081916,176.450346,560.335 -OK121,06/16/2020 22:24,-38.081916,176.450346,560.335 -OK121,06/16/2020 22:25,-38.081916,176.450346,560.335 -OK100,06/16/2020 22:59,-38.085725,176.461508,571.934 -OK100,06/16/2020 23:00,-38.085725,176.461508,571.934 -OK100,06/16/2020 23:01,-38.085725,176.461508,571.934 -OK122,06/16/2020 23:31,-38.145088,176.547568,138.257 -OK122,06/16/2020 23:32,-38.145088,176.547568,138.257 -OK122,06/16/2020 23:33,-38.145088,176.547568,138.257 -OK123,06/16/2020 23:48,-38.147439,176.529044,151.811 -OK123,06/16/2020 23:49,-38.147439,176.529044,151.811 -OK123,06/16/2020 23:50,-38.147439,176.529044,151.811 -OK124,06/16/2020 23:58,-38.152082,176.523221,165.996 -OK124,06/16/2020 23:59,-38.152082,176.523221,165.996 -OK124,06/17/2020 00:00,-38.152082,176.523221,165.996 -OK125,06/17/2020 00:32,-38.161871,176.556924,269.597 -OK125,06/17/2020 00:33,-38.161871,176.556924,269.597 -OK125,06/17/2020 00:34,-38.161871,176.556924,269.597 -OK126,06/17/2020 00:48,-38.159109,176.567787,275.636 -OK126,06/17/2020 00:49,-38.159109,176.567787,275.636 -OK126,06/17/2020 00:50,-38.159109,176.567787,275.636 -OK127,06/17/2020 01:11,-38.164775,176.539095,328.887 -OK127,06/17/2020 01:12,-38.164775,176.539095,328.887 -OK127,06/17/2020 01:13,-38.164775,176.539095,328.887 -OK128,06/17/2020 01:28,-38.171419,176.550971,321.940 -OK128,06/17/2020 01:29,-38.171419,176.550971,321.940 -OK128,06/17/2020 01:30,-38.171419,176.550971,321.940 -OK129,06/17/2020 01:43,-38.178758,176.546944,324.494 -OK129,06/17/2020 01:44,-38.178758,176.546944,324.494 -OK129,06/17/2020 01:45,-38.178758,176.546944,324.494 -OK130,06/17/2020 01:56,-38.188041,176.536996,315.136 -OK130,06/17/2020 01:58,-38.188041,176.536996,315.136 -OK130,06/17/2020 01:59,-38.188041,176.536996,315.136 -OK131,06/17/2020 02:14,-38.174561,176.533057,325.182 -OK131,06/17/2020 02:15,-38.174561,176.533057,325.182 -OK131,06/17/2020 02:16,-38.174561,176.533057,325.182 -OK100,06/17/2020 02:50,-38.085725,176.461508,571.934 -OK100,06/17/2020 02:51,-38.085725,176.461508,571.934 -OK100,06/17/2020 02:52,-38.085725,176.461508,571.934 -OK100,06/17/2020 02:53,-38.085725,176.461508,571.934 -OK116,06/17/2020 03:16,-38.058756,176.439179,358.501 -OK116,06/17/2020 03:17,-38.058756,176.439179,358.501 -OK116,06/17/2020 03:18,-38.058756,176.439179,358.501 -AGUP,06/17/2020 03:27,-38.054648,176.441513,284.462 -AGUP,06/17/2020 03:28,-38.054648,176.441513,284.462 -AGUP,06/17/2020 03:29,-38.054648,176.441513,284.462 -AGUP,06/17/2020 03:30,-38.054648,176.441513,284.462 -AGUP,06/23/2020 23:09,-38.054648,176.441513,284.462 -AGUP,06/23/2020 23:10,-38.054648,176.441513,284.462 -OK133,06/24/2020 00:19,-38.181733,176.529888,358.585 -OK133,06/24/2020 00:20,-38.181733,176.529888,358.585 -OK134,06/24/2020 00:40,-38.187150,176.516708,383.824 -OK134,06/24/2020 00:41,-38.187150,176.516708,383.824 -OK134,06/24/2020 00:42,-38.187150,176.516708,383.824 -OK135,06/24/2020 00:58,-38.193711,176.518258,417.043 -OK135,06/24/2020 00:59,-38.193711,176.518258,417.043 -OK136,06/24/2020 01:13,-38.190659,176.512660,394.510 -OK136,06/24/2020 01:14,-38.190659,176.512660,394.510 -OK133,06/24/2020 01:40,-38.181733,176.529888,358.585 -OK133,06/24/2020 01:41,-38.181733,176.529888,358.585 -OK137,06/24/2020 02:04,-38.201600,176.556378,400.296 -OK137,06/24/2020 02:05,-38.201600,176.556378,400.296 -OK138,06/24/2020 02:31,-38.215092,176.559455,536.408 -OK138,06/24/2020 02:32,-38.215092,176.559455,536.408 -OK139,06/24/2020 02:48,-38.219739,176.556725,517.360 -OK139,06/24/2020 02:49,-38.219739,176.556725,517.360 -OK140,06/24/2020 03:05,-38.211466,176.553502,444.138 -OK140,06/24/2020 03:06,-38.211466,176.553502,444.138 -OK141,06/24/2020 03:16,-38.206190,176.559453,402.706 -OK141,06/24/2020 03:17,-38.206190,176.559453,402.706 -OK137,06/24/2020 03:26,-38.201600,176.556378,400.296 -OK137,06/24/2020 03:27,-38.201600,176.556378,400.296 -AGUP,06/24/2020 04:55,-38.054648,176.441513,284.462 -AGUP,06/24/2020 04:56,-38.054648,176.441513,284.462 -AGUP,07/01/2020 20:28,-38.054648,176.441513,284.462 -AGUP,07/01/2020 20:29,-38.054648,176.441513,284.462 -AGUP,07/01/2020 20:30,-38.054648,176.441513,284.462 -AGUP,07/01/2020 20:31,-38.054648,176.441513,284.462 -OK138A,07/01/2020 21:45,-38.195393,176.603737,193.810 -OK138A,07/01/2020 21:46,-38.195393,176.603737,193.810 -OK138A,07/01/2020 21:47,-38.195393,176.603737,193.810 -OK139A,07/01/2020 21:58,-38.192269,176.612474,190.458 -OK139A,07/01/2020 21:59,-38.192269,176.612474,190.458 -OK139A,07/01/2020 22:00,-38.192269,176.612474,190.458 -OK140A,07/01/2020 22:24,-38.188830,176.618648,215.986 -OK140A,07/01/2020 22:25,-38.188830,176.618648,215.986 -OK140A,07/01/2020 22:26,-38.188830,176.618648,215.986 -OK141A,07/01/2020 23:01,-38.212563,176.634155,366.801 -OK141A,07/01/2020 23:02,-38.212563,176.634155,366.801 -OK141A,07/01/2020 23:03,-38.212563,176.634155,366.801 -OK141A,07/01/2020 23:04,-38.212563,176.634155,366.801 -OK142,07/01/2020 23:29,-38.230168,176.632750,423.289 -OK142,07/01/2020 23:30,-38.230168,176.632750,423.289 -OK142,07/01/2020 23:31,-38.230168,176.632750,423.289 -OK143,07/01/2020 23:43,-38.239846,176.624572,409.859 -OK143,07/01/2020 23:45,-38.239846,176.624572,409.859 -OK143,07/01/2020 23:46,-38.239846,176.624572,409.859 -OK144,07/01/2020 23:58,-38.246316,176.618187,453.636 -OK144,07/01/2020 23:59,-38.246316,176.618187,453.636 -OK144,07/02/2020 00:00,-38.246316,176.618187,453.636 -OK145,07/02/2020 00:12,-38.251962,176.613961,445.032 -OK145,07/02/2020 00:13,-38.251962,176.613961,445.032 -OK145,07/02/2020 00:14,-38.251962,176.613961,445.032 -OK146,07/02/2020 00:30,-38.264961,176.597951,489.019 -OK146,07/02/2020 00:31,-38.264961,176.597951,489.019 -OK146,07/02/2020 00:32,-38.264961,176.597951,489.019 -OK146,07/02/2020 00:34,-38.264961,176.597951,489.019 -OK147,07/02/2020 01:14,-38.246345,176.596586,478.170 -OK147,07/02/2020 01:15,-38.246345,176.596586,478.170 -OK147,07/02/2020 01:16,-38.246345,176.596586,478.170 -OK148,07/02/2020 01:32,-38.240404,176.606183,470.007 -OK148,07/02/2020 01:33,-38.240404,176.606183,470.007 -OK148,07/02/2020 01:34,-38.240404,176.606183,470.007 -OK146,07/02/2020 01:49,-38.264961,176.597951,489.019 -OK146,07/02/2020 01:50,-38.264961,176.597951,489.019 -OK146,07/02/2020 01:51,-38.264961,176.597951,489.019 -OK144,07/02/2020 02:02,-38.246316,176.618187,453.636 -OK144,07/02/2020 02:03,-38.246316,176.618187,453.636 -OK144,07/02/2020 02:04,-38.246316,176.618187,453.636 -OK141A,07/02/2020 02:21,-38.212563,176.634155,366.801 -OK141A,07/02/2020 02:22,-38.212563,176.634155,366.801 -OK141A,07/02/2020 02:23,-38.212563,176.634155,366.801 -OK149,07/02/2020 02:35,-38.208633,176.625981,348.487 -OK149,07/02/2020 02:36,-38.208633,176.625981,348.487 -OK149,07/02/2020 02:37,-38.208633,176.625981,348.487 -OK150,07/02/2020 02:49,-38.202049,176.625910,308.349 -OK150,07/02/2020 02:50,-38.202049,176.625910,308.349 -OK150,07/02/2020 02:51,-38.202049,176.625910,308.349 -OK151,07/02/2020 03:07,-38.196244,176.614920,199.383 -OK151,07/02/2020 03:08,-38.196244,176.614920,199.383 -OK151,07/02/2020 03:09,-38.196244,176.614920,199.383 -OK139A,07/02/2020 03:15,-38.192269,176.612474,190.458 -OK139A,07/02/2020 03:16,-38.192269,176.612474,190.458 -OK139A,07/02/2020 03:17,-38.192269,176.612474,190.458 -OK100,07/02/2020 03:53,-38.085725,176.461508,571.934 -OK100,07/02/2020 03:54,-38.085725,176.461508,571.934 -OK100,07/02/2020 03:55,-38.085725,176.461508,571.934 -AGUP,07/02/2020 04:11,-38.054648,176.441513,284.462 -AGUP,07/02/2020 04:12,-38.054648,176.441513,284.462 -AGUP,07/02/2020 04:14,-38.054648,176.441513,284.462 -AGUP,07/02/2020 04:16,-38.054648,176.441513,284.462 -AGUP,07/02/2020 04:17,-38.054648,176.441513,284.462 -AGUP,07/09/2020 22:00,-38.054648,176.441513,284.462 -AGUP,07/09/2020 22:01,-38.054648,176.441513,284.462 -AGUP,07/09/2020 22:02,-38.054648,176.441513,284.462 -OK137,07/09/2020 22:53,-38.201600,176.556378,400.296 -OK137,07/09/2020 22:54,-38.201600,176.556378,400.296 -OK137,07/09/2020 22:55,-38.201600,176.556378,400.296 -OK171,07/09/2020 23:31,-38.210813,176.577778,417.779 -OK171,07/09/2020 23:32,-38.210813,176.577778,417.779 -OK171,07/09/2020 23:33,-38.210813,176.577778,417.779 -OK172,07/10/2020 00:25,-38.198771,176.564368,380.106 -OK172,07/10/2020 00:26,-38.198771,176.564368,380.106 -OK172,07/10/2020 00:27,-38.198771,176.564368,380.106 -OK137,07/10/2020 00:38,-38.201600,176.556378,400.296 -OK137,07/10/2020 00:39,-38.201600,176.556378,400.296 -OK137,07/10/2020 00:40,-38.201600,176.556378,400.296 -OK174,07/10/2020 01:11,-38.195509,176.585421,317.670 -OK174,07/10/2020 01:12,-38.195509,176.585421,317.670 -OK174,07/10/2020 01:13,-38.195509,176.585421,317.670 -OK176,07/10/2020 01:34,-38.195406,176.601072,211.301 -OK176,07/10/2020 01:35,-38.195406,176.601072,211.301 -OK176,07/10/2020 01:36,-38.195406,176.601072,211.301 -OK172,07/10/2020 01:56,-38.198771,176.564368,380.106 -OK172,07/10/2020 01:57,-38.198771,176.564368,380.106 -OK172,07/10/2020 01:58,-38.198771,176.564368,380.106 -AGUP,07/10/2020 02:56,-38.054648,176.441513,284.462 -AGUP,07/10/2020 02:57,-38.054648,176.441513,284.462 -AGUP,07/10/2020 02:58,-38.054648,176.441513,284.462 -AGUP,07/13/2020 20:28,-38.054648,176.441513,284.462 -AGUP,07/13/2020 20:29,-38.054648,176.441513,284.462 -AGUP,07/13/2020 20:30,-38.054648,176.441513,284.462 -AGUP,07/13/2020 20:31,-38.054648,176.441513,284.462 -OK138A,07/13/2020 21:18,-38.195393,176.603737,193.810 -OK138A,07/13/2020 21:19,-38.195393,176.603737,193.810 -OK138A,07/13/2020 21:20,-38.195393,176.603737,193.810 -OK177,07/13/2020 22:13,-38.233895,176.611976,442.387 -OK177,07/13/2020 22:15,-38.233895,176.611976,442.387 -OK177,07/13/2020 22:16,-38.233895,176.611976,442.387 -OK178,07/13/2020 22:33,-38.228040,176.616384,387.498 -OK178,07/13/2020 22:34,-38.228040,176.616384,387.498 -OK178,07/13/2020 22:35,-38.228040,176.616384,387.498 -OK179,07/13/2020 22:49,-38.215902,176.616529,390.535 -OK179,07/13/2020 22:50,-38.215902,176.616529,390.535 -OK179,07/13/2020 22:51,-38.215902,176.616529,390.535 -OK177,07/13/2020 23:02,-38.233895,176.611976,442.387 -OK177,07/13/2020 23:03,-38.233895,176.611976,442.387 -OK177,07/13/2020 23:04,-38.233895,176.611976,442.387 -OK148,07/13/2020 23:11,-38.240404,176.606183,470.007 -OK148,07/13/2020 23:12,-38.240404,176.606183,470.007 -OK148,07/13/2020 23:13,-38.240404,176.606183,470.007 -OK180,07/13/2020 23:27,-38.234471,176.601010,448.107 -OK180,07/13/2020 23:28,-38.234471,176.601010,448.107 -OK180,07/13/2020 23:30,-38.234471,176.601010,448.107 -OK181,07/14/2020 00:15,-38.240445,176.587644,415.143 -OK181,07/14/2020 00:16,-38.240445,176.587644,415.143 -OK181,07/14/2020 00:17,-38.240445,176.587644,415.143 -OK146,07/14/2020 00:49,-38.264961,176.597951,489.019 -OK146,07/14/2020 00:50,-38.264961,176.597951,489.019 -OK146,07/14/2020 00:52,-38.264961,176.597951,489.019 -OK141A,07/14/2020 01:10,-38.212563,176.634155,366.801 -OK141A,07/14/2020 01:11,-38.212563,176.634155,366.801 -OK141A,07/14/2020 01:12,-38.212563,176.634155,366.801 -OK182,07/14/2020 01:46,-38.204861,176.603277,331.123 -OK182,07/14/2020 01:47,-38.204861,176.603277,331.123 -OK182,07/14/2020 01:48,-38.204861,176.603277,331.123 -OK183,07/14/2020 02:51,-38.045402,176.612645,400.326 -OK183,07/14/2020 02:52,-38.045402,176.612645,400.326 -OK183,07/14/2020 02:53,-38.045402,176.612645,400.326 -OK184,07/14/2020 03:01,-38.039413,176.619614,435.705 -OK184,07/14/2020 03:02,-38.039413,176.619614,435.705 -OK184,07/14/2020 03:03,-38.039413,176.619614,435.705 -OK184,07/14/2020 03:04,-38.039413,176.619614,435.705 -OK185,07/14/2020 03:15,-38.027859,176.622243,411.981 -OK185,07/14/2020 03:16,-38.027859,176.622243,411.981 -OK185,07/14/2020 03:17,-38.027859,176.622243,411.981 -OK186,07/14/2020 03:26,-38.017519,176.620095,381.278 -OK186,07/14/2020 03:27,-38.017519,176.620095,381.278 -OK186,07/14/2020 03:28,-38.017519,176.620095,381.278 -OK185,07/14/2020 03:40,-38.027859,176.622243,411.981 -OK185,07/14/2020 03:41,-38.027859,176.622243,411.981 -OK185,07/14/2020 03:42,-38.027859,176.622243,411.981 -OK187,07/14/2020 04:09,-38.032377,176.486226,308.838 -OK187,07/14/2020 04:10,-38.032377,176.486226,308.838 -OK187,07/14/2020 04:11,-38.032377,176.486226,308.838 -AGUP,07/14/2020 04:22,-38.054648,176.441513,284.462 -AGUP,07/14/2020 04:23,-38.054648,176.441513,284.462 -AGUP,07/14/2020 04:24,-38.054648,176.441513,284.462 -AGUP,07/14/2020 04:25,-38.054648,176.441513,284.462 -AGUP,08/03/2020 21:04,-38.054648,176.441513,284.462 -AGUP,08/03/2020 21:05,-38.054648,176.441513,284.462 -AGUP,08/03/2020 21:07,-38.054648,176.441513,284.462 -OK188,08/03/2020 21:39,-38.093211,176.358686,478.667 -OK188,08/03/2020 21:40,-38.093211,176.358686,478.667 -OK188,08/03/2020 21:41,-38.093211,176.358686,478.667 -OK189,08/03/2020 21:53,-38.095590,176.364162,479.764 -OK189,08/03/2020 21:55,-38.095590,176.364162,479.764 -OK189,08/03/2020 21:56,-38.095590,176.364162,479.764 -OK190,08/03/2020 22:19,-38.094084,176.378021,634.881 -OK190,08/03/2020 22:20,-38.094084,176.378021,634.881 -OK190,08/03/2020 22:21,-38.094084,176.378021,634.881 -OK191,08/03/2020 22:37,-38.099299,176.384629,706.346 -OK191,08/03/2020 22:39,-38.099299,176.384629,706.346 -OK191,08/03/2020 22:40,-38.099299,176.384629,706.346 -OK190,08/03/2020 22:50,-38.094084,176.378021,634.881 -OK190,08/03/2020 22:51,-38.094084,176.378021,634.881 -OK190,08/03/2020 22:52,-38.094084,176.378021,634.881 -OK188,08/03/2020 23:09,-38.093211,176.358686,478.667 -OK188,08/03/2020 23:10,-38.093211,176.358686,478.667 -OK188,08/03/2020 23:11,-38.093211,176.358686,478.667 -OK192,08/03/2020 23:31,-38.121561,176.323775,342.614 -OK192,08/03/2020 23:32,-38.121561,176.323775,342.614 -OK192,08/03/2020 23:33,-38.121561,176.323775,342.614 -OK193,08/03/2020 23:55,-38.142186,176.294049,332.718 -OK193,08/03/2020 23:57,-38.142186,176.294049,332.718 -OK193,08/03/2020 23:58,-38.142186,176.294049,332.718 -OK194,08/04/2020 01:37,-38.183641,176.356454,396.364 -OK194,08/04/2020 01:38,-38.183641,176.356454,396.364 -OK194,08/04/2020 01:39,-38.183641,176.356454,396.364 -OK195,08/04/2020 01:56,-38.185005,176.366806,529.801 -OK195,08/04/2020 01:57,-38.185005,176.366806,529.801 -OK195,08/04/2020 01:58,-38.185005,176.366806,529.801 -OK196,08/04/2020 02:13,-38.189933,176.362674,595.614 -OK196,08/04/2020 02:14,-38.189933,176.362674,595.614 -OK196,08/04/2020 02:15,-38.189933,176.362674,595.614 -OK197,08/04/2020 02:27,-38.195770,176.357778,644.529 -OK197,08/04/2020 02:29,-38.195770,176.357778,644.529 -OK197,08/04/2020 02:30,-38.195770,176.357778,644.529 -OK198,08/04/2020 02:47,-38.201981,176.354741,674.669 -OK198,08/04/2020 02:48,-38.201981,176.354741,674.669 -OK198,08/04/2020 02:49,-38.201981,176.354741,674.669 -OK197,08/04/2020 02:57,-38.195770,176.357778,644.529 -OK197,08/04/2020 02:58,-38.195770,176.357778,644.529 -OK197,08/04/2020 02:59,-38.195770,176.357778,644.529 -OK199,08/04/2020 03:28,-38.189724,176.372250,552.176 -OK199,08/04/2020 03:29,-38.189724,176.372250,552.176 -OK199,08/04/2020 03:30,-38.189724,176.372250,552.176 -OK200,08/04/2020 03:38,-38.195507,176.373097,554.431 -OK200,08/04/2020 03:39,-38.195507,176.373097,554.431 -OK194,08/04/2020 03:56,-38.183641,176.356454,396.364 -OK194,08/04/2020 03:57,-38.183641,176.356454,396.364 -OK194,08/04/2020 03:58,-38.183641,176.356454,396.364 -OK194,08/04/2020 03:59,-38.183641,176.356454,396.364 -AGUP,08/04/2020 04:36,-38.054648,176.441513,284.462 -AGUP,08/04/2020 04:37,-38.054648,176.441513,284.462 -AGUP,08/04/2020 04:38,-38.054648,176.441513,284.462 -AGUP,08/04/2020 04:39,-38.054648,176.441513,284.462 -AGUP,08/04/2020 20:21,-38.054648,176.441513,284.462 -AGUP,08/04/2020 20:22,-38.054648,176.441513,284.462 -AGUP,08/04/2020 20:23,-38.054648,176.441513,284.462 -OK192,08/04/2020 20:44,-38.121561,176.323775,342.614 -OK192,08/04/2020 20:45,-38.121561,176.323775,342.614 -OK192,08/04/2020 20:46,-38.121561,176.323775,342.614 -OK201,08/04/2020 21:03,-38.131740,176.326182,370.204 -OK201,08/04/2020 21:04,-38.131740,176.326182,370.204 -OK201,08/04/2020 21:05,-38.131740,176.326182,370.204 -OK202,08/04/2020 21:16,-38.133073,176.332289,418.035 -OK202,08/04/2020 21:17,-38.133073,176.332289,418.035 -OK202,08/04/2020 21:18,-38.133073,176.332289,418.035 -OK203,08/04/2020 21:27,-38.135381,176.339115,444.017 -OK203,08/04/2020 21:28,-38.135381,176.339115,444.017 -OK203,08/04/2020 21:29,-38.135381,176.339115,444.017 -OK204,08/04/2020 21:41,-38.138838,176.342339,516.432 -OK204,08/04/2020 21:42,-38.138838,176.342339,516.432 -OK204,08/04/2020 21:43,-38.138838,176.342339,516.432 -OK205,08/04/2020 21:53,-38.137376,176.347594,604.821 -OK205,08/04/2020 21:54,-38.137376,176.347594,604.821 -OK205,08/04/2020 21:55,-38.137376,176.347594,604.821 -OK206,08/04/2020 22:14,-38.143476,176.343121,562.832 -OK206,08/04/2020 22:16,-38.143476,176.343121,562.832 -OK206,08/04/2020 22:17,-38.143476,176.343121,562.832 -OK193,08/04/2020 22:46,-38.142186,176.294049,332.718 -OK193,08/04/2020 22:47,-38.142186,176.294049,332.718 -OK193,08/04/2020 22:48,-38.142186,176.294049,332.718 -OK207,08/05/2020 01:11,-38.146965,176.320984,429.110 -OK207,08/05/2020 01:12,-38.146965,176.320984,429.110 -OK207,08/05/2020 01:13,-38.146965,176.320984,429.110 -OK208,08/05/2020 01:25,-38.148213,176.328482,474.397 -OK208,08/05/2020 01:26,-38.148213,176.328482,474.397 -OK208,08/05/2020 01:28,-38.148213,176.328482,474.397 -OK209,08/05/2020 01:44,-38.144801,176.339130,531.496 -OK209,08/05/2020 01:45,-38.144801,176.339130,531.496 -OK209,08/05/2020 01:46,-38.144801,176.339130,531.496 -OK207,08/05/2020 01:59,-38.146965,176.320984,429.110 -OK207,08/05/2020 02:00,-38.146965,176.320984,429.110 -OK207,08/05/2020 02:01,-38.146965,176.320984,429.110 -OK210,08/05/2020 02:54,-38.009821,176.565920,355.129 -OK210,08/05/2020 02:55,-38.009821,176.565920,355.129 -OK210,08/05/2020 02:56,-38.009821,176.565920,355.129 -OK211,08/05/2020 03:16,-38.008722,176.598310,358.532 -OK211,08/05/2020 03:17,-38.008722,176.598310,358.532 -OK211,08/05/2020 03:18,-38.008722,176.598310,358.532 -OK212,08/05/2020 03:26,-38.002019,176.601507,345.520 -OK212,08/05/2020 03:27,-38.002019,176.601507,345.520 -OK212,08/05/2020 03:28,-38.002019,176.601507,345.520 -OK213,08/05/2020 03:38,-38.005984,176.624406,391.087 -OK213,08/05/2020 03:39,-38.005984,176.624406,391.087 -OK213,08/05/2020 03:40,-38.005984,176.624406,391.087 -AGUP,08/05/2020 04:12,-38.054648,176.441513,284.462 -AGUP,08/05/2020 04:13,-38.054648,176.441513,284.462 -AGUP,08/05/2020 04:14,-38.054648,176.441513,284.462 -AGUP,08/05/2020 20:27,-38.054648,176.441513,284.462 -AGUP,08/05/2020 20:28,-38.054648,176.441513,284.462 -AGUP,08/05/2020 20:29,-38.054648,176.441513,284.462 -AGUP,08/05/2020 20:30,-38.054648,176.441513,284.462 -OK214,08/05/2020 21:33,-38.254737,176.340638,620.728 -OK214,08/05/2020 21:34,-38.254737,176.340638,620.728 -OK214,08/05/2020 21:35,-38.254737,176.340638,620.728 -OK215,08/05/2020 21:47,-38.250738,176.340473,626.858 -OK215,08/05/2020 21:48,-38.250738,176.340473,626.858 -OK215,08/05/2020 21:49,-38.250738,176.340473,626.858 -OK216,08/05/2020 22:00,-38.257281,176.351303,607.274 -OK216,08/05/2020 22:01,-38.257281,176.351303,607.274 -OK216,08/05/2020 22:02,-38.257281,176.351303,607.274 -OK217,08/05/2020 22:13,-38.252441,176.358712,629.077 -OK217,08/05/2020 22:14,-38.252441,176.358712,629.077 -OK217,08/05/2020 22:15,-38.252441,176.358712,629.077 -OK218,08/05/2020 22:35,-38.245770,176.359060,616.591 -OK218,08/05/2020 22:36,-38.245770,176.359060,616.591 -OK218,08/05/2020 22:37,-38.245770,176.359060,616.591 -OK217,08/05/2020 22:46,-38.252441,176.358712,629.077 -OK217,08/05/2020 22:47,-38.252441,176.358712,629.077 -OK217,08/05/2020 22:48,-38.252441,176.358712,629.077 -OK219,08/05/2020 23:00,-38.251288,176.371234,604.630 -OK219,08/05/2020 23:01,-38.251288,176.371234,604.630 -OK219,08/05/2020 23:02,-38.251288,176.371234,604.630 -OK220,08/05/2020 23:17,-38.246592,176.382302,558.717 -OK220,08/05/2020 23:18,-38.246592,176.382302,558.717 -OK220,08/05/2020 23:19,-38.246592,176.382302,558.717 -OK221,08/05/2020 23:39,-38.257584,176.380017,390.101 -OK221,08/05/2020 23:40,-38.257584,176.380017,390.101 -OK221,08/05/2020 23:41,-38.257584,176.380017,390.101 -OK222,08/05/2020 23:54,-38.262789,176.374937,401.484 -OK222,08/05/2020 23:55,-38.262789,176.374937,401.484 -OK222,08/05/2020 23:56,-38.262789,176.374937,401.484 -OK223,08/06/2020 00:08,-38.271050,176.374644,454.465 -OK223,08/06/2020 00:09,-38.271050,176.374644,454.465 -OK223,08/06/2020 00:10,-38.271050,176.374644,454.465 -OK224,08/06/2020 00:24,-38.275782,176.372950,497.412 -OK224,08/06/2020 00:25,-38.275782,176.372950,497.412 -OK224,08/06/2020 00:26,-38.275782,176.372950,497.412 -OK221,08/06/2020 00:43,-38.257584,176.380017,390.101 -OK221,08/06/2020 00:44,-38.257584,176.380017,390.101 -OK221,08/06/2020 00:45,-38.257584,176.380017,390.101 -OK214,08/06/2020 01:00,-38.254737,176.340638,620.728 -OK214,08/06/2020 01:01,-38.254737,176.340638,620.728 -OK214,08/06/2020 01:02,-38.254737,176.340638,620.728 -OK193,08/06/2020 01:53,-38.142186,176.294049,332.718 -OK193,08/06/2020 01:54,-38.142186,176.294049,332.718 -OK193,08/06/2020 01:55,-38.142186,176.294049,332.718 -AGUP,08/06/2020 02:23,-38.054648,176.441513,284.462 -AGUP,08/06/2020 02:24,-38.054648,176.441513,284.462 -AGUP,08/06/2020 02:25,-38.054648,176.441513,284.462 +ACNN,03/16/2020 21:08,-38.512209,176.331926,297.958 +ACNN,03/16/2020 21:12,-38.512209,176.331926,297.958 +ACNN,03/16/2020 21:13,-38.512209,176.331926,297.958 +WP93,03/16/2020 22:29,-38.265116,176.564573,467.265 +WP93,03/16/2020 22:30,-38.265116,176.564573,467.265 +WP146,03/16/2020 22:44,-38.268071,176.572404,446.828 +WP146,03/16/2020 22:45,-38.268071,176.572404,446.828 +WP140,03/16/2020 22:56,-38.269557,176.577605,434.051 +WP140,03/16/2020 22:59,-38.269557,176.577605,434.051 +WP140,03/16/2020 23:00,-38.269557,176.577605,434.051 +WP143,03/16/2020 23:24,-38.275345,176.584047,479.006 +WP143,03/16/2020 23:25,-38.275345,176.584047,479.006 +WP143,03/16/2020 23:26,-38.275345,176.584047,479.006 +WP144,03/16/2020 23:55,-38.274621,176.568323,448.606 +WP144,03/16/2020 23:57,-38.274621,176.568323,448.606 +WP144,03/16/2020 23:58,-38.274621,176.568323,448.606 +WP93,03/17/2020 00:13,-38.265116,176.564573,467.265 +WP93,03/17/2020 00:14,-38.265116,176.564573,467.265 +WP98,03/17/2020 00:28,-38.256793,176.571165,457.455 +WP139,03/17/2020 01:04,-38.262333,176.556635,494.174 +WP139,03/17/2020 01:06,-38.262333,176.556635,494.174 +WP139,03/17/2020 01:07,-38.262333,176.556635,494.174 +WP138,03/17/2020 01:15,-38.255525,176.560111,495.930 +WP138,03/17/2020 01:18,-38.255525,176.560111,495.930 +WP138,03/17/2020 01:19,-38.255525,176.560111,495.930 +WP96,03/17/2020 02:16,-38.262988,176.543263,514.214 +WP96,03/17/2020 02:17,-38.262988,176.543263,514.214 +WP93,03/17/2020 02:36,-38.265116,176.564573,467.265 +WP93,03/17/2020 02:37,-38.265116,176.564573,467.265 +ACNN,03/17/2020 03:39,-38.512209,176.331926,297.958 +ACNN,03/17/2020 03:41,-38.512209,176.331926,297.958 +ACNN,03/17/2020 03:42,-38.512209,176.331926,297.958 +ACNN,03/17/2020 20:44,-38.512209,176.331926,297.958 +ACNN,03/17/2020 20:46,-38.512209,176.331926,297.958 +ACNN,03/17/2020 20:47,-38.512209,176.331926,297.958 +WP93,03/17/2020 21:40,-38.265116,176.564573,467.265 +WP93,03/17/2020 21:42,-38.265116,176.564573,467.265 +WP93,03/17/2020 21:43,-38.265116,176.564573,467.265 +WP148,03/17/2020 22:01,-38.290511,176.575760,471.560 +WP148,03/17/2020 22:06,-38.290511,176.575760,471.560 +WP148,03/17/2020 22:07,-38.290511,176.575760,471.560 +WP141,03/17/2020 22:28,-38.281541,176.576093,453.541 +WP141,03/17/2020 22:29,-38.281541,176.576093,453.541 +WP141,03/17/2020 22:30,-38.281541,176.576093,453.541 +WP142,03/17/2020 22:52,-38.281560,176.566694,474.395 +WP142,03/17/2020 22:53,-38.281560,176.566694,474.395 +WP142,03/17/2020 22:54,-38.281560,176.566694,474.395 +WP147,03/17/2020 23:14,-38.293007,176.555309,449.272 +WP147,03/17/2020 23:17,-38.293007,176.555309,449.272 +WP139,03/17/2020 23:39,-38.262333,176.556635,494.174 +WP139,03/17/2020 23:40,-38.262333,176.556635,494.174 +WP93,03/17/2020 23:52,-38.265116,176.564573,467.265 +WP93,03/17/2020 23:54,-38.265116,176.564573,467.265 +WP93,03/17/2020 23:55,-38.265116,176.564573,467.265 +WP99,03/18/2020 00:17,-38.269413,176.550480,475.842 +WP99,03/18/2020 00:20,-38.269413,176.550480,475.842 +WP136,03/18/2020 00:39,-38.274086,176.545530,473.901 +WP136,03/18/2020 00:44,-38.274086,176.545530,473.901 +WP95,03/18/2020 00:58,-38.272596,176.535114,486.335 +WP95,03/18/2020 01:03,-38.272596,176.535114,486.335 +WP95,03/18/2020 01:04,-38.272596,176.535114,486.335 +WP145,03/18/2020 01:43,-38.281429,176.543511,458.052 +WP145,03/18/2020 01:45,-38.281429,176.543511,458.052 +WP145,03/18/2020 01:46,-38.281429,176.543511,458.052 +WP93,03/18/2020 02:03,-38.265116,176.564573,467.265 +WP93,03/18/2020 02:07,-38.265116,176.564573,467.265 +WP93,03/18/2020 02:08,-38.265116,176.564573,467.265 +WP149,03/18/2020 02:26,-38.307750,176.558839,445.231 +WP149,03/18/2020 02:29,-38.307750,176.558839,445.231 +WP149,03/18/2020 02:30,-38.307750,176.558839,445.231 +ACNN,03/18/2020 03:10,-38.512209,176.331926,297.958 +ACNN,03/18/2020 03:15,-38.512209,176.331926,297.958 +AGUP,06/10/2020 23:48,-38.054648,176.441513,284.462 +AGUP,06/10/2020 23:50,-38.054648,176.441513,284.462 +OG32,06/11/2020 00:56,-38.122774,176.475586,820.424 +OG32,06/11/2020 00:57,-38.122774,176.475586,820.424 +OG36,06/11/2020 01:55,-38.138471,176.467108,926.489 +OG36,06/11/2020 01:57,-38.138471,176.467108,926.489 +OG37,06/11/2020 02:23,-38.138224,176.459507,854.027 +OG37,06/11/2020 02:24,-38.138224,176.459507,854.027 +OG38,06/11/2020 02:44,-38.134208,176.461352,851.227 +OG38,06/11/2020 02:45,-38.134208,176.461352,851.227 +OG34,06/11/2020 03:12,-38.131201,176.474881,800.569 +OG34,06/11/2020 03:13,-38.131201,176.474881,800.569 +OG34,06/11/2020 03:14,-38.131201,176.474881,800.569 +OG33,06/11/2020 03:32,-38.128162,176.479851,837.787 +OG33,06/11/2020 03:33,-38.128162,176.479851,837.787 +OG32,06/11/2020 03:43,-38.122774,176.475586,820.424 +OG32,06/11/2020 03:44,-38.122774,176.475586,820.424 +AGUP,06/11/2020 04:35,-38.054648,176.441513,284.462 +AGUP,06/11/2020 04:36,-38.054648,176.441513,284.462 +AGUP,06/11/2020 23:06,-38.054648,176.441513,284.462 +AGUP,06/11/2020 23:08,-38.054648,176.441513,284.462 +AGUP,06/11/2020 23:10,-38.054648,176.441513,284.462 +OG29,06/12/2020 00:36,-38.090789,176.456845,591.652 +OG29,06/12/2020 00:37,-38.090789,176.456845,591.652 +OG29,06/12/2020 00:38,-38.090789,176.456845,591.652 +OG16,06/12/2020 00:51,-38.096062,176.456555,620.377 +OG16,06/12/2020 00:53,-38.096062,176.456555,620.377 +OG16,06/12/2020 00:54,-38.096062,176.456555,620.377 +OG09,06/12/2020 01:05,-38.094752,176.447202,646.313 +OG09,06/12/2020 01:06,-38.094752,176.447202,646.313 +OG07,06/12/2020 01:21,-38.086364,176.446698,592.772 +OG05,06/12/2020 01:34,-38.083088,176.456330,545.289 +OG05,06/12/2020 01:35,-38.083088,176.456330,545.289 +OG05,06/12/2020 01:36,-38.083088,176.456330,545.289 +OG29,06/12/2020 01:52,-38.090789,176.456845,591.652 +OG29,06/12/2020 01:53,-38.090789,176.456845,591.652 +OG32,06/12/2020 02:32,-38.122774,176.475586,820.424 +OG32,06/12/2020 02:33,-38.122774,176.475586,820.424 +OG31,06/12/2020 02:45,-38.117953,176.479049,756.718 +OG31,06/12/2020 02:46,-38.117953,176.479049,756.718 +OG20,06/12/2020 03:03,-38.115873,176.472735,673.949 +OG20,06/12/2020 03:04,-38.115873,176.472735,673.949 +OG20,06/12/2020 03:05,-38.115873,176.472735,673.949 +OG28,06/12/2020 03:20,-38.105198,176.474171,662.676 +OG28,06/12/2020 03:21,-38.105198,176.474171,662.676 +OG27,06/12/2020 03:34,-38.099356,176.468858,628.158 +OG27,06/12/2020 03:35,-38.099356,176.468858,628.158 +OG27,06/12/2020 03:36,-38.099356,176.468858,628.158 +OG05,06/12/2020 03:54,-38.083088,176.456330,545.289 +OG05,06/12/2020 03:55,-38.083088,176.456330,545.289 +OG05,06/12/2020 03:56,-38.083088,176.456330,545.289 +AGUP,06/12/2020 04:16,-38.054648,176.441513,284.462 +AGUP,06/12/2020 04:18,-38.054648,176.441513,284.462 +AGUP,06/12/2020 04:19,-38.054648,176.441513,284.462 +AGUP,06/15/2020 20:18,-38.054648,176.441513,284.462 +AGUP,06/15/2020 20:20,-38.054648,176.441513,284.462 +AGUP,06/15/2020 20:21,-38.054648,176.441513,284.462 +AGUP,06/15/2020 20:22,-38.054648,176.441513,284.462 +OK100,06/15/2020 21:02,-38.085725,176.461508,571.934 +OK100,06/15/2020 21:03,-38.085725,176.461508,571.934 +OK100,06/15/2020 21:04,-38.085725,176.461508,571.934 +OK100,06/15/2020 21:05,-38.085725,176.461508,571.934 +OK101,06/15/2020 21:29,-38.095606,176.464133,611.804 +OK101,06/15/2020 21:30,-38.095606,176.464133,611.804 +OK101,06/15/2020 21:31,-38.095606,176.464133,611.804 +OK101,06/15/2020 21:32,-38.095606,176.464133,611.804 +OK103,06/15/2020 22:13,-38.126974,176.457878,817.623 +OK103,06/15/2020 22:14,-38.126974,176.457878,817.623 +OK103,06/15/2020 22:16,-38.126974,176.457878,817.623 +OK103,06/15/2020 22:17,-38.126974,176.457878,817.623 +OK102,06/15/2020 22:55,-38.116363,176.464753,653.245 +OK102,06/15/2020 22:56,-38.116363,176.464753,653.245 +OK102,06/15/2020 22:57,-38.116363,176.464753,653.245 +OK104,06/15/2020 23:08,-38.116836,176.459708,653.269 +OK104,06/15/2020 23:09,-38.116836,176.459708,653.269 +OK104,06/15/2020 23:10,-38.116836,176.459708,653.269 +OK105,06/15/2020 23:22,-38.113316,176.450891,624.164 +OK105,06/15/2020 23:23,-38.113316,176.450891,624.164 +OK105,06/15/2020 23:24,-38.113316,176.450891,624.164 +OK105,06/15/2020 23:25,-38.113316,176.450891,624.164 +OK106,06/15/2020 23:45,-38.109690,176.447081,595.380 +OK106,06/15/2020 23:46,-38.109690,176.447081,595.380 +OK106,06/15/2020 23:47,-38.109690,176.447081,595.380 +OK107,06/15/2020 23:59,-38.105259,176.443636,569.412 +OK107,06/16/2020 00:00,-38.105259,176.443636,569.412 +OK107,06/16/2020 00:01,-38.105259,176.443636,569.412 +OK101,06/16/2020 00:19,-38.095606,176.464133,611.804 +OK101,06/16/2020 00:20,-38.095606,176.464133,611.804 +OK101,06/16/2020 00:21,-38.095606,176.464133,611.804 +OK108,06/16/2020 00:35,-38.089592,176.462151,570.424 +OK108,06/16/2020 00:36,-38.089592,176.462151,570.424 +OK108,06/16/2020 00:37,-38.089592,176.462151,570.424 +OK100,06/16/2020 00:47,-38.085725,176.461508,571.934 +OK100,06/16/2020 00:48,-38.085725,176.461508,571.934 +OK100,06/16/2020 00:49,-38.085725,176.461508,571.934 +OK109,06/16/2020 01:01,-38.090300,176.473812,574.586 +OK109,06/16/2020 01:02,-38.090300,176.473812,574.586 +OK109,06/16/2020 01:03,-38.090300,176.473812,574.586 +OK110,06/16/2020 01:27,-38.089956,176.509779,724.067 +OK110,06/16/2020 01:28,-38.089956,176.509779,724.067 +OK110,06/16/2020 01:29,-38.089956,176.509779,724.067 +OK111,06/16/2020 01:44,-38.092895,176.507268,766.928 +OK111,06/16/2020 01:45,-38.092895,176.507268,766.928 +OK111,06/16/2020 01:46,-38.092895,176.507268,766.928 +OK112,06/16/2020 01:57,-38.098088,176.503781,745.889 +OK112,06/16/2020 01:58,-38.098088,176.503781,745.889 +OK112,06/16/2020 01:59,-38.098088,176.503781,745.889 +OK113,06/16/2020 02:10,-38.101380,176.501816,699.390 +OK113,06/16/2020 02:11,-38.101380,176.501816,699.390 +OK113,06/16/2020 02:12,-38.101380,176.501816,699.390 +OK110,06/16/2020 02:33,-38.089956,176.509779,724.067 +OK110,06/16/2020 02:34,-38.089956,176.509779,724.067 +OK110,06/16/2020 02:35,-38.089956,176.509779,724.067 +OK110,06/16/2020 02:36,-38.089956,176.509779,724.067 +OK114,06/16/2020 02:49,-38.095670,176.514649,676.003 +OK114,06/16/2020 02:51,-38.095670,176.514649,676.003 +OK114,06/16/2020 02:52,-38.095670,176.514649,676.003 +OK100,06/16/2020 03:17,-38.085725,176.461508,571.934 +OK100,06/16/2020 03:18,-38.085725,176.461508,571.934 +OK100,06/16/2020 03:19,-38.085725,176.461508,571.934 +OK115,06/16/2020 03:48,-38.072775,176.445752,531.606 +OK115,06/16/2020 03:49,-38.072775,176.445752,531.606 +OK115,06/16/2020 03:50,-38.072775,176.445752,531.606 +AGUP,06/16/2020 04:13,-38.054648,176.441513,284.462 +AGUP,06/16/2020 04:14,-38.054648,176.441513,284.462 +AGUP,06/16/2020 04:15,-38.054648,176.441513,284.462 +AGUP,06/16/2020 04:16,-38.054648,176.441513,284.462 +AGUP,06/16/2020 20:24,-38.054648,176.441513,284.462 +AGUP,06/16/2020 20:25,-38.054648,176.441513,284.462 +AGUP,06/16/2020 20:26,-38.054648,176.441513,284.462 +AGUP,06/16/2020 20:27,-38.054648,176.441513,284.462 +AGUP,06/16/2020 20:28,-38.054648,176.441513,284.462 +OK116,06/16/2020 20:47,-38.058756,176.439179,358.501 +OK116,06/16/2020 20:48,-38.058756,176.439179,358.501 +OK116,06/16/2020 20:49,-38.058756,176.439179,358.501 +OK117,06/16/2020 21:03,-38.068929,176.437052,483.316 +OK117,06/16/2020 21:04,-38.068929,176.437052,483.316 +OK117,06/16/2020 21:05,-38.068929,176.437052,483.316 +OK118,06/16/2020 21:16,-38.073657,176.441712,522.573 +OK118,06/16/2020 21:17,-38.073657,176.441712,522.573 +OK118,06/16/2020 21:18,-38.073657,176.441712,522.573 +OK115,06/16/2020 21:24,-38.072775,176.445752,531.606 +OK115,06/16/2020 21:26,-38.072775,176.445752,531.606 +OK115,06/16/2020 21:27,-38.072775,176.445752,531.606 +OK120,06/16/2020 21:58,-38.082193,176.443110,557.141 +OK120,06/16/2020 21:59,-38.082193,176.443110,557.141 +OK120,06/16/2020 22:00,-38.082193,176.443110,557.141 +OK121,06/16/2020 22:22,-38.081916,176.450346,560.335 +OK121,06/16/2020 22:23,-38.081916,176.450346,560.335 +OK121,06/16/2020 22:24,-38.081916,176.450346,560.335 +OK121,06/16/2020 22:25,-38.081916,176.450346,560.335 +OK100,06/16/2020 22:59,-38.085725,176.461508,571.934 +OK100,06/16/2020 23:00,-38.085725,176.461508,571.934 +OK100,06/16/2020 23:01,-38.085725,176.461508,571.934 +OK122,06/16/2020 23:31,-38.145088,176.547568,138.257 +OK122,06/16/2020 23:32,-38.145088,176.547568,138.257 +OK122,06/16/2020 23:33,-38.145088,176.547568,138.257 +OK123,06/16/2020 23:48,-38.147439,176.529044,151.811 +OK123,06/16/2020 23:49,-38.147439,176.529044,151.811 +OK123,06/16/2020 23:50,-38.147439,176.529044,151.811 +OK124,06/16/2020 23:58,-38.152082,176.523221,165.996 +OK124,06/16/2020 23:59,-38.152082,176.523221,165.996 +OK124,06/17/2020 00:00,-38.152082,176.523221,165.996 +OK125,06/17/2020 00:32,-38.161871,176.556924,269.597 +OK125,06/17/2020 00:33,-38.161871,176.556924,269.597 +OK125,06/17/2020 00:34,-38.161871,176.556924,269.597 +OK126,06/17/2020 00:48,-38.159109,176.567787,275.636 +OK126,06/17/2020 00:49,-38.159109,176.567787,275.636 +OK126,06/17/2020 00:50,-38.159109,176.567787,275.636 +OK127,06/17/2020 01:11,-38.164775,176.539095,328.887 +OK127,06/17/2020 01:12,-38.164775,176.539095,328.887 +OK127,06/17/2020 01:13,-38.164775,176.539095,328.887 +OK128,06/17/2020 01:28,-38.171419,176.550971,321.940 +OK128,06/17/2020 01:29,-38.171419,176.550971,321.940 +OK128,06/17/2020 01:30,-38.171419,176.550971,321.940 +OK129,06/17/2020 01:43,-38.178758,176.546944,324.494 +OK129,06/17/2020 01:44,-38.178758,176.546944,324.494 +OK129,06/17/2020 01:45,-38.178758,176.546944,324.494 +OK130,06/17/2020 01:56,-38.188041,176.536996,315.136 +OK130,06/17/2020 01:58,-38.188041,176.536996,315.136 +OK130,06/17/2020 01:59,-38.188041,176.536996,315.136 +OK131,06/17/2020 02:14,-38.174561,176.533057,325.182 +OK131,06/17/2020 02:15,-38.174561,176.533057,325.182 +OK131,06/17/2020 02:16,-38.174561,176.533057,325.182 +OK100,06/17/2020 02:50,-38.085725,176.461508,571.934 +OK100,06/17/2020 02:51,-38.085725,176.461508,571.934 +OK100,06/17/2020 02:52,-38.085725,176.461508,571.934 +OK100,06/17/2020 02:53,-38.085725,176.461508,571.934 +OK116,06/17/2020 03:16,-38.058756,176.439179,358.501 +OK116,06/17/2020 03:17,-38.058756,176.439179,358.501 +OK116,06/17/2020 03:18,-38.058756,176.439179,358.501 +AGUP,06/17/2020 03:27,-38.054648,176.441513,284.462 +AGUP,06/17/2020 03:28,-38.054648,176.441513,284.462 +AGUP,06/17/2020 03:29,-38.054648,176.441513,284.462 +AGUP,06/17/2020 03:30,-38.054648,176.441513,284.462 +AGUP,06/23/2020 23:09,-38.054648,176.441513,284.462 +AGUP,06/23/2020 23:10,-38.054648,176.441513,284.462 +OK133,06/24/2020 00:19,-38.181733,176.529888,358.585 +OK133,06/24/2020 00:20,-38.181733,176.529888,358.585 +OK134,06/24/2020 00:40,-38.187150,176.516708,383.824 +OK134,06/24/2020 00:41,-38.187150,176.516708,383.824 +OK134,06/24/2020 00:42,-38.187150,176.516708,383.824 +OK135,06/24/2020 00:58,-38.193711,176.518258,417.043 +OK135,06/24/2020 00:59,-38.193711,176.518258,417.043 +OK136,06/24/2020 01:13,-38.190659,176.512660,394.510 +OK136,06/24/2020 01:14,-38.190659,176.512660,394.510 +OK133,06/24/2020 01:40,-38.181733,176.529888,358.585 +OK133,06/24/2020 01:41,-38.181733,176.529888,358.585 +OK137,06/24/2020 02:04,-38.201600,176.556378,400.296 +OK137,06/24/2020 02:05,-38.201600,176.556378,400.296 +OK138,06/24/2020 02:31,-38.215092,176.559455,536.408 +OK138,06/24/2020 02:32,-38.215092,176.559455,536.408 +OK139,06/24/2020 02:48,-38.219739,176.556725,517.360 +OK139,06/24/2020 02:49,-38.219739,176.556725,517.360 +OK140,06/24/2020 03:05,-38.211466,176.553502,444.138 +OK140,06/24/2020 03:06,-38.211466,176.553502,444.138 +OK141,06/24/2020 03:16,-38.206190,176.559453,402.706 +OK141,06/24/2020 03:17,-38.206190,176.559453,402.706 +OK137,06/24/2020 03:26,-38.201600,176.556378,400.296 +OK137,06/24/2020 03:27,-38.201600,176.556378,400.296 +AGUP,06/24/2020 04:55,-38.054648,176.441513,284.462 +AGUP,06/24/2020 04:56,-38.054648,176.441513,284.462 +AGUP,07/01/2020 20:28,-38.054648,176.441513,284.462 +AGUP,07/01/2020 20:29,-38.054648,176.441513,284.462 +AGUP,07/01/2020 20:30,-38.054648,176.441513,284.462 +AGUP,07/01/2020 20:31,-38.054648,176.441513,284.462 +OK138A,07/01/2020 21:45,-38.195393,176.603737,193.810 +OK138A,07/01/2020 21:46,-38.195393,176.603737,193.810 +OK138A,07/01/2020 21:47,-38.195393,176.603737,193.810 +OK139A,07/01/2020 21:58,-38.192269,176.612474,190.458 +OK139A,07/01/2020 21:59,-38.192269,176.612474,190.458 +OK139A,07/01/2020 22:00,-38.192269,176.612474,190.458 +OK140A,07/01/2020 22:24,-38.188830,176.618648,215.986 +OK140A,07/01/2020 22:25,-38.188830,176.618648,215.986 +OK140A,07/01/2020 22:26,-38.188830,176.618648,215.986 +OK141A,07/01/2020 23:01,-38.212563,176.634155,366.801 +OK141A,07/01/2020 23:02,-38.212563,176.634155,366.801 +OK141A,07/01/2020 23:03,-38.212563,176.634155,366.801 +OK141A,07/01/2020 23:04,-38.212563,176.634155,366.801 +OK142,07/01/2020 23:29,-38.230168,176.632750,423.289 +OK142,07/01/2020 23:30,-38.230168,176.632750,423.289 +OK142,07/01/2020 23:31,-38.230168,176.632750,423.289 +OK143,07/01/2020 23:43,-38.239846,176.624572,409.859 +OK143,07/01/2020 23:45,-38.239846,176.624572,409.859 +OK143,07/01/2020 23:46,-38.239846,176.624572,409.859 +OK144,07/01/2020 23:58,-38.246316,176.618187,453.636 +OK144,07/01/2020 23:59,-38.246316,176.618187,453.636 +OK144,07/02/2020 00:00,-38.246316,176.618187,453.636 +OK145,07/02/2020 00:12,-38.251962,176.613961,445.032 +OK145,07/02/2020 00:13,-38.251962,176.613961,445.032 +OK145,07/02/2020 00:14,-38.251962,176.613961,445.032 +OK146,07/02/2020 00:30,-38.264961,176.597951,489.019 +OK146,07/02/2020 00:31,-38.264961,176.597951,489.019 +OK146,07/02/2020 00:32,-38.264961,176.597951,489.019 +OK146,07/02/2020 00:34,-38.264961,176.597951,489.019 +OK147,07/02/2020 01:14,-38.246345,176.596586,478.170 +OK147,07/02/2020 01:15,-38.246345,176.596586,478.170 +OK147,07/02/2020 01:16,-38.246345,176.596586,478.170 +OK148,07/02/2020 01:32,-38.240404,176.606183,470.007 +OK148,07/02/2020 01:33,-38.240404,176.606183,470.007 +OK148,07/02/2020 01:34,-38.240404,176.606183,470.007 +OK146,07/02/2020 01:49,-38.264961,176.597951,489.019 +OK146,07/02/2020 01:50,-38.264961,176.597951,489.019 +OK146,07/02/2020 01:51,-38.264961,176.597951,489.019 +OK144,07/02/2020 02:02,-38.246316,176.618187,453.636 +OK144,07/02/2020 02:03,-38.246316,176.618187,453.636 +OK144,07/02/2020 02:04,-38.246316,176.618187,453.636 +OK141A,07/02/2020 02:21,-38.212563,176.634155,366.801 +OK141A,07/02/2020 02:22,-38.212563,176.634155,366.801 +OK141A,07/02/2020 02:23,-38.212563,176.634155,366.801 +OK149,07/02/2020 02:35,-38.208633,176.625981,348.487 +OK149,07/02/2020 02:36,-38.208633,176.625981,348.487 +OK149,07/02/2020 02:37,-38.208633,176.625981,348.487 +OK150,07/02/2020 02:49,-38.202049,176.625910,308.349 +OK150,07/02/2020 02:50,-38.202049,176.625910,308.349 +OK150,07/02/2020 02:51,-38.202049,176.625910,308.349 +OK151,07/02/2020 03:07,-38.196244,176.614920,199.383 +OK151,07/02/2020 03:08,-38.196244,176.614920,199.383 +OK151,07/02/2020 03:09,-38.196244,176.614920,199.383 +OK139A,07/02/2020 03:15,-38.192269,176.612474,190.458 +OK139A,07/02/2020 03:16,-38.192269,176.612474,190.458 +OK139A,07/02/2020 03:17,-38.192269,176.612474,190.458 +OK100,07/02/2020 03:53,-38.085725,176.461508,571.934 +OK100,07/02/2020 03:54,-38.085725,176.461508,571.934 +OK100,07/02/2020 03:55,-38.085725,176.461508,571.934 +AGUP,07/02/2020 04:11,-38.054648,176.441513,284.462 +AGUP,07/02/2020 04:12,-38.054648,176.441513,284.462 +AGUP,07/02/2020 04:14,-38.054648,176.441513,284.462 +AGUP,07/02/2020 04:16,-38.054648,176.441513,284.462 +AGUP,07/02/2020 04:17,-38.054648,176.441513,284.462 +AGUP,07/09/2020 22:00,-38.054648,176.441513,284.462 +AGUP,07/09/2020 22:01,-38.054648,176.441513,284.462 +AGUP,07/09/2020 22:02,-38.054648,176.441513,284.462 +OK137,07/09/2020 22:53,-38.201600,176.556378,400.296 +OK137,07/09/2020 22:54,-38.201600,176.556378,400.296 +OK137,07/09/2020 22:55,-38.201600,176.556378,400.296 +OK171,07/09/2020 23:31,-38.210813,176.577778,417.779 +OK171,07/09/2020 23:32,-38.210813,176.577778,417.779 +OK171,07/09/2020 23:33,-38.210813,176.577778,417.779 +OK172,07/10/2020 00:25,-38.198771,176.564368,380.106 +OK172,07/10/2020 00:26,-38.198771,176.564368,380.106 +OK172,07/10/2020 00:27,-38.198771,176.564368,380.106 +OK137,07/10/2020 00:38,-38.201600,176.556378,400.296 +OK137,07/10/2020 00:39,-38.201600,176.556378,400.296 +OK137,07/10/2020 00:40,-38.201600,176.556378,400.296 +OK174,07/10/2020 01:11,-38.195509,176.585421,317.670 +OK174,07/10/2020 01:12,-38.195509,176.585421,317.670 +OK174,07/10/2020 01:13,-38.195509,176.585421,317.670 +OK176,07/10/2020 01:34,-38.195406,176.601072,211.301 +OK176,07/10/2020 01:35,-38.195406,176.601072,211.301 +OK176,07/10/2020 01:36,-38.195406,176.601072,211.301 +OK172,07/10/2020 01:56,-38.198771,176.564368,380.106 +OK172,07/10/2020 01:57,-38.198771,176.564368,380.106 +OK172,07/10/2020 01:58,-38.198771,176.564368,380.106 +AGUP,07/10/2020 02:56,-38.054648,176.441513,284.462 +AGUP,07/10/2020 02:57,-38.054648,176.441513,284.462 +AGUP,07/10/2020 02:58,-38.054648,176.441513,284.462 +AGUP,07/13/2020 20:28,-38.054648,176.441513,284.462 +AGUP,07/13/2020 20:29,-38.054648,176.441513,284.462 +AGUP,07/13/2020 20:30,-38.054648,176.441513,284.462 +AGUP,07/13/2020 20:31,-38.054648,176.441513,284.462 +OK138A,07/13/2020 21:18,-38.195393,176.603737,193.810 +OK138A,07/13/2020 21:19,-38.195393,176.603737,193.810 +OK138A,07/13/2020 21:20,-38.195393,176.603737,193.810 +OK177,07/13/2020 22:13,-38.233895,176.611976,442.387 +OK177,07/13/2020 22:15,-38.233895,176.611976,442.387 +OK177,07/13/2020 22:16,-38.233895,176.611976,442.387 +OK178,07/13/2020 22:33,-38.228040,176.616384,387.498 +OK178,07/13/2020 22:34,-38.228040,176.616384,387.498 +OK178,07/13/2020 22:35,-38.228040,176.616384,387.498 +OK179,07/13/2020 22:49,-38.215902,176.616529,390.535 +OK179,07/13/2020 22:50,-38.215902,176.616529,390.535 +OK179,07/13/2020 22:51,-38.215902,176.616529,390.535 +OK177,07/13/2020 23:02,-38.233895,176.611976,442.387 +OK177,07/13/2020 23:03,-38.233895,176.611976,442.387 +OK177,07/13/2020 23:04,-38.233895,176.611976,442.387 +OK148,07/13/2020 23:11,-38.240404,176.606183,470.007 +OK148,07/13/2020 23:12,-38.240404,176.606183,470.007 +OK148,07/13/2020 23:13,-38.240404,176.606183,470.007 +OK180,07/13/2020 23:27,-38.234471,176.601010,448.107 +OK180,07/13/2020 23:28,-38.234471,176.601010,448.107 +OK180,07/13/2020 23:30,-38.234471,176.601010,448.107 +OK181,07/14/2020 00:15,-38.240445,176.587644,415.143 +OK181,07/14/2020 00:16,-38.240445,176.587644,415.143 +OK181,07/14/2020 00:17,-38.240445,176.587644,415.143 +OK146,07/14/2020 00:49,-38.264961,176.597951,489.019 +OK146,07/14/2020 00:50,-38.264961,176.597951,489.019 +OK146,07/14/2020 00:52,-38.264961,176.597951,489.019 +OK141A,07/14/2020 01:10,-38.212563,176.634155,366.801 +OK141A,07/14/2020 01:11,-38.212563,176.634155,366.801 +OK141A,07/14/2020 01:12,-38.212563,176.634155,366.801 +OK182,07/14/2020 01:46,-38.204861,176.603277,331.123 +OK182,07/14/2020 01:47,-38.204861,176.603277,331.123 +OK182,07/14/2020 01:48,-38.204861,176.603277,331.123 +OK183,07/14/2020 02:51,-38.045402,176.612645,400.326 +OK183,07/14/2020 02:52,-38.045402,176.612645,400.326 +OK183,07/14/2020 02:53,-38.045402,176.612645,400.326 +OK184,07/14/2020 03:01,-38.039413,176.619614,435.705 +OK184,07/14/2020 03:02,-38.039413,176.619614,435.705 +OK184,07/14/2020 03:03,-38.039413,176.619614,435.705 +OK184,07/14/2020 03:04,-38.039413,176.619614,435.705 +OK185,07/14/2020 03:15,-38.027859,176.622243,411.981 +OK185,07/14/2020 03:16,-38.027859,176.622243,411.981 +OK185,07/14/2020 03:17,-38.027859,176.622243,411.981 +OK186,07/14/2020 03:26,-38.017519,176.620095,381.278 +OK186,07/14/2020 03:27,-38.017519,176.620095,381.278 +OK186,07/14/2020 03:28,-38.017519,176.620095,381.278 +OK185,07/14/2020 03:40,-38.027859,176.622243,411.981 +OK185,07/14/2020 03:41,-38.027859,176.622243,411.981 +OK185,07/14/2020 03:42,-38.027859,176.622243,411.981 +OK187,07/14/2020 04:09,-38.032377,176.486226,308.838 +OK187,07/14/2020 04:10,-38.032377,176.486226,308.838 +OK187,07/14/2020 04:11,-38.032377,176.486226,308.838 +AGUP,07/14/2020 04:22,-38.054648,176.441513,284.462 +AGUP,07/14/2020 04:23,-38.054648,176.441513,284.462 +AGUP,07/14/2020 04:24,-38.054648,176.441513,284.462 +AGUP,07/14/2020 04:25,-38.054648,176.441513,284.462 +AGUP,08/03/2020 21:04,-38.054648,176.441513,284.462 +AGUP,08/03/2020 21:05,-38.054648,176.441513,284.462 +AGUP,08/03/2020 21:07,-38.054648,176.441513,284.462 +OK188,08/03/2020 21:39,-38.093211,176.358686,478.667 +OK188,08/03/2020 21:40,-38.093211,176.358686,478.667 +OK188,08/03/2020 21:41,-38.093211,176.358686,478.667 +OK189,08/03/2020 21:53,-38.095590,176.364162,479.764 +OK189,08/03/2020 21:55,-38.095590,176.364162,479.764 +OK189,08/03/2020 21:56,-38.095590,176.364162,479.764 +OK190,08/03/2020 22:19,-38.094084,176.378021,634.881 +OK190,08/03/2020 22:20,-38.094084,176.378021,634.881 +OK190,08/03/2020 22:21,-38.094084,176.378021,634.881 +OK191,08/03/2020 22:37,-38.099299,176.384629,706.346 +OK191,08/03/2020 22:39,-38.099299,176.384629,706.346 +OK191,08/03/2020 22:40,-38.099299,176.384629,706.346 +OK190,08/03/2020 22:50,-38.094084,176.378021,634.881 +OK190,08/03/2020 22:51,-38.094084,176.378021,634.881 +OK190,08/03/2020 22:52,-38.094084,176.378021,634.881 +OK188,08/03/2020 23:09,-38.093211,176.358686,478.667 +OK188,08/03/2020 23:10,-38.093211,176.358686,478.667 +OK188,08/03/2020 23:11,-38.093211,176.358686,478.667 +OK192,08/03/2020 23:31,-38.121561,176.323775,342.614 +OK192,08/03/2020 23:32,-38.121561,176.323775,342.614 +OK192,08/03/2020 23:33,-38.121561,176.323775,342.614 +OK193,08/03/2020 23:55,-38.142186,176.294049,332.718 +OK193,08/03/2020 23:57,-38.142186,176.294049,332.718 +OK193,08/03/2020 23:58,-38.142186,176.294049,332.718 +OK194,08/04/2020 01:37,-38.183641,176.356454,396.364 +OK194,08/04/2020 01:38,-38.183641,176.356454,396.364 +OK194,08/04/2020 01:39,-38.183641,176.356454,396.364 +OK195,08/04/2020 01:56,-38.185005,176.366806,529.801 +OK195,08/04/2020 01:57,-38.185005,176.366806,529.801 +OK195,08/04/2020 01:58,-38.185005,176.366806,529.801 +OK196,08/04/2020 02:13,-38.189933,176.362674,595.614 +OK196,08/04/2020 02:14,-38.189933,176.362674,595.614 +OK196,08/04/2020 02:15,-38.189933,176.362674,595.614 +OK197,08/04/2020 02:27,-38.195770,176.357778,644.529 +OK197,08/04/2020 02:29,-38.195770,176.357778,644.529 +OK197,08/04/2020 02:30,-38.195770,176.357778,644.529 +OK198,08/04/2020 02:47,-38.201981,176.354741,674.669 +OK198,08/04/2020 02:48,-38.201981,176.354741,674.669 +OK198,08/04/2020 02:49,-38.201981,176.354741,674.669 +OK197,08/04/2020 02:57,-38.195770,176.357778,644.529 +OK197,08/04/2020 02:58,-38.195770,176.357778,644.529 +OK197,08/04/2020 02:59,-38.195770,176.357778,644.529 +OK199,08/04/2020 03:28,-38.189724,176.372250,552.176 +OK199,08/04/2020 03:29,-38.189724,176.372250,552.176 +OK199,08/04/2020 03:30,-38.189724,176.372250,552.176 +OK200,08/04/2020 03:38,-38.195507,176.373097,554.431 +OK200,08/04/2020 03:39,-38.195507,176.373097,554.431 +OK194,08/04/2020 03:56,-38.183641,176.356454,396.364 +OK194,08/04/2020 03:57,-38.183641,176.356454,396.364 +OK194,08/04/2020 03:58,-38.183641,176.356454,396.364 +OK194,08/04/2020 03:59,-38.183641,176.356454,396.364 +AGUP,08/04/2020 04:36,-38.054648,176.441513,284.462 +AGUP,08/04/2020 04:37,-38.054648,176.441513,284.462 +AGUP,08/04/2020 04:38,-38.054648,176.441513,284.462 +AGUP,08/04/2020 04:39,-38.054648,176.441513,284.462 +AGUP,08/04/2020 20:21,-38.054648,176.441513,284.462 +AGUP,08/04/2020 20:22,-38.054648,176.441513,284.462 +AGUP,08/04/2020 20:23,-38.054648,176.441513,284.462 +OK192,08/04/2020 20:44,-38.121561,176.323775,342.614 +OK192,08/04/2020 20:45,-38.121561,176.323775,342.614 +OK192,08/04/2020 20:46,-38.121561,176.323775,342.614 +OK201,08/04/2020 21:03,-38.131740,176.326182,370.204 +OK201,08/04/2020 21:04,-38.131740,176.326182,370.204 +OK201,08/04/2020 21:05,-38.131740,176.326182,370.204 +OK202,08/04/2020 21:16,-38.133073,176.332289,418.035 +OK202,08/04/2020 21:17,-38.133073,176.332289,418.035 +OK202,08/04/2020 21:18,-38.133073,176.332289,418.035 +OK203,08/04/2020 21:27,-38.135381,176.339115,444.017 +OK203,08/04/2020 21:28,-38.135381,176.339115,444.017 +OK203,08/04/2020 21:29,-38.135381,176.339115,444.017 +OK204,08/04/2020 21:41,-38.138838,176.342339,516.432 +OK204,08/04/2020 21:42,-38.138838,176.342339,516.432 +OK204,08/04/2020 21:43,-38.138838,176.342339,516.432 +OK205,08/04/2020 21:53,-38.137376,176.347594,604.821 +OK205,08/04/2020 21:54,-38.137376,176.347594,604.821 +OK205,08/04/2020 21:55,-38.137376,176.347594,604.821 +OK206,08/04/2020 22:14,-38.143476,176.343121,562.832 +OK206,08/04/2020 22:16,-38.143476,176.343121,562.832 +OK206,08/04/2020 22:17,-38.143476,176.343121,562.832 +OK193,08/04/2020 22:46,-38.142186,176.294049,332.718 +OK193,08/04/2020 22:47,-38.142186,176.294049,332.718 +OK193,08/04/2020 22:48,-38.142186,176.294049,332.718 +OK207,08/05/2020 01:11,-38.146965,176.320984,429.110 +OK207,08/05/2020 01:12,-38.146965,176.320984,429.110 +OK207,08/05/2020 01:13,-38.146965,176.320984,429.110 +OK208,08/05/2020 01:25,-38.148213,176.328482,474.397 +OK208,08/05/2020 01:26,-38.148213,176.328482,474.397 +OK208,08/05/2020 01:28,-38.148213,176.328482,474.397 +OK209,08/05/2020 01:44,-38.144801,176.339130,531.496 +OK209,08/05/2020 01:45,-38.144801,176.339130,531.496 +OK209,08/05/2020 01:46,-38.144801,176.339130,531.496 +OK207,08/05/2020 01:59,-38.146965,176.320984,429.110 +OK207,08/05/2020 02:00,-38.146965,176.320984,429.110 +OK207,08/05/2020 02:01,-38.146965,176.320984,429.110 +OK210,08/05/2020 02:54,-38.009821,176.565920,355.129 +OK210,08/05/2020 02:55,-38.009821,176.565920,355.129 +OK210,08/05/2020 02:56,-38.009821,176.565920,355.129 +OK211,08/05/2020 03:16,-38.008722,176.598310,358.532 +OK211,08/05/2020 03:17,-38.008722,176.598310,358.532 +OK211,08/05/2020 03:18,-38.008722,176.598310,358.532 +OK212,08/05/2020 03:26,-38.002019,176.601507,345.520 +OK212,08/05/2020 03:27,-38.002019,176.601507,345.520 +OK212,08/05/2020 03:28,-38.002019,176.601507,345.520 +OK213,08/05/2020 03:38,-38.005984,176.624406,391.087 +OK213,08/05/2020 03:39,-38.005984,176.624406,391.087 +OK213,08/05/2020 03:40,-38.005984,176.624406,391.087 +AGUP,08/05/2020 04:12,-38.054648,176.441513,284.462 +AGUP,08/05/2020 04:13,-38.054648,176.441513,284.462 +AGUP,08/05/2020 04:14,-38.054648,176.441513,284.462 +AGUP,08/05/2020 20:27,-38.054648,176.441513,284.462 +AGUP,08/05/2020 20:28,-38.054648,176.441513,284.462 +AGUP,08/05/2020 20:29,-38.054648,176.441513,284.462 +AGUP,08/05/2020 20:30,-38.054648,176.441513,284.462 +OK214,08/05/2020 21:33,-38.254737,176.340638,620.728 +OK214,08/05/2020 21:34,-38.254737,176.340638,620.728 +OK214,08/05/2020 21:35,-38.254737,176.340638,620.728 +OK215,08/05/2020 21:47,-38.250738,176.340473,626.858 +OK215,08/05/2020 21:48,-38.250738,176.340473,626.858 +OK215,08/05/2020 21:49,-38.250738,176.340473,626.858 +OK216,08/05/2020 22:00,-38.257281,176.351303,607.274 +OK216,08/05/2020 22:01,-38.257281,176.351303,607.274 +OK216,08/05/2020 22:02,-38.257281,176.351303,607.274 +OK217,08/05/2020 22:13,-38.252441,176.358712,629.077 +OK217,08/05/2020 22:14,-38.252441,176.358712,629.077 +OK217,08/05/2020 22:15,-38.252441,176.358712,629.077 +OK218,08/05/2020 22:35,-38.245770,176.359060,616.591 +OK218,08/05/2020 22:36,-38.245770,176.359060,616.591 +OK218,08/05/2020 22:37,-38.245770,176.359060,616.591 +OK217,08/05/2020 22:46,-38.252441,176.358712,629.077 +OK217,08/05/2020 22:47,-38.252441,176.358712,629.077 +OK217,08/05/2020 22:48,-38.252441,176.358712,629.077 +OK219,08/05/2020 23:00,-38.251288,176.371234,604.630 +OK219,08/05/2020 23:01,-38.251288,176.371234,604.630 +OK219,08/05/2020 23:02,-38.251288,176.371234,604.630 +OK220,08/05/2020 23:17,-38.246592,176.382302,558.717 +OK220,08/05/2020 23:18,-38.246592,176.382302,558.717 +OK220,08/05/2020 23:19,-38.246592,176.382302,558.717 +OK221,08/05/2020 23:39,-38.257584,176.380017,390.101 +OK221,08/05/2020 23:40,-38.257584,176.380017,390.101 +OK221,08/05/2020 23:41,-38.257584,176.380017,390.101 +OK222,08/05/2020 23:54,-38.262789,176.374937,401.484 +OK222,08/05/2020 23:55,-38.262789,176.374937,401.484 +OK222,08/05/2020 23:56,-38.262789,176.374937,401.484 +OK223,08/06/2020 00:08,-38.271050,176.374644,454.465 +OK223,08/06/2020 00:09,-38.271050,176.374644,454.465 +OK223,08/06/2020 00:10,-38.271050,176.374644,454.465 +OK224,08/06/2020 00:24,-38.275782,176.372950,497.412 +OK224,08/06/2020 00:25,-38.275782,176.372950,497.412 +OK224,08/06/2020 00:26,-38.275782,176.372950,497.412 +OK221,08/06/2020 00:43,-38.257584,176.380017,390.101 +OK221,08/06/2020 00:44,-38.257584,176.380017,390.101 +OK221,08/06/2020 00:45,-38.257584,176.380017,390.101 +OK214,08/06/2020 01:00,-38.254737,176.340638,620.728 +OK214,08/06/2020 01:01,-38.254737,176.340638,620.728 +OK214,08/06/2020 01:02,-38.254737,176.340638,620.728 +OK193,08/06/2020 01:53,-38.142186,176.294049,332.718 +OK193,08/06/2020 01:54,-38.142186,176.294049,332.718 +OK193,08/06/2020 01:55,-38.142186,176.294049,332.718 +AGUP,08/06/2020 02:23,-38.054648,176.441513,284.462 +AGUP,08/06/2020 02:24,-38.054648,176.441513,284.462 +AGUP,08/06/2020 02:25,-38.054648,176.441513,284.462 diff --git a/project-words.txt b/project-words.txt index a006a95..8d58f98 100644 --- a/project-words.txt +++ b/project-words.txt @@ -1,5 +1,6 @@ addopts afactor +aimport airgap Aleksandr alisonk diff --git a/pyproject.toml b/pyproject.toml index 2e2682f..4cee5db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,7 @@ dev = [ "burocrata>=0.3.0", "ipykernel>=7.2.0", "ipywidgets>=8.1.8", + "marimo>=0.25.0", "pandas-stubs==2.3.3.260113", "pandas-vet>=2023.8.2", "pyrefly>=1.3.1", diff --git a/src/gsolve/core/data.py b/src/gsolve/core/data.py index 6a8ef39..f3f04f3 100644 --- a/src/gsolve/core/data.py +++ b/src/gsolve/core/data.py @@ -21,7 +21,6 @@ import abc import copy import dataclasses -import warnings from collections.abc import Callable from copy import deepcopy from types import MappingProxyType @@ -42,6 +41,7 @@ write_excel_worksheet, ) from gsolve.core.utils import ( + GSolveUserWarning, merge_datetime_columns, normalize_field_names, prepare_writable_df, @@ -104,7 +104,9 @@ class DataFieldSpecification: DataFieldSpecification("absolute_gravity", float, default=np.nan), ] # TODO: make this a class? -COMMON_FIELDS: dict[str, DataFieldSpecification] = {f.name: f for f in _COMMON_FIELDS} +COMMON_FIELDS: MappingProxyType[str, DataFieldSpecification] = MappingProxyType( + {f.name: f for f in _COMMON_FIELDS} +) @dataclasses.dataclass @@ -503,18 +505,19 @@ def set_column( def _data_ok(self, warn: bool = True) -> bool: """Test whether data are complete according to specifications in ``obj._known_fields``.""" - rval = True + all_ok = True + warner = GSolveUserWarning() for f in self.required_fields(): if f not in self.data.columns: if warn: - warnings.warn(f"Missing required field: '{f}'") - rval = False + warner.warn(f"Missing required field: '{f}'") + all_ok = False if self.data[f].isna().any() or self.data[f].eq("").any(): if warn: - warnings.warn(f"Required field has empty records: '{f}'") - rval = False + warner.warn(f"Required field has empty records: '{f}'") + all_ok = False - return rval + return all_ok @classmethod def from_dataframe( diff --git a/src/gsolve/core/utils.py b/src/gsolve/core/utils.py index f7898c5..2e19823 100644 --- a/src/gsolve/core/utils.py +++ b/src/gsolve/core/utils.py @@ -22,7 +22,9 @@ import itertools import sys +import warnings from collections.abc import Sequence +from pathlib import Path from typing import Any, Literal, TypeAliasType, get_args, get_origin, overload import numpy as np @@ -49,6 +51,7 @@ __all__ = [ "DEFAULT_TIMESTAMP_COLUMNS", "GSolveDataWarning", + "GSolveUserWarning", "check_duplicate_index", "columns_to_timestamp", "expand_datetime_column", @@ -926,7 +929,7 @@ def _display(self, msg: str) -> None: def print_msgs(self) -> None: """Print all stored warning messages.""" for msg in self.messages: - print(f"{self.prefix}: {msg}") # ruff: ignore[print] + print(f"{self.prefix}: {msg}", file=sys.stderr) # ruff: ignore[print] def final_msg(self) -> None: """Print closing summary message.""" @@ -1158,3 +1161,71 @@ def convert_single_timestamp_arg( raise TypeError(msg) return t_ + + +class GSolveUserWarning: + """Simple class to make python warnings friendlier. + + For cases where the issue is with the user's code or data. + + - Ensures that a warning's trace points to the users code. + - Maintains a count and cache of warnings issued + + + Parameters + ---------- + prefix : str, optional + Prepend prefix to all messages. + default_category : Warning, default is UserWarning + The category to assign warnings. + """ + + prefix: str | None + default_category: Warning | None + _count: int + skip_file_prefixes: tuple[str, ...] + _messages: list[str] + + def __init__( + self, prefix: str | None = None, default_category: Warning = UserWarning + ): + self.prefix = prefix + self._count = 0 + self.default_category = default_category + self.skip_file_prefixes = (str(Path(__file__).parents[1]),) + self._messages = [] + + def warn( + self, message: str, show_prefix: bool = True, category: Warning | None = None + ): + """ + Issue a python warning for user errors. + + Parameters + ---------- + message : str + The warning message to issue. + show_prefix : bool, default True + Prepend message with the ``default_prefix`` set at initialisation. + category : Warning | None, optional + If specified, use ``category`` for the warning category, otherwise use + the category specified at initialisation (default=UserWarning). + """ + if not self.prefix is None and show_prefix: + msg = f"{self.prefix} {message}" + else: + msg = f"{message}" + + if category is None: + category = self.default_category + + warnings.warn( + message=msg, category=category, skip_file_prefixes=self.skip_file_prefixes + ) + self._count += 1 + self._messages.append([msg, category]) + + @property + def count(self) -> int: + """The number of warnings issued by this object.""" + return self._count diff --git a/src/gsolve/gsolve_algorithms.py b/src/gsolve/gsolve_algorithms.py index 60ee014..25efbfc 100644 --- a/src/gsolve/gsolve_algorithms.py +++ b/src/gsolve/gsolve_algorithms.py @@ -23,10 +23,12 @@ import pandas as pd from gsolve.core._typing import GSolveSolverMethod, GSolveSolverReturn +from gsolve.core.utils import GSolveUserWarning from gsolve.gsolve_outputs import GSolveResults __all__ = ["GSolveSolverMethod", "call_gsolve_calibration", "call_gsolve_lstsq"] + _GSOLVE_SOLVER_METHODS: dict[int, str] = { 1: "Unconstrained least squares", 2: "Partially constrained least squares", @@ -34,6 +36,10 @@ } +class GSolveSolverWarning(UserWarning): + """Raised when gsolve may produce unreliable results.""" + + def call_gsolve_lstsq( obs: pd.DataFrame, ref_sites: pd.DataFrame, @@ -387,13 +393,20 @@ def g_solver_lstsq( # ruff: ignore[too-many-positional-arguments] residuals = b - np.dot(A, solution[:n_parameters]) # Define percentile clipping interval + # TODO: Should this be done using residual**2 and clip upper only? perc = (100.0 - percentile_clipping) / 2 ci_l = np.percentile(residuals[:n_obs], perc) ci_h = np.percentile(residuals[:n_obs], 100.0 - perc) # Build mask of outliers mask = ((residuals[:n_obs] > ci_l) & (residuals[:n_obs] < ci_h)).flatten() - + _check_post_clip_data_are_ok( + mask=mask, + obs_site_id=obs_site_id, + ties_site_id=ties_site_id, + obs_loop=obs_loop, + use_loops=use_loops, + ) # Mask outliers A[:n_obs, :][~mask] = 0 b[:n_obs, :][~mask] = 0 @@ -446,3 +459,80 @@ def g_solver_lstsq( # ruff: ignore[too-many-positional-arguments] calibration_factor = None return gravity, residuals, gravity_var, drift, baseline, calibration_factor, mask + + +def _check_post_clip_data_are_ok( + mask: np.ndarray[tuple[int]], + obs_site_id: np.ndarray[tuple[int]], + ties_site_id: np.ndarray[tuple[int]], + obs_loop: np.ndarray[tuple[int]], + use_loops: bool, +) -> bool: + """Check if percentile clipping does damage.""" + warner = GSolveUserWarning( + prefix="After percentile clipping:", default_category=GSolveSolverWarning + ) + obs_site_id_remain = obs_site_id[mask] + obs_loop_remain = obs_loop[mask] + + # warn about site removal + if len(dropped_sites := np.setdiff1d(obs_site_id, obs_site_id_remain)) > 0: + warner.warn(f"sites were completely removed: {dropped_sites}") + + # ensure all tie sites made it + dropped_ties = np.intersect1d(ties_site_id, obs_site_id_remain) + if len(dropped_ties) == 0: + msg = ( + "All reference sites were completely removed due to " + f"percentile clipping: {dropped_ties}" + ) + raise ValueError(msg) + + if len(dropped_ties) < len(ties_site_id): + warner.warn( + f"{len(dropped_ties)} of {len(ties_site_id)} reference sites " + f"were completely: {dropped_ties})" + ) + + # if using loops and there was actually more than 1 loop + # - check that loops were not completely removed + # - check that loops have common stations or include a ref site + + # if use_loops and have > 1 loops, then check_loops + check_loops = use_loops and not (obs_loop[0] == obs_loop).all() + if check_loops: + if len(dropped_loops := np.setdiff1d(obs_loop, obs_loop_remain)) > 0: + warner.warn(f"some loops were completely removed: {dropped_loops}") + + # check if loops are now isolated from rest of survey + for loop_id in np.unique(obs_loop_remain): + m_pre = obs_loop == loop_id + m_post = obs_loop_remain == loop_id + + in_other_loops_pre = np.intersect1d(obs_site_id[m_pre], obs_site_id[~m_pre]) + in_other_loops_pre = len(in_other_loops_pre) > 0 + in_other_loops_post = np.intersect1d( + obs_site_id_remain[m_post], obs_site_id_remain[~m_post] + ) + in_other_loops_post = len(in_other_loops_post) > 0 + + has_ref_gravity_pre = np.isin(ties_site_id, obs_site_id[m_pre]).any() + has_ref_gravity_post = np.isin( + ties_site_id, obs_site_id_remain[m_post] + ).any() + + isolated_loop_pre = not in_other_loops_pre and not has_ref_gravity_pre + isolated_loop_post = not in_other_loops_post and not has_ref_gravity_post + + if isolated_loop_pre: + # Already isolated so, nothing will have changed + continue + if isolated_loop_post: + warner.warn( + f"loop '{loop_id}' has no sites in common with the rest of survey" + ) + + if has_ref_gravity_pre and not has_ref_gravity_post: + warner.warn(f"all reference sites removed from loop '{loop_id}'") + + return warner.count == 0 diff --git a/src/gsolve/gsolve_outputs.py b/src/gsolve/gsolve_outputs.py index 02ef1cd..31276ca 100644 --- a/src/gsolve/gsolve_outputs.py +++ b/src/gsolve/gsolve_outputs.py @@ -233,6 +233,7 @@ def plot_residual_cdf( unit: _PlotGravityUnit = "mGal", filename: FilePath | None = None, show: bool = True, + ax: plt.Axes | None = None, ) -> plt.Axes: """ Plot the empirical cumulative density function of residuals. @@ -250,6 +251,8 @@ def plot_residual_cdf( to the end of the filename (before suffix). show: bool, default True Show the plot in a new window. + ax : matplotlib.axes.Axes, optional + Plot data to ``ax`` if specified, otherwise instantiate a new Axes object. Returns ------- @@ -257,6 +260,15 @@ def plot_residual_cdf( The plot axes instance. """ + if ax is None: + fig = plt.figure() + ax = fig.add_subplot(111) + elif isinstance(ax, plt.Axes): + fig = ax.get_figure() + else: + msg = f"invalid type for ax: {type(ax).__name__}" + raise TypeError(msg) + m = self.obs_solution.active.eq(True) & self.obs_solution.residual.notna() df = self.obs_solution.loc[m].copy() @@ -296,8 +308,6 @@ def plot_residual_cdf( raise ValueError(msg) df = df.loc[df["loop"].isin(loops)] - fig = plt.figure() - ax = fig.add_subplot(111) for l, loop_df in df.groupby("loop"): residuals = loop_df["residual"].to_numpy() @@ -352,13 +362,15 @@ def calibration_factor(self) -> float: """Convenience property to access the calculated calibration factor.""" return float(np.asarray(self.params.calculated_calibration_factor).item()) - def plot_residual_drift( + def plot_residual_drift( # ruff: ignore[too-many-positional-arguments] self, loop: str | float, plot_drift: bool = True, unit: _PlotGravityUnit = "mGal", filename: FilePath | None = None, show: bool = True, + ax: plt.Axes | None = None, + **kwargs, ) -> plt.Axes: """ Plot the residuals and drift curve. @@ -370,20 +382,36 @@ def plot_residual_drift( plot_drift : bool, default True If True, plot the drift curve along with the residuals + drift. If False, plot only the residuals as stem plot. - unit: {'uGal', 'mGal'}, default 'mGal' + unit : {'uGal', 'mGal'}, default 'mGal' If 'uGal', plot residuals in microGal's. If 'mGal', plot residuals in milliGal's. - filename: str, default None + filename : str, default None If not None, save plot to ``filename``. The specified loop id is appended to the end of the filename (before suffix). - show: bool, default True + show : bool, default True Show the plot in a new window. + ax : matplotlib.axes.Axes, optional + Plot data to ``ax`` if specified, otherwise instantiate a new Axes object. + **kwargs : + Options to pass to the underlying matplotlib method. + + - ``plt.scatter`` if ``plot_drift=True`` + - ``plt.stem`` otherwise Returns ------- matplotlib.axes.Axes The plot axes instance. """ + if ax is None: + fig = plt.figure() + ax = fig.add_subplot(111) + elif isinstance(ax, plt.Axes): + fig = ax.get_figure() + else: + msg = f"invalid type for ax: {type(ax).__name__}" + raise TypeError(msg) + loop = str(loop) x_col: str = "timedelta" y_col: str = "residual" @@ -412,18 +440,19 @@ def plot_residual_drift( x = df[x_col].to_numpy() y = df[y_col].to_numpy() - fig = plt.figure() - ax = fig.add_subplot(111) - if plot_drift: drift_y = drift * x y += drift_y - ax.scatter(x, y, marker=".", label="residuals") + _ = kwargs.setdefault("label", "residuals") + _ = kwargs.setdefault("marker", ".") + + ax.scatter(x, y, **kwargs) ax.plot( x, drift_y, c="orange", label=f"drift curve ({drift:{precision}} {unit_label}/hr)", + **kwargs, ) ax.set_ylabel(f"{y_col} + drift ({unit_label})") ax.set_title( @@ -432,7 +461,9 @@ def plot_residual_drift( f"Percentile clipping = {self.params.percentile_clipping:.1f}" ) else: - ax.stem(x, y, label="residuals", markerfmt=".") + _ = kwargs.setdefault("label", "residuals") + _ = kwargs.setdefault("markerfmt", ".") + ax.stem(x, y, **kwargs) ax.set_ylabel(f"{y_col} ({unit_label})") ax.legend(loc="best") diff --git a/src/gsolve/observations.py b/src/gsolve/observations.py index 67e700b..44910cb 100644 --- a/src/gsolve/observations.py +++ b/src/gsolve/observations.py @@ -49,6 +49,7 @@ from gsolve.core.excel_io import write_excel_worksheet from gsolve.core.utils import ( GSolveDataWarning, + GSolveUserWarning, is_list_like, prepare_writable_df, to_naive_utc_datetime, @@ -347,10 +348,11 @@ def __init__( self.data.loc[:, ["meter_reading", "meter_reading_mgal"]].isna().all(axis=1) ) if has_nan_readings.any(): - _warnings.warn( + GSolveUserWarning().warn( "neither 'meter_reading' or 'meter_reading_mgal' present for " "1 or more records" ) + _ = self._data_ok(warn=True) self.set_timedelta_unit(timedelta_unit, set_tdelta=False) self.set_fixed_time_datum(fixed_time_datum, set_tdelta=False) @@ -481,10 +483,12 @@ def set_obs_id( if duplicated_obs_id == "error": msg_0 = f"{msg}" raise ValueError(msg_0) + + warner = GSolveUserWarning() if duplicated_obs_id == "keep": - _warnings.warn(f"keeping {msg}") + warner.warn(f"keeping {msg}") elif duplicated_obs_id == "rename": - _warnings.warn(f"renaming {msg}") + warner.warn(f"renaming {msg}") new_idx = self._index_deduplicator(new_idx) self.data = self.data.set_index(new_idx) @@ -1530,6 +1534,7 @@ def merge( The new GravityObservations object. """ + warner = GSolveUserWarning() if not isinstance(other, type(self)): msg = ( f"invalid type for other: " @@ -1569,15 +1574,15 @@ def merge( raise ValueError(msg) if if_duplicate_loops == "keep": - _warnings.warn(f"keeping {msg}") + warner.warn(f"keeping {msg}") elif if_duplicate_loops == "drop": - _warnings.warn(f"dropping {msg}") + warner.warn(f"dropping {msg}") m = ~other.data["loop"].isin(duplicated_loops) other.data = other.data.loc[m, :] elif if_duplicate_loops == "rename": - _warnings.warn(f"{msg}: adding suffix '{rename_suffix}' to loop id's") + warner.warn(f"{msg}: adding suffix '{rename_suffix}' to loop id's") for l in duplicated_loops: m = other.data["loop"].eq(l) other.data.loc[m, "loop"] += f"_{rename_suffix}" @@ -1592,11 +1597,11 @@ def merge( raise ValueError(msg) if if_duplicate_obs_ids == "drop": - _warnings.warn(f"dropping {msg}") + warner.warn(f"dropping {msg}") other.data = other.data.loc[~is_duplicated_obs_id, :] elif if_duplicate_obs_ids == "rename": - _warnings.warn(f"adding suffix '{rename_suffix}' to {msg}") + warner.warn(f"adding suffix '{rename_suffix}' to {msg}") rename_dict = { i: f"{i}_{rename_suffix}" for i in other.data.index[is_duplicated_obs_id] @@ -1604,7 +1609,7 @@ def merge( other.data = other.data.rename(index=rename_dict) if if_duplicate_obs_ids == "regenerate": - _warnings.warn(f"{msg}: will regenerate 'obs_id for all data") + warner.warn(f"{msg}: will regenerate 'obs_id for all data") # defer regeneration until after concat regen_obs_ids = True diff --git a/src/gsolve/reductions/terrain_corrections.py b/src/gsolve/reductions/terrain_corrections.py index e748bb5..90ca672 100644 --- a/src/gsolve/reductions/terrain_corrections.py +++ b/src/gsolve/reductions/terrain_corrections.py @@ -45,6 +45,7 @@ from gsolve.core.data import DataFieldSpecification, GSolveParameters, GSolveTable from gsolve.core.excel_io import read_excel_worksheet, write_excel_worksheet from gsolve.core.utils import ( + GSolveUserWarning, is_filepath_like, is_in_literal, is_list_like, @@ -548,11 +549,7 @@ def _sanity_check(self, if_errors: Literal["warn", "error"] = "error") -> None: an exception. If ``'warn'``, issue a warning and continue checking. """ throw_error: bool = if_errors == "error" - # error_count: int = 0 - - def warn_(m: str) -> None: - warnings.warn(m, category=UserWarning) - # error_count += 1 + warner = GSolveUserWarning() if ( np.isnan(self.min_dist) @@ -567,7 +564,7 @@ def warn_(m: str) -> None: ) if throw_error: raise ValueError(msg) - warn_(msg) + warner.warn(msg) # check distance msk type is valid if not is_in_literal(self.distance_mask_type, TCorrDistanceMaskType): @@ -577,7 +574,7 @@ def warn_(m: str) -> None: ) if throw_error: raise ValueError(msg) - warn_(msg) + warner.warn(msg) # check dem_source if not _is_dataarray(self.dem_source) and not is_filepath_like(self.dem_source): @@ -587,21 +584,21 @@ def warn_(m: str) -> None: ) if throw_error: raise ValueError(msg) - warn_(msg) + warner.warn(msg) if _is_dataarray(self.dem_source): if not self.dem_source.tcorr.is_valid_dem: msg = "invalid dem_source DataArray: must be a 2D array of floats" if throw_error: raise ValueError(msg) - warn_(msg) + warner.warn(msg) elif is_filepath_like(self.dem_source): if not self.dem_source: msg = "invalid dem_source file-path like" if throw_error: raise ValueError(msg) - warn_(msg) + warner.warn(msg) else: msg = ( f"invalid dem_source: must be an xarray.DataArray or file-path like" @@ -609,7 +606,7 @@ def warn_(m: str) -> None: ) if throw_error: raise ValueError(msg) - warn_(msg) + warner.warn(msg) # check density_dataset_source if _is_dataarray(self.density_dataset_source): @@ -620,7 +617,7 @@ def warn_(m: str) -> None: ) if throw_error: raise ValueError(msg) - warn_(msg) + warner.warn(msg) elif is_filepath_like(self.density_dataset_source): if not self.density_dataset_source: @@ -928,7 +925,7 @@ def compute( ) else: x, y = None, None - warnings.warn( + GSolveUserWarning().warn( "TerrainCorrector parameters specify variable easting " "and/or northing fields. Easting and Northing will not be " "written to TerrainCorrectionData output." @@ -1746,17 +1743,18 @@ def get_corrections( err_msg = ( f"no terrain correction data found for {len(site_id_missing)} of " - f"{len(site_id_idx)} site_id's " + f"{len(site_id_idx)} site_id's" ) + warner = GSolveUserWarning(prefix=err_msg + ", ") if if_missing == "raise": raise ValueError(err_msg) if if_missing == "drop": - warnings.warn(f"{err_msg}, dropping from output") + warnings.warn("dropping from output") return tcorrs.loc[site_id_found, cols] - warnings.warn(f"{err_msg}, filling with {fill_value}") + warner.warn(f"filling with {fill_value}") rval = tcorrs.loc[site_id_found, cols].copy() rval_fill = pd.DataFrame(index=site_id_missing, columns=cols, data=fill_value) return pd.concat([rval, rval_fill]).loc[site_id_idx] diff --git a/src/gsolve/scintrex.py b/src/gsolve/scintrex.py index a13fa78..e613da8 100644 --- a/src/gsolve/scintrex.py +++ b/src/gsolve/scintrex.py @@ -19,7 +19,6 @@ import abc import copy import pathlib -import warnings from collections.abc import Callable, Mapping, Sequence from types import MappingProxyType from typing import Literal, Self @@ -35,6 +34,7 @@ TimedeltaScalar, ) from gsolve.core.utils import ( + GSolveUserWarning, generate_loop_intervals, generate_loop_names, is_datetime_array, @@ -305,8 +305,9 @@ def _set_data(self, data: pd.DataFrame, on_error: str = "raise") -> None: raise TypeError(msg) from err_cant_replace else: if on_error == "warn": - msg = f"bad data encountered in column '{c}', setting to nan" - warnings.warn(msg) + GSolveUserWarning().warn( + f"bad data encountered in column '{c}', setting to nan" + ) if ( "datetime" not in df.columns @@ -412,7 +413,7 @@ def from_file( metadata_units[k] = u if not file_id_found: - warnings.warn( + GSolveUserWarning().warn( f"Expected file type identifier '{cls._file_id_header}'" f"not found in file {cg6_file}." ) diff --git a/src/gsolve/tide/earth_tide.py b/src/gsolve/tide/earth_tide.py index a15f4ce..656f731 100644 --- a/src/gsolve/tide/earth_tide.py +++ b/src/gsolve/tide/earth_tide.py @@ -40,6 +40,7 @@ ) from gsolve.core.utils import ( GSolveDataWarning, + GSolveUserWarning, convert_single_timestamp_arg, dms2rad, to_1d_ndarray, @@ -755,7 +756,7 @@ def sort_and_validate(self, gap_threshold: float | None = None) -> None: .to_numpy() ) if gaps.any(): - warnings.warn( + GSolveUserWarning().warn( message=( f"some frequency {gaps.sum()} intervals separated by" f"greater than {gap_threshold} " @@ -1261,8 +1262,8 @@ def tidal_correction( # of date_time for this site t0 = (date_time[site_mask].min() - pd.Timedelta(hours=1)).normalize() - # TODO: need to break this up into multiple calls to time_series if the - # duration is too long for pygtide to handle + # TODO: need to break this up into multiple calls to time_series + # if the duration is too long for pygtide to handle # e.g. sites visited days/weeks/years apart -> lots of work for nowt duration_hrs = ( int(np.ceil((date_time[site_mask].max() - t0).total_seconds() / 3600.0)) diff --git a/src/gsolve/tide/ocean_load.py b/src/gsolve/tide/ocean_load.py index 6b0d072..b22d90d 100644 --- a/src/gsolve/tide/ocean_load.py +++ b/src/gsolve/tide/ocean_load.py @@ -18,7 +18,6 @@ """Methods and classes for reading and applying ocean load corrections to gravity data.""" -import warnings from pathlib import Path from typing import Any, Literal, Protocol, runtime_checkable @@ -34,7 +33,7 @@ FloatArray, SiteIDArray, ) -from gsolve.core.utils import to_1d_ndarray, to_naive_utc_datetime +from gsolve.core.utils import GSolveUserWarning, to_1d_ndarray, to_naive_utc_datetime def _read_csv_with_fallback(file_path: FilePath, **kwargs) -> pd.DataFrame: @@ -213,7 +212,7 @@ def ocean_load_correction( ) if if_not_matched == "error": raise ValueError(msg) - warnings.warn(msg, UserWarning) + GSolveUserWarning().warn(msg) if any(present_mask): rval.loc[present_mask] = self.data.loc[ @@ -359,7 +358,7 @@ class since it provides corrections for a single station. f"({self.starttime} <-> {self.endtime})" ) if if_not_matched == "warn": - warnings.warn(msg, UserWarning) + GSolveUserWarning().warn(msg) else: raise ValueError(msg) @@ -418,7 +417,7 @@ def _validate_timeseries_data(df: pd.DataFrame) -> None: # warn if non-uniform sampling interval/rate sample_intervals = (df.index[1:] - df.index[:-1]).total_seconds() if not np.allclose(sample_intervals[1:], sample_intervals[1]): - warnings.warn("timeseries has non-uniform sampling interval/rate.", UserWarning) + GSolveUserWarning().warn("timeseries has non-uniform sampling interval/rate.") def qtp_to_corrector( @@ -766,7 +765,7 @@ def ocean_load_correction( ) if if_not_matched == "error": raise ValueError(msg) - warnings.warn(msg, UserWarning) + GSolveUserWarning().warn(msg) uniq_site_id = [s for s in uniq_site_id if s not in bad_site_ids] # set up the computers for each station diff --git a/tests/test_gsolve_algorithms.py b/tests/test_gsolve_algorithms.py index af44802..3bdb290 100644 --- a/tests/test_gsolve_algorithms.py +++ b/tests/test_gsolve_algorithms.py @@ -25,6 +25,8 @@ import pytest from gsolve.gsolve_algorithms import ( + GSolveSolverWarning, + _check_post_clip_data_are_ok, call_gsolve_calibration, call_gsolve_lstsq, g_solver_lstsq, @@ -355,3 +357,176 @@ def test_percentile_clipping_robust_geometry_has_finite_outputs(self) -> None: assert np.sum(~mask) >= 1 assert np.all(np.isfinite(gravity)) assert np.all(np.isfinite(gravity_var)) + + +class TestCheckPostClipDataAreOk: + """Tests for the post-clipping sanity checker `_check_post_clip_data_are_ok`. + + Inputs are plain numpy arrays. The `mask` selects observations retained + after percentile clipping; the checker warns (via `GSolveSolverWarning`) + or raises when clipping degrades the network geometry. + """ + + def test_clean_data_returns_true_without_warnings(self) -> None: + """Nothing dropped: returns True and issues no warnings.""" + obs_site_id = np.array(["A", "B", "A", "B"]) + obs_loop = np.array(["L1", "L1", "L1", "L1"]) + ties_site_id = np.array(["A"]) + mask = np.array([True, True, True, True]) + + with warnings.catch_warnings(): + warnings.simplefilter("error", GSolveSolverWarning) + result = _check_post_clip_data_are_ok( + mask=mask, + obs_site_id=obs_site_id, + ties_site_id=ties_site_id, + obs_loop=obs_loop, + use_loops=False, + ) + + assert result is True + + def test_dropped_site_warns_and_returns_false(self) -> None: + """A site fully removed by the mask warns and returns False.""" + obs_site_id = np.array(["A", "B", "C", "A", "B"]) + obs_loop = np.array(["L1", "L1", "L1", "L1", "L1"]) + ties_site_id = np.array(["A"]) + # every observation of site "C" is clipped + mask = np.array([True, True, False, True, True]) + + with pytest.warns(GSolveSolverWarning, match="sites were completely removed"): + result = _check_post_clip_data_are_ok( + mask=mask, + obs_site_id=obs_site_id, + ties_site_id=ties_site_id, + obs_loop=obs_loop, + use_loops=False, + ) + + assert result is False + + def test_all_ties_removed_raises_value_error(self) -> None: + """Removing every reference/tie site raises ValueError.""" + obs_site_id = np.array(["A", "B", "A", "B"]) + obs_loop = np.array(["L1", "L1", "L1", "L1"]) + ties_site_id = np.array(["A"]) + # all observations of tie site "A" are clipped + mask = np.array([False, True, False, True]) + + with pytest.raises(ValueError, match="All reference sites were completely"): + _check_post_clip_data_are_ok( + mask=mask, + obs_site_id=obs_site_id, + ties_site_id=ties_site_id, + obs_loop=obs_loop, + use_loops=False, + ) + + def test_some_ties_removed_warns_and_returns_false(self) -> None: + """Removing some (but not all) tie sites warns and returns False.""" + obs_site_id = np.array(["A", "B", "C", "A", "B", "C"]) + obs_loop = np.array(["L1", "L1", "L1", "L1", "L1", "L1"]) + ties_site_id = np.array(["A", "B"]) + # tie site "B" is fully clipped, tie site "A" survives + mask = np.array([True, False, True, True, False, True]) + + with pytest.warns(GSolveSolverWarning, match="reference sites were completely"): + result = _check_post_clip_data_are_ok( + mask=mask, + obs_site_id=obs_site_id, + ties_site_id=ties_site_id, + obs_loop=obs_loop, + use_loops=False, + ) + + assert result is False + + def test_dropped_loop_warns_and_returns_false(self) -> None: + """With use_loops and >1 loop, a fully removed loop warns.""" + obs_site_id = np.array(["A", "B", "A", "B", "A", "B"]) + obs_loop = np.array(["L1", "L1", "L2", "L2", "L3", "L3"]) + ties_site_id = np.array(["A", "B"]) + # loop "L3" is entirely clipped while two loops remain + mask = np.array([True, True, True, True, False, False]) + + with pytest.warns( + GSolveSolverWarning, match="some loops were completely removed" + ): + result = _check_post_clip_data_are_ok( + mask=mask, + obs_site_id=obs_site_id, + ties_site_id=ties_site_id, + obs_loop=obs_loop, + use_loops=True, + ) + + assert result is False + + def test_loop_loses_common_sites_warns_and_returns_false(self) -> None: + """A surviving loop stripped of its reference anchor warns. + + When a connected loop loses its only reference site after clipping + (while still sharing a site with the rest of the survey), the checker + emits the "no sites in common" warning. In the current implementation + this is coupled with the reference-removal warning below. + """ + # L1 = {A, B, C}, L2 = {A, B, D}; the only tie site "A" is in both loops. + obs_site_id = np.array(["A", "B", "C", "A", "B", "D"]) + obs_loop = np.array(["L1", "L1", "L1", "L2", "L2", "L2"]) + ties_site_id = np.array(["A"]) + # Clip tie "A" from L2 only; "A" survives globally via L1. + mask = np.array([True, True, True, False, True, True]) + + with pytest.warns( + GSolveSolverWarning, match="all reference sites removed from loop" + ): + result = _check_post_clip_data_are_ok( + mask=mask, + obs_site_id=obs_site_id, + ties_site_id=ties_site_id, + obs_loop=obs_loop, + use_loops=True, + ) + + assert result is False + + def test_all_reference_sites_removed_from_loop_warns(self) -> None: + """A loop that loses all its reference sites warns and returns False.""" + # L1 = {A, B, C}, L2 = {A, B, D}; the only tie site "A" is in both loops. + obs_site_id = np.array(["A", "B", "C", "A", "B", "D"]) + obs_loop = np.array(["L1", "L1", "L1", "L2", "L2", "L2"]) + ties_site_id = np.array(["A"]) + # Clip tie "A" from L2 only; "A" survives globally via L1. + mask = np.array([True, True, True, False, True, True]) + + with pytest.warns( + GSolveSolverWarning, match="all reference sites removed from loop" + ): + result = _check_post_clip_data_are_ok( + mask=mask, + obs_site_id=obs_site_id, + ties_site_id=ties_site_id, + obs_loop=obs_loop, + use_loops=True, + ) + + assert result is False + + def test_single_loop_skips_loop_checks(self) -> None: + """With only one loop, loop-specific checks are skipped even if use_loops.""" + obs_site_id = np.array(["A", "B", "A", "B"]) + obs_loop = np.array(["L1", "L1", "L1", "L1"]) + ties_site_id = np.array(["A", "B"]) + mask = np.array([True, True, True, True]) + + with warnings.catch_warnings(): + warnings.simplefilter("error", GSolveSolverWarning) + result = _check_post_clip_data_are_ok( + mask=mask, + obs_site_id=obs_site_id, + ties_site_id=ties_site_id, + obs_loop=obs_loop, + use_loops=True, + ) + + assert result is True diff --git a/uv.lock b/uv.lock index 75a7b8f..92ee761 100644 --- a/uv.lock +++ b/uv.lock @@ -32,6 +32,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, ] +[[package]] +name = "anyio" +version = "4.15.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.15'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/d2/f4d173e22df740bc37b1db102b386ba719b66e95b0f0d751f556b387e6d2/anyio-4.15.1.tar.gz", hash = "sha256:9f28306018cbd6d329e64a36d58256edff76dd996fe423bc957326e578b82a94", size = 276966, upload-time = "2026-09-05T10:42:39.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b8/4bd346e22b28902df4d651910f5242c28d84e4a5c2435ca5c3f797ed7e2e/anyio-4.15.1-py3-none-any.whl", hash = "sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101", size = 132079, upload-time = "2026-09-05T10:42:37.923Z" }, +] + [[package]] name = "appnope" version = "0.1.4" @@ -642,6 +655,7 @@ dev = [ { name = "burocrata" }, { name = "ipykernel" }, { name = "ipywidgets" }, + { name = "marimo" }, { name = "pandas-stubs" }, { name = "pandas-vet" }, { name = "pyrefly" }, @@ -688,6 +702,7 @@ dev = [ { name = "burocrata", specifier = ">=0.3.0" }, { name = "ipykernel", specifier = ">=7.2.0" }, { name = "ipywidgets", specifier = ">=8.1.8" }, + { name = "marimo", specifier = ">=0.25.0" }, { name = "pandas-stubs", specifier = "==2.3.3.260113" }, { name = "pandas-vet", specifier = ">=2023.8.2" }, { name = "pyrefly", specifier = ">=1.3.1" }, @@ -708,6 +723,15 @@ docs = [ { name = "sphinx-gallery", specifier = ">=0.21.0" }, ] +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + [[package]] name = "harmonica" version = "0.7.0" @@ -828,6 +852,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl", hash = "sha256:ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e", size = 139808, upload-time = "2025-11-01T21:18:10.956Z" }, ] +[[package]] +name = "itsdangerous" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, +] + [[package]] name = "jedi" version = "0.20.0" @@ -1019,6 +1052,105 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl", hash = "sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3", size = 4398, upload-time = "2022-04-20T22:04:42.23Z" }, ] +[[package]] +name = "loro" +version = "1.16.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/83/1dd9181d4b3abfa56c2a7e677a18ae209b38e754a1503e4007adfde47c72/loro-1.16.2.tar.gz", hash = "sha256:b3e30b8d9aadc600662acd31e90ae4da9b84c98900225aa044d4c28c140a12ce", size = 70470, upload-time = "2026-09-21T10:53:40.636Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/10/67676c4f0b247b340179a68fad7bb5d981c2e54e7f4682513d9250d90c85/loro-1.16.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:84ef4084a7be2fc3391d530ef302840459ee23dd95ef77dd638b3c8fe24c863f", size = 3408380, upload-time = "2026-09-21T10:50:54.686Z" }, + { url = "https://files.pythonhosted.org/packages/08/d3/e90f2c9db0b2420a4501eea1898d10769e82b67787e8a505eca176d73dc4/loro-1.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3e158f81a2227b9ccd9b66139c098b79ff0eccc4825f2977a8ecf6247dfd4983", size = 3215934, upload-time = "2026-09-21T10:50:36.555Z" }, + { url = "https://files.pythonhosted.org/packages/54/cc/4226e8156d80640afd74d1b3053c62adbd307d080a21d2a4256156a3ddc0/loro-1.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad39c737e42007b9d1e63d4936798a444f5fbd9dce76a1fdc41096900a8ae58c", size = 3560484, upload-time = "2026-09-21T10:47:16.306Z" }, + { url = "https://files.pythonhosted.org/packages/68/a6/3aca16bad28189450fff14aed1f7a5fec2577bfba95778aa1a580f514df3/loro-1.16.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1c09f50be03b526c9823bfe3e2cc02f42bd53c1d4c6d81fe9b22035b12399594", size = 3636885, upload-time = "2026-09-21T10:47:53.506Z" }, + { url = "https://files.pythonhosted.org/packages/72/35/581373a232c53e6e205600e0d065c42824e3106aea35cb0990ad9bd6edd9/loro-1.16.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad8b88e00a1e7f9a8348935c73abb33dbc573af7d1bd542f180804a39e8f7988", size = 4011097, upload-time = "2026-09-21T10:48:29.927Z" }, + { url = "https://files.pythonhosted.org/packages/37/ee/b55a0971765f129582ae7862ed9f30981f71f93cf78b7cd401e56b3d3091/loro-1.16.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5ef353110b2e1c2cc332e66aa07704b8571960523117841cfc0f5711dc4310c", size = 3721604, upload-time = "2026-09-21T10:49:06.991Z" }, + { url = "https://files.pythonhosted.org/packages/6c/07/f539e4d5dcf252430af9c4b76a27be756c3dbcb400ebc0e33578fa8552b6/loro-1.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d42620092340597fc9b8c76ec76bed92de1326b7c9418a49a8909371b598803f", size = 3558887, upload-time = "2026-09-21T10:50:09.16Z" }, + { url = "https://files.pythonhosted.org/packages/79/18/093a00b64aedd5d7ce33e75b88f9f25278baf46fffbaf54f60e6495411c7/loro-1.16.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fd2c787299b6332b308f543253f4bb2885536cb80799799168836936cfa619", size = 3951738, upload-time = "2026-09-21T10:49:42.201Z" }, + { url = "https://files.pythonhosted.org/packages/29/6e/bfb0c49f06f99b7acbe90872f327b49ba7ca5a7b22d777f528aab67bf94c/loro-1.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b19e18c5c0deefded5b1f41d15a34c3c3dd8e89491c1f086cada9e9b6ab5942c", size = 3736893, upload-time = "2026-09-21T10:51:13.212Z" }, + { url = "https://files.pythonhosted.org/packages/93/cc/0f08597cdd6124dbbb42330dda2e25e6e7231df3e809c212dec2c419e3f2/loro-1.16.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7af386703e10df2d9613479b2d558225063023f726902cefd39a799a404ee69a", size = 3909291, upload-time = "2026-09-21T10:51:49.644Z" }, + { url = "https://files.pythonhosted.org/packages/38/1d/3ce1099cf71e882906e01d476864459956c136a41a561ce73a34b0a02818/loro-1.16.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ef6d5ca7f32aa26d5c4f61f794ed0343b893f3e6034bea760e9ece1d526ba23", size = 3967519, upload-time = "2026-09-21T10:52:26.537Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2d/9453c9381cc9002cf2eff160c705aa3404711c909d162e3585640223c3fe/loro-1.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4ac4641cacf192d59f0daa92a5cbea101f50a5d7c44c0f466ad98f4571dd1d53", size = 3877159, upload-time = "2026-09-21T10:53:04.999Z" }, + { url = "https://files.pythonhosted.org/packages/24/bb/9b078f371c6372667253fa82d15184dfcfcbdf1f478d7e57f3a20abd9ef7/loro-1.16.2-cp312-cp312-win32.whl", hash = "sha256:5a29103d094e592df751cb35b1f3197586f1fdda9cdcf707b80bedbe5394ef56", size = 2950327, upload-time = "2026-09-21T10:54:06.791Z" }, + { url = "https://files.pythonhosted.org/packages/34/0d/6b8140ff5fa6d350548b4e088d2303f667ace864b189da441c9e1dcf6593/loro-1.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:503af039fe68fff1874cfbac86801784f541d00cce61284f15f28fc0ba8bbfd2", size = 3183597, upload-time = "2026-09-21T10:53:45.227Z" }, + { url = "https://files.pythonhosted.org/packages/77/85/21ea0adba99b7a890318ea69a31f72eafc411449b9024f845f07793d6e57/loro-1.16.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f10995db58779d3cfc5f233f84fca09fac6fc20bc5b7db71b4afe7b366f41b24", size = 3408650, upload-time = "2026-09-21T10:50:56.222Z" }, + { url = "https://files.pythonhosted.org/packages/43/05/c6f98a5638373ca2b967194fe1c778cbd7bdd715adcefb91b79f325c0191/loro-1.16.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:455771cfda2c84d08861ab64f0fb541d67e32193ac82a83a9dc8ea6e711e79ce", size = 3215484, upload-time = "2026-09-21T10:50:38.224Z" }, + { url = "https://files.pythonhosted.org/packages/fb/fa/94c321f615fe2cc0178d466e8c92c00c77615b89994c5378335b52f3cb90/loro-1.16.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11e29b820fd88f86e18e4f05055db724fd0a68372356581f4318cb4b9e368f62", size = 3561932, upload-time = "2026-09-21T10:47:17.786Z" }, + { url = "https://files.pythonhosted.org/packages/30/1a/3b73c87eed13667fc04bf4627b628e8e38fdcf9ed5898b9c122f0aaaa3d5/loro-1.16.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd0738bd6d2d3149a7c2d9496abbdcb6d5105a70d8d61e23a6536d253d7fadae", size = 3636574, upload-time = "2026-09-21T10:47:54.873Z" }, + { url = "https://files.pythonhosted.org/packages/12/eb/776be0d65ea35a83d52d84817ef04ee62e9cb496285f7d13582baf9b065a/loro-1.16.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d277aa9422ec314a1eb96503a827138dbc0e5650301304904fb9b35eb3605911", size = 4011370, upload-time = "2026-09-21T10:48:31.564Z" }, + { url = "https://files.pythonhosted.org/packages/41/de/6aa57039390bd0fc39c33cd025d524ca8927bcfe1540f7d9b9b31e1001e3/loro-1.16.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d812435e3a26b5a7b1417bf1a4fd7c9b951adb9817b407b1a5f935f2829617a", size = 3722827, upload-time = "2026-09-21T10:49:08.519Z" }, + { url = "https://files.pythonhosted.org/packages/18/f4/dc9ec2b7c347a3b7694bbb4412e58a650f5ad79a7ee72a70277f31cd98b5/loro-1.16.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6c069242a3a7128a6c929c7bc87d730644bac01c83fc29141755b014621772", size = 3558981, upload-time = "2026-09-21T10:50:10.469Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a9/17658f6ec319e195ae86d38c11d0478404aac0f13296cace2fc8002e0786/loro-1.16.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:adec0565eecc806ee9dc6470ca26b784c0d67270129ba8611f546552140629be", size = 3950831, upload-time = "2026-09-21T10:49:43.565Z" }, + { url = "https://files.pythonhosted.org/packages/48/f1/e055e5a8f047f404425399ef09431bea6bf7404aae5fd120d20579a241ae/loro-1.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:acb942480d16226a538dd63dc1fbe532ae66dd1fb9e8800ed454bc1e6a12cda8", size = 3738048, upload-time = "2026-09-21T10:51:14.845Z" }, + { url = "https://files.pythonhosted.org/packages/58/fd/e84706fde319f217dab5e6b5a53d88619a22f9b32b8cddb52ef1cf49c561/loro-1.16.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:8e0c1108c204fef6db8d1107a4c2c4367ddc6759c6b3428c904d5a283d0e9f72", size = 3909244, upload-time = "2026-09-21T10:51:51.163Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ee/6cd5e8b3ef105bd28d005747e3a2846bd2a76dfd49b710dec7279af4a0ee/loro-1.16.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:aa72e367432153907849b4f290ce287932563b73818b83f8aa3d5f2a2142af02", size = 3967937, upload-time = "2026-09-21T10:52:28.48Z" }, + { url = "https://files.pythonhosted.org/packages/fa/db/979b4a54007caee21885b21ef319d465671242e57551ea5cbedb1d327722/loro-1.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:32d7979ef4bd2f4dff73cca1d8b2634e035bbaee590e167570866721623edfeb", size = 3878292, upload-time = "2026-09-21T10:53:06.785Z" }, + { url = "https://files.pythonhosted.org/packages/1d/b6/186255c8859f2c27e7bf94ef6d80d56e9a30fb8ecf3131b3d8a6a027e783/loro-1.16.2-cp313-cp313-win32.whl", hash = "sha256:4eaf8e500d4c1e9da8edbec6ded28758f44d59e0f923778301480ead59504e97", size = 2949712, upload-time = "2026-09-21T10:54:08.75Z" }, + { url = "https://files.pythonhosted.org/packages/b9/76/a4abc1bdb824b130508eab9ffaab7e99eedc2325070300713adcae6a46be/loro-1.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:c05c11ad43c57190e7d912a570328f7294a6b569ccbff6eedb788414710e4245", size = 3183368, upload-time = "2026-09-21T10:53:47.093Z" }, + { url = "https://files.pythonhosted.org/packages/05/6f/f9ae6e61722041e062245b3f2d9464fc2eb28631b688ca2589b6321f48e7/loro-1.16.2-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:a02cc0c788a070a8b6b8c111642fce80ed0f9bc52cfb8361f3a671ed29880bf7", size = 3388067, upload-time = "2026-09-21T10:50:57.712Z" }, + { url = "https://files.pythonhosted.org/packages/75/43/7d69e5faf912c51fe03c133ccb847fa7ed6f003a742d1959247c862e144e/loro-1.16.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6c72a7d1e6a05c9630f75de9a9a78231c80eb1ad2a3c9f6554ef287fb3d57aa8", size = 3202677, upload-time = "2026-09-21T10:50:39.61Z" }, + { url = "https://files.pythonhosted.org/packages/52/d7/c19d7d6e984cae8a2a3a6171d16565e39fb0eb5fdeccd507af5ba1946e05/loro-1.16.2-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a523e5c3a7b321b9664ac9ebf992b8f872f53280d2735e2340dbd77f7cceb8d", size = 3551977, upload-time = "2026-09-21T10:47:19.047Z" }, + { url = "https://files.pythonhosted.org/packages/49/d6/33b86554151228fc562e069eb9cd7246466864ca0d22242515029ab802dd/loro-1.16.2-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf8f3d7fbbbe8921eb0a89dea6fbbef4bec361aaa03541a957e3778a820c72ec", size = 3615097, upload-time = "2026-09-21T10:47:56.763Z" }, + { url = "https://files.pythonhosted.org/packages/73/aa/bd12570b97cc9afa306be444ef45322433c1a630b8816923c497da85d182/loro-1.16.2-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6276a87a64904a568f7f846d568a187fcd125213f4f1a3f756ab3f9350dc9aac", size = 4007066, upload-time = "2026-09-21T10:48:32.928Z" }, + { url = "https://files.pythonhosted.org/packages/61/11/334982f10a2ff7f66b1d91157ed502c5ebffff7d1f6cbd7199ee9a722d8d/loro-1.16.2-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0ada36b1965a81d50d7dc9e35df42fd84077ea8192b072f9286822fa53f74af", size = 3714840, upload-time = "2026-09-21T10:49:09.904Z" }, + { url = "https://files.pythonhosted.org/packages/4a/f3/c5f18b9883bf30703b9d5e02f878e4c81960cf7c20a4c6502b669eb00e39/loro-1.16.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb3aab12b9e7e4b85141a47fc90183a1cb0fe6549f6cd33666827b5da470721c", size = 3541250, upload-time = "2026-09-21T10:50:12.242Z" }, + { url = "https://files.pythonhosted.org/packages/9e/72/0bcf0d64ff5e5071667e2a059a81223586ffee493c116e6975bc5c95d429/loro-1.16.2-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0822ec78a2cb2087203adc0f7c4c105de5c9ab31a735efdc6e0d64c05d8e30b", size = 3935828, upload-time = "2026-09-21T10:49:45.12Z" }, + { url = "https://files.pythonhosted.org/packages/ed/f0/0d2be34b9ddfa38f0990e17456a91e5cb39d1cf740dbe302063999bfa917/loro-1.16.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:333778715b84d9d46f547d4c4f53d8f02739f3a1199fed172f345d472002b642", size = 3726581, upload-time = "2026-09-21T10:51:16.402Z" }, + { url = "https://files.pythonhosted.org/packages/ac/a2/a924c60fc045f35ffab0f3b05d84cc62787b85ed8177b92b724c15d2076a/loro-1.16.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:ecaa21e06a3707cdb7066b8bd5e9752aff4a2196bd6154a55863ab26185ae718", size = 3889480, upload-time = "2026-09-21T10:51:52.908Z" }, + { url = "https://files.pythonhosted.org/packages/b9/39/9aedb1538a672b5d9867d080ce23f2af169f36bc2302e6a96fb6d96a1988/loro-1.16.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:671f5270d9520eb157de9be16365c29e921919e9bc622f15e7ae7d28196b9209", size = 3959009, upload-time = "2026-09-21T10:52:29.843Z" }, + { url = "https://files.pythonhosted.org/packages/8f/45/6305eae57f5b55fcea8334a4fbb828440e4a8abe532889f2e05872f4e103/loro-1.16.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e3dc7188c2a68a38350a98838d97e216f93b803d2a93fe501111c08d219095a", size = 3861624, upload-time = "2026-09-21T10:53:08.504Z" }, + { url = "https://files.pythonhosted.org/packages/f2/25/e2eb3cc092d64ba5e579d6c217082a10c2d55090b9ac30c0a1728672579e/loro-1.16.2-cp314-cp314-win32.whl", hash = "sha256:c6d28f85e19ac88ecee4fd535999d71196d1a3fba2c66dae54b6168687419c1d", size = 2937950, upload-time = "2026-09-21T10:54:10.436Z" }, + { url = "https://files.pythonhosted.org/packages/6e/40/6557fddb37ad3adfb36b60350d930e1eb69412e7a5328c46108fdae67cf1/loro-1.16.2-cp314-cp314-win_amd64.whl", hash = "sha256:e420efe54720a7a6b2c9f421d0cc5c56c01b09351162a452d33d377f2ee87778", size = 3162432, upload-time = "2026-09-21T10:53:48.75Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/56abbe5452186e8546ca62f4f508016550202e1551d136eebab45090317d/loro-1.16.2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46f2ff5434616e6d5b118dad992804ed1d4e8dfefe1a4c4c64273b0bd3e5616f", size = 3553092, upload-time = "2026-09-21T10:47:20.883Z" }, + { url = "https://files.pythonhosted.org/packages/a2/19/fbf6efa486978407882395062b65687c2074d831c3f5d1211dfdac63ccb5/loro-1.16.2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c551daf053fa5ca594db147c8b2044b57144595111b0f57a672edf54b5756c4", size = 3617321, upload-time = "2026-09-21T10:47:58.106Z" }, + { url = "https://files.pythonhosted.org/packages/c1/96/fafc3df7cf5ef142c77327c9fcfde24a9825e31fa87cc20bbf164bf3a9e9/loro-1.16.2-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4931866c3a6bb09715c55ce9ba01062a678f44d6478cf1b1c163222f954f2f98", size = 4004449, upload-time = "2026-09-21T10:48:34.467Z" }, + { url = "https://files.pythonhosted.org/packages/22/37/e9c6db12d1daa3df1cd78ccc4232bb20a2e9b09d702c7e57fc8c6c60775b/loro-1.16.2-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:93f62f2939544319d2bac1292c788e473ba5aac946ac8f03e0a19ebe46ee882b", size = 3709917, upload-time = "2026-09-21T10:49:11.304Z" }, + { url = "https://files.pythonhosted.org/packages/90/4f/26f496f65fd053ee527a8da720138b52a521404fcaa58110c4329f7b68e4/loro-1.16.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1298a0f27e22589df53ffbc6178785965bf86cabd0a7fdf839b112c37f034c4d", size = 3536458, upload-time = "2026-09-21T10:50:13.773Z" }, + { url = "https://files.pythonhosted.org/packages/90/fb/0b5760638b48c5cd7c16831797b151697c08fb10b7f629803efc655f683e/loro-1.16.2-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4281a93df46ec02583365b7403e703787e0a794303495b7b61d6a121090bed15", size = 3940244, upload-time = "2026-09-21T10:49:46.804Z" }, + { url = "https://files.pythonhosted.org/packages/58/3b/dae1e99592b225b9b757059c15c5351fd0f165ce2309631d73a534cf4428/loro-1.16.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:505f78453cda745dd1ef6e9e13cce11208a546730e45989ae4bccabee5e72697", size = 3728368, upload-time = "2026-09-21T10:51:17.814Z" }, + { url = "https://files.pythonhosted.org/packages/54/7f/59737c7bee98d07b3057bdd3f8824e42347d3846d235336fedaf3980fd07/loro-1.16.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf2dc9dee8b12aa87585decdc11f337ff7f67a31629c3cda00094c894e3f69ff", size = 3889805, upload-time = "2026-09-21T10:51:54.693Z" }, + { url = "https://files.pythonhosted.org/packages/1b/79/2602758cea0d22b07c7b63aa7277d64a10d2017fe7d2b6349811b64b1d50/loro-1.16.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:6dc4e8ed7bcdbceb784fc4976428016fa572177f7757503d489d3aee8b8d31f9", size = 3961692, upload-time = "2026-09-21T10:52:31.548Z" }, + { url = "https://files.pythonhosted.org/packages/50/8e/df588b63fe352bf6ea9154df1417b4bb061237068beaba24bf7b2b8a5435/loro-1.16.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d95c5223f23f6be9cd1439ab5b65ad9e7e23ca6b294f8ac14af982bed36d984a", size = 3860841, upload-time = "2026-09-21T10:53:10.065Z" }, +] + +[[package]] +name = "marimo" +version = "0.25.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click", marker = "sys_platform != 'emscripten'" }, + { name = "docutils" }, + { name = "itsdangerous" }, + { name = "jedi" }, + { name = "loro", marker = "sys_platform != 'android' and sys_platform != 'emscripten'" }, + { name = "markdown" }, + { name = "msgspec" }, + { name = "narwhals" }, + { name = "packaging" }, + { name = "psutil", marker = "sys_platform != 'android' and sys_platform != 'emscripten'" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "python-multipart" }, + { name = "pyyaml" }, + { name = "pyzmq", marker = "python_full_version < '3.15' and sys_platform != 'emscripten'" }, + { name = "starlette", marker = "sys_platform != 'emscripten'" }, + { name = "tomlkit" }, + { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, + { name = "websockets", marker = "sys_platform != 'emscripten'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d3/a7/4f0cc52e7c875997e7026e737f7a20f75786d2d65e572a1a0ef9cd5204ce/marimo-0.25.0.tar.gz", hash = "sha256:0005827578027cf9ea2cce039e099c029a9323a3467cb15100228918c1608ad1", size = 50236089, upload-time = "2026-09-23T21:48:33.867Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/0d/055b436b509ffd6e7f9307dacd95f58c7fbb6c75a1eafca3c6047e7f13a6/marimo-0.25.0-py3-none-any.whl", hash = "sha256:43bb4d82d713f44fc064e77668e59a9fbb6172a6cf7c3abe25c15ef2cb1cce31", size = 50902999, upload-time = "2026-09-23T21:48:29.047Z" }, +] + +[[package]] +name = "markdown" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/4f/700155c8c20d9e655dd0732b5fc3c7614f291b9148da271d7388e50bf774/markdown-3.11.tar.gz", hash = "sha256:180224db6aed87ba9ce1f2781ebcd5826253de8ff637112090e24b84502bbf9f", size = 485623, upload-time = "2026-09-25T13:46:23.473Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/1e/32971905a7ab47f8b66866ed949fa48b104ba1c4a6fa57794c4f2c4b2cb8/markdown-3.11-py3-none-any.whl", hash = "sha256:cd6c89e7eb308c8b332ed673215a52d208a43f8bacc030b1419376129408719e", size = 111296, upload-time = "2026-09-25T13:46:22.163Z" }, +] + [[package]] name = "markdown-it-py" version = "4.2.0" @@ -1190,6 +1322,46 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] +[[package]] +name = "msgspec" +version = "0.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/60/f79b9b013a16fa3a58350c9295ddc6789f2e335f36ea61ed10a21b215364/msgspec-0.21.1.tar.gz", hash = "sha256:2313508e394b0d208f8f56892ca9b2799e2561329de9763b19619595a6c0f72c", size = 319193, upload-time = "2026-04-12T21:44:50.394Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/cf/317224852c00248c620a9bcf4b26e2e4ab8afd752f18d2a6ef73ebd423b6/msgspec-0.21.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4248cf0b6129b7d230eacd493c17cc2d4f3989f3bb7f633a928a85b7dcfa251", size = 196188, upload-time = "2026-04-12T21:44:07.181Z" }, + { url = "https://files.pythonhosted.org/packages/6d/81/074612945c0666078f7366f40000013de9f6ba687491d450df699bceebc9/msgspec-0.21.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5102c7e9b3acff82178449b85006d96310e690291bb1ea0142f1b24bcb8aabcb", size = 188473, upload-time = "2026-04-12T21:44:08.736Z" }, + { url = "https://files.pythonhosted.org/packages/8a/37/655101799590bcc5fddb2bd3fe0e6194e816c2d1da7c361725f5eb89a910/msgspec-0.21.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:846758412e9518252b2ac9bffd6f0e54d9ff614f5f9488df7749f81ff5c80920", size = 218871, upload-time = "2026-04-12T21:44:09.917Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d1/d4cd9fe89c7d400d7a18f86ccc94daa3f0927f53558846fcb60791dce5d6/msgspec-0.21.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21995e74b5c598c2e004110ad66ec7f1b8c20bf2bcf3b2de8fd9a3094422d3ff", size = 225025, upload-time = "2026-04-12T21:44:11.191Z" }, + { url = "https://files.pythonhosted.org/packages/24/bf/e20549e602b9edccadeeff98760345a416f9cce846a657e8b18e3396b212/msgspec-0.21.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6129f0cca52992e898fd5344187f7c8127b63d810b2fd73e36fca73b4c6475ee", size = 222672, upload-time = "2026-04-12T21:44:12.481Z" }, + { url = "https://files.pythonhosted.org/packages/b4/68/04d7a8f0f786545cf9b8c280c57aa6befb5977af6e884b8b54191cbe44b3/msgspec-0.21.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ef3ec2296248d1f8b9231acb051b6d471dfde8f21819e86c9adaaa9f42918521", size = 227303, upload-time = "2026-04-12T21:44:13.709Z" }, + { url = "https://files.pythonhosted.org/packages/cc/4d/619866af2840875be408047bf9e70ceafbae6ab50660de7134ed1b25eb86/msgspec-0.21.1-cp312-cp312-win_amd64.whl", hash = "sha256:d4ab834a054c6f0cbeef6df9e7e1b33d5f1bc7b86dea1d2fd7cad003873e783d", size = 190017, upload-time = "2026-04-12T21:44:14.977Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/a8f9eca8fd00e097d7a9e99ba8a4685db994494448e3d4f0b7f6e9a3c0f7/msgspec-0.21.1-cp312-cp312-win_arm64.whl", hash = "sha256:628aaa35c74950a8c59da330d7e98917e1c7188f983745782027748ee4ca573e", size = 175345, upload-time = "2026-04-12T21:44:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/7e/74/f11ede02839b19ff459f88e3145df5d711626ca84da4e23520cebf819367/msgspec-0.21.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:764173717a01743f007e9f74520ed281f24672c604514f7d76c1c3a10e8edb66", size = 196176, upload-time = "2026-04-12T21:44:17.613Z" }, + { url = "https://files.pythonhosted.org/packages/bb/40/4476c1bd341418a046c4955aff632ec769315d1e3cb94e6acf86d461f9ed/msgspec-0.21.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:344c7cd0eaed1fb81d7959f99100ef71ec9b536881a376f11b9a6c4803365697", size = 188524, upload-time = "2026-04-12T21:44:18.815Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d9/9e9d7d7e5061b47540d03d640fab9b3965ba7ae49c1b2154861c8f007518/msgspec-0.21.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48943e278b3854c2f89f955ddc6f9f430d3f0784b16e47d10604ee0463cd21f5", size = 218880, upload-time = "2026-04-12T21:44:20.028Z" }, + { url = "https://files.pythonhosted.org/packages/74/66/2bb344f34abb4b57e60c7c9c761994e0417b9718ec1460bf00c296f2a7ea/msgspec-0.21.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9aa659ebb0101b1cbc31461212b87e341d961f0ab0772aaf068a99e001ec4aa", size = 225050, upload-time = "2026-04-12T21:44:21.577Z" }, + { url = "https://files.pythonhosted.org/packages/1a/84/7c1e412f76092277bf760cef12b7979d03314d259ab5b5cafde5d0c1722d/msgspec-0.21.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7b27d1a8ead2b6f5b0c4f2d07b8be1ccfcc041c8a0e704781edebe3ae13c484", size = 222713, upload-time = "2026-04-12T21:44:22.83Z" }, + { url = "https://files.pythonhosted.org/packages/4e/27/0bba04b2b4ef05f3d068429410bc71d2cea925f1596a8f41152cccd5edb8/msgspec-0.21.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38fe93e86b61328fe544cb7fd871fad5a27c8734bfda90f65e5dbe288ae50f61", size = 227259, upload-time = "2026-04-12T21:44:24.11Z" }, + { url = "https://files.pythonhosted.org/packages/b0/2d/09574b0eea02fed2c2c1383dbaae2c7f79dc16dcd6487a886000afb5d7c4/msgspec-0.21.1-cp313-cp313-win_amd64.whl", hash = "sha256:8bc666331c35fcce05a7cd2d6221adbe0f6058f8e750711413d22793c080ac6a", size = 189857, upload-time = "2026-04-12T21:44:25.359Z" }, + { url = "https://files.pythonhosted.org/packages/46/34/105b1576ad182879914f0c821f17ee1d13abb165cb060448f96fe2aff078/msgspec-0.21.1-cp313-cp313-win_arm64.whl", hash = "sha256:42bb1241e0750c1a4346f2aa84db26c5ffd99a4eb3a954927d9f149ff2f42898", size = 175403, upload-time = "2026-04-12T21:44:26.608Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ad/86954e987d1d6a5c579e2c2e7832b65e0fff194179fdac4f581536086024/msgspec-0.21.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fab48eb45fdbfbdb2c0edfec00ffc53b6b6085beefc6b50b61e01659f9f8757f", size = 196261, upload-time = "2026-04-12T21:44:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a1/c5e46c3e42b866199365e35d11dddfd1fbd8bba4fdb3c52f965b1607ce94/msgspec-0.21.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3cb779ea0c35bc807ff941d415875c1f69ca0be91a2e907ab99a171811d86a9a", size = 188729, upload-time = "2026-04-12T21:44:28.99Z" }, + { url = "https://files.pythonhosted.org/packages/85/7d/1e29a319d678d6cb962ae5bdf32a6858ebdf38f73bc654c0e9c742a0c2c8/msgspec-0.21.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68604db36b3b4dd9bf160e436e12798a4738848144cea1aca1cb984011eb160f", size = 219866, upload-time = "2026-04-12T21:44:31.104Z" }, + { url = "https://files.pythonhosted.org/packages/25/1f/cca084ca2572810fff12ea9dbdcbe39eac048f40daf4a9077b49fcbe8cee/msgspec-0.21.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3d6b9dc50948eaf65df54d2fd0ff66e6d8c32f116037209ee861810eb9b676cb", size = 224993, upload-time = "2026-04-12T21:44:32.649Z" }, + { url = "https://files.pythonhosted.org/packages/71/94/d2120fc9d419a89a3a7c13e5b7078798c4b392a96a02a6e2b3ce43a8766c/msgspec-0.21.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:52c5e21930942302394429c5a582ce7e6b62c7f983b3760834c2ce107e0dd6df", size = 223535, upload-time = "2026-04-12T21:44:33.839Z" }, + { url = "https://files.pythonhosted.org/packages/75/17/42418b66a3ad972a89bab73dd78b79cc6282bb488a25e73c853cee7443b9/msgspec-0.21.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:abbb39d65681fa24ed394e01af3d59d869068324f900c61d06062b7fb9980f2f", size = 227222, upload-time = "2026-04-12T21:44:35.093Z" }, + { url = "https://files.pythonhosted.org/packages/c4/33/265c894268cca88ff67b144ca2b4c522fc8b9a6f1966a3640c70516e78e1/msgspec-0.21.1-cp314-cp314-win_amd64.whl", hash = "sha256:5666b1b560b97b6ec2eb3fca8a502298ebac56e13bbca1f88523538ce83d01ea", size = 193810, upload-time = "2026-04-12T21:44:36.612Z" }, + { url = "https://files.pythonhosted.org/packages/3b/8f/a6d35f25bf1fc63c492fdd88fdce01ba0875ead48c2b91f90f33653b4131/msgspec-0.21.1-cp314-cp314-win_arm64.whl", hash = "sha256:d8b8578e4c83b14ceea4cef0d0b747e31d9330fe4b03b2b2ad4063866a178f93", size = 179125, upload-time = "2026-04-12T21:44:38.198Z" }, + { url = "https://files.pythonhosted.org/packages/c6/39/74839641e64b99d87da55af0fc472854d42b46e2183b9e2a67fe1bb2a512/msgspec-0.21.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:15f523d51c00ebad412213bfe9f06f0a50ec2b93e0c19e824a2d267cabb48ea2", size = 200171, upload-time = "2026-04-12T21:44:39.414Z" }, + { url = "https://files.pythonhosted.org/packages/70/9b/ce0cca6d2d87fcd4b6ff97600790494e64f26a2c55d61507cd2755c16193/msgspec-0.21.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e47390360583ba3d5c6cb44cf0a9f61b0a06a899d3c2c00627cedebb2e2884b", size = 192879, upload-time = "2026-04-12T21:44:40.882Z" }, + { url = "https://files.pythonhosted.org/packages/a7/08/673a7bb05e5702dc787ddd3011195b509f9867927970da59052211929987/msgspec-0.21.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f60800e6299b798142dc40b0644da77ceac5ea0568be58228417eae14135c847", size = 226281, upload-time = "2026-04-12T21:44:42.181Z" }, + { url = "https://files.pythonhosted.org/packages/7d/45/86508cf57283e9070b3c447e3ab25b792a7a0855a3ea4e0c6d111ac34c97/msgspec-0.21.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5f8e9dfcd98419cf7568808470c4317a3fb30bef0e3715b568730a2b272a20d7", size = 229863, upload-time = "2026-04-12T21:44:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/2c/62/e7c9367cd08d590559faacd711edbae36840342843e669440363f33c7d36/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92d89dfad13bd1ea640dc3e37e724ed380da1030b272bdf5ecafb983c3ad7c75", size = 230445, upload-time = "2026-04-12T21:44:44.806Z" }, + { url = "https://files.pythonhosted.org/packages/42/b4/c0f54632103846b658a10930025f4de41c8724b5e4805a5f3b395586cb7e/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0d03867786e5d7ba25d666df4b11320c27170f4aeafcb8e3a8b0a50a4fb742ca", size = 231822, upload-time = "2026-04-12T21:44:46.343Z" }, + { url = "https://files.pythonhosted.org/packages/ea/1d/0d85cc79d0ccf5508e9c846cc66552a6a16bf92abd1dbd8362617f7b35cd/msgspec-0.21.1-cp314-cp314t-win_amd64.whl", hash = "sha256:740fbf1c9d59992ca3537d6fbe9ebbf9eaf726a65fbf31448e0ecbc710697a63", size = 206650, upload-time = "2026-04-12T21:44:47.601Z" }, + { url = "https://files.pythonhosted.org/packages/90/91/56c5d560f20e6c20e9e4f55bd0e458f7f162aa689ee350346c04c48eac0b/msgspec-0.21.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0d2cc73df6058d811a126ac3a8ad63a4dfa210c82f9cf5a004802eaf4712de90", size = 183149, upload-time = "2026-04-12T21:44:48.833Z" }, +] + [[package]] name = "myst-parser" version = "5.1.0" @@ -1717,6 +1889,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/87/6bbe3586cfa3d20159c566cde5b9266faf66a0bd51b9cbe98d462532e5c1/pyhardisp-0.2.4-py3-none-any.whl", hash = "sha256:d1b772bd4a9ade194e10ad55c17185308bd5edcf4092f11380b1b56d5b0539a8", size = 20777, upload-time = "2026-05-25T00:16:57.1Z" }, ] +[[package]] +name = "pymdown-extensions" +version = "11.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ad/17/2db4b414de89659144488e0d9c6c0bf0c8395841dc12d81d0532cc6ef310/pymdown_extensions-11.0.2.tar.gz", hash = "sha256:9506fcbe66fa355a775b768084334238dd6805020ac4b92bea0c0dda6f8f223d", size = 855419, upload-time = "2026-08-22T19:28:47.236Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/43/9f45ec4d14e596efc32c925a78104934790438b0c0628b70d741016734ad/pymdown_extensions-11.0.2-py3-none-any.whl", hash = "sha256:259910762019732caa1dfd76f3faa62c59f191d46573e80bcb1d13c0f675bbe5", size = 269929, upload-time = "2026-08-22T19:28:45.389Z" }, +] + [[package]] name = "pyparsing" version = "3.3.2" @@ -1855,6 +2040,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "python-multipart" +version = "0.0.32" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/42/55c32bb9b12693c092ad250a0e82edb5b31ddeda6eb772de5f308b3804ad/python_multipart-0.0.32.tar.gz", hash = "sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e", size = 46881, upload-time = "2026-06-04T16:18:58.647Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/04/e8135ebd1ad02c56ec633277529b2602ff99ff634be76cdba5744cf554fd/python_multipart-0.0.32-py3-none-any.whl", hash = "sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23", size = 30042, upload-time = "2026-06-04T16:18:57.319Z" }, +] + [[package]] name = "pytz" version = "2026.3.post1" @@ -2343,6 +2537,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, ] +[[package]] +name = "starlette" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7b/2b/3850dc6bf7ef71b088962eba31dafc6cffd2f96e577ebb0bb316df96da3e/starlette-1.7.0.tar.gz", hash = "sha256:c79f74ea63cff761804fbbfb182f1e0b440c2d07b164d24700c5a1bab5d6ff5d", size = 2736246, upload-time = "2026-09-23T07:30:26.35Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/d6/1ec1b290f9e0fb067899b61e1d37a30c923068bad260b216dbe37a7d2967/starlette-1.7.0-py3-none-any.whl", hash = "sha256:67f8e99895493dd2911a03f11314af6ceebeae4e704bb9f43dfc6a9db151c93e", size = 78980, upload-time = "2026-09-23T07:30:24.567Z" }, +] + [[package]] name = "threadpoolctl" version = "3.6.0" @@ -2397,6 +2604,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, ] +[[package]] +name = "tomlkit" +version = "0.15.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/96/e07752635b98536177fa1f37671c8f3cdde2e724c6bcf6034b2cfb571565/tomlkit-0.15.1.tar.gz", hash = "sha256:e25bbf38843005246210a12982776f27f99cb9be67160e14434d0c0d21ee1e97", size = 180129, upload-time = "2026-07-17T01:48:04.562Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/bc/8c13eb66537dce1d2bd3a57132902f38d0e7f5bb46fa9f4daed9fe9d76ee/tomlkit-0.15.1-py3-none-any.whl", hash = "sha256:177a05aece5a8ca5266fd3c448abb47b8d352f09d477d3ca8332db4d89b24304", size = 49449, upload-time = "2026-07-17T01:48:05.728Z" }, +] + [[package]] name = "toolz" version = "1.1.0" @@ -2505,6 +2721,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, ] +[[package]] +name = "uvicorn" +version = "0.54.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/34/30e9280707135d2cfc589dfff3cb796bd07a3aeb1a3e415ba09dd89d7bb4/uvicorn-0.54.0.tar.gz", hash = "sha256:a2e33cbfaa0306f8e6b0c13e0cb89d7d7a2da3e62b90c66e18c33d9807b28620", size = 112283, upload-time = "2026-09-25T06:52:37.601Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/0c/b54a4fdd7f90a3af8b02ebc9ce6712c2c208b7926a2f7bad95c33ebbe943/uvicorn-0.54.0-py3-none-any.whl", hash = "sha256:505bdb0f318731d45f1f712071fc781a8981f6847a31c902c9f5e652d4f67faf", size = 87427, upload-time = "2026-09-25T06:52:35.829Z" }, +] + [[package]] name = "verde" version = "1.9.0" @@ -2532,6 +2761,135 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/96/42/3e5985a0a7e57de470b320c6d6a1a67c844f6737a587f3d44dd13d1819e7/wcwidth-0.8.2-py3-none-any.whl", hash = "sha256:d63947694a0539a1d51e01eda7caf800c291020e6cdd7e28ad7b14dd33ad4f85", size = 323166, upload-time = "2026-06-29T18:11:09.888Z" }, ] +[[package]] +name = "websockets" +version = "17.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/72/fba934cb3dff7a85d811820efffcd141ddd52b5a2a01637f64551373ff4d/websockets-17.1.tar.gz", hash = "sha256:acfea4c20bf54384883ea33b1240fc1db4f52e190823a4e2b334bc3e8bfca96a", size = 187520, upload-time = "2026-08-26T17:25:33.063Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/0d/098f23c4c858e5de9459ffc554fa07d5493fbcfca7f040b5800cf1cecc35/websockets-17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:76dd004f59115087c7b700474cb18f01325e37250032e19396c08ae41448e4b3", size = 217015, upload-time = "2026-08-26T14:55:45.194Z" }, + { url = "https://files.pythonhosted.org/packages/13/86/bc1317b1a4d8c4688e2a7e564b5e004dab44c2534d7ca05de6ae9a863fca/websockets-17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:581fa678ef46f4277cc8491312468e582f8ad609dbab907ba6096a08c6a0ff98", size = 214692, upload-time = "2026-08-26T14:55:46.366Z" }, + { url = "https://files.pythonhosted.org/packages/8f/e7/df821761772beaa48c211ee0e234930b35c1473778470773823f56d3911b/websockets-17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:87f0d5e77548b0c40c8464cdb6108792e7e53f487c6400028a4ec28a8afbe5ab", size = 214959, upload-time = "2026-08-26T14:55:47.885Z" }, + { url = "https://files.pythonhosted.org/packages/3e/92/c3fb72f11764812fc648bf3838d224972427b348e8b3989d9e0a9df87da3/websockets-17.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:882af300d2c6a092b93767d5de03c7bb56dfb06314140c8e872d3f48e09f7b74", size = 224278, upload-time = "2026-08-26T14:55:49.241Z" }, + { url = "https://files.pythonhosted.org/packages/fb/05/9f82d090c8d2d861604147ef6dfb938a90b039f9358d5193f1df62558593/websockets-17.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0c863507ada5805517ca6dff1c524dcd42942efe6304dacf06700878398d21a6", size = 224557, upload-time = "2026-08-26T14:55:50.348Z" }, + { url = "https://files.pythonhosted.org/packages/8a/50/5cbf677b865290fe36819ff00615826e7edc1df38786f770123ff39a933d/websockets-17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d41ef69d5416fbc1d98cf96c37be6192d10fd101c3e0f8b3ddc36e09432b3c08", size = 225791, upload-time = "2026-08-26T14:55:51.75Z" }, + { url = "https://files.pythonhosted.org/packages/c1/1c/eb8a032285243381b09a221ae384c972d5000453ad136add4d1595cec798/websockets-17.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5aefe78e6a3077fe22b5e64b04666a85a3eb8b934d40e8595a693adcbceb6f11", size = 228574, upload-time = "2026-08-26T14:55:52.922Z" }, + { url = "https://files.pythonhosted.org/packages/69/85/413736251cb3ac04ce84cbd90e893d9a36a9698d4820b323aff3aa187e50/websockets-17.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f64e001bb7fa89b9f32cfa600bf8e9ac8ca26759d9b92ae01453ee303d9cd7b4", size = 226428, upload-time = "2026-08-26T14:55:54.263Z" }, + { url = "https://files.pythonhosted.org/packages/d2/2b/a08bcc7fa1ca81a10f84ba32b6e6edd73a913f4b0c2640eed1fd626efacd/websockets-17.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:677014a073bcb1fbaa7e21144786864f16c08f856d66834f611eceb9006cbab8", size = 225184, upload-time = "2026-08-26T14:55:55.943Z" }, + { url = "https://files.pythonhosted.org/packages/e5/8a/3bd2d0cf6b148c8c866d5d9fdcde30c04bfd81fdfac86813e69377eb4448/websockets-17.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0de501b7f2db11e83739ac20e2d33d46da4604b829f506c24be80e7def069391", size = 222430, upload-time = "2026-08-26T14:55:57.103Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c9/8e891ae342668735eabbbc669895e15195e4b45f24a4beeb58af76f414c7/websockets-17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f62114a54117e4948a1e414e89521f7fe1e3c2f83f2a571a06a4fc6718b0900a", size = 225227, upload-time = "2026-08-26T14:55:58.375Z" }, + { url = "https://files.pythonhosted.org/packages/e1/6f/c816f332dca11425e9bda7c07f7573eb5c5f8a735849d02b0d81e8ee20fa/websockets-17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:eec113a5b41d124ef42ff56b0d74a6da3fd986400038eab9e58ee42a4024e837", size = 223831, upload-time = "2026-08-26T14:55:59.664Z" }, + { url = "https://files.pythonhosted.org/packages/53/67/5e91d5308ce24fc1ec74f56536c12f4888bad45ff5ea50f3180f8c518c57/websockets-17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5f051f8030a51815dc00e24bd2e5f1435af095c1cc111d747ac6e2a3620d7641", size = 224600, upload-time = "2026-08-26T14:56:00.873Z" }, + { url = "https://files.pythonhosted.org/packages/bb/96/faa298ecf2570d35b0eb37caddf4992178d907e108ed74bfffb6bc092c29/websockets-17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:655a8e28010f09fd6fa317e857afab3af7647f33e41dee88fa421e92086d1090", size = 225707, upload-time = "2026-08-26T14:56:02.001Z" }, + { url = "https://files.pythonhosted.org/packages/0b/12/5710d2482ca5061c1eec5eb46f6313837c760d4115b1795c85b6c08be4e3/websockets-17.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:dc2b79afc074d2f3e64b26539350f697fe1b85ea1c49ea24eb588f247b053ce1", size = 223263, upload-time = "2026-08-26T14:56:03.092Z" }, + { url = "https://files.pythonhosted.org/packages/27/47/0c30f4eebfd1d93fae779d268f678d48847fb98516f5200849574eee8820/websockets-17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e4bd7eacb87d8cf3ed70d6392c770a0d92441f05d7d2a3efafb5bc171d5e3067", size = 224244, upload-time = "2026-08-26T14:56:04.321Z" }, + { url = "https://files.pythonhosted.org/packages/41/33/46c256195a1255079ae23d1b1267b2e1843dc5f46a67f973cdf2a3523dff/websockets-17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ccbf3f4a9890d50b3a08ee04029fde30a03bfdeffaa19977628bf17251764e60", size = 224520, upload-time = "2026-08-26T14:56:05.521Z" }, + { url = "https://files.pythonhosted.org/packages/06/9a/aef0792731df4352e5f417369b532b3325fe434765ca90c193f594ae1e67/websockets-17.1-cp312-cp312-win32.whl", hash = "sha256:7e724f843fa6a0614aece65a7c73e51d0f4412ca41dccac13c3caf98e69536bb", size = 217485, upload-time = "2026-08-26T14:56:06.715Z" }, + { url = "https://files.pythonhosted.org/packages/50/23/493ecfdaf32898e5ea24dc900e33e5e317f9662d5d9ab2d44b2e111b4e1c/websockets-17.1-cp312-cp312-win_amd64.whl", hash = "sha256:617243e19a0992095956f406ee9cd3bc4ba92862d83cb1d83bb59ce574412bec", size = 217786, upload-time = "2026-08-26T14:56:08.055Z" }, + { url = "https://files.pythonhosted.org/packages/97/3d/91954e2f7876f74ce1213e9b92c65a63b559cc4b942a931ebeb351cd9932/websockets-17.1-cp312-cp312-win_arm64.whl", hash = "sha256:9f4a08ff7cb68c27b18e09223cc6304e01d0f82d5a240d251266dfd2e6e44729", size = 217711, upload-time = "2026-08-26T14:56:09.267Z" }, + { url = "https://files.pythonhosted.org/packages/1d/31/5f6450a7879f4f063ef08897cc385ea3ce3f1fe17f08b11e3fd959abdf27/websockets-17.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2a0162a6372110a5601cb5c9fd826635cedf69f3e110c545dd19774e040b970e", size = 217006, upload-time = "2026-08-26T14:56:10.509Z" }, + { url = "https://files.pythonhosted.org/packages/d0/2a/c1b006fc861695d2aa4e35327b842015ce1d98cf8f99241829b3d6460bfc/websockets-17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:829dba1bc049779de9b332088c1a6a9858e96bd67e50b6b644a95e02b67836bc", size = 214690, upload-time = "2026-08-26T14:56:11.681Z" }, + { url = "https://files.pythonhosted.org/packages/46/69/66e5b7d01445e0eeb1d4ab419c30315f2c90cf7a8a8cd4ecc47f894dba54/websockets-17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fd8f47dbf2e8adb15c847215f83436de3fdb120b51fdae0fbbdf69fd97a3ad80", size = 214947, upload-time = "2026-08-26T14:56:12.923Z" }, + { url = "https://files.pythonhosted.org/packages/07/ce/033cafe2d2538562efa876b9149a2c7a0f7787870a4b1bb6e28adc9ceb6b/websockets-17.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9f4c0377a83e163a303514fdfab501dbe379bdc13e5b9312a91d112658b29dce", size = 224329, upload-time = "2026-08-26T14:56:14.212Z" }, + { url = "https://files.pythonhosted.org/packages/34/c7/e1c2e8a67f6cc0aa43abe0046fb3b7a020980649e6a843751dc7ce9eb170/websockets-17.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c3241d684a76eaaef8b2dc789afde4343cd3aad55ea81e4e8ab3605b529bae51", size = 224611, upload-time = "2026-08-26T14:56:15.702Z" }, + { url = "https://files.pythonhosted.org/packages/be/de/07c6d48eb3d2069709410c851e7de10ab83d752c4bd09862899627c2729b/websockets-17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e5f5c7a893507d0e83a80b88aefd6522f7e882cd53f9722c6f23f5a020c9557c", size = 225848, upload-time = "2026-08-26T14:56:16.962Z" }, + { url = "https://files.pythonhosted.org/packages/f3/dd/3c68572d20509648cc2fb6f50ccf3deeb4b87270f2c8966e99476e278ea3/websockets-17.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:00bf34b64501e3477e81fc281532ff3cbf4da26633c10b63979d5085d46602d3", size = 227290, upload-time = "2026-08-26T14:56:18.204Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4a/8f6651c8a22093539c9215af0c5bbf217b87b382c99d2112039b92d593c2/websockets-17.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ce0305b702b20d1e1d60a9aaace6bc89970e1753565543f310d549eab22c2435", size = 226476, upload-time = "2026-08-26T14:56:19.459Z" }, + { url = "https://files.pythonhosted.org/packages/f5/be/f6fc33cea86b1127fd1297b18c107e81580ab55a73a39f9a934441ef321f/websockets-17.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29176d8b429cfa0fa443c473878d37a5c06cfd0cb36b71ba4314accc71e05906", size = 225233, upload-time = "2026-08-26T14:56:20.939Z" }, + { url = "https://files.pythonhosted.org/packages/cb/83/65edaf05f7c9b1dea82f4d252fdc37706a84571646f06119a27b0a16fe19/websockets-17.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3709a1ab30b4b922027d22f68d2b61a0656a91680ac894a537624e6be7dd7f7c", size = 222488, upload-time = "2026-08-26T14:56:22.208Z" }, + { url = "https://files.pythonhosted.org/packages/07/42/d1169c2f7f1f0032b0d4b0c00f0711a070cd7c735de37bfeb876bc0f9606/websockets-17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:43bd0c1ceb924d67f5c1a5254d8361dd9d94246e6331a726064dfa2917880780", size = 225295, upload-time = "2026-08-26T14:56:23.445Z" }, + { url = "https://files.pythonhosted.org/packages/a6/f4/64e2a386c3899b917c2933225c9b47887874229d159797f3bf1a11c20d51/websockets-17.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:1fce0f43e0d41422e0b2cad6561e1970df22f212f4c7e884967df7cf591b031c", size = 223891, upload-time = "2026-08-26T14:56:24.647Z" }, + { url = "https://files.pythonhosted.org/packages/26/b3/dfb5c482f7e310a3432fdbb045ddfe6d34114680e89a233d4ff900a32961/websockets-17.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4031152769179ab8dcdeafc7b0e58052a49117560a28671700b47b2c7b717aad", size = 224661, upload-time = "2026-08-26T14:56:26.027Z" }, + { url = "https://files.pythonhosted.org/packages/a4/cf/94865130a336029f46412adc127c4fbe380f46172b90ce251369e35c4302/websockets-17.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a06f3b5085176763182449559e20391d7ce616a8972a9f7a33deda87ea6d4f3c", size = 225766, upload-time = "2026-08-26T14:56:27.455Z" }, + { url = "https://files.pythonhosted.org/packages/96/34/eb8c658f86dfe562ed49a887a27424bfe9e618c26ea6f865b093d075d3a6/websockets-17.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:77b37cceca17291897c3c73bd30a7c7c7909593554b5da574ec852af83c1742a", size = 223323, upload-time = "2026-08-26T14:56:28.807Z" }, + { url = "https://files.pythonhosted.org/packages/1b/7e/2629609652ece5ca0c7ac235927dd4511b08131e3a5d53439b798fddf002/websockets-17.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d8e83333385cac6030a5167fd18bf96cc6c58b914c308e683f05b0cf94bc8dd0", size = 224276, upload-time = "2026-08-26T14:56:29.991Z" }, + { url = "https://files.pythonhosted.org/packages/a1/6b/8525737fe840b38e5f40956c198fb586a4fac1e07144d41a5b949b989cf8/websockets-17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:073c5c3f7e127041fa9d34a9e29ceefee8c3cafbd267ed2927318f425144380d", size = 224558, upload-time = "2026-08-26T14:56:31.184Z" }, + { url = "https://files.pythonhosted.org/packages/74/ab/3a958c6cbcf74b118f601c20a80ac8bd5e8dfec0bcf7345116feaeefb121/websockets-17.1-cp313-cp313-win32.whl", hash = "sha256:2afb58c7ba48b329d56769f8dfd89f394efe587b65ef806bae810a484d6d3608", size = 217475, upload-time = "2026-08-26T14:56:32.431Z" }, + { url = "https://files.pythonhosted.org/packages/22/36/fb521f0f2994c25509651f169efe5582dddd8713d57a0757ba87859372ef/websockets-17.1-cp313-cp313-win_amd64.whl", hash = "sha256:0340bbef6bfbe16da888b3983d666a4db4954ac3253c38f13bc7aba0c7db5a2f", size = 217784, upload-time = "2026-08-26T14:56:33.608Z" }, + { url = "https://files.pythonhosted.org/packages/68/92/9b8419584681a12a7534b746dfb2737c466efe2455483e2fbf8b941a04ec/websockets-17.1-cp313-cp313-win_arm64.whl", hash = "sha256:7a72efa3bf4fa3a6669a54420a472ad056da3973d827f10e3a536da463f926c2", size = 217715, upload-time = "2026-08-26T14:56:34.865Z" }, + { url = "https://files.pythonhosted.org/packages/90/0d/500cf5daea09d4669dff3a7d67159094a0bd6c4ef130381404f6edd3eb5f/websockets-17.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:0c9982938980e086da59f70d05f9418cd143401a601a0faac10fa48f7bb1cd3e", size = 217048, upload-time = "2026-08-26T14:56:36.03Z" }, + { url = "https://files.pythonhosted.org/packages/97/12/5b12c6168aa269cffbfd24d177cd492b130120403a418c7e89462e27b4ac/websockets-17.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:57b39dc8541cf7ed3f639da82bf7451060483967f9e733da1f8173e4095f0642", size = 214737, upload-time = "2026-08-26T14:56:37.43Z" }, + { url = "https://files.pythonhosted.org/packages/0c/36/e453e5106e4e2416f008ac222837c2f1637a063b08008afcd1088889b631/websockets-17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:96abdecbaae746851b87c3a36cb4a661df93ca3d92f114270f79228bf1d00de6", size = 214955, upload-time = "2026-08-26T14:56:38.71Z" }, + { url = "https://files.pythonhosted.org/packages/dd/30/0204bb86176db02cdfc678ce65ed808a66fab87d250ce61a8790800a60b0/websockets-17.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d9fc873e239c5abeb150bc24dbd1a7af23a9254526383ce0a077f5e20adbeb19", size = 224331, upload-time = "2026-08-26T14:56:39.924Z" }, + { url = "https://files.pythonhosted.org/packages/46/c8/d8372256e00c4e3cab1115c45075d1eeedb642a3f2b42bd70c4deae03f06/websockets-17.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6f42912fa9eb4cb7c7ec9fde9b3332ba339eb8a8811981043d4029599f3d950b", size = 224685, upload-time = "2026-08-26T14:56:41.169Z" }, + { url = "https://files.pythonhosted.org/packages/12/7d/650355b8f67f908ff99603351d4458d1a0b787d627950a47c38db7e25308/websockets-17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f98bf378d7a5be047a044a1a27c987a8f355e10e3b5754617dbe756248cbc5ce", size = 225927, upload-time = "2026-08-26T14:56:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/34/6c/a9ffa5b903579eed76017870f055d75ecc73988d9d0c9b65a92ba0bf2a27/websockets-17.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d334d11398086bb5559606cb42d51c013ea7c061c7db701521392373d3c087f5", size = 227300, upload-time = "2026-08-26T14:56:43.538Z" }, + { url = "https://files.pythonhosted.org/packages/9b/5d/4551c2269066af7481ee44605a0813770961615b5b5da3e87a8f5cb859ea/websockets-17.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c27336b1a0ac56569493e858497870347854372395f50483725f8cdacc5a45c", size = 226533, upload-time = "2026-08-26T14:56:44.669Z" }, + { url = "https://files.pythonhosted.org/packages/3c/43/237a99233e5c445759a613831b3a92e91905afc064dc3bd0ad33c35fd1e2/websockets-17.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:67258b00302a5aaf0b267771c7014b13429abd7ea17eebc4c55bd935ff101555", size = 225280, upload-time = "2026-08-26T14:56:45.83Z" }, + { url = "https://files.pythonhosted.org/packages/d3/b5/e9407a91613d1d1cd932414143a1012096b26674a782fc55a0bd23217ee4/websockets-17.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:455ffeea0879d313205df1e745e5883e1feb7f31ecd26be882f5f0babd3db04f", size = 222540, upload-time = "2026-08-26T14:56:47.053Z" }, + { url = "https://files.pythonhosted.org/packages/db/d2/db76628db0577b783205d9779f64d8e373416b04c62d1546be4b75dc8540/websockets-17.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f7233eaf441a345a5943a929fd4b5ea3278f11aed35a9ed0f3106b8cb3ca846a", size = 225354, upload-time = "2026-08-26T14:56:48.32Z" }, + { url = "https://files.pythonhosted.org/packages/a9/4c/2174181c067b89a74ae18e2650c2ac29959f4b796afe876ab3f4d30d642c/websockets-17.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:c65da239a5ad553619804c1f9d65c1a0b3005381c6158ee14da2c7444cbd0c78", size = 223867, upload-time = "2026-08-26T14:56:49.579Z" }, + { url = "https://files.pythonhosted.org/packages/df/75/274decb9a8253561b5be3261e02a6676fc8ecdf31e95b722e53d5bfb8fd2/websockets-17.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9fa1ffa08c81a4f809cdab6129f8e55bee4650b9d6d3461019dda73aacd146b6", size = 224652, upload-time = "2026-08-26T14:56:50.885Z" }, + { url = "https://files.pythonhosted.org/packages/9f/e6/49824f1fb4db7656d2f7492b1d8be16147b759d909490e32f4776843ee64/websockets-17.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:406b8107943a43ef4649b1e0cb0cdc052bbf08fe1c8905a623c4af9586e5cebb", size = 225822, upload-time = "2026-08-26T14:56:52.356Z" }, + { url = "https://files.pythonhosted.org/packages/b8/6a/5dc43838c0b02a95f42c47a0de33c5ddd7767a9feeb4d0d8777ac1cfefe4/websockets-17.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:4e8ffcb486c8490a34a4cef5e4409d8da5a1cb1681e5bf7d786ce5e84aa8540d", size = 223379, upload-time = "2026-08-26T14:56:53.699Z" }, + { url = "https://files.pythonhosted.org/packages/c2/62/585637cf06d6b321232f79c55dc14d65518d12cf87c94c44f5864068810e/websockets-17.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:fb88076df585b69c5761c387c0081aa87d7b9eb1b205a6535ca4777e25650d81", size = 224330, upload-time = "2026-08-26T14:56:55.184Z" }, + { url = "https://files.pythonhosted.org/packages/de/68/c3b234a6a1366b6ab5bbfaa4434a1b946e1dc4e8ddd6824bfd93a8835b7f/websockets-17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5d4724255fb8398acd9e583b97eb2279cec20e0bd0f9a94bf75f6056ef9f13da", size = 224622, upload-time = "2026-08-26T14:56:56.393Z" }, + { url = "https://files.pythonhosted.org/packages/6a/d4/84cf3d1376f5d8207f55f43c1c818babd6b89447f5dcd01f18a6d5526796/websockets-17.1-cp314-cp314-win32.whl", hash = "sha256:be3f0129c5654517b2abf07dcb75bb1d9479759a4ccfb569e8293579e9fc029a", size = 217036, upload-time = "2026-08-26T14:56:57.652Z" }, + { url = "https://files.pythonhosted.org/packages/d0/0f/9e7ac63c5d7cb642952200814f584318e65146df008b7d375d5d9c6b2c97/websockets-17.1-cp314-cp314-win_amd64.whl", hash = "sha256:2a4dc6ef83f4559e0d05f313a375cb38f63c986096a9da99fe94fdd779d313e5", size = 217382, upload-time = "2026-08-26T14:56:59.065Z" }, + { url = "https://files.pythonhosted.org/packages/54/bb/1ae6b91f7f3ac05f5c9f14a72dc2181c115ff370bcd8a7f10f02c174adfd/websockets-17.1-cp314-cp314-win_arm64.whl", hash = "sha256:46c0331c9eaaf73a559f3a9e388466be0df96eb83d40f06f1ca6ab6613b35c82", size = 217268, upload-time = "2026-08-26T14:57:00.654Z" }, + { url = "https://files.pythonhosted.org/packages/b3/f0/f65644d0e0b2b90918a8c41503841cc4072a58f2bf76c09bc36e751fc0dd/websockets-17.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d411ea5ca18ac1b12c0c94be88b60c18ca641ac43bcdfdf1c9f79d46cdbe1603", size = 217379, upload-time = "2026-08-26T14:57:02.181Z" }, + { url = "https://files.pythonhosted.org/packages/ff/35/4c46d1f620ac1a30f92b6eae78ee40a772a93f568647ca7ccdc5ea283cf8/websockets-17.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:07fa3e7c30e2c577928d359b56bf872a3e0cbcc15553eaa0907c1ee86344b56f", size = 214911, upload-time = "2026-08-26T14:57:03.478Z" }, + { url = "https://files.pythonhosted.org/packages/04/6e/4587e8406d7c1188e97b9cf466c081e93399380d447f885bfce81626cd37/websockets-17.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6de9acef07e3a78e9567fcd26c29011a4da8f050b13004bbf880a0fd82a6eea5", size = 215115, upload-time = "2026-08-26T14:57:04.692Z" }, + { url = "https://files.pythonhosted.org/packages/ec/06/1381c8fff525041025909eb80ace32489194a00ba22a0a8d428030afcc84/websockets-17.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ea0ed9373b880115911d9d39634bccc95b8ce590c9c42e8589f5cacc3ef3cee2", size = 224696, upload-time = "2026-08-26T14:57:05.899Z" }, + { url = "https://files.pythonhosted.org/packages/36/9d/9034e867dc85340be058619751742b895f722326e83100d110063461ca07/websockets-17.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50903d335bfda026c2fa11dd9aed09d8cbee0c451e3a85122a9acb041b7dc69b", size = 224975, upload-time = "2026-08-26T14:57:07.262Z" }, + { url = "https://files.pythonhosted.org/packages/40/eb/ed03aa3cae748ebf6397e5d44028f433f746bad09dc568ff754fda3a3c9b/websockets-17.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a74531ce81af587f906ab42f194032388fcff8fc7938402e5917c9147a39441", size = 226151, upload-time = "2026-08-26T14:57:08.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/c9/cc1964a096d16f3b73cb1ee5f14f277f5a3bcac07c6e8f9a1dcded99f4c8/websockets-17.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8fbf28e639544503b7d1c96452a5e5e043e4108d89b1f3fa02910603622d19db", size = 228292, upload-time = "2026-08-26T14:57:09.846Z" }, + { url = "https://files.pythonhosted.org/packages/1a/26/46da6dd0363c2db2e4876fd59a40fd40c1943a82d7018d0a33afbce47d52/websockets-17.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f612dc57f00c07cf4aa2673f7cbceabd654ad2457b7e639f061b794d6e11f9fd", size = 226722, upload-time = "2026-08-26T14:57:11.118Z" }, + { url = "https://files.pythonhosted.org/packages/78/98/ecd8f5e1c5d0e54c08ebc5c66852271112166db68107cb0e17ca1bf25009/websockets-17.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c7ac77401227212dc6e849182feee50d57cf456ec6329ffd6979c94bb136c5c", size = 225451, upload-time = "2026-08-26T14:57:12.601Z" }, + { url = "https://files.pythonhosted.org/packages/65/4d/da8d2760db53e17aae763738b6ba834b1fcf16813d3632f3edb6951e1ec8/websockets-17.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:32a2a68d989d6e5b74a9d5095415c51189ebae29fceb7cf2b64a1c0318a81256", size = 223003, upload-time = "2026-08-26T14:57:13.875Z" }, + { url = "https://files.pythonhosted.org/packages/a4/40/ea401c141a79c5b1d0021a0dab9d0df2051c108f1620fbb39a6e7c714c3b/websockets-17.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:aec00f018d34c67500ff0438dc314b40277be4a1b983cbacbf53ccf7db63e257", size = 225704, upload-time = "2026-08-26T14:57:15.091Z" }, + { url = "https://files.pythonhosted.org/packages/e1/8e/07ab3f44215d89840d5385fdcaaab1fed8caeffa67c6899e15062957c12c/websockets-17.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:0014eaff8ad5b3b43feda2279f9d34bf2eaae040720b9fbbb55944b10f40b14d", size = 224192, upload-time = "2026-08-26T14:57:16.3Z" }, + { url = "https://files.pythonhosted.org/packages/58/93/ccf1af0a23e5748d4e22292a377d78d15cf294d7e707bbb11a8990ae6bd5/websockets-17.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:db9d7ee47f3ba531e278be539af39e2c7c7d28fb94897b6cd1120d63b0ef5922", size = 225082, upload-time = "2026-08-26T14:57:17.531Z" }, + { url = "https://files.pythonhosted.org/packages/e2/db/e32200f99ce282e728d2929f2c429db353cf3282db7d0eba99eb32c9fec1/websockets-17.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:ff3e2ba7a9f0a110b0555452e9b5a03a34e11662544e01beea15f144b48ba7b7", size = 226101, upload-time = "2026-08-26T14:57:18.802Z" }, + { url = "https://files.pythonhosted.org/packages/28/3d/e7a6e9777b29433620167c98f3caaff0d6b08b1239a273ef7f7fd1393349/websockets-17.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:6da17fc94bd270f5987b10bee113461ac36a36a98b0481ddcc98056e5a90001a", size = 223794, upload-time = "2026-08-26T14:57:20.313Z" }, + { url = "https://files.pythonhosted.org/packages/48/05/ac569090726dedd6656f3ee28b0c02dfb1ba76e898dceaccc2987a237cef/websockets-17.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:e8dc3fa6d6b7ead3f9de57895f41b116a28787548e066365d9d90f7356bcaad2", size = 224567, upload-time = "2026-08-26T14:57:21.634Z" }, + { url = "https://files.pythonhosted.org/packages/14/50/4ef62941111db6b31193f4fabbb65f845a5177579040cb8fe0d774d25034/websockets-17.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b65d5fe48219dc2d5e158de9e6514e75600f379cc7e37108d35f31764c155566", size = 224993, upload-time = "2026-08-26T14:57:22.86Z" }, + { url = "https://files.pythonhosted.org/packages/28/42/2b95ada4ea19bf3a2072b68669ce4f4afb212690b727d31640576287fd68/websockets-17.1-cp314-cp314t-win32.whl", hash = "sha256:2cce251f3e2469b99b6802b55435bcdd07123b41870f54c87b336183af9d7e68", size = 217168, upload-time = "2026-08-26T14:57:24.466Z" }, + { url = "https://files.pythonhosted.org/packages/32/0a/67d5ee08dd8060a37d612fd40a625b5376ad19ae48fe1c8ad428c278b817/websockets-17.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8f6c38cdcaf98a911d7acc25577f2f9e710f3a2fc2bde1563556784320196b51", size = 217508, upload-time = "2026-08-26T14:57:25.983Z" }, + { url = "https://files.pythonhosted.org/packages/76/a3/822005d0c674451d2411027b878cdc128a2b7ea5a30d337d9e279da22eba/websockets-17.1-cp314-cp314t-win_arm64.whl", hash = "sha256:d1e2f5fa2b6d01f0d85b4f223fea7ed1d504be282a02a81bd2be4817ef7a2f03", size = 217425, upload-time = "2026-08-26T14:57:27.324Z" }, + { url = "https://files.pythonhosted.org/packages/de/d5/99a6c6a1eb5d5ae9f45f59a3c97f4e3b21f310eb404a547fb3e7d2fc054c/websockets-17.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:88381602e379165b66244b2ebc29f9b23ea0851fbe63ae157f91ca324f072d6f", size = 216970, upload-time = "2026-08-26T14:57:28.575Z" }, + { url = "https://files.pythonhosted.org/packages/a6/0e/1e7f6e833728193958d3ed3d67b5d57c3c7cfa948abf94d4bc553257c954/websockets-17.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:88bc5138e53903a85c354e59df7ba73ce306f7b09724cef74dba121e60a88ce2", size = 214699, upload-time = "2026-08-26T14:57:29.862Z" }, + { url = "https://files.pythonhosted.org/packages/07/00/95d39549f86e34425a0412bcbe61708dd1fc46af654e2134a6c4389102ad/websockets-17.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:3546ef55b3a074494106508bc6505c73825970d2d9505f7bf53882b3e88b0d1e", size = 214927, upload-time = "2026-08-26T14:57:31.148Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ff/b442415fc4f7f9943b0fc8e8eebaa13923ca73361e167c439ba634eecbd9/websockets-17.1-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9ae55d24241fc055f22aea3ac924559069848bd0ad4ea065fdd72d2194685fe8", size = 224373, upload-time = "2026-08-26T14:57:32.833Z" }, + { url = "https://files.pythonhosted.org/packages/a8/dd/b83537aae4cf61615b9d8b2dbb235c0030ba85457a6d934798273814600f/websockets-17.1-cp315-cp315-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d7b349265fad6244013eecd99df8d83c12bf3013943e431f4fadd5bffc37db42", size = 224801, upload-time = "2026-08-26T14:57:34.041Z" }, + { url = "https://files.pythonhosted.org/packages/76/83/5ab0abed58454909e8dbab45086ac68ee4556d7a8ada26735addc909b903/websockets-17.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc5789e5ea182b77a38881383ada5347202a6c66f4857d054e075290e80b604b", size = 225967, upload-time = "2026-08-26T14:57:35.292Z" }, + { url = "https://files.pythonhosted.org/packages/4b/26/e2412f2b998a8c1dfc00c0709ff6ee0c634dd0b0b4f92bdfe9667876b71c/websockets-17.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ce13c7d233239e739600a57d4a73c1192ad8259e655a4d55aa1a454242bc809d", size = 227664, upload-time = "2026-08-26T14:57:36.493Z" }, + { url = "https://files.pythonhosted.org/packages/ec/25/0dd4495df3c0e02f6db705312ba85ab9b2dd42257dc23eb0da10066e4844/websockets-17.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1036189bd34b0bc1b10a4679321e2c7968af317efe6e8e4c1c5141c4254fb5bb", size = 226447, upload-time = "2026-08-26T14:57:37.781Z" }, + { url = "https://files.pythonhosted.org/packages/be/67/6df3f63ffc48f08126ed0cd2fd2a41092967c3e364f8ec100deae90b6d77/websockets-17.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e78fd4b7b2c5086a38671c9c882c1e643385eccea360b5b1fda4a105e590087e", size = 225343, upload-time = "2026-08-26T14:57:39.133Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8d/a8479bbb09ff054907d141123d8f52fb6ae5ac39c6dbe39e6a02a8408309/websockets-17.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:46e7a10bf04318c7b0c0273791925ae5e1cbe4a11e34aa934d2ef27862058a80", size = 222748, upload-time = "2026-08-26T14:57:40.478Z" }, + { url = "https://files.pythonhosted.org/packages/40/fb/4c3d2a3269cde3f3087916de9c3d9fc5d7196b46846d8c3a9ae59ad0a884/websockets-17.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:33e45c7ea38428e740a7f233555d71df0b875cef7fc080acebc9654475e35335", size = 225453, upload-time = "2026-08-26T14:57:41.859Z" }, + { url = "https://files.pythonhosted.org/packages/7f/1c/6467b401d19408f34e1c7389c222c2c7e1dfdf08c551190269b5eabc726c/websockets-17.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:6e63c01803be425ff062b7f7fc201a74def1d49fc94a2410dd17375df75936e9", size = 224112, upload-time = "2026-08-26T14:57:43.136Z" }, + { url = "https://files.pythonhosted.org/packages/c5/5f/744e032ac80e11039a7447657ebabb46e9b5c2dbcec83be571335212932f/websockets-17.1-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:722ec21717eec6477bce582147a28acdfe034e604239466a6a95daedb863e774", size = 224646, upload-time = "2026-08-26T14:57:44.871Z" }, + { url = "https://files.pythonhosted.org/packages/9f/47/bcb9128d9afc4d0934d9192e2a24897ca2f7a63df2654904915349c6c46d/websockets-17.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:e74e41f0ad12ff1e8983e349daef79d37cc8280c743ce9d134d6c74c18dab5d6", size = 225797, upload-time = "2026-08-26T14:57:46.338Z" }, + { url = "https://files.pythonhosted.org/packages/c7/e0/b058047b7cf565e1105b10ef6b6b24a6ebe3575678c7dc75a645334705a7/websockets-17.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:12fe8984a32dbfd084e0603f1a8d740c0180cb85b3174585c54a80d2455a8394", size = 223605, upload-time = "2026-08-26T14:57:48.175Z" }, + { url = "https://files.pythonhosted.org/packages/b9/69/fc1555bff884de363f1bf9eebf2836dbeb29fa7e4f957debb7bbcf43abba/websockets-17.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:01dcb47deebc40b38fd4a493b9b9f4d0a704b7bec6f35e4d34085b329abce71a", size = 224508, upload-time = "2026-08-26T14:57:49.407Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f9/648d4e68621688b19093b06f7b497d520952e68cdea1c1b54371fe9491de/websockets-17.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:f4c45ee2512d3757b5e6c67c5a34e435143f2ecb7df3324f9fd888688c45c0f4", size = 224767, upload-time = "2026-08-26T14:57:50.799Z" }, + { url = "https://files.pythonhosted.org/packages/58/93/f8342b55864f71df13eb8e9ef7dce691b87a87f04f75bb8a1385b3336e7c/websockets-17.1-cp315-cp315-win32.whl", hash = "sha256:0f4f50dfe2cc810fc4e2de979b35e83bf8bb4bccdc6fe472d93762ea7b1d5927", size = 217003, upload-time = "2026-08-26T14:57:52.122Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f0/7b5fdb774c245e0b6217009e2a24d2105c1a64923949f33be41aa7959302/websockets-17.1-cp315-cp315-win_amd64.whl", hash = "sha256:4af784f3e436f65b355c117c6497320f2b5cf6a559295cb1c4c7338e335d45cc", size = 217300, upload-time = "2026-08-26T14:57:53.492Z" }, + { url = "https://files.pythonhosted.org/packages/76/33/1fe6ed1b5087516115ca451b2c240314b010647071f8fc3bd78a21e4dddb/websockets-17.1-cp315-cp315-win_arm64.whl", hash = "sha256:d58159af7835fde09c462394293c0d7aaf8fb4557d8f8e5699f5e722ccae013d", size = 217214, upload-time = "2026-08-26T14:57:54.88Z" }, + { url = "https://files.pythonhosted.org/packages/94/ca/ed02e75996a266d76c5fcb5dd9b930db4cf2b388ca5fa3d2a72086f81568/websockets-17.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:1a5cf4e7bbe3ca499e6a289206cb4fcb7444b09919e129bd517f57d5fa192c13", size = 217282, upload-time = "2026-08-26T14:57:56.108Z" }, + { url = "https://files.pythonhosted.org/packages/bd/7d/d536f5bc89ea5b52fd1c1727c59fabafee6bc41f5ce92c3bd2f83047908c/websockets-17.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:416b4bc8789a1865a3ff643ec4ee073a5f52402d0dbeafd27b1798d5dd6b6a51", size = 214863, upload-time = "2026-08-26T14:57:57.355Z" }, + { url = "https://files.pythonhosted.org/packages/37/37/944cf17bad668e9be1247e6314f88a48b9faf7c250e383410db8b38af0b9/websockets-17.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:259f45358c76d3b18489e3e80636cdbe807e05ecf1b10fdf1a779106d23d0c8e", size = 215073, upload-time = "2026-08-26T14:57:58.719Z" }, + { url = "https://files.pythonhosted.org/packages/74/bf/3267966cc1bbc2b8fa62fd329651b0af502df1f5d1c0eed027ff339d6aa8/websockets-17.1-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d9d01e8ede41fea4f5a847dad9d628355f74905f437a5b6856d67aa66d193800", size = 225229, upload-time = "2026-08-26T14:58:00.235Z" }, + { url = "https://files.pythonhosted.org/packages/7f/d8/85ea722f483510abb39fc71aafb4465d17cf9051a275ab036874ff3c300c/websockets-17.1-cp315-cp315t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a7b35181a14cbfcae163b4de545d22abfd07d06c2c41ca69cfcd99251d6888ab", size = 225500, upload-time = "2026-08-26T14:58:01.994Z" }, + { url = "https://files.pythonhosted.org/packages/50/ce/64c7d00005bd0d15ecb5c5fcb7fb2597b6b92ddd16c4fa6bbc3d2835ad63/websockets-17.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a8e768a048c2220697477ce2e67e4345dc9f693d0ee6af53945b5e30227c6a7", size = 226829, upload-time = "2026-08-26T14:58:03.327Z" }, + { url = "https://files.pythonhosted.org/packages/b4/dc/096c67940fb957e667ca3c542818150434eb0388c6fdc90b3a502f3c3e96/websockets-17.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:880069d21cc33a558dcf180924a546d1ecf8ada5be3e4e70acee87019d706a24", size = 228457, upload-time = "2026-08-26T14:58:04.78Z" }, + { url = "https://files.pythonhosted.org/packages/51/fe/f2331b6b7ccc67589891da354fa46a5cb79e95f83b9fd0e734d77f1f2140/websockets-17.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cec1bb8f22abccc8d20f8ca63df9be41600c26c190f4b97ee86c675fd4a863a6", size = 227265, upload-time = "2026-08-26T14:58:06.102Z" }, + { url = "https://files.pythonhosted.org/packages/47/a5/fb1642302f8ec77ca922203074f155a9831a5128ad75e725059a476d1227/websockets-17.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f3a1d577e081667dda7f8e5b4796e6e32f9713c93e2a3d930669519840a3c623", size = 226143, upload-time = "2026-08-26T14:58:07.464Z" }, + { url = "https://files.pythonhosted.org/packages/d7/41/7133fcfb63f5562750b269d6a845c689dde6a2c6407286da395beea19ddd/websockets-17.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dc053f9e95a76213c5eb7ed95779f7daf0d2bf0e4e03073629ebfa43a033f151", size = 223501, upload-time = "2026-08-26T14:58:08.766Z" }, + { url = "https://files.pythonhosted.org/packages/64/b1/82b36bfabc79ff2d383a1fc043cee6a13f794ef4f6bf1b4810ad6988cf6f/websockets-17.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:bb0efe019480a1c93e168ce96479273aaebd672fc8c350d5eed1e507ababb1b8", size = 226330, upload-time = "2026-08-26T14:58:09.987Z" }, + { url = "https://files.pythonhosted.org/packages/41/7d/5b511b9bf6e9ad331e6ff902fcbcc71c3794d10ef3b5efe80ccb8f0a7861/websockets-17.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:615746b12b26a3fd4077bc6fbeb277a1c192a45dd57b531d07ad9ed5c52a9a7a", size = 224980, upload-time = "2026-08-26T14:58:11.303Z" }, + { url = "https://files.pythonhosted.org/packages/e0/50/aed08f25301f8eef23be903ff9319fcf35630ca2bdec9d226f7d804dd5b3/websockets-17.1-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:1a20136d61f9ca3a31493732762661fafc2c20e8861930214e21afc6a8a692a2", size = 225478, upload-time = "2026-08-26T14:58:12.543Z" }, + { url = "https://files.pythonhosted.org/packages/3e/47/0d63d4168536b4682c9d19b7399443b1176f25dbb68878374fa716670230/websockets-17.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:2786cbd273ab69c22612db8a41229ddf2c158060b17b5928884bf388d07887f3", size = 226588, upload-time = "2026-08-26T14:58:14.457Z" }, + { url = "https://files.pythonhosted.org/packages/b3/dd/844bd0b6386fc81ed6a55f4b6dd26f01c6987eda205afa10175ea12b2164/websockets-17.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:b1c323fc3be1dc3f87f6c59458cb7d9e13dcbbf971d6c3f3e2bbaf58d3bfcdfe", size = 224336, upload-time = "2026-08-26T14:58:15.778Z" }, + { url = "https://files.pythonhosted.org/packages/96/18/03709c84bc88ec4dcea68d4be4ccd07d611073dec111203a5bf45af8809d/websockets-17.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:12c8e2b25df59755954a04dfa09c990b96691025aaf7eafd19ed6da24b09c18d", size = 225197, upload-time = "2026-08-26T14:58:17.141Z" }, + { url = "https://files.pythonhosted.org/packages/27/cf/0d1c694b6466c89e875b85b32b51312c472cf6708eee91914866f5087dde/websockets-17.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f58f58b4b29bbea2a3635e2c56eff4a3adab011fe383802a9e542e31b97085fc", size = 225493, upload-time = "2026-08-26T14:58:18.521Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f5/99857c3dd9676749f33e3668665a34ad6099505fb8d75eb084f49f7807a9/websockets-17.1-cp315-cp315t-win32.whl", hash = "sha256:f78a3ffb1994304db2c0c4588e4d1a518079b557054fa3bb985a6f5e50ff49a3", size = 217130, upload-time = "2026-08-26T14:58:20.037Z" }, + { url = "https://files.pythonhosted.org/packages/2c/84/77599922ab441bfe61508f97dab2c71f8e114d31793993ea54011db16199/websockets-17.1-cp315-cp315t-win_amd64.whl", hash = "sha256:ad68c28a27246fed109a4409393d677b7e1388345cbbd2f5aee5c182d8506110", size = 217448, upload-time = "2026-08-26T14:58:21.382Z" }, + { url = "https://files.pythonhosted.org/packages/ce/3c/8b9a225b523f06a9389be81f1b0ab07c49bec6014742e6aa359c1f920f1f/websockets-17.1-cp315-cp315t-win_arm64.whl", hash = "sha256:e552e0037230ac16e5f568de7012041344d1b18c9feed30ec2891b8eba55af81", size = 217372, upload-time = "2026-08-26T14:58:22.807Z" }, + { url = "https://files.pythonhosted.org/packages/41/63/23572870e01836a98346075b9e17a8bc24a6ddd9800a3204ceee58677f3c/websockets-17.1-py3-none-any.whl", hash = "sha256:f221081107b8c48184d99f7019604486376e7ef826037e70aad6b02540732c23", size = 211134, upload-time = "2026-08-26T17:25:31.397Z" }, +] + [[package]] name = "widgetsnbextension" version = "4.0.15"