flightdata 0.2.24__tar.gz → 0.2.26__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. {flightdata-0.2.24 → flightdata-0.2.26}/PKG-INFO +11 -5
  2. {flightdata-0.2.24 → flightdata-0.2.26}/README.md +6 -3
  3. {flightdata-0.2.24 → flightdata-0.2.26}/pyproject.toml +5 -5
  4. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/scripts/flightline.py +53 -37
  5. flightdata-0.2.26/test/data/script_tests/c6_on_0001.BIN +0 -0
  6. flightdata-0.2.26/test/data/script_tests/center_0003.bin +0 -0
  7. flightdata-0.2.26/test/data/script_tests/pilot_0004.BIN +0 -0
  8. flightdata-0.2.26/test/test_scripts.py +25 -0
  9. {flightdata-0.2.24 → flightdata-0.2.26}/uv.lock +17 -32
  10. {flightdata-0.2.24 → flightdata-0.2.26}/.github/workflows/publish_pypi.yml +0 -0
  11. {flightdata-0.2.24 → flightdata-0.2.26}/.gitignore +0 -0
  12. {flightdata-0.2.24 → flightdata-0.2.26}/.vscode/launch.json +0 -0
  13. {flightdata-0.2.24 → flightdata-0.2.26}/.vscode/settings.json +0 -0
  14. {flightdata-0.2.24 → flightdata-0.2.26}/LICENSE +0 -0
  15. {flightdata-0.2.24 → flightdata-0.2.26}/examples/__init__.py +0 -0
  16. {flightdata-0.2.24 → flightdata-0.2.26}/examples/data/__init__.py +0 -0
  17. {flightdata-0.2.24 → flightdata-0.2.26}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
  18. {flightdata-0.2.24 → flightdata-0.2.26}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
  19. {flightdata-0.2.24 → flightdata-0.2.26}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
  20. {flightdata-0.2.24 → flightdata-0.2.26}/examples/flight_dynamics/00000150.json +0 -0
  21. {flightdata-0.2.24 → flightdata-0.2.26}/examples/flight_dynamics/__init__.py +0 -0
  22. {flightdata-0.2.24 → flightdata-0.2.26}/examples/flight_dynamics/box.f3a +0 -0
  23. {flightdata-0.2.24 → flightdata-0.2.26}/examples/flight_dynamics/param_id.py +0 -0
  24. {flightdata-0.2.24 → flightdata-0.2.26}/examples/state_analysis/__init__.py +0 -0
  25. {flightdata-0.2.24 → flightdata-0.2.26}/examples/state_analysis/axes.py +0 -0
  26. {flightdata-0.2.24 → flightdata-0.2.26}/examples/state_analysis/state_fill_plot.py +0 -0
  27. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/__init__.py +0 -0
  28. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/base/__init__.py +0 -0
  29. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/base/collection.py +0 -0
  30. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/base/constructs.py +0 -0
  31. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/base/labeling.py +0 -0
  32. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/base/numpy_encoder.py +0 -0
  33. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/base/table.py +0 -0
  34. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/bindata.py +0 -0
  35. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/coefficients.py +0 -0
  36. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/environment/__init__.py +0 -0
  37. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/environment/environment.py +0 -0
  38. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/environment/wind.py +0 -0
  39. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/flight/__init__.py +0 -0
  40. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/flight/ardupilot.py +0 -0
  41. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/flight/fields.py +0 -0
  42. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/flight/flight.py +0 -0
  43. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/flight/parameters.py +0 -0
  44. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/flow.py +0 -0
  45. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/model/__init__.py +0 -0
  46. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/model/aerodynamic.py +0 -0
  47. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/model/thrust.py +0 -0
  48. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/origin.py +0 -0
  49. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/py.typed +0 -0
  50. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/schemas/__init__.py +0 -0
  51. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/schemas/fcj.py +0 -0
  52. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/scripts/collect_logs.py +0 -0
  53. {flightdata-0.2.24 → flightdata-0.2.26}/src/flightdata/state.py +0 -0
  54. {flightdata-0.2.24 → flightdata-0.2.26}/test/EmailedBox.f3a +0 -0
  55. {flightdata-0.2.24 → flightdata-0.2.26}/test/__init__.py +0 -0
  56. {flightdata-0.2.24 → flightdata-0.2.26}/test/base/__init__.py +0 -0
  57. {flightdata-0.2.24 → flightdata-0.2.26}/test/base/test_base_constructs.py +0 -0
  58. {flightdata-0.2.24 → flightdata-0.2.26}/test/base/test_table.py +0 -0
  59. {flightdata-0.2.24 → flightdata-0.2.26}/test/conftest.py +0 -0
  60. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/bin_parser_GPS.csv +0 -0
  61. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/bin_parser_POS.csv +0 -0
  62. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/make_inputs.py +0 -0
  63. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/manual_F3A_P23.json +0 -0
  64. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/p23.BIN +0 -0
  65. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/p23.json +0 -0
  66. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/p23_box.f3a +0 -0
  67. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/p23_fc.json +0 -0
  68. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/p23_flight.json +0 -0
  69. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/vtol_hover.bin +0 -0
  70. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/vtol_hover.json +0 -0
  71. {flightdata-0.2.24 → flightdata-0.2.26}/test/data/web_bin_parse.json +0 -0
  72. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_bindata.py +0 -0
  73. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_environment/__init__.py +0 -0
  74. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_environment/test_environment.py +0 -0
  75. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_environment/test_environment_wind.py +0 -0
  76. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_fields.py +0 -0
  77. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_flight.py +0 -0
  78. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_model/__init__.py +0 -0
  79. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_model/test_model_coefficients.py +0 -0
  80. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_model/test_model_flow.py +0 -0
  81. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_origin.py +0 -0
  82. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_state/__init__.py +0 -0
  83. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_state/test_state.py +0 -0
  84. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_state/test_state_builders.py +0 -0
  85. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_state/test_state_conversions.py +0 -0
  86. {flightdata-0.2.24 → flightdata-0.2.26}/test/test_state/test_state_measurements.py +0 -0
