r5py 1.0.6__tar.gz → 1.0.7__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.

Potentially problematic release.


This version of r5py might be problematic. Click here for more details.

Files changed (123) hide show
  1. {r5py-1.0.6/src/r5py.egg-info → r5py-1.0.7}/PKG-INFO +3 -3
  2. {r5py-1.0.6 → r5py-1.0.7}/README.md +2 -2
  3. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/__init__.py +1 -1
  4. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/regional_task.py +42 -11
  5. {r5py-1.0.6 → r5py-1.0.7/src/r5py.egg-info}/PKG-INFO +3 -3
  6. {r5py-1.0.6 → r5py-1.0.7}/tests/test_regional_task.py +3 -1
  7. {r5py-1.0.6 → r5py-1.0.7}/LICENSE +0 -0
  8. {r5py-1.0.6 → r5py-1.0.7}/MANIFEST.in +0 -0
  9. {r5py-1.0.6 → r5py-1.0.7}/pyproject.toml +0 -0
  10. {r5py-1.0.6 → r5py-1.0.7}/setup.cfg +0 -0
  11. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/__main__.py +0 -0
  12. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/__init__.py +0 -0
  13. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/access_leg.py +0 -0
  14. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/base_travel_time_matrix.py +0 -0
  15. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/detailed_itineraries.py +0 -0
  16. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/direct_leg.py +0 -0
  17. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/egress_leg.py +0 -0
  18. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/elevation_cost_function.py +0 -0
  19. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/elevation_model.py +0 -0
  20. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/file_storage.py +0 -0
  21. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/isochrones.py +0 -0
  22. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/scenario.py +0 -0
  23. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/street_layer.py +0 -0
  24. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/street_segment.py +0 -0
  25. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/transfer_leg.py +0 -0
  26. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/transit_layer.py +0 -0
  27. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/transit_leg.py +0 -0
  28. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/transport_mode.py +0 -0
  29. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/transport_network.py +0 -0
  30. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/travel_time_matrix.py +0 -0
  31. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/trip.py +0 -0
  32. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/trip_leg.py +0 -0
  33. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/r5/trip_planner.py +0 -0
  34. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/__init__.py +0 -0
  35. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/camel_to_snake_case.py +0 -0
  36. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/classpath.py +0 -0
  37. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/config.py +0 -0
  38. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/contains_gtfs_data.py +0 -0
  39. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/data_validation.py +0 -0
  40. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/environment.py +0 -0
  41. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/exceptions.py +0 -0
  42. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/file_digest.py +0 -0
  43. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/good_enough_equidistant_crs.py +0 -0
  44. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/jvm.py +0 -0
  45. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/memory_footprint.py +0 -0
  46. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/parse_int_date.py +0 -0
  47. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/sample_data_set.py +0 -0
  48. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/snake_to_camel_case.py +0 -0
  49. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/spatially_clustered_geodataframe.py +0 -0
  50. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/validating_requests_session.py +0 -0
  51. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/warnings.py +0 -0
  52. {r5py-1.0.6 → r5py-1.0.7}/src/r5py/util/working_copy.py +0 -0
  53. {r5py-1.0.6 → r5py-1.0.7}/src/r5py.egg-info/SOURCES.txt +0 -0
  54. {r5py-1.0.6 → r5py-1.0.7}/src/r5py.egg-info/dependency_links.txt +0 -0
  55. {r5py-1.0.6 → r5py-1.0.7}/src/r5py.egg-info/requires.txt +0 -0
  56. {r5py-1.0.6 → r5py-1.0.7}/src/r5py.egg-info/top_level.txt +0 -0
  57. {r5py-1.0.6 → r5py-1.0.7}/tests/__init__.py +0 -0
  58. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest.py +0 -0
  59. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/__init__.py +0 -0
  60. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/data_directory.py +0 -0
  61. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/destinations.py +0 -0
  62. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/file_digest.py +0 -0
  63. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/garbage_collection.py +0 -0
  64. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/origins.py +0 -0
  65. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/r5_jar.py +0 -0
  66. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/routing_parameters.py +0 -0
  67. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/routing_results.py +0 -0
  68. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/sample_data.py +0 -0
  69. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/transport_network.py +0 -0
  70. {r5py-1.0.6 → r5py-1.0.7}/tests/conftest_d/upstream_r5.py +0 -0
  71. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_broken_gtfs.zip +0 -0
  72. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_detailed_itineraries_bicycle.gpkg.zip +0 -0
  73. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_detailed_itineraries_car.gpkg.zip +0 -0
  74. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_detailed_itineraries_transit.gpkg.zip +0 -0
  75. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_detailed_itineraries_walk.gpkg.zip +0 -0
  76. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_invalid_points_duplicate_ids.geojson +0 -0
  77. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_invalid_points_no_id_column.geojson +0 -0
  78. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_isochrones_bicycle.gpkg.zip +0 -0
  79. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_isochrones_car.gpkg.zip +0 -0
  80. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_isochrones_from_multiple_origins.gpkg.zip +0 -0
  81. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_isochrones_transit.gpkg.zip +0 -0
  82. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_isochrones_walk.gpkg.zip +0 -0
  83. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_multiple_origins.geojson +0 -0
  84. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_snapped_population_grid_centroids.geojson +0 -0
  85. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_travel_times_bicycle.csv +0 -0
  86. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_travel_times_car.csv +0 -0
  87. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_travel_times_transit.csv +0 -0
  88. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_travel_times_walk.csv +0 -0
  89. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_valid_points_data.geojson +0 -0
  90. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_valid_single_point_data.geojson +0 -0
  91. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_walking_details_not_snapped.csv +0 -0
  92. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_walking_details_snapped.csv +0 -0
  93. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_walking_times_not_snapped.csv +0 -0
  94. {r5py-1.0.6 → r5py-1.0.7}/tests/data/test_walking_times_snapped.csv +0 -0
  95. {r5py-1.0.6 → r5py-1.0.7}/tests/temporary_directory.py +0 -0
  96. {r5py-1.0.6 → r5py-1.0.7}/tests/test_camel_to_snake_case.py +0 -0
  97. {r5py-1.0.6 → r5py-1.0.7}/tests/test_classpath.py +0 -0
  98. {r5py-1.0.6 → r5py-1.0.7}/tests/test_config.py +0 -0
  99. {r5py-1.0.6 → r5py-1.0.7}/tests/test_contains_gtfs_data.py +0 -0
  100. {r5py-1.0.6 → r5py-1.0.7}/tests/test_data_validation.py +0 -0
  101. {r5py-1.0.6 → r5py-1.0.7}/tests/test_detailed_itineraries.py +0 -0
  102. {r5py-1.0.6 → r5py-1.0.7}/tests/test_deterministic_behaviour.py +0 -0
  103. {r5py-1.0.6 → r5py-1.0.7}/tests/test_elevation_cost_function.py +0 -0
  104. {r5py-1.0.6 → r5py-1.0.7}/tests/test_file_digest.py +0 -0
  105. {r5py-1.0.6 → r5py-1.0.7}/tests/test_file_storage.py +0 -0
  106. {r5py-1.0.6 → r5py-1.0.7}/tests/test_good_enough_equidistant_crs.py +0 -0
  107. {r5py-1.0.6 → r5py-1.0.7}/tests/test_isochrones.py +0 -0
  108. {r5py-1.0.6 → r5py-1.0.7}/tests/test_java_casting.py +0 -0
  109. {r5py-1.0.6 → r5py-1.0.7}/tests/test_memory_footprint.py +0 -0
  110. {r5py-1.0.6 → r5py-1.0.7}/tests/test_parse_int_date.py +0 -0
  111. {r5py-1.0.6 → r5py-1.0.7}/tests/test_sample_data_set.py +0 -0
  112. {r5py-1.0.6 → r5py-1.0.7}/tests/test_snake_to_camel_case.py +0 -0
  113. {r5py-1.0.6 → r5py-1.0.7}/tests/test_street_layer.py +0 -0
  114. {r5py-1.0.6 → r5py-1.0.7}/tests/test_transit_layer.py +0 -0
  115. {r5py-1.0.6 → r5py-1.0.7}/tests/test_transport_mode.py +0 -0
  116. {r5py-1.0.6 → r5py-1.0.7}/tests/test_transport_network.py +0 -0
  117. {r5py-1.0.6 → r5py-1.0.7}/tests/test_travel_time_matrix.py +0 -0
  118. {r5py-1.0.6 → r5py-1.0.7}/tests/test_trip.py +0 -0
  119. {r5py-1.0.6 → r5py-1.0.7}/tests/test_trip_leg.py +0 -0
  120. {r5py-1.0.6 → r5py-1.0.7}/tests/test_trip_planner.py +0 -0
  121. {r5py-1.0.6 → r5py-1.0.7}/tests/test_validating_request_session.py +0 -0
  122. {r5py-1.0.6 → r5py-1.0.7}/tests/test_verbose_warnings.py +0 -0
  123. {r5py-1.0.6 → r5py-1.0.7}/tests/test_working_directory.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: r5py
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: Python wrapper for the R5 routing analysis engine
5
5
  Author: Christoph Fink, Willem Klumpenhouwer, Marcus Sairava, Rafael Pereira, Henrikki Tenkanen
