sonolus.py 0.5.2__py3-none-any.whl → 0.6.1__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/backend/utils.py CHANGED
@@ -1,4 +1,3 @@
1
- # ruff: noqa: N802
2
1
  import ast
3
2
  import inspect
4
3
  from collections.abc import Callable
@@ -1,4 +1,3 @@
1
- # ruff: noqa: N802
2
1
  from __future__ import annotations
3
2
 
4
3
  import ast
@@ -244,7 +244,9 @@ class Collection:
244
244
  use_item = level[key]
245
245
  if "item" not in use_item:
246
246
  continue
247
- use_item["item"] = self.get_item(category, use_item["item"])
247
+ name = use_item["item"]["name"]
248
+ if name in self.categories.get(category, {}):
249
+ use_item["item"] = self.get_item(category, name)
248
250
 
249
251
  def _create_base_directory(self, path: Asset) -> Path:
250
252
  base_dir = Path(path) / BASE_PATH.strip("/")
sonolus/build/project.py CHANGED
@@ -19,6 +19,9 @@ BLANK_AUDIO = (
19
19
 
20
20
  def build_project_to_collection(project: Project, config: BuildConfig | None):
21
21
  collection = load_resources_files_to_collection(project.resources)
22
+ if config.override_resource_level_engines:
23
+ for level in collection.categories.get("levels", {}).values():
24
+ level["item"]["engine"] = project.engine.name
22
25
  add_engine_to_collection(collection, project, project.engine, config)
23
26
  for level in project.levels:
24
27
  add_level_to_collection(collection, project, level)
@@ -245,6 +245,21 @@ class _KeyDescriptor(SonolusDescriptor):
245
245
  raise AttributeError("Archetype key is read-only and cannot be set")
246
246
 
247
247
 
248
+ class _ArchetypeLifeDescriptor(SonolusDescriptor):
249
+ def __get__(self, instance, owner):
250
+ if not ctx():
251
+ raise RuntimeError("Archetype life is only available during compilation")
252
+ if ctx().global_state.mode not in {Mode.PLAY, Mode.WATCH}:
253
+ raise RuntimeError(f"Archetype life is not available in mode '{ctx().global_state.mode.value}'")
254
+ if instance is not None:
255
+ return _deref(ctx().blocks.ArchetypeLife, instance.id * ArchetypeLife._size_(), ArchetypeLife)
256
+ else:
257
+ return _deref(ctx().blocks.ArchetypeLife, owner.id * ArchetypeLife._size_(), ArchetypeLife)
258
+
259
+ def __set__(self, instance, value):
260
+ raise AttributeError("Archetype life is read-only and cannot be set")
261
+
262
+
248
263
  def imported(*, name: str | None = None) -> Any:
249
264
  """Declare a field as imported.
250
265
 
@@ -590,6 +605,7 @@ class _BaseArchetype:
590
605
  cls.key = _KeyDescriptor(cls.key)
591
606
  cls.name = _NameDescriptor(cls.name)
592
607
  cls.is_scored = _IsScoredDescriptor(cls.is_scored)
608
+ cls.life = _ArchetypeLifeDescriptor()
593
609
 
594
610
  @classmethod
595
611
  def _init_fields(cls):
@@ -605,6 +621,7 @@ class _BaseArchetype:
605
621
  "id",
606
622
  "key",
607
623
  "name",
624
+ "life",
608
625
  "is_scored",
609
626
  "_key_",
610
627
  "_derived_base_",
@@ -809,7 +826,10 @@ class PlayArchetype(_BaseArchetype):
809
826
  _supported_callbacks_ = PLAY_CALLBACKS
810
827
 
811
828
  is_scored: ClassVar[bool] = False
812
- """Whether the entity contributes to combo and score."""
829
+ """Whether entities of this archetype contribute to combo and score."""
830
+
831
+ life: ClassVar[ArchetypeLife]
832
+ """How this entities of this archetype contribute to life depending on judgment."""
813
833
 
814
834
  def preprocess(self):
815
835
  """Perform upfront processing.
@@ -925,18 +945,6 @@ class PlayArchetype(_BaseArchetype):
925
945
  """Whether this entity is despawned."""
926
946
  return self._info.state == 2
927
947
 
928
- @property
929
- @meta_fn
930
- def life(self) -> ArchetypeLife:
931
- """How this entity contributes to life."""
932
- if not ctx():
933
- raise RuntimeError("Calling life is only allowed within a callback")
934
- match self._data_:
935
- case _ArchetypeSelfData() | _ArchetypeReferenceData():
936
- return _deref(ctx().blocks.ArchetypeLife, self.id * ArchetypeLife._size_(), ArchetypeLife)
937
- case _:
938
- raise RuntimeError("Life is not available in level data")
939
-
940
948
  @property
941
949
  @meta_fn
942
950
  def result(self) -> PlayEntityInput:
@@ -952,26 +960,6 @@ class PlayArchetype(_BaseArchetype):
952
960
  case _:
953
961
  raise RuntimeError("Result is only accessible from the entity itself")
954
962
 
955
- @classmethod
956
- def update_life(
957
- cls,
958
- perfect_increment: int | None = None,
959
- great_increment: int | None = None,
960
- good_increment: int | None = None,
961
- miss_increment: int | None = None,
962
- ):
963
- """Update the life of this archetype.
964
-
965
- Values default to 0.
966
-
967
- Args:
968
- perfect_increment: The increment for perfect life.
969
- great_increment: The increment for great life.
970
- good_increment: The increment for good life.
971
- miss_increment: The increment for miss life.
972
- """
973
- archetype_life_of(cls).update(perfect_increment, great_increment, good_increment, miss_increment)
974
-
975
963
 
976
964
  class WatchArchetype(_BaseArchetype):
977
965
  """Base class for watch mode archetypes.
@@ -993,6 +981,12 @@ class WatchArchetype(_BaseArchetype):
993
981
 
994
982
  _supported_callbacks_ = WATCH_ARCHETYPE_CALLBACKS
995
983
 
984
+ is_scored: ClassVar[bool] = False
985
+ """Whether entities of this archetype contribute to combo and score."""
986
+
987
+ life: ClassVar[ArchetypeLife]
988
+ """How this entities of this archetype contribute to life depending on judgment."""
989
+
996
990
  def preprocess(self):
997
991
  """Perform upfront processing.
998
992
 
@@ -1058,18 +1052,6 @@ class WatchArchetype(_BaseArchetype):
1058
1052
  """Whether this entity is active."""
1059
1053
  return self._info.state == 1
1060
1054
 
1061
- @property
1062
- @meta_fn
1063
- def life(self) -> ArchetypeLife:
1064
- """How this entity contributes to life."""
1065
- if not ctx():
1066
- raise RuntimeError("Calling life is only allowed within a callback")
1067
- match self._data_:
1068
- case _ArchetypeSelfData() | _ArchetypeReferenceData():
1069
- return _deref(ctx().blocks.ArchetypeLife, self.id * ArchetypeLife._size_(), ArchetypeLife)
1070
- case _:
1071
- raise RuntimeError("Life is not available in level data")
1072
-
1073
1055
  @property
1074
1056
  @meta_fn
1075
1057
  def result(self) -> WatchEntityInput:
@@ -1090,26 +1072,6 @@ class WatchArchetype(_BaseArchetype):
1090
1072
  if cls._exported_fields_:
1091
1073
  raise RuntimeError("Watch archetypes cannot have exported fields")
1092
1074
 
1093
- @classmethod
1094
- def update_life(
1095
- cls,
1096
- perfect_increment: int | None = None,
1097
- great_increment: int | None = None,
1098
- good_increment: int | None = None,
1099
- miss_increment: int | None = None,
1100
- ):
1101
- """Update the life of this archetype.
1102
-
1103
- Values default to 0.
1104
-
1105
- Args:
1106
- perfect_increment: The increment for perfect life.
1107
- great_increment: The increment for great life.
1108
- good_increment: The increment for good life.
1109
- miss_increment: The increment for miss life.
1110
- """
1111
- archetype_life_of(cls).update(perfect_increment, great_increment, good_increment, miss_increment)
1112
-
1113
1075
 
1114
1076
  class PreviewArchetype(_BaseArchetype):
1115
1077
  """Base class for preview mode archetypes.
@@ -1167,6 +1129,23 @@ class PreviewArchetype(_BaseArchetype):
1167
1129
  raise RuntimeError("Preview archetypes cannot have exported fields")
1168
1130
 
1169
1131
 
1132
+ @meta_fn
1133
+ def get_archetype_by_name(name: str) -> AnyArchetype:
1134
+ """Return the archetype with the given name in the current mode."""
1135
+ if not ctx():
1136
+ raise RuntimeError("Archetypes by name are only available during compilation.")
1137
+ name = validate_value(name)
1138
+ if not name._is_py_():
1139
+ raise TypeError(f"Invalid name: '{name}'")
1140
+ name = name._as_py_()
1141
+ if not isinstance(name, str):
1142
+ raise TypeError(f"Invalid name: '{name}'")
1143
+ archetypes_by_name = ctx().global_state.archetypes_by_name
1144
+ if name not in archetypes_by_name:
1145
+ raise KeyError(f"Unknown archetype: '{name}'")
1146
+ return archetypes_by_name[name]
1147
+
1148
+
1170
1149
  @meta_fn
1171
1150
  def entity_info_at(index: int) -> PlayEntityInfo | WatchEntityInfo | PreviewEntityInfo:
1172
1151
  """Retrieve entity info of the entity at the given index.
@@ -1186,23 +1165,6 @@ def entity_info_at(index: int) -> PlayEntityInfo | WatchEntityInfo | PreviewEnti
1186
1165
  raise RuntimeError(f"Entity info is not available in mode '{ctx().global_state.mode}'")
1187
1166
 
1188
1167
 
1189
- @meta_fn
1190
- def archetype_life_of(archetype: type[_BaseArchetype] | _BaseArchetype) -> ArchetypeLife:
1191
- """Retrieve the archetype life of the given archetype.
1192
-
1193
- Available in play and watch mode.
1194
- """
1195
- archetype = validate_value(archetype) # type: ignore
1196
- archetype = archetype._as_py_() # type: ignore
1197
- if not ctx():
1198
- raise RuntimeError("Calling archetype_life_of is only allowed within a callback")
1199
- match ctx().global_state.mode:
1200
- case Mode.PLAY | Mode.WATCH:
1201
- return _deref(ctx().blocks.ArchetypeLife, archetype.id * ArchetypeLife._size_(), ArchetypeLife)
1202
- case _:
1203
- raise RuntimeError(f"Archetype life is not available in mode '{ctx().global_state.mode}'")
1204
-
1205
-
1206
1168
  class PlayEntityInfo(Record):
1207
1169
  index: int
1208
1170
  archetype_id: int
sonolus/script/bucket.py CHANGED
@@ -230,7 +230,7 @@ def bucket(*, sprites: list[_BucketSprite], unit: str | None = None) -> Any:
230
230
  type Buckets = NewType("Buckets", Any) # type: ignore
231
231
 
232
232
 
233
- @dataclass_transform()
233
+ @dataclass_transform(kw_only_default=True)
234
234
  def buckets[T](cls: type[T]) -> T | Buckets:
235
235
  """Decorator to define a buckets class.
236
236
 
sonolus/script/debug.py CHANGED
@@ -82,6 +82,9 @@ def assert_false(value: int | float | bool, message: str | None = None):
82
82
 
83
83
  @meta_fn
84
84
  def assert_unreachable(message: str | None = None) -> Never:
85
+ # This works a bit differently from assert_never from typing in that it throws an error if the Sonolus.py
86
+ # compiler cannot guarantee that this function will not be called, which is different from what type checkers
87
+ # may be able to infer.
85
88
  message = validate_value(message)._as_py_() or "Unreachable code reached" # type: ignore
86
89
  raise RuntimeError(message)
87
90
 
sonolus/script/effect.py CHANGED
@@ -139,7 +139,7 @@ def effect(name: str) -> Any:
139
139
  type Effects = NewType("Effects", Any) # type: ignore
140
140
 
141
141
 
142
- @dataclass_transform()
142
+ @dataclass_transform(kw_only_default=True)
143
143
  def effects[T](cls: type[T]) -> T | Effects:
144
144
  """Decorator to define effect clips.
145
145
 
@@ -74,7 +74,7 @@ type TutorialInstructions = NewType("TutorialInstructions", Any) # type: ignore
74
74
  type TutorialInstructionIcons = NewType("TutorialInstructionIcons", Any) # type: ignore
75
75
 
76
76
 
77
- @dataclass_transform()
77
+ @dataclass_transform(kw_only_default=True)
78
78
  def instructions[T](cls: type[T]) -> T | TutorialInstructions:
79
79
  """Decorator to define tutorial instructions.
80
80
 
@@ -109,7 +109,7 @@ def instructions[T](cls: type[T]) -> T | TutorialInstructions:
109
109
  return instance
110
110
 
111
111
 
112
- @dataclass_transform()
112
+ @dataclass_transform(kw_only_default=True)
113
113
  def instruction_icons[T](cls: type[T]) -> T | TutorialInstructionIcons:
114
114
  """Decorator to define tutorial instruction icons.
115
115
 
@@ -1,3 +1,5 @@
1
+ from typing import Never, assert_never
2
+
1
3
  from sonolus.backend.ops import Op
2
4
  from sonolus.script.array import Array
3
5
  from sonolus.script.array_like import ArrayLike
@@ -78,10 +80,13 @@ def _reversed(iterable):
78
80
 
79
81
 
80
82
  @meta_fn
81
- def _zip(*iterables):
83
+ def _zip(*iterables, strict: bool = False):
82
84
  from sonolus.backend.visitor import compile_and_call
83
85
  from sonolus.script.containers import Pair
84
86
 
87
+ if validate_value(strict)._as_py_():
88
+ raise NotImplementedError("Strict zipping is not supported")
89
+
85
90
  if not iterables:
86
91
  return _EmptyIterator()
87
92
 
@@ -383,6 +388,11 @@ def _super(*args):
383
388
  return super(*(arg._as_py_() if arg._is_py_() else arg for arg in args))
384
389
 
385
390
 
391
+ @meta_fn
392
+ def _assert_never(arg: Never, /):
393
+ error("Expected code to be unreachable")
394
+
395
+
386
396
  # classmethod, property, staticmethod are supported as decorators, but not within functions
387
397
 
388
398
  BUILTIN_IMPLS = {
@@ -407,6 +417,7 @@ BUILTIN_IMPLS = {
407
417
  id(reversed): _reversed,
408
418
  id(super): _super,
409
419
  id(zip): _zip,
420
+ id(assert_never): _assert_never,
410
421
  **MATH_BUILTIN_IMPLS, # Includes round
411
422
  **RANDOM_BUILTIN_IMPLS,
412
423
  }
@@ -41,6 +41,7 @@ debug_var = ContextVar("debug_var", default=_disabled_debug_config)
41
41
 
42
42
  class GlobalContextState:
43
43
  archetypes: dict[type, int]
44
+ archetypes_by_name: dict[str, type]
44
45
  keys: Sequence[int] | None
45
46
  rom: ReadOnlyMemory
46
47
  const_mappings: dict[Any, int]
@@ -53,6 +54,7 @@ class GlobalContextState:
53
54
  from sonolus.script.array import Array
54
55
 
55
56
  self.archetypes = archetypes or {}
57
+ self.archetypes_by_name = {type_.name: type_ for type_, _ in self.archetypes.items()} # type: ignore
56
58
  self.keys = (
57
59
  Array(*((getattr(a, "_key_", -1)) for a in sorted(self.archetypes, key=lambda a: archetypes[a])))
58
60
  if archetypes
@@ -92,7 +92,7 @@ def try_validate_value(value: Any) -> Value | None:
92
92
  Union,
93
93
  }:
94
94
  return TypingSpecialFormConstant.of(special_form)
95
- case other_type if get_origin(value) in {Literal, Annotated, UnionType, tuple}:
95
+ case other_type if get_origin(value) in {Literal, Annotated, UnionType, tuple, type}:
96
96
  return BasicConstantValue.of(other_type)
97
97
  case _GlobalPlaceholder():
98
98
  return value.get()
sonolus/script/options.py CHANGED
@@ -230,7 +230,7 @@ class _OptionField(SonolusDescriptor):
230
230
  raise AttributeError("Options are read-only")
231
231
 
232
232
 
233
- @dataclass_transform()
233
+ @dataclass_transform(kw_only_default=True)
234
234
  def options[T](cls: type[T]) -> T | Options:
235
235
  """Decorator to define options.
236
236
 
@@ -98,7 +98,7 @@ def particle(name: str) -> Any:
98
98
  type Particles = NewType("Particles", Any) # type: ignore
99
99
 
100
100
 
101
- @dataclass_transform()
101
+ @dataclass_transform(kw_only_default=True)
102
102
  def particles[T](cls: type[T]) -> T | Particles:
103
103
  """Decorator to define particles.
104
104
 
sonolus/script/project.py CHANGED
@@ -129,3 +129,6 @@ class BuildConfig:
129
129
 
130
130
  build_tutorial: bool = True
131
131
  """Whether to build the tutorial package."""
132
+
133
+ override_resource_level_engines: bool = True
134
+ """Whether to override any levels included in resources to use the engine of this project."""
sonolus/script/record.py CHANGED
@@ -230,6 +230,8 @@ class Record(GenericValue, metaclass=RecordMeta):
230
230
  result = []
231
231
  for field in cls._fields_:
232
232
  result.extend(field.type._flat_keys_(f"{prefix}.{field.name}"))
233
+ if len(result) == 1:
234
+ return [prefix]
233
235
  return result
234
236
 
235
237
  def _get_(self) -> Self:
sonolus/script/sprite.py CHANGED
@@ -283,7 +283,7 @@ class RenderMode(StrEnum):
283
283
  """Use the lightweight render mode with projective interpolation of textures."""
284
284
 
285
285
 
286
- @dataclass_transform()
286
+ @dataclass_transform(kw_only_default=True)
287
287
  def skin[T](cls: type[T]) -> T | Skin:
288
288
  """Decorator to define a skin.
289
289
 
sonolus/script/stream.py CHANGED
@@ -59,7 +59,7 @@ class _StreamDataField(SonolusDescriptor):
59
59
  self._get()._copy_from_(value)
60
60
 
61
61
 
62
- @dataclass_transform()
62
+ @dataclass_transform(kw_only_default=True)
63
63
  def streams[T](cls: type[T]) -> T:
64
64
  """Decorator to define streams and stream groups.
65
65
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sonolus.py
3
- Version: 0.5.2
3
+ Version: 0.6.1
4
4
  Summary: Sonolus engine development in Python
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -10,8 +10,8 @@ sonolus/backend/mode.py,sha256=NkcPZJm8dn83LX35uP24MtQOCnfRDFZ280dHeEEfauE,613
10
10
  sonolus/backend/node.py,sha256=eEzPP14jzWJp2xrZCAaPlNtokxdoqg0bSM7xQiwx1j8,1254
11
11
  sonolus/backend/ops.py,sha256=5weB_vIxbkwCSJuzYZyKUk7vVXsSIEDJYRlvE-2ke8A,10572
12
12
  sonolus/backend/place.py,sha256=7qwV732hZ4WP-9GNN8FQSEKssPJZELip1wLXTWfop7Y,4717
13
- sonolus/backend/utils.py,sha256=DDgYUVHh4h_eSY65v2KcxUaLSBYGYS6oHar5gTdV7QU,2356
14
- sonolus/backend/visitor.py,sha256=Dz_3w3gvmJraNC2fMMlkYthEmT0AkZfHGFsrracELuo,63121
13
+ sonolus/backend/utils.py,sha256=OwD1EPh8j-hsfkLzeKNzPQojT_3kklpJou0WTJNoCbc,2337
14
+ sonolus/backend/visitor.py,sha256=oq8IhuuhigXMZtNgxD9ZjI_ZLVrp9ikFm9Yz636F5Fo,63102
15
15
  sonolus/backend/optimize/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  sonolus/backend/optimize/allocate.py,sha256=CuumoMphkpQlGRNeKLHT4FBGE0XVj5pwhfNdrqiLFSs,7535
17
17
  sonolus/backend/optimize/constant_evaluation.py,sha256=U--9moGsXFzrgweWWwHIiEuuMzwetd1IOjjtrCscoNM,21450
@@ -27,40 +27,40 @@ sonolus/backend/optimize/simplify.py,sha256=RDNVTKfC7ByRyxY5z30_ShimOAKth_pKlVFV
27
27
  sonolus/backend/optimize/ssa.py,sha256=raQO0furQQRPYb8iIBKfNrJlj-_5wqtI4EWNfLZ8QFo,10834
28
28
  sonolus/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  sonolus/build/cli.py,sha256=-_lTN8zT7nQB2lySM8itAEPVutcEQI-TJ13BcPIfGb4,10113
30
- sonolus/build/collection.py,sha256=kOVnpQC_KHAsyTM4nAplSh6QE16CgO-H6PP1GItWm78,12187
30
+ sonolus/build/collection.py,sha256=sMYLfEIVn6UydLy7iEnNwrpIXDs7bGG32uQQgHXyhSI,12289
31
31
  sonolus/build/compile.py,sha256=Yex-ZbSZmv9ujyAOVaMcfq-0NnZzFIqtmNYYaplF4Uc,6761
32
32
  sonolus/build/engine.py,sha256=zUl0KfRygqNhIM8BABNJkKG-0zXFwcYwck-5hJy59yk,13338
33
33
  sonolus/build/level.py,sha256=yXsQtnabkJK0vuVmZ_Wr1jx37jFLgInCS7lTlXjkv9Q,706
34
34
  sonolus/build/node.py,sha256=gnX71RYDUOK_gYMpinQi-bLWO4csqcfiG5gFmhxzSec,1330
35
- sonolus/build/project.py,sha256=mv2OuzgIDG-E9G4SIRiUDL5XiPCd1i81wVl1p7itFHA,6329
35
+ sonolus/build/project.py,sha256=eHh4ioOjaFtt26bcefUuDZhMhFw8NXnjRTYPiEInQV8,6505
36
36
  sonolus/script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- sonolus/script/archetype.py,sha256=-i7TQMI0_ztNTwd1bXu39q3wSaa70kRlPoNZFUHNbHY,48534
37
+ sonolus/script/archetype.py,sha256=DMtg-wWId6UAoh1L_jbMq4EMwLuY6tPY29wVoB8oD6A,47279
38
38
  sonolus/script/array.py,sha256=9uOUHZIDMyMT9q3APcXJWXWt97yG-AZoRlxwrvSY6SU,12367
39
39
  sonolus/script/array_like.py,sha256=jFOfXkniTLrIK4ER6HO_tUyKn_TvwjyM4B3SDd9cUS8,9678
40
- sonolus/script/bucket.py,sha256=VxsSgHidYhY_Y5UXpBZY_tzjQff0TRgNJVj4Al8LVec,7654
40
+ sonolus/script/bucket.py,sha256=SNqnfLGpnO_u-3LFFazdgzNk332OdDUIlmZHsuoVZuE,7674
41
41
  sonolus/script/containers.py,sha256=WX0qRnr6gNtn3C0q7MwMyrzvY-C0Bd1tzLGxSkUwL9U,18680
42
- sonolus/script/debug.py,sha256=_Hg1cXQJ8fBXMiwhmoPb2X9CKcQ8QO26WNa59K518og,4305
42
+ sonolus/script/debug.py,sha256=Vi97opuk9fMB5bdpzPCBpa2oZeTff7FQ4WzdeDE5trk,4557
43
43
  sonolus/script/easing.py,sha256=txf0OPFP5v7cOFDvJKCyKLK-d2uKIOu56ntLEHfD9QI,11377
44
- sonolus/script/effect.py,sha256=mhl58IgHUl7GI6kDdwK6l_KWVXYWxxpAcfOjSkdrLj4,5944
44
+ sonolus/script/effect.py,sha256=OedYn0uOgYdZIGeJ6dATBSo5MSD21_v1Uvgoe6yVr9U,5964
45
45
  sonolus/script/engine.py,sha256=etI9dJsQ7V9YZICVNZg54WqpLijPxG8eTPHiV-_EiG8,10687
46
46
  sonolus/script/globals.py,sha256=USwh_TuyZh1qORPVLk6x9qe3ca9iLhf5gnqT773gVvY,10007
47
- sonolus/script/instruction.py,sha256=iBjY7nCNDT3w0SBJKlix3Z-85e7eE2qKeHp6C2Nq7KA,6753
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
50
  sonolus/script/level.py,sha256=vnotMbdr_4-MJUsTXMbvWiw2MlMjMHme3q0XRdNFXRg,6349
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
54
- sonolus/script/options.py,sha256=KlOud4QOf_lW1o6avKXbkjcMCDPkhLcEwt5PW7ZCH3s,9435
55
- sonolus/script/particle.py,sha256=XczhwTJvU3dMOXXTxJI_5Mskro2LgVlNgrCSwYreO0Q,8369
54
+ sonolus/script/options.py,sha256=XVN-mL7Rwhd2Tu9YysYq9YDGpH_LazdmhqzSYE6nR3Q,9455
55
+ sonolus/script/particle.py,sha256=m6VLH_05zKQIyiqyVyD6z0sbzjOYhRuZwgPY82u-BOo,8389
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=2XVUXcW49iiTfljvcFuYqtFzqhQIRvD7H7OwH1Mm98w,4009
58
+ sonolus/script/project.py,sha256=BDGaae3lXWQqZgY3lF3_27VSSk_oGEA4sbN-gQFlhAM,4157
59
59
  sonolus/script/quad.py,sha256=XoAjaUqR60zIrC_CwheZs7HwS-DRS58yUmlj9GIjX7k,11179
60
- sonolus/script/record.py,sha256=-Ff60wBoF1v4-MJWzCNI9n5K3os6WphswZpdTBezeRs,12713
60
+ sonolus/script/record.py,sha256=igmawc0hqb98YVcZnPTThHvnIP88Qelhoge4cNJx45Q,12770
61
61
  sonolus/script/runtime.py,sha256=rJZM_KbKmnwpjhDEpR0DrM6EMSEu46apIErWA_pfLJA,33321
62
- sonolus/script/sprite.py,sha256=pgFQvzWB-uy9MsOfV8QabXKjnNgx5vN6md9uNYztHco,16297
63
- sonolus/script/stream.py,sha256=q3uJUfUP9fx0Go7qXQopl9DMh_RJkT-96p5WlAo4x0M,24693
62
+ sonolus/script/sprite.py,sha256=kqFESwQjR-tTJ3EEMnXmMBxX-gCjtPYwF5Pgx1OInNM,16317
63
+ sonolus/script/stream.py,sha256=qVljaCxJJtQs7aBwfUG15pYvztb4jFYzSLGDh5t4DTA,24713
64
64
  sonolus/script/text.py,sha256=wxujIgKYcCfl2AD2_Im8g3vh0lDEHYwTSRZg9wsBPEU,13402
65
65
  sonolus/script/timing.py,sha256=ZR0ypV2PIoDCMHHGOMfCeezStCsBQdzomdqaz5VKex0,2981
66
66
  sonolus/script/transform.py,sha256=w5mr7hTuNYU0eTAdnN_wTVibaQa0mZrkl-W-kgewJxQ,21345
@@ -68,15 +68,15 @@ sonolus/script/ui.py,sha256=DYPGWIjHj1IFPxW1zaEuIUQx0b32FJPXtiwCvrtJ6oo,7528
68
68
  sonolus/script/values.py,sha256=6iJG6h4IDlbcK8FH4GENSHOQc7C_7fCGa34wM80qToA,1629
69
69
  sonolus/script/vec.py,sha256=oVx5C5zGj8gX37F7y1FEJOrTYzb7EWfQWQuKU8KGLdc,7486
70
70
  sonolus/script/internal/__init__.py,sha256=T6rzLoiOUaiSQtaHMZ88SNO-ijSjSSv33TKtUwu-Ms8,136
71
- sonolus/script/internal/builtin_impls.py,sha256=POmWRyTQa-9mpQ_jATDYlFWo_n0a65vXAgqitkKYzGY,12870
71
+ sonolus/script/internal/builtin_impls.py,sha256=lu0Je_DD7xGjgF766sf0S0EiBEHiKuyre-2arI-ysZA,13170
72
72
  sonolus/script/internal/callbacks.py,sha256=vWzJG8uiJoEtsNnbeZPqOHogCwoLpz2D1MnHY2wVV8s,2801
73
73
  sonolus/script/internal/constant.py,sha256=3ycbGkDJVUwcrCZ96vLjAoAARgsvaqDM8rJ_YCrLrvo,4289
74
- sonolus/script/internal/context.py,sha256=JtKyjFlt7t2YwR1qFUGGjzYrE8v0yfsP-7XA196gtaQ,17211
74
+ sonolus/script/internal/context.py,sha256=jto68tBpmF3As_h22tNVNP7ctJjt4S0HySF_DbFhbok,17361
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
78
  sonolus/script/internal/generic.py,sha256=F0-cCiRNGTaUJvYlpmkiOsU3Xge_XjoBpBwBhH_qS_s,7577
79
- sonolus/script/internal/impl.py,sha256=alcFJs1yDx9ixEOxg-r_1IvWG2arMSUKSc-Eg9nAHOw,3255
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
82
82
  sonolus/script/internal/native.py,sha256=DQxmzxgLG_UsLpXhIEtBdO7eIeDFprU78UBDC4OZzw0,1597
@@ -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.5.2.dist-info/METADATA,sha256=95TnAW9JgpYR6UNXhEm3rZbHCqKWkUY6cGr93eYo4Wo,302
90
- sonolus_py-0.5.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
91
- sonolus_py-0.5.2.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
92
- sonolus_py-0.5.2.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
93
- sonolus_py-0.5.2.dist-info/RECORD,,
89
+ sonolus_py-0.6.1.dist-info/METADATA,sha256=OMfsfCDRgKYqEstwDRS406iyVIZR6yofrkS3VOP7kVg,302
90
+ sonolus_py-0.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
91
+ sonolus_py-0.6.1.dist-info/entry_points.txt,sha256=oTYspY_b7SA8TptEMTDxh4-Aj-ZVPnYC9f1lqH6s9G4,54
92
+ sonolus_py-0.6.1.dist-info/licenses/LICENSE,sha256=JEKpqVhQYfEc7zg3Mj462sKbKYmO1K7WmvX1qvg9IJk,1067
93
+ sonolus_py-0.6.1.dist-info/RECORD,,