maps4fs 1.8.242__py3-none-any.whl → 1.8.244__py3-none-any.whl
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.
- maps4fs/generator/component/background.py +1 -1
- maps4fs/generator/component/i3d.py +90 -52
- maps4fs/generator/component/layer.py +6 -0
- maps4fs/generator/component/texture.py +33 -5
- maps4fs/generator/dem.py +13 -4
- maps4fs/generator/map.py +19 -0
- maps4fs/generator/settings.py +1 -0
- {maps4fs-1.8.242.dist-info → maps4fs-1.8.244.dist-info}/METADATA +5 -1
- {maps4fs-1.8.242.dist-info → maps4fs-1.8.244.dist-info}/RECORD +12 -12
- {maps4fs-1.8.242.dist-info → maps4fs-1.8.244.dist-info}/LICENSE.md +0 -0
- {maps4fs-1.8.242.dist-info → maps4fs-1.8.244.dist-info}/WHEEL +0 -0
- {maps4fs-1.8.242.dist-info → maps4fs-1.8.244.dist-info}/top_level.txt +0 -0
@@ -291,7 +291,7 @@ class Background(MeshComponent, ImageComponent):
|
|
291
291
|
mesh = self.mesh_from_np(
|
292
292
|
dem_data,
|
293
293
|
include_zeros=include_zeros,
|
294
|
-
z_scaling_factor=self.get_z_scaling_factor(),
|
294
|
+
z_scaling_factor=self.get_z_scaling_factor(ignore_height_scale_multiplier=True),
|
295
295
|
resize_factor=self.map.background_settings.resize_factor,
|
296
296
|
apply_decimation=self.map.background_settings.apply_decimation,
|
297
297
|
decimation_percent=self.map.background_settings.decimation_percent,
|
@@ -430,80 +430,118 @@ class I3d(XMLComponent):
|
|
430
430
|
|
431
431
|
return tree_schema # type: ignore
|
432
432
|
|
433
|
+
def _get_random_tree(
|
434
|
+
self, tree_schema: list[dict[str, str]], leaf_type: str | None = None
|
435
|
+
) -> dict[str, str]:
|
436
|
+
"""Gets a random tree from the tree schema.
|
437
|
+
If the leaf type is provided, the method tries to get a tree with the same leaf type.
|
438
|
+
|
439
|
+
Arguments:
|
440
|
+
tree_schema (list[dict[str, str]]): The tree schema.
|
441
|
+
leaf_type (str, optional): The leaf type of the tree. Defaults to None.
|
442
|
+
|
443
|
+
Returns:
|
444
|
+
dict[str, str]: The random tree from the schema
|
445
|
+
"""
|
446
|
+
if not leaf_type:
|
447
|
+
return choice(tree_schema)
|
448
|
+
|
449
|
+
try:
|
450
|
+
leaf_type = leaf_type.split("_")[0]
|
451
|
+
except IndexError:
|
452
|
+
return choice(tree_schema)
|
453
|
+
|
454
|
+
if leaf_type == "mixed":
|
455
|
+
trees_with_leaf_type = [tree for tree in tree_schema if tree.get("leaf_type")]
|
456
|
+
return choice(trees_with_leaf_type)
|
457
|
+
|
458
|
+
trees_by_leaf_type = [tree for tree in tree_schema if tree.get("leaf_type") == leaf_type]
|
459
|
+
if not trees_by_leaf_type:
|
460
|
+
return choice(tree_schema)
|
461
|
+
|
462
|
+
return choice(trees_by_leaf_type)
|
463
|
+
|
433
464
|
def _add_forests(self) -> None:
|
434
465
|
"""Adds forests to the map I3D file."""
|
435
466
|
tree_schema = self._read_tree_schema()
|
436
467
|
if not tree_schema:
|
437
468
|
return
|
438
469
|
|
439
|
-
|
440
|
-
|
470
|
+
if self.map.texture_settings.use_precise_tags:
|
471
|
+
forest_layers = self.map.get_texture_layers(by_usage=Parameters.FOREST)
|
472
|
+
else:
|
473
|
+
layer = self.map.get_texture_layer(by_usage=Parameters.FOREST)
|
474
|
+
forest_layers = [layer] if layer else []
|
475
|
+
if not forest_layers:
|
441
476
|
self.logger.warning("Forest layer not found.")
|
442
477
|
return
|
443
478
|
|
444
|
-
|
445
|
-
forest_image_path = forest_layer.get_preview_or_path(weights_directory)
|
479
|
+
node_id = TREE_NODE_ID_STARTING_VALUE
|
446
480
|
|
447
|
-
|
448
|
-
self.
|
449
|
-
|
481
|
+
for forest_layer in forest_layers:
|
482
|
+
weights_directory = self.game.weights_dir_path(self.map_directory)
|
483
|
+
forest_image_path = forest_layer.get_preview_or_path(weights_directory)
|
450
484
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
if scene_node is None:
|
455
|
-
self.logger.warning("Scene element not found in I3D file.")
|
456
|
-
return
|
485
|
+
if not forest_image_path or not os.path.isfile(forest_image_path):
|
486
|
+
self.logger.warning("Forest image not found.")
|
487
|
+
continue
|
457
488
|
|
458
|
-
|
489
|
+
tree = self.get_tree()
|
490
|
+
root = tree.getroot()
|
491
|
+
scene_node = root.find(".//Scene")
|
492
|
+
if scene_node is None:
|
493
|
+
self.logger.warning("Scene element not found in I3D file.")
|
494
|
+
return
|
459
495
|
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
496
|
+
trees_node = self.create_element(
|
497
|
+
"TransformGroup",
|
498
|
+
{
|
499
|
+
"name": "trees",
|
500
|
+
"translation": "0 0 0",
|
501
|
+
"nodeId": str(node_id),
|
502
|
+
},
|
503
|
+
)
|
504
|
+
node_id += 1
|
469
505
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
506
|
+
not_resized_dem = self.get_not_resized_dem()
|
507
|
+
if not_resized_dem is None:
|
508
|
+
self.logger.warning("Not resized DEM not found.")
|
509
|
+
return
|
474
510
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
self.
|
480
|
-
|
481
|
-
|
511
|
+
forest_image = cv2.imread(forest_image_path, cv2.IMREAD_UNCHANGED)
|
512
|
+
for x, y in self.non_empty_pixels(
|
513
|
+
forest_image, step=self.map.i3d_settings.forest_density
|
514
|
+
):
|
515
|
+
shifted_x, shifted_y = self.randomize_coordinates(
|
516
|
+
(x, y),
|
517
|
+
self.map.i3d_settings.forest_density,
|
518
|
+
self.map.i3d_settings.trees_relative_shift,
|
519
|
+
)
|
482
520
|
|
483
|
-
|
521
|
+
shifted_x, shifted_y = int(shifted_x), int(shifted_y)
|
484
522
|
|
485
|
-
|
523
|
+
z = self.get_z_coordinate_from_dem(not_resized_dem, shifted_x, shifted_y)
|
486
524
|
|
487
|
-
|
488
|
-
|
525
|
+
xcs, ycs = self.top_left_coordinates_to_center((shifted_x, shifted_y))
|
526
|
+
node_id += 1
|
489
527
|
|
490
|
-
|
528
|
+
rotation = randint(-180, 180)
|
491
529
|
|
492
|
-
|
493
|
-
|
494
|
-
|
530
|
+
random_tree = self._get_random_tree(tree_schema, forest_layer.precise_usage)
|
531
|
+
tree_name = random_tree["name"]
|
532
|
+
tree_id = random_tree["reference_id"]
|
495
533
|
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
534
|
+
data = {
|
535
|
+
"name": tree_name,
|
536
|
+
"translation": f"{xcs} {z} {ycs}",
|
537
|
+
"rotation": f"0 {rotation} 0",
|
538
|
+
"referenceId": str(tree_id),
|
539
|
+
"nodeId": str(node_id),
|
540
|
+
}
|
541
|
+
trees_node.append(self.create_element("ReferenceNode", data))
|
504
542
|
|
505
|
-
|
506
|
-
|
543
|
+
scene_node.append(trees_node)
|
544
|
+
self.save_tree(tree)
|
507
545
|
|
508
546
|
@staticmethod
|
509
547
|
def randomize_coordinates(
|
@@ -44,6 +44,8 @@ class Layer:
|
|
44
44
|
invisible: bool = False,
|
45
45
|
procedural: list[str] | None = None,
|
46
46
|
border: int | None = None,
|
47
|
+
precise_tags: dict[str, str | list[str] | bool] | None = None,
|
48
|
+
precise_usage: str | None = None,
|
47
49
|
):
|
48
50
|
self.name = name
|
49
51
|
self.count = count
|
@@ -58,6 +60,8 @@ class Layer:
|
|
58
60
|
self.invisible = invisible
|
59
61
|
self.procedural = procedural
|
60
62
|
self.border = border
|
63
|
+
self.precise_tags = precise_tags
|
64
|
+
self.precise_usage = precise_usage
|
61
65
|
|
62
66
|
def to_json(self) -> dict[str, str | list[str] | bool]: # type: ignore
|
63
67
|
"""Returns dictionary with layer data.
|
@@ -78,6 +82,8 @@ class Layer:
|
|
78
82
|
"invisible": self.invisible,
|
79
83
|
"procedural": self.procedural,
|
80
84
|
"border": self.border,
|
85
|
+
"precise_tags": self.precise_tags,
|
86
|
+
"precise_usage": self.precise_usage,
|
81
87
|
}
|
82
88
|
|
83
89
|
data = {k: v for k, v in data.items() if v is not None}
|
@@ -123,6 +123,17 @@ class Texture(ImageComponent):
|
|
123
123
|
return layer
|
124
124
|
return None
|
125
125
|
|
126
|
+
def get_layers_by_usage(self, usage: str) -> list[Layer]:
|
127
|
+
"""Returns layer by usage.
|
128
|
+
|
129
|
+
Arguments:
|
130
|
+
usage (str): Usage of the layer.
|
131
|
+
|
132
|
+
Returns:
|
133
|
+
list[Layer]: List of layers.
|
134
|
+
"""
|
135
|
+
return [layer for layer in self.layers if layer.usage == usage]
|
136
|
+
|
126
137
|
def process(self) -> None:
|
127
138
|
"""Processes the data to generate textures."""
|
128
139
|
self._prepare_weights()
|
@@ -211,7 +222,7 @@ class Texture(ImageComponent):
|
|
211
222
|
if self.rotation:
|
212
223
|
# Iterate over the layers which have tags and rotate them.
|
213
224
|
for layer in tqdm(self.layers, desc="Rotating textures", unit="layer"):
|
214
|
-
if layer.tags:
|
225
|
+
if layer.tags or layer.precise_tags:
|
215
226
|
self.logger.debug("Rotating layer %s.", layer.name)
|
216
227
|
layer_paths = layer.paths(self._weights_dir)
|
217
228
|
layer_paths += [layer.path_preview(self._weights_dir)]
|
@@ -263,7 +274,7 @@ class Texture(ImageComponent):
|
|
263
274
|
Arguments:
|
264
275
|
layer (Layer): Layer with textures and tags.
|
265
276
|
"""
|
266
|
-
if layer.tags is None:
|
277
|
+
if layer.tags is None and layer.precise_tags is None:
|
267
278
|
size = (self.map_size, self.map_size)
|
268
279
|
else:
|
269
280
|
size = (self.map_rotated_size, self.map_rotated_size)
|
@@ -316,7 +327,9 @@ class Texture(ImageComponent):
|
|
316
327
|
def draw(self) -> None:
|
317
328
|
"""Iterates over layers and fills them with polygons from OSM data."""
|
318
329
|
layers = self.layers_by_priority()
|
319
|
-
layers = [
|
330
|
+
layers = [
|
331
|
+
layer for layer in layers if layer.tags is not None or layer.precise_tags is not None
|
332
|
+
]
|
320
333
|
|
321
334
|
cumulative_image = None
|
322
335
|
|
@@ -376,7 +389,18 @@ class Texture(ImageComponent):
|
|
376
389
|
info_layer_data (dict[list[list[int]]]): Dictionary to store info layer data.
|
377
390
|
layer_image (np.ndarray): Layer image.
|
378
391
|
"""
|
379
|
-
|
392
|
+
tags = layer.tags
|
393
|
+
if self.map.texture_settings.use_precise_tags:
|
394
|
+
if layer.precise_tags:
|
395
|
+
self.logger.debug(
|
396
|
+
"Using precise tags: %s for layer %s.", layer.precise_tags, layer.name
|
397
|
+
)
|
398
|
+
tags = layer.precise_tags
|
399
|
+
|
400
|
+
if tags is None:
|
401
|
+
return
|
402
|
+
|
403
|
+
for polygon in self.objects_generator(tags, layer.width, layer.info_layer):
|
380
404
|
if not len(polygon) > 2:
|
381
405
|
self.logger.debug("Skipping polygon with less than 3 points.")
|
382
406
|
continue
|
@@ -746,7 +770,11 @@ class Texture(ImageComponent):
|
|
746
770
|
preview_size,
|
747
771
|
)
|
748
772
|
|
749
|
-
active_layers = [
|
773
|
+
active_layers = [
|
774
|
+
layer
|
775
|
+
for layer in self.layers
|
776
|
+
if layer.tags is not None or layer.precise_tags is not None
|
777
|
+
]
|
750
778
|
self.logger.debug("Following layers have tag textures: %s.", len(active_layers))
|
751
779
|
|
752
780
|
images = [
|
maps4fs/generator/dem.py
CHANGED
@@ -144,15 +144,24 @@ class DEM(Component):
|
|
144
144
|
data = self.dtm_provider.get_numpy()
|
145
145
|
except Exception as e: # pylint: disable=W0718
|
146
146
|
self.logger.error("Failed to get DEM data from DTM provider: %s.", e)
|
147
|
-
raise
|
147
|
+
raise ValueError(
|
148
|
+
f"Failed to get DEM data from DTM provider: {e}. "
|
149
|
+
"Try using different DTM provider."
|
150
|
+
)
|
148
151
|
|
149
152
|
if len(data.shape) != 2:
|
150
153
|
self.logger.error("DTM provider returned incorrect data: more than 1 channel.")
|
151
|
-
raise ValueError(
|
154
|
+
raise ValueError(
|
155
|
+
"DTM provider returned incorrect data: more than 1 channel. "
|
156
|
+
"Try using different DTM provider."
|
157
|
+
)
|
152
158
|
|
153
159
|
if data.dtype not in ["int16", "uint16", "float", "float32"]:
|
154
160
|
self.logger.error("DTM provider returned incorrect data type: %s.", data.dtype)
|
155
|
-
raise ValueError(
|
161
|
+
raise ValueError(
|
162
|
+
f"DTM provider returned incorrect data type: {data.dtype}. "
|
163
|
+
"Try using different DTM provider."
|
164
|
+
)
|
156
165
|
|
157
166
|
self.logger.debug(
|
158
167
|
"DEM data was retrieved from DTM provider. Shape: %s, dtype: %s. Min: %s, max: %s.",
|
@@ -167,7 +176,7 @@ class DEM(Component):
|
|
167
176
|
# Check if the data contains any non zero values, otherwise raise an error.
|
168
177
|
if not np.any(data):
|
169
178
|
self.logger.error("DTM provider returned empty data.")
|
170
|
-
raise ValueError("DTM provider returned empty data.")
|
179
|
+
raise ValueError("DTM provider returned empty data. Try using different DTM provider.")
|
171
180
|
|
172
181
|
# 1. Resize DEM data to the output resolution.
|
173
182
|
resampled_data = self.resize_to_output(data)
|
maps4fs/generator/map.py
CHANGED
@@ -307,6 +307,25 @@ class Map:
|
|
307
307
|
return texture_component.get_layer_by_usage(by_usage)
|
308
308
|
return None
|
309
309
|
|
310
|
+
def get_texture_layers(
|
311
|
+
self,
|
312
|
+
by_usage: str | None = None,
|
313
|
+
) -> None | list[Layer]:
|
314
|
+
"""Get texture layers by usage.
|
315
|
+
|
316
|
+
Arguments:
|
317
|
+
by_usage (str, optional): Texture usage.
|
318
|
+
|
319
|
+
Returns:
|
320
|
+
None | list[Layer]: List of texture layers.
|
321
|
+
"""
|
322
|
+
texture_component = self.get_texture_component()
|
323
|
+
if not texture_component:
|
324
|
+
return None
|
325
|
+
if by_usage:
|
326
|
+
return texture_component.get_layers_by_usage(by_usage)
|
327
|
+
return None
|
328
|
+
|
310
329
|
def previews(self) -> list[str]:
|
311
330
|
"""Get list of preview images.
|
312
331
|
|
maps4fs/generator/settings.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: maps4fs
|
3
|
-
Version: 1.8.
|
3
|
+
Version: 1.8.244
|
4
4
|
Summary: Generate map templates for Farming Simulator from real places.
|
5
5
|
Author-email: iwatkot <iwatkot@gmail.com>
|
6
6
|
License: MIT License
|
@@ -523,6 +523,8 @@ Let's have a closer look at the fields:
|
|
523
523
|
- `invisible` - set it to True for the textures, which should not be drawn in the files, but only to save the data in the JSON file (related to the previous field).
|
524
524
|
- `procedural` - is a list of corresponding files, that will be used for a procedural generation. For example: `"procedural": ["PG_meadow", "PG_acres"]` - means that the texture will be used for two procedural generation files: `masks/PG_meadow.png` and `masks/PG_acres.png`. Note, that the one procuderal name can be applied to multiple textures, in this case they will be merged into one mask.
|
525
525
|
- `border` - this value defines the border between the texture and the edge of the map. It's used to prevent the texture from being drawn on the edge of the map. The value is in pixels.
|
526
|
+
- `precise_tags` - can be used for more specific tags, for example instead of `"natural": "wood"` you can use `"leaf_type": "broadleaved"` to draw only broadleaved trees.
|
527
|
+
- `precise_usage` - the same as `usage`, but being used with `precise_tags`.
|
526
528
|
|
527
529
|
## Background terrain
|
528
530
|
|
@@ -655,6 +657,8 @@ You can also apply some advanced settings to the map generation process.<br>
|
|
655
657
|
|
656
658
|
- Use cache - if enabled, the tool will use the cached OSM data for generating the map. It's useful when you're generating the same map multiple times and don't want to download the OSM data each time. But if you've made some changes to the OSM data, you should disable this option to get the updated data. By default, it's set to True. This option has no effect when you're using the custom OSM file.
|
657
659
|
|
660
|
+
- Use precise tags - if enabled, the tool will use the precise tags from the texture schema and will ignore basic tags specified for the texture. In the default schema being used for specific types of forests: broadleaved, needleleaved, mixed, and so on. Note, that if it's enabled and the object does not have the precise tag, it will not be drawn on the map. By default, it's set to False.
|
661
|
+
|
658
662
|
### Splines Advanced settings
|
659
663
|
|
660
664
|
- Splines density - number of points, which will be added (interpolate) between each pair of existing points. The higher the value, the denser the spline will be. It can smooth the splines, but high values can in opposite make the splines look unnatural.
|
@@ -1,20 +1,20 @@
|
|
1
1
|
maps4fs/__init__.py,sha256=EGvLVoRpSt4jITswsGbe1ISVmGAZAMQJcBmTwtyuVxI,335
|
2
2
|
maps4fs/logger.py,sha256=HQrDyj72mUjVYo25aR_-_SxVn2rfFjDCNbj-JKJdSnE,1488
|
3
3
|
maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
4
|
-
maps4fs/generator/dem.py,sha256=
|
4
|
+
maps4fs/generator/dem.py,sha256=CDfdDGCWhFn2_QYY5TtxgsXm3lgJ4W4qD-46UU3u-ck,13207
|
5
5
|
maps4fs/generator/game.py,sha256=NZaxj5z7WzMiHzAvQyr-TvVjGoHgqGldM6ZsItuYyzA,11292
|
6
|
-
maps4fs/generator/map.py,sha256=
|
6
|
+
maps4fs/generator/map.py,sha256=64uIHCwfpFyFXZJSayB0tuRFn0LVuTwf0wrAi4KMv00,13600
|
7
7
|
maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
|
8
|
-
maps4fs/generator/settings.py,sha256=
|
8
|
+
maps4fs/generator/settings.py,sha256=285LjC5mUuzpHNPubBqd928MU7Yd_ZlLEnkBY3RbiHs,6937
|
9
9
|
maps4fs/generator/statistics.py,sha256=aynS3zbAtiwnU_YLKHPTiiaKW98_suvQUhy1SGBA6mc,2448
|
10
10
|
maps4fs/generator/component/__init__.py,sha256=s01yVVVi8R2xxNvflu2D6wTd9I_g73AMM2x7vAC7GX4,490
|
11
|
-
maps4fs/generator/component/background.py,sha256=
|
11
|
+
maps4fs/generator/component/background.py,sha256=QwyTaltQOTo3lD1uxewY99zw5Wd91CBWRQ35cC67WuE,21047
|
12
12
|
maps4fs/generator/component/config.py,sha256=RitKgFDZPzjA1fi8GcEi1na75qqaueUvpcITHjBvCXc,3674
|
13
13
|
maps4fs/generator/component/grle.py,sha256=KlNbbYY4oyFfB_0qTInrweBTyLUW0koSSpqclkRw-Lk,19381
|
14
|
-
maps4fs/generator/component/i3d.py,sha256=
|
15
|
-
maps4fs/generator/component/layer.py,sha256=
|
14
|
+
maps4fs/generator/component/i3d.py,sha256=QsqtyOLyc_Y10UthV03EjZO60mHBubPvbEvLIsxzank,23017
|
15
|
+
maps4fs/generator/component/layer.py,sha256=hbTBMLamKOWv_MXbnk-LjLyNV91jPsF33UEc17rBZCM,6185
|
16
16
|
maps4fs/generator/component/satellite.py,sha256=oZBHjP_QY0ik1-Vk7JqMS__zIG8ffw2voeozB7-HUQc,4946
|
17
|
-
maps4fs/generator/component/texture.py,sha256=
|
17
|
+
maps4fs/generator/component/texture.py,sha256=ELU5QwysZaMPH9QQkE5jzIHAOzZ_Y8khcT9ruZuxQpQ,31803
|
18
18
|
maps4fs/generator/component/base/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
19
19
|
maps4fs/generator/component/base/component.py,sha256=CIR4Fjn9YfLU4y7nB_jOaz7PjGFvBcDnHlvXxeahpdM,21499
|
20
20
|
maps4fs/generator/component/base/component_image.py,sha256=2QnJ9xm0D54v4whg7bc1s-kwRVjZHhOo1OR5jHr1Qp0,4786
|
@@ -53,8 +53,8 @@ maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,4
|
|
53
53
|
maps4fs/toolbox/background.py,sha256=RclEqxEWLbMxuEkkegQP8jybzugwQ1_R3rdfDe0s21U,2104
|
54
54
|
maps4fs/toolbox/custom_osm.py,sha256=X6ZlPqiOhNjkmdD_qVroIfdOl9Rb90cDwVSLDVYgx80,1892
|
55
55
|
maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
|
56
|
-
maps4fs-1.8.
|
57
|
-
maps4fs-1.8.
|
58
|
-
maps4fs-1.8.
|
59
|
-
maps4fs-1.8.
|
60
|
-
maps4fs-1.8.
|
56
|
+
maps4fs-1.8.244.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
|
57
|
+
maps4fs-1.8.244.dist-info/METADATA,sha256=P1k1UFEjijon_156MSDJV1TQq3LXmyrUg5XXhQ-F2SQ,47093
|
58
|
+
maps4fs-1.8.244.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
59
|
+
maps4fs-1.8.244.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
|
60
|
+
maps4fs-1.8.244.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|