6
6
  License: GPL-3.0-or-later or MIT
@@ -164,6 +164,6 @@ your project better.
164
164
  [r5-github]: https://github.com/conveyal/r5/
165
165
  [r5r-github]: https://github.com/ipeaGIT/r5r/
166
166
  [r5r-vignette]: https://ipeagit.github.io/r5r/
167
- [rtd-quickstart]: https://r5py.readthedocs.io/en/stable/user-guide/user-manual/quickstart.html
168
- [rtd-installation]: https://r5py.readthedocs.io/en/stable/user-guide/installation/installation.html
167
+ [rtd-quickstart]: https://r5py.readthedocs.io/stable/user-guide/user-manual/quickstart.html
168
+ [rtd-installation]: https://r5py.readthedocs.io/stable/user-guide/installation/installation.html
169
169
  [rtd-link]: https://r5py.readthedocs.io/
@@ -101,6 +101,6 @@ your project better.
101
101
  [r5-github]: https://github.com/conveyal/r5/
102
102
  [r5r-github]: https://github.com/ipeaGIT/r5r/
103
103
  [r5r-vignette]: https://ipeagit.github.io/r5r/
104
- [rtd-quickstart]: https://r5py.readthedocs.io/en/stable/user-guide/user-manual/quickstart.html
105
- [rtd-installation]: https://r5py.readthedocs.io/en/stable/user-guide/installation/installation.html
104
+ [rtd-quickstart]: https://r5py.readthedocs.io/stable/user-guide/user-manual/quickstart.html
105
+ [rtd-installation]: https://r5py.readthedocs.io/stable/user-guide/installation/installation.html
106
106
  [rtd-link]: https://r5py.readthedocs.io/
