sonolus.py 0.6.6__py3-none-any.whl → 0.7.0__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.
Potentially problematic release.
This version of sonolus.py might be problematic. Click here for more details.
- sonolus/build/engine.py +11 -6
- sonolus/build/level.py +2 -2
- sonolus/build/project.py +34 -2
- sonolus/script/archetype.py +9 -2
- sonolus/script/internal/generic.py +3 -4
- sonolus/script/level.py +49 -1
- sonolus/script/project.py +4 -1
- {sonolus_py-0.6.6.dist-info → sonolus_py-0.7.0.dist-info}/METADATA +1 -1
- {sonolus_py-0.6.6.dist-info → sonolus_py-0.7.0.dist-info}/RECORD +12 -12
- {sonolus_py-0.6.6.dist-info → sonolus_py-0.7.0.dist-info}/WHEEL +0 -0
- {sonolus_py-0.6.6.dist-info → sonolus_py-0.7.0.dist-info}/entry_points.txt +0 -0
- {sonolus_py-0.6.6.dist-info → sonolus_py-0.7.0.dist-info}/licenses/LICENSE +0 -0
sonolus/build/engine.py
CHANGED
|
@@ -182,11 +182,11 @@ def package_engine(
|
|
|
182
182
|
)
|
|
183
183
|
|
|
184
184
|
return PackagedEngine(
|
|
185
|
-
configuration=
|
|
186
|
-
play_data=
|
|
187
|
-
watch_data=
|
|
188
|
-
preview_data=
|
|
189
|
-
tutorial_data=
|
|
185
|
+
configuration=package_data(configuration),
|
|
186
|
+
play_data=package_data(play_data),
|
|
187
|
+
watch_data=package_data(watch_data),
|
|
188
|
+
preview_data=package_data(preview_data),
|
|
189
|
+
tutorial_data=package_data(tutorial_data),
|
|
190
190
|
rom=package_rom(rom),
|
|
191
191
|
)
|
|
192
192
|
|
|
@@ -410,6 +410,11 @@ def package_rom(rom: ReadOnlyMemory) -> bytes:
|
|
|
410
410
|
return gzip.compress(bytes(output))
|
|
411
411
|
|
|
412
412
|
|
|
413
|
-
def
|
|
413
|
+
def package_data(value: JsonValue) -> bytes:
|
|
414
414
|
json_data = json.dumps(value, separators=(",", ":")).encode("utf-8")
|
|
415
415
|
return gzip.compress(json_data)
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def unpackage_data(data: bytes) -> JsonValue:
|
|
419
|
+
json_data = gzip.decompress(data)
|
|
420
|
+
return json.loads(json_data)
|
sonolus/build/level.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
from sonolus.build.engine import JsonValue,
|
|
1
|
+
from sonolus.build.engine import JsonValue, package_data
|
|
2
2
|
from sonolus.script.level import LevelData
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def package_level_data(
|
|
6
6
|
level_data: LevelData,
|
|
7
7
|
) -> bytes:
|
|
8
|
-
return
|
|
8
|
+
return package_data(build_level_data(level_data))
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def build_level_data(
|
sonolus/build/project.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
1
2
|
from pathlib import Path
|
|
3
|
+
from typing import cast
|
|
2
4
|
|
|
3
5
|
from sonolus.build.collection import Asset, Collection, Srl
|
|
4
|
-
from sonolus.build.engine import package_engine
|
|
6
|
+
from sonolus.build.engine import package_engine, unpackage_data
|
|
5
7
|
from sonolus.build.level import package_level_data
|
|
6
8
|
from sonolus.script.engine import Engine
|
|
7
|
-
from sonolus.script.level import Level
|
|
9
|
+
from sonolus.script.level import ExternalLevelData, ExternalLevelDataDict, Level, LevelData, parse_external_level_data
|
|
8
10
|
from sonolus.script.project import BuildConfig, Project, ProjectSchema
|
|
9
11
|
|
|
10
12
|
BLANK_PNG = (
|
|
@@ -19,6 +21,13 @@ BLANK_AUDIO = (
|
|
|
19
21
|
|
|
20
22
|
def build_project_to_collection(project: Project, config: BuildConfig | None):
|
|
21
23
|
collection = load_resources_files_to_collection(project.resources)
|
|
24
|
+
for src_engine, converter in project.converters.items():
|
|
25
|
+
if src_engine is None:
|
|
26
|
+
continue
|
|
27
|
+
apply_converter_to_collection(collection, src_engine, converter)
|
|
28
|
+
fallback_converter = project.converters.get(None)
|
|
29
|
+
if fallback_converter is not None:
|
|
30
|
+
apply_converter_to_collection(collection, None, fallback_converter)
|
|
22
31
|
if config.override_resource_level_engines:
|
|
23
32
|
for level in collection.categories.get("levels", {}).values():
|
|
24
33
|
level["item"]["engine"] = project.engine.name
|
|
@@ -29,6 +38,29 @@ def build_project_to_collection(project: Project, config: BuildConfig | None):
|
|
|
29
38
|
return collection
|
|
30
39
|
|
|
31
40
|
|
|
41
|
+
def apply_converter_to_collection(
|
|
42
|
+
self, src_engine: str | None, converter: Callable[[ExternalLevelData], LevelData]
|
|
43
|
+
) -> None:
|
|
44
|
+
for level_details in self.categories.get("levels", {}).values():
|
|
45
|
+
level = level_details["item"]
|
|
46
|
+
if (
|
|
47
|
+
src_engine is not None
|
|
48
|
+
and level["engine"] != src_engine
|
|
49
|
+
and not (isinstance(level["engine"], dict) and level["engine"].get("name") == src_engine)
|
|
50
|
+
):
|
|
51
|
+
continue
|
|
52
|
+
packaged_data_srl = level.get("data")
|
|
53
|
+
packaged_data = self.repository.get(packaged_data_srl["hash"])
|
|
54
|
+
data = unpackage_data(packaged_data)
|
|
55
|
+
if not (isinstance(data, dict) and "bgmOffset" in data and "entities" in data):
|
|
56
|
+
raise ValueError(f"Level data for level '{level['name']}' is not valid")
|
|
57
|
+
parsed_data = parse_external_level_data(cast(ExternalLevelDataDict, data))
|
|
58
|
+
new_data = converter(parsed_data)
|
|
59
|
+
packaged_new_data = package_level_data(new_data)
|
|
60
|
+
new_data_srl = self.add_asset(packaged_new_data)
|
|
61
|
+
level["data"] = new_data_srl
|
|
62
|
+
|
|
63
|
+
|
|
32
64
|
def add_engine_to_collection(collection: Collection, project: Project, engine: Engine, config: BuildConfig | None):
|
|
33
65
|
packaged_engine = package_engine(engine.data, config)
|
|
34
66
|
item = {
|
sonolus/script/archetype.py
CHANGED
|
@@ -23,6 +23,7 @@ from sonolus.script.internal.value import BackingValue, DataValue, Value
|
|
|
23
23
|
from sonolus.script.num import Num
|
|
24
24
|
from sonolus.script.pointer import _backing_deref, _deref
|
|
25
25
|
from sonolus.script.record import Record
|
|
26
|
+
from sonolus.script.timing import TimescaleEase
|
|
26
27
|
from sonolus.script.values import zeros
|
|
27
28
|
|
|
28
29
|
_ENTITY_MEMORY_SIZE = 64
|
|
@@ -1226,6 +1227,12 @@ class EntityRef[A: _BaseArchetype](Record):
|
|
|
1226
1227
|
"""Return a new reference with the given archetype type."""
|
|
1227
1228
|
return EntityRef[archetype](index=self.index)
|
|
1228
1229
|
|
|
1230
|
+
@meta_fn
|
|
1231
|
+
def __eq__(self, other: Any) -> bool:
|
|
1232
|
+
if not ctx() and hasattr(self, "_ref_") and hasattr(other, "_ref_"):
|
|
1233
|
+
return self._ref_ is other._ref_
|
|
1234
|
+
return super().__eq__(other)
|
|
1235
|
+
|
|
1229
1236
|
@meta_fn
|
|
1230
1237
|
def get(self) -> A:
|
|
1231
1238
|
"""Get the entity."""
|
|
@@ -1361,10 +1368,10 @@ class StandardImport:
|
|
|
1361
1368
|
TIMESCALE_GROUP = Annotated[EntityRef[Any], imported(name=StandardImportName.TIMESCALE_GROUP)]
|
|
1362
1369
|
"""The timescale group, for timescale change markers."""
|
|
1363
1370
|
|
|
1364
|
-
TIMESCALE_EASE = Annotated[
|
|
1371
|
+
TIMESCALE_EASE = Annotated[TimescaleEase, imported(name=StandardImportName.TIMESCALE_EASE)]
|
|
1365
1372
|
"""The timescale ease type, for timescale change markers."""
|
|
1366
1373
|
|
|
1367
|
-
JUDGMENT = Annotated[
|
|
1374
|
+
JUDGMENT = Annotated[Judgment, imported(name=StandardImportName.JUDGMENT)]
|
|
1368
1375
|
"""The judgment of the entity.
|
|
1369
1376
|
|
|
1370
1377
|
Automatically set in watch mode for archetypes with a corresponding scored play mode archetype.
|
|
@@ -16,6 +16,9 @@ def validate_type_arg(arg: Any) -> Any:
|
|
|
16
16
|
if not arg._is_py_():
|
|
17
17
|
raise TypeError(f"Expected a compile-time constant type argument, got {arg}")
|
|
18
18
|
result = arg._as_py_()
|
|
19
|
+
if isinstance(result, type) and issubclass(result, Enum):
|
|
20
|
+
# E.g. if this is an IntEnum subclass, we call it on IntEnum, and then int, which gets us the result we want
|
|
21
|
+
result = validate_type_arg(result.__mro__[1])
|
|
19
22
|
if hasattr(result, "_type_mapping_"):
|
|
20
23
|
return result._type_mapping_
|
|
21
24
|
if get_origin(result) is Annotated:
|
|
@@ -27,10 +30,6 @@ def validate_type_arg(arg: Any) -> Any:
|
|
|
27
30
|
|
|
28
31
|
def validate_type_spec(spec: Any) -> PartialGeneric | TypeVar | type[Value]:
|
|
29
32
|
spec = validate_type_arg(spec)
|
|
30
|
-
if isinstance(spec, type) and issubclass(spec, Enum):
|
|
31
|
-
# For values like IntEnum subclasses, this will call validate_type_spec(IntEnum),
|
|
32
|
-
# which in turn will call it on int, so this works.
|
|
33
|
-
spec = validate_type_spec(spec.__mro__[1])
|
|
34
33
|
if isinstance(spec, PartialGeneric | TypeVar) or (isinstance(spec, type) and issubclass(spec, Value)):
|
|
35
34
|
return spec
|
|
36
35
|
if typing.get_origin(spec) is UnionType:
|
sonolus/script/level.py
CHANGED
|
@@ -4,7 +4,7 @@ import json
|
|
|
4
4
|
from collections.abc import Iterator
|
|
5
5
|
from os import PathLike
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any, NamedTuple, NotRequired, TypedDict
|
|
8
8
|
|
|
9
9
|
from sonolus.build.collection import Asset, load_asset
|
|
10
10
|
from sonolus.script.archetype import PlayArchetype, StandardArchetypeName, StandardImport
|
|
@@ -196,3 +196,51 @@ class TimescaleChange(PlayArchetype):
|
|
|
196
196
|
|
|
197
197
|
beat: StandardImport.BEAT
|
|
198
198
|
timescale: StandardImport.TIMESCALE
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class ExternalLevelDataDict(TypedDict):
|
|
202
|
+
bgmOffset: float
|
|
203
|
+
entities: list[ExternalEntityDataDict]
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class ExternalEntityDataDict(TypedDict):
|
|
207
|
+
name: NotRequired[str]
|
|
208
|
+
archetype: str
|
|
209
|
+
data: NotRequired[list[ExternalEntityDataValueDict]]
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
class ExternalEntityDataValueDict(TypedDict):
|
|
213
|
+
name: str
|
|
214
|
+
value: NotRequired[int | float]
|
|
215
|
+
ref: NotRequired[str]
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class ExternalLevelData(NamedTuple):
|
|
219
|
+
"""Level data parsed from an external source."""
|
|
220
|
+
|
|
221
|
+
bgm_offset: float
|
|
222
|
+
entities: list[ExternalEntityData]
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class ExternalEntityData(NamedTuple):
|
|
226
|
+
"""Entity data parsed from an external source."""
|
|
227
|
+
|
|
228
|
+
archetype: str
|
|
229
|
+
data: dict[str, Any]
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def parse_external_level_data(raw_data: ExternalLevelDataDict) -> ExternalLevelData:
|
|
233
|
+
bgm_offset = raw_data["bgmOffset"]
|
|
234
|
+
raw_entities = raw_data["entities"]
|
|
235
|
+
entity_name_to_index = {e["name"]: i for i, e in enumerate(raw_entities) if "name" in e}
|
|
236
|
+
entities = []
|
|
237
|
+
for raw_entity in raw_entities:
|
|
238
|
+
archetype = raw_entity["archetype"]
|
|
239
|
+
data = {}
|
|
240
|
+
for entry in raw_entity.get("data", []):
|
|
241
|
+
if "value" in entry:
|
|
242
|
+
data[entry["name"]] = entry["value"]
|
|
243
|
+
elif "ref" in entry:
|
|
244
|
+
data[entry["name"]] = entity_name_to_index.get(entry["ref"], 0)
|
|
245
|
+
entities.append(ExternalEntityData(archetype=archetype, data=data))
|
|
246
|
+
return ExternalLevelData(bgm_offset=bgm_offset, entities=entities)
|
sonolus/script/project.py
CHANGED
|
@@ -10,7 +10,7 @@ from sonolus.backend.optimize import optimize
|
|
|
10
10
|
from sonolus.backend.optimize.passes import CompilerPass
|
|
11
11
|
from sonolus.script.archetype import ArchetypeSchema
|
|
12
12
|
from sonolus.script.engine import Engine
|
|
13
|
-
from sonolus.script.level import Level
|
|
13
|
+
from sonolus.script.level import ExternalLevelData, Level, LevelData
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class Project:
|
|
@@ -20,6 +20,7 @@ class Project:
|
|
|
20
20
|
engine: The engine of the project.
|
|
21
21
|
levels: The levels of the project.
|
|
22
22
|
resources: The path to the resources of the project.
|
|
23
|
+
converters: A dictionary mapping engine names to converter functions, for converting loaded levels.
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
26
|
def __init__(
|
|
@@ -27,6 +28,7 @@ class Project:
|
|
|
27
28
|
engine: Engine,
|
|
28
29
|
levels: Iterable[Level] | Callable[[], Iterable[Level]] | None = None,
|
|
29
30
|
resources: PathLike | None = None,
|
|
31
|
+
converters: dict[str | None, Callable[[ExternalLevelData], LevelData]] | None = None,
|
|
30
32
|
):
|
|
31
33
|
self.engine = engine
|
|
32
34
|
match levels:
|
|
@@ -40,6 +42,7 @@ class Project:
|
|
|
40
42
|
raise TypeError(f"Invalid type for levels: {type(levels)}. Expected Iterable or Callable.")
|
|
41
43
|
self._levels = None
|
|
42
44
|
self.resources = Path(resources or "resources")
|
|
45
|
+
self.converters = converters or {}
|
|
43
46
|
|
|
44
47
|
def with_levels(self, levels: Iterable[Level] | Callable[[], Iterable[Level]] | None) -> Project:
|
|
45
48
|
"""Create a new project with the specified levels.
|
|
@@ -29,12 +29,12 @@ sonolus/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
29
29
|
sonolus/build/cli.py,sha256=-_lTN8zT7nQB2lySM8itAEPVutcEQI-TJ13BcPIfGb4,10113
|
|
30
30
|
sonolus/build/collection.py,sha256=sMYLfEIVn6UydLy7iEnNwrpIXDs7bGG32uQQgHXyhSI,12289
|
|
31
31
|
sonolus/build/compile.py,sha256=Yex-ZbSZmv9ujyAOVaMcfq-0NnZzFIqtmNYYaplF4Uc,6761
|
|
32
|
-
sonolus/build/engine.py,sha256=
|
|
33
|
-
sonolus/build/level.py,sha256=
|
|
32
|
+
sonolus/build/engine.py,sha256=xPhNnaFkfAuflp7CYb2NrXTgh9xCNN2h_hT_uWAYl1g,13445
|
|
33
|
+
sonolus/build/level.py,sha256=KLqUAtxIuIqrzeFURJA97rdqjA5pcvYSmwNZQhElaMQ,702
|
|
34
34
|
sonolus/build/node.py,sha256=gnX71RYDUOK_gYMpinQi-bLWO4csqcfiG5gFmhxzSec,1330
|
|
35
|
-
sonolus/build/project.py,sha256=
|
|
35
|
+
sonolus/build/project.py,sha256=h-9tcC60KqrpUOxGHFCK9trGVhGPUkciXiibasBEzu4,8097
|
|
36
36
|
sonolus/script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
-
sonolus/script/archetype.py,sha256=
|
|
37
|
+
sonolus/script/archetype.py,sha256=xoBVt4sQcC0e1ikyaM4NfcDZrMrJ0lHHUrxznl6dsU4,49492
|
|
38
38
|
sonolus/script/array.py,sha256=9uOUHZIDMyMT9q3APcXJWXWt97yG-AZoRlxwrvSY6SU,12367
|
|
39
39
|
sonolus/script/array_like.py,sha256=hUDdDaP306kflVv9YomdHIMXogrVjxsBXCrLvB9QpuE,9681
|
|
40
40
|
sonolus/script/bucket.py,sha256=SNqnfLGpnO_u-3LFFazdgzNk332OdDUIlmZHsuoVZuE,7674
|
|
@@ -47,7 +47,7 @@ sonolus/script/globals.py,sha256=nlXSNS4NRXsgQU2AJImVIs752h1WqsMnShSKgU011c4,102
|
|
|
47
47
|
sonolus/script/instruction.py,sha256=Dd-14D5Amo8nhPBr6DNyg2lpYw_rqZkT8Kix3HkfE7k,6793
|
|
48
48
|
sonolus/script/interval.py,sha256=dj6F2wn5uP6I6_mcZn-wIREgRUQbsLzhvhzB0oEyAdU,11290
|
|
49
49
|
sonolus/script/iterator.py,sha256=_ICY_yX7FG0Zbgs3NhVnaIBdVDpAeXjxJ_CQtq30l7Y,3774
|
|
50
|
-
sonolus/script/level.py,sha256=
|
|
50
|
+
sonolus/script/level.py,sha256=5M_XTzvXpFZTY-ODlS6M3GOiCIYN3F8rFuUgOiGxVBI,7824
|
|
51
51
|
sonolus/script/maybe.py,sha256=VYvTWgEfPzoXqI3i3zXhc4dz0pWBVoHmW8FtWH0GQvM,8194
|
|
52
52
|
sonolus/script/metadata.py,sha256=ttRK27eojHf3So50KQJ-8yj3udZoN1bli5iD-knaeLw,753
|
|
53
53
|
sonolus/script/num.py,sha256=924kWWZusW7oaWuvtQzdAMzkb4ZItWSJwNj3W9XrqZU,16041
|
|
@@ -55,7 +55,7 @@ sonolus/script/options.py,sha256=XVN-mL7Rwhd2Tu9YysYq9YDGpH_LazdmhqzSYE6nR3Q,945
|
|
|
55
55
|
sonolus/script/particle.py,sha256=RTfamg_ZTq7-qJ6j9paduNVUHCkw3hzkBK1QUbwwN7I,8403
|
|
56
56
|
sonolus/script/pointer.py,sha256=FoOfyD93r0G5d_2BaKfeOT9SqkOP3hq6sqtOs_Rb0c8,1511
|
|
57
57
|
sonolus/script/printing.py,sha256=mNYu9QWiacBBGZrnePZQMVwbbguoelUps9GiOK_aVRU,2096
|
|
58
|
-
sonolus/script/project.py,sha256=
|
|
58
|
+
sonolus/script/project.py,sha256=a9bRY5T8deRMR35iC-6cuqn4HiKwZHvVy9K-np-rAfI,4432
|
|
59
59
|
sonolus/script/quad.py,sha256=XoAjaUqR60zIrC_CwheZs7HwS-DRS58yUmlj9GIjX7k,11179
|
|
60
60
|
sonolus/script/record.py,sha256=igmawc0hqb98YVcZnPTThHvnIP88Qelhoge4cNJx45Q,12770
|
|
61
61
|
sonolus/script/runtime.py,sha256=rJZM_KbKmnwpjhDEpR0DrM6EMSEu46apIErWA_pfLJA,33321
|
|
@@ -75,7 +75,7 @@ sonolus/script/internal/context.py,sha256=Cd9US3GNHxs_96UcVdBAXGD-H4gCNnV9h5OfCW
|
|
|
75
75
|
sonolus/script/internal/descriptor.py,sha256=XRFey-EjiAm_--KsNl-8N0Mi_iyQwlPh68gDp0pKf3E,392
|
|
76
76
|
sonolus/script/internal/dict_impl.py,sha256=alu_wKGSk1kZajNf64qbe7t71shEzD4N5xNIATH8Swo,1885
|
|
77
77
|
sonolus/script/internal/error.py,sha256=ZNnsvQVQAnFKzcvsm6-sste2lo-tP5pPI8sD7XlAZWc,490
|
|
78
|
-
sonolus/script/internal/generic.py,sha256=
|
|
78
|
+
sonolus/script/internal/generic.py,sha256=_3d5Rn_tn214-77fPE67vdbdqt1PQF8-2WB_XDu5YRg,7551
|
|
79
79
|
sonolus/script/internal/impl.py,sha256=JzRk2iylXHNk7q7f_H84spsix2gcnoTqo-hLbIegjoI,3261
|
|
80
80
|
sonolus/script/internal/introspection.py,sha256=guL9_NR2D3OJAnNpeFdyYkO_vVXk-3KQr2-y4YielM0,1133
|
|
81
81
|
sonolus/script/internal/math_impls.py,sha256=nHSLgA7Tcx7jY1p07mYBCeSRmVx713bwdNayCIcaXSE,2652
|
|
@@ -86,8 +86,8 @@ sonolus/script/internal/simulation_context.py,sha256=LGxLTvxbqBIhoe1R-SfwGajNIDw
|
|
|
86
86
|
sonolus/script/internal/transient.py,sha256=y2AWABqF1aoaP6H4_2u4MMpNioC4OsZQCtPyNI0txqo,1634
|
|
87
87
|
sonolus/script/internal/tuple_impl.py,sha256=DPNdmmRmupU8Ah4_XKq6-PdT336l4nt15_uCJKQGkkk,3587
|
|
88
88
|
sonolus/script/internal/value.py,sha256=OngrCdmY_h6mV2Zgwqhuo4eYFad0kTk6263UAxctZcY,6963
|
|
89
|
-
sonolus_py-0.
|
|
90
|
-
sonolus_py-0.
|
|
91
|
-
sonolus_py-0.
|
|
92
|
-
sonolus_py-0.
|
|
93
|
-
sonolus_py-0.
|
|
89
|
+
sonolus_py-0.7.0.dist-info/METADATA,sha256=aTrZv-zipIgHI36FFgSO_bmIjPOAixQa4-CdHcq7Cvc,302
|
|
90
|
+
sonolus_py-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
91
|
+
sonolus_py-0.7.0.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
|
|
92
|
+
sonolus_py-0.7.0.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
|
|
93
|
+
sonolus_py-0.7.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|