@@ -1,12 +1,15 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: flightdata
3
- Version: 0.2.24
3
+ Version: 0.2.26
4
4
  Summary: Python tools for handling flight data
5
5
  Author-email: Thomas David <thomasdavid0@gmail.com>
6
+ License-File: LICENSE
6
7
  Requires-Python: >=3.12
7
8
  Requires-Dist: numpy>=2.1.3
8
9
  Requires-Dist: pandas>=2.2.3
9
10
  Requires-Dist: pfc-geometry>=0.2.13
11
+ Provides-Extra: dataflash
12
+ Requires-Dist: ardupilot-log-reader>=0.3.5; extra == 'dataflash'
10
13
  Description-Content-Type: text/markdown
11
14
 
12
15
  ## FlightData
@@ -28,11 +31,14 @@ Further documentation will be provided here: https://pfcdocumentation.readthedoc
28
31
  ### Installation
29
32
 
30
33
  ```bash
31
- pip install pfc-geometry
34
+ pip install flightdata
35
+ # or to include ardupilot dataflash log parsing capability:
36
+ pip install flightdata[dataflash]
32
37
  ```
33
38
 
34
39
  ### Setup from source
35
40
 
36
41
  ```bash
37
- pip install .
38
- ```
42
+ pip install .
43
+ ```
44
+
@@ -17,11 +17,14 @@ Further documentation will be provided here: https://pfcdocumentation.readthedoc
17
17
  ### Installation
18
18
 
19
19
  ```bash
20
- pip install pfc-geometry
20
+ pip install flightdata
21
+ # or to include ardupilot dataflash log parsing capability:
22
+ pip install flightdata[dataflash]
21
23
  ```
22
24
 
23
25
  ### Setup from source
24
26
 
25
27
  ```bash
26
- pip install .
27
- ```
28
+ pip install .
29
+ ```
30
+
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "flightdata"
3
- version = "v0.2.24"
3
+ version = "0.2.26"
4
4
  description = "Python tools for handling flight data"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Thomas David", email = "thomasdavid0@gmail.com" }]
@@ -15,9 +15,9 @@ dependencies = [
15
15
  requires = ["hatchling"]
16
16
  build-backend = "hatchling.build"
17
17
 
18
- [tool.uv.sources]
19
- pfc-geometry = { path = "../geometry" , editable = true }
20
- ardupilot_log_reader = { path = "../ArdupilotLogReader" , editable = true }
18
+
19
+ [project.optional-dependencies]
20
+ dataflash = ["ardupilot_log_reader>=0.3.5"]
21
21
 
22
22
  [dependency-groups]
23
- dev = ["ardupilot_log_reader>=0.3.5", "pymavlink>=2.4.42", "pytest>=8.3.3"]
23
+ dev = ["pytest>=8.3.3"]
@@ -1,8 +1,10 @@
1
+ from ast import In
2
+ import sys
1
3
  from flightdata import Flight, Origin
2
4
  from geometry import GPS
3
5
  from pathlib import Path
4
6
  import argparse
5
-
7
+ import re
6
8
 
7
9
 
8
10
  def get_con_groups(log: Flight, channel: int):
@@ -14,64 +16,78 @@ def box_from_log(log: Flight, channel: int):
14
16
  grps = get_con_groups(log, channel)
15
17
  pilot = grps[0]
16
18
  centre = grps[1]
17
- # c6on = Flight(log.data.loc[log.data[f'rcin_c{channel}']>=1500])
18
- # groups = (c6on.time_flight.diff() > 1).cumsum()
19
- # pilot = Flight(c6on.data.loc[groups==0])
20
- # centre = Flight(c6on.data.loc[groups==1])
21
19
 
22
20
  return Origin.from_points("new", GPS(pilot.pos)[-1], GPS(centre.pos)[-1])
23
21
 
24
22
  def box_from_logs(pilot: Flight, centre: Flight):
25
23
  return Origin.from_points("new", GPS(*pilot.pos.iloc[-1]), GPS(*centre.pos.iloc[-1]))
26
24
 
25
+ re_logid = re.compile(r'[\d+]$')
26
+ def get_bin_from_number(folder: Path, number: str):
27
+ try:
28
+ return list(folder.glob(f"*{number}.BIN"))[0]
29
+ except IndexError:
30
+ return list(folder.glob(f"*{number}.bin"))[0]
27
31
 
28
- def main():
29
- parser = argparse.ArgumentParser(description='A tool for creating a flightline .f3a file from bin logs')
30
32
 
31
- parser.add_argument('-l', '--logdir', default='', help='folder to look for logs in')
32
- parser.add_argument('-p', '--pilot', default=None, help='flight log bin file to use, None for first')
33
- parser.add_argument('-c', '--centre', default=None, help='centre position bin file to use if input==None')
34
- parser.add_argument('-d', '--direction', default=None, help='heading of the box, if this is specified only pilot will be read')
35
- parser.add_argument('-i', '--input', default=6, help='channel used to indicate pilot or centre postions (pwm>=1500), None for two files')
36
33
 
37
- args = parser.parse_args()
34
+ def create_flightline(args) -> argparse.Namespace:
35
+ logdir = Path(args.logdir)
38
36
 
39
- print(args)
37
+ plog = logdir / args.pilot
38
+ if not plog.exists():
39
+ if args.pilot is None:
40
+ plog=sorted(list(logdir.glob("*.BIN")))[0]
41
+ elif args.pilot.isdigit():
42
+ plog = get_bin_from_number(logdir, args.pilot)
43
+ else:
44
+ raise FileNotFoundError(f'Could not find pilot log file: {args.pilot}')
40
45
 
41
- logs = sorted(list(Path(args.logdir).glob("*.BIN")))
42
- logids = [int(log.stem) for log in logs]
43
-
44
- if args.pilot in logs:
45
- plog = args.pilot
46
- elif args.pilot is None:
47
- plog=logs[0]
48
- elif args.pilot.isdigit():
49
- plog = logs[logids.index(int(args.pilot))]
50
-
51
46
  pilot = Flight.from_log(plog)
52
47
 
53
48
  print(f'Pilot position log: {plog}')
54
49
 
55
- if args.centre in logs:
56
- clog = args.centre
57
- elif args.centre is None:
58
- clog=None
59
- elif args.centre.isdigit():
60
- clog = logs[logids.index(int(args.centre))]
61
- if clog:
62
- centre = Flight.from_log(clog)
63
- print(f'Centre position log: {clog}')
64
-
65
50
  if args.centre:
51
+ clog = logdir / args.centre
52
+ if not clog.exists():
53
+ if args.centre is None:
54
+ clog=None
55
+ elif args.centre.isdigit():
56
+ clog = get_bin_from_number(logdir, args.centre)
57
+
58
+ print(f'Centre position log: {clog}' if clog else "No centre position log")
59
+ centre = Flight.from_log(clog) if clog else None
60
+
66
61
  box = Origin.from_points("new", GPS(*pilot.pos.iloc[-1]), GPS(*centre.pos.iloc[-1]))
67
62
  else:
68
- groups = get_con_groups(pilot, args.input)
69
63
  if args.direction:
70
- box = Origin("new", GPS(groups[0].pos)[-1], float(args.direction))
64
+ box = Origin("new", GPS(plog.pos)[-1], float(args.direction))
71
65
  else:
66
+ groups = get_con_groups(pilot, args.input)
72
67
  box = Origin.from_points("new", GPS(groups[0].pos)[-1], GPS(groups[1].pos)[-1])
73
68
 
74
- box.to_f3a_zone(Path(args.logdir) / f'box_{plog.stem}.f3a')
69
+ return box, plog.stem
70
+
71
+
72
+ def parse_args(args):
73
+ parser = argparse.ArgumentParser(description='A tool for creating a flightline .f3a file from bin logs')
74
+
75
+ parser.add_argument('-l', '--logdir', default='', help='folder to look for logs in')
76
+ parser.add_argument('-p', '--pilot', default=None, help='flight log bin file to use, None for first')
77
+ parser.add_argument('-c', '--centre', default=None, help='centre position bin file to use if input==None')
78
+ parser.add_argument('-d', '--direction', default=None, help='heading of the box, if this is specified only pilot will be read')
79
+ parser.add_argument('-i', '--input', default=6, help='channel used to indicate pilot or centre postions (pwm>=1500), None for two files')
80
+
81
+ args = parser.parse_args(args)
82
+
83
+ return args
84
+
85
+
86
+ def main():
87
+ args = parse_args(sys.argv[1:])
88
+ box, name = create_flightline(args)
89
+ box.to_f3a_zone(Path(args.logdir) / f'box_{name}.f3a')
90
+
75
91
 
76
92
  if __name__ == '__main__':
77
93
  main()
@@ -0,0 +1,25 @@
1
+ from flightdata.scripts import flightline as fl
2
+ import geometry as g
3
+ from pathlib import Path
4
+ import numpy as np
5
+ from pytest import approx
6
+
7
+ def test_get_bin_from_number():
8
+ bin = fl.get_bin_from_number(Path("test/data/script_tests"), 1)
9
+ assert bin.stem == "c6_on_0001"
10
+
11
+ bin = fl.get_bin_from_number(Path("test/data/script_tests"), 3)
12
+ assert bin.stem == "center_0003"
13
+
14
+
15
+
16
+ def test_flightline_two_bins():
17
+ box, name = fl.create_flightline(fl.parse_args(["-l", "test/data/script_tests", "-p", "pilot_0004.BIN", "-c", "3"]))
18
+ assert name == "pilot_0004"
19
+ assert isinstance(box.pos, g.GPS)
20
+
21
+ def test_flightline_c6on():
22
+ box, name = fl.create_flightline(fl.parse_args(["-l", "test/data/script_tests", "-p", "1"]))
23
+ assert name == "c6_on_0001"
24
+
25
+ assert np.degrees(box.heading) == approx(-34.44699010)
@@ -4,24 +4,17 @@ requires-python = ">=3.12"
4
4
  [[package]]
5
5
  name = "ardupilot-log-reader"
6
6
  version = "0.3.5"
7
- source = { editable = "../ArdupilotLogReader" }
7
+ source = { registry = "https://pypi.org/simple" }
8
8
  dependencies = [
9
9
  { name = "numpy" },
10
10
  { name = "pandas" },
11
11
  { name = "pymavlink" },
12
12
  ]
13
-
14
- [package.metadata]
15
- requires-dist = [
16
- { name = "numpy", specifier = ">=2.1.3" },
17
- { name = "pandas", specifier = ">=2.2.3" },
18
- { name = "pymavlink", specifier = ">=2.4.42" },
13
+ sdist = { url = "https://files.pythonhosted.org/packages/d4/81/f2f4b0d24cfee5b9bda0aa454cb6aaacc92f5cba2afc281be6fc9c466b4c/ardupilot_log_reader-0.3.5.tar.gz", hash = "sha256:8523a963e3c89254b6c7a72b5adedfe152ed1aec256e9fc2c1bbd7dd5c3033a9", size = 76674282 }
14
+ wheels = [
15
+ { url = "https://files.pythonhosted.org/packages/00/1f/1f49ca2e43e1e9abce1ff42d22409ccff3321c9dd4cd378d335b945966c3/ardupilot_log_reader-0.3.5-py3-none-any.whl", hash = "sha256:8f4aaae17a81fd6296ff883bc1d924b16ab4aa3783cc68131c10c222f6a87d91", size = 3756 },
19
16
  ]
20
17
 
21
- [package.metadata.requires-dev]
22
- dev = [{ name = "pytest", specifier = ">=8.3.3" }]
23
- lint = [{ name = "ruff", specifier = ">=0.7.3" }]
24
-
25
18
  [[package]]
26
19
  name = "colorama"
27
20
  version = "0.4.6"
@@ -33,7 +26,7 @@ wheels = [
33
26
 
34
27
  [[package]]
35
28
  name = "flightdata"
36
- version = "0.2.24"
29
+ version = "0.2.25"
37
30
  source = { editable = "." }
38
31
  dependencies = [
39
32
  { name = "numpy" },
@@ -41,26 +34,26 @@ dependencies = [
41
34
  { name = "pfc-geometry" },
42
35
  ]
43
36
 
37
+ [package.optional-dependencies]
38
+ dataflash = [
39
+ { name = "ardupilot-log-reader" },
40
+ ]
41
+
44
42
  [package.dev-dependencies]
45
43
  dev = [
46
- { name = "ardupilot-log-reader" },
47
- { name = "pymavlink" },
48
44
  { name = "pytest" },
49
45
  ]
50
46
 
51
47
  [package.metadata]
52
48
  requires-dist = [
49
+ { name = "ardupilot-log-reader", marker = "extra == 'dataflash'", specifier = ">=0.3.5" },
53
50
  { name = "numpy", specifier = ">=2.1.3" },
54
51
  { name = "pandas", specifier = ">=2.2.3" },
55
- { name = "pfc-geometry", editable = "../geometry" },
52
+ { name = "pfc-geometry", specifier = ">=0.2.13" },
56
53
  ]
57
54
 
58
55
  [package.metadata.requires-dev]
59
- dev = [
60
- { name = "ardupilot-log-reader", editable = "../ArdupilotLogReader" },
61
- { name = "pymavlink", specifier = ">=2.4.42" },
62
- { name = "pytest", specifier = ">=8.3.3" },
63
- ]
56
+ dev = [{ name = "pytest", specifier = ">=8.3.3" }]
64
57
 
65
58
  [[package]]
66
59
  name = "future"
@@ -206,22 +199,14 @@ wheels = [
206
199
  [[package]]
207
200
  name = "pfc-geometry"
208
201
  version = "0.2.13"
209
- source = { editable = "../geometry" }
202
+ source = { registry = "https://pypi.org/simple" }
210
203
  dependencies = [
211
204
  { name = "numpy" },
212
205
  { name = "pandas" },
213
206
  ]
214
-
215
- [package.metadata]
216
- requires-dist = [
217
- { name = "numpy", specifier = ">=2.1.3" },
218
- { name = "pandas", specifier = ">=2.2.3" },
219
- ]
220
-
221
- [package.metadata.requires-dev]
222
- dev = [
223
- { name = "numpy-quaternion", specifier = ">=2023.0.3" },
224
- { name = "pytest", specifier = ">=8.3.3" },
207
+ sdist = { url = "https://files.pythonhosted.org/packages/32/fb/496a3e54f846b296d3e52a7b7249e21469ac00209688687378c1ce55e35b/pfc_geometry-0.2.13.tar.gz", hash = "sha256:86fa4966d5e95f28dde75c7f39594ca14e4f3146d53bd9a8ccfbc0db3f5e424d", size = 28602 }
208
+ wheels = [
209
+ { url = "https://files.pythonhosted.org/packages/fe/2b/38166979e43c98b7b72c7c16d86e6994087a0e924a8f11f772aa2d1f09e6/pfc_geometry-0.2.13-py3-none-any.whl", hash = "sha256:29747fa647b4d72b67bf5d0a90fb0eac2bc973013da329518df1a554a293c2ea", size = 19823 },
225
210
  ]
226
211
 
227
212
  [[package]]
File without changes
File without changes