@@ -2,7 +2,7 @@
2
2
 
3
3
  """Python wrapper for the R5 routing analysis engine."""
4
4
 
5
- __version__ = "1.0.6"
5
+ __version__ = "1.0.7"
6
6
 
7
7
 
8
8
  from .r5 import (
@@ -38,9 +38,9 @@ class RegionalTask:
38
38
  access_modes=[TransportMode.WALK],
39
39
  egress_modes=None, # default: access_modes
40
40
  max_time=datetime.timedelta(hours=2),
41
- max_time_walking=datetime.timedelta(hours=2),
42
- max_time_cycling=datetime.timedelta(hours=2),
43
- max_time_driving=datetime.timedelta(hours=2),
41
+ max_time_walking=None,
42
+ max_time_cycling=None,
43
+ max_time_driving=None,
44
44
  speed_walking=3.6,
45
45
  speed_cycling=12.0,
46
46
  max_public_transport_rides=8,
@@ -90,7 +90,10 @@ class RegionalTask:
90
90
  egress_modes : list[r5py.TransportMode]
91
91
  Mode of transport from public transport stops. Default: access_modes
92
92
  max_time : datetime.timedelta
93
- Maximum trip duration. Default: 2 hours
93
+ Maximum trip duration. If any of ``max_time_walking``,
94
+ ``max_time_cycling``, or ``max_time_driving`` are set, ``max_time``
95
+ is increased to the maximum value of those, if it is lower.
96
+ Default: 2 hours
94
97
  max_time_walking : datetime.timedelta
95
98
  Maximum time spent walking, potentially including access and egress
96
99
  Default: max_time
@@ -128,15 +131,15 @@ class RegionalTask:
128
131
  self.percentiles = percentiles
129
132
 
130
133
  self.max_time = max_time
131
- self.max_time_walking = (
132
- max_time_walking if max_time_walking is not None else max_time
133
- )
134
134
  self.max_time_cycling = (
135
135
  max_time_cycling if max_time_cycling is not None else max_time
136
136
  )
137
137
  self.max_time_driving = (
138
138
  max_time_driving if max_time_driving is not None else max_time
139
139
  )
140
+ self.max_time_walking = (
141
+ max_time_walking if max_time_walking is not None else max_time
142
+ )
140
143
 
141
144
  self.speed_cycling = speed_cycling
142
145
  self.speed_walking = speed_walking
@@ -333,10 +336,29 @@ class RegionalTask:
333
336
  @max_time.setter
334
337
  def max_time(self, max_time):
335
338
  self._max_time = max_time
336
- max_time = int(max_time.total_seconds() / 60)
337
- self._regional_task.streetTime = max_time
338
- self._regional_task.maxTripDurationMinutes = max_time
339
- self._regional_task.maxCarTime = max_time
339
+
340
+ try:
341
+ max_time_cycling = self.max_time_cycling
342
+ if max_time_cycling > max_time:
343
+ max_time_cycling = max_time
344
+ except AttributeError:
345
+ pass
346
+ try:
347
+ max_time_driving = self.max_time_driving
348
+ if max_time_driving > max_time:
349
+ max_time_driving = max_time
350
+ except AttributeError:
351
+ pass
352
+ try:
353
+ max_time_walking = self.max_time_walking
354
+ if max_time_walking > max_time:
355
+ max_time_walking = max_time
356
+ except AttributeError:
357
+ pass
358
+
359
+ max_time_sec = int(max_time.total_seconds() / 60)
360
+ self._regional_task.streetTime = max_time_sec
361
+ self._regional_task.maxTripDurationMinutes = max_time_sec
340
362
 
341
363
  @property
342
364
  def max_time_cycling(self):
@@ -353,6 +375,9 @@ class RegionalTask:
353
375
  self._max_time_cycling = max_time_cycling
354
376
  self._regional_task.maxBikeTime = int(max_time_cycling.total_seconds() / 60)
355
377
 
378
+ if self.max_time < max_time_cycling:
379
+ self.max_time = max_time_cycling
380
+
356
381
  @property
357
382
  def max_time_driving(self):
358
383
  """Restrict routes to at most this duration of driving (datetime.timedelta)."""
@@ -363,6 +388,9 @@ class RegionalTask:
363
388
  self._max_time_driving = max_time_driving
364
389
  self._regional_task.maxCarTime = int(max_time_driving.total_seconds() / 60)
365
390
 
391
+ if self.max_time < max_time_driving:
392
+ self.max_time = max_time_driving
393
+
366
394
  @property
367
395
  def max_time_walking(self):
368
396
  """
@@ -378,6 +406,9 @@ class RegionalTask:
378
406
  self._max_time_walking = max_time_walking
379
407
  self._regional_task.maxWalkTime = int(max_time_walking.total_seconds() / 60)
380
408
 
409
+ if self.max_time < max_time_walking:
410
+ self.max_time = max_time_walking
411
+
381
412
  @property
382
413
  def percentiles(self):
383
414
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: r5py
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: Python wrapper for the R5 routing analysis engine
5
5
  Author: Christoph Fink, Willem Klumpenhouwer, Marcus Sairava, Rafael Pereira, Henrikki Tenkanen
6
6
  License: GPL-3.0-or-later or MIT
@@ -164,6 +164,6 @@ your project better.
164
164
  [r5-github]: https://github.com/conveyal/r5/
165
165
  [r5r-github]: https://github.com/ipeaGIT/r5r/
166
166
  [r5r-vignette]: https://ipeagit.github.io/r5r/
167
- [rtd-quickstart]: https://r5py.readthedocs.io/en/stable/user-guide/user-manual/quickstart.html
168
- [rtd-installation]: https://r5py.readthedocs.io/en/stable/user-guide/installation/installation.html
167
+ [rtd-quickstart]: https://r5py.readthedocs.io/stable/user-guide/user-manual/quickstart.html
168
+ [rtd-installation]: https://r5py.readthedocs.io/stable/user-guide/installation/installation.html
169
169
  [rtd-link]: https://r5py.readthedocs.io/
@@ -281,7 +281,6 @@ class TestRegionalTask:
281
281
  assert regional_task.max_time == expected
282
282
  assert regional_task._regional_task.streetTime == expected_java
283
283
  assert regional_task._regional_task.maxTripDurationMinutes == expected_java
284
- assert regional_task._regional_task.maxCarTime == expected_java
285
284
 
286
285
  @pytest.mark.parametrize(
287
286
  ["max_time_cycling", "expected", "expected_java"],
@@ -313,6 +312,7 @@ class TestRegionalTask:
313
312
  regional_task.max_time_cycling = max_time_cycling
314
313
  assert regional_task.max_time_cycling == expected
315
314
  assert regional_task._regional_task.maxBikeTime == expected_java
315
+ assert regional_task.max_time >= regional_task.max_time_cycling
316
316
 
317
317
  @pytest.mark.parametrize(
318
318
  ["max_time_driving", "expected", "expected_java"],
@@ -344,6 +344,7 @@ class TestRegionalTask:
344
344
  regional_task.max_time_driving = max_time_driving
345
345
  assert regional_task.max_time_driving == expected
346
346
  assert regional_task._regional_task.maxCarTime == expected_java
347
+ assert regional_task.max_time >= regional_task.max_time_driving
347
348
 
348
349
  @pytest.mark.parametrize(
349
350
  ["max_time_walking", "expected", "expected_java"],
@@ -375,6 +376,7 @@ class TestRegionalTask:
375
376
  regional_task.max_time_walking = max_time_walking
376
377
  assert regional_task.max_time_walking == expected
377
378
  assert regional_task._regional_task.maxWalkTime == expected_java
379
+ assert regional_task.max_time >= regional_task.max_time_walking
378
380
 
379
381
  @pytest.mark.parametrize(
380
382
  ["percentiles"],
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes