salabim 25.0.9.post4__py3-none-any.whl → 25.0.11__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.
- salabim/salabim.py +155 -32
- {salabim-25.0.9.post4.dist-info → salabim-25.0.11.dist-info}/METADATA +1 -1
- salabim-25.0.11.dist-info/RECORD +10 -0
- {salabim-25.0.9.post4.dist-info → salabim-25.0.11.dist-info}/WHEEL +1 -1
- salabim-25.0.9.post4.dist-info/RECORD +0 -10
- {salabim-25.0.9.post4.dist-info → salabim-25.0.11.dist-info}/top_level.txt +0 -0
salabim/salabim.py
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
# _ _ _ ____ ____ ___
|
2
|
-
# ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | ___| / _ \
|
3
|
-
# / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) ||___ \ | | | | |
|
4
|
-
# \__ \| (_| || || (_| || |_) || || | | | | | / __/ ___) | _ | |_| | _
|
5
|
-
# |___/ \__,_||_| \__,_||_.__/ |_||_| |_| |_| |_____||____/ (_) \___/ (_)
|
1
|
+
# _ _ _ ____ ____ ___ _ _
|
2
|
+
# ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | ___| / _ \ / |/ |
|
3
|
+
# / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) ||___ \ | | | | | || |
|
4
|
+
# \__ \| (_| || || (_| || |_) || || | | | | | / __/ ___) | _ | |_| | _ | || |
|
5
|
+
# |___/ \__,_||_| \__,_||_.__/ |_||_| |_| |_| |_____||____/ (_) \___/ (_)|_||_|
|
6
6
|
# discrete event simulation
|
7
7
|
#
|
8
8
|
# see www.salabim.org for more information, the documentation and license information
|
9
9
|
|
10
|
-
__version__ = "25.0.
|
10
|
+
__version__ = "25.0.11"
|
11
11
|
import heapq
|
12
12
|
import random
|
13
13
|
import time
|
@@ -43,7 +43,6 @@ import base64
|
|
43
43
|
import zipfile
|
44
44
|
from pathlib import Path
|
45
45
|
|
46
|
-
|
47
46
|
from typing import Any, Union, Iterable, Tuple, List, Callable, TextIO, Dict, Set, Type, Hashable, Optional
|
48
47
|
|
49
48
|
dataframe = None # to please PyLance
|
@@ -52,6 +51,7 @@ ColorType = Union[str, Iterable[float]]
|
|
52
51
|
|
53
52
|
Pythonista = sys.platform == "ios"
|
54
53
|
Windows = sys.platform.startswith("win")
|
54
|
+
MacOS = platform.system == "Darwin"
|
55
55
|
PyPy = platform.python_implementation() == "PyPy"
|
56
56
|
Chromebook = "penguin" in platform.uname()
|
57
57
|
Xlwings = "xlwings" in sys.modules
|
@@ -110,6 +110,7 @@ def a_log(*args):
|
|
110
110
|
|
111
111
|
class g: ...
|
112
112
|
|
113
|
+
|
113
114
|
if Pythonista:
|
114
115
|
try:
|
115
116
|
import scene # type: ignore
|
@@ -2889,6 +2890,14 @@ class Monitor:
|
|
2889
2890
|
|
2890
2891
|
if False (default), the normal 2D plane will be used.
|
2891
2892
|
|
2893
|
+
screen_coordinates : bool
|
2894
|
+
use screen_coordinates
|
2895
|
+
|
2896
|
+
if True (default), screen_coordinates will be used instead.
|
2897
|
+
|
2898
|
+
if False, all parameters are scaled for positioning and scaling
|
2899
|
+
objects.
|
2900
|
+
|
2892
2901
|
Returns
|
2893
2902
|
-------
|
2894
2903
|
reference to AnimateMonitor object : AnimateMonitor
|
@@ -3665,11 +3674,11 @@ class AnimateMonitor(DynamicClass):
|
|
3665
3674
|
screen_coordinates : bool
|
3666
3675
|
use screen_coordinates
|
3667
3676
|
|
3668
|
-
if
|
3669
|
-
objects.
|
3670
|
-
|
3671
|
-
if True (default), screen_coordinates will be used.
|
3677
|
+
if True (default), screen_coordinates will be used instead.
|
3672
3678
|
|
3679
|
+
if False, all parameters are scaled for positioning and scaling
|
3680
|
+
objects.
|
3681
|
+
|
3673
3682
|
Note
|
3674
3683
|
----
|
3675
3684
|
All measures are in screen coordinates
|
@@ -3714,9 +3723,9 @@ class AnimateMonitor(DynamicClass):
|
|
3714
3723
|
as_points: bool = None,
|
3715
3724
|
over3d: bool = None,
|
3716
3725
|
layer: Union[float, Callable] = 0,
|
3726
|
+
screen_coordinates=True,
|
3717
3727
|
visible: Union[bool, Callable] = True,
|
3718
3728
|
keep: Union[bool, Callable] = True,
|
3719
|
-
screen_coordinates: bool = True,
|
3720
3729
|
arg: Any = None,
|
3721
3730
|
):
|
3722
3731
|
super().__init__()
|
@@ -4396,6 +4405,14 @@ class Queue:
|
|
4396
4405
|
|
4397
4406
|
default: self (instance itself)
|
4398
4407
|
|
4408
|
+
screen_coordinates : bool
|
4409
|
+
use screen_coordinates
|
4410
|
+
|
4411
|
+
if True (default), screen_coordinates will be used instead.
|
4412
|
+
|
4413
|
+
if False, all parameters are scaled for positioning and scaling
|
4414
|
+
objects.
|
4415
|
+
|
4399
4416
|
Returns
|
4400
4417
|
-------
|
4401
4418
|
reference to AnimationQueue object : AnimationQueue
|
@@ -7204,7 +7221,7 @@ by adding at the end:
|
|
7204
7221
|
|
7205
7222
|
overridden_lineno = None
|
7206
7223
|
|
7207
|
-
def animation_objects(self, id: Any) -> Tuple:
|
7224
|
+
def animation_objects(self, id: Any, screen_coordinates: bool = True) -> Tuple:
|
7208
7225
|
"""
|
7209
7226
|
defines how to display a component in AnimateQueue
|
7210
7227
|
|
@@ -7234,7 +7251,9 @@ by adding at the end:
|
|
7234
7251
|
"""
|
7235
7252
|
size_x = 50
|
7236
7253
|
size_y = 50
|
7237
|
-
ao0 = AnimateRectangle(
|
7254
|
+
ao0 = AnimateRectangle(
|
7255
|
+
text=str(self.sequence_number()), textcolor="bg", spec=(-20, -20, 20, 20), linewidth=0, fillcolor="fg", screen_coordinates=screen_coordinates
|
7256
|
+
)
|
7238
7257
|
return (size_x, size_y, ao0)
|
7239
7258
|
|
7240
7259
|
def animation3d_objects(self, id: Any) -> Tuple:
|
@@ -10583,6 +10602,8 @@ class Environment:
|
|
10583
10602
|
self._step_pressed = False
|
10584
10603
|
self.stopped = False
|
10585
10604
|
self._paused = False
|
10605
|
+
self._zoom_factor = 1.1
|
10606
|
+
|
10586
10607
|
self.last_s0 = ""
|
10587
10608
|
if Xlwings:
|
10588
10609
|
if blind_animation is None:
|
@@ -10711,6 +10732,23 @@ class Environment:
|
|
10711
10732
|
"""
|
10712
10733
|
if self._ui:
|
10713
10734
|
self._handle_ui_event()
|
10735
|
+
self._x0_org = self._x0
|
10736
|
+
self._x1_org = self._x1
|
10737
|
+
self._y0_org = self._y0
|
10738
|
+
self._y1_org = self._y1
|
10739
|
+
self._scale_org = self._scale
|
10740
|
+
self._x0 = self._x0z
|
10741
|
+
self._y0 = self._y0z
|
10742
|
+
self._x1 = self._x1z # 0+self._width/self._scale
|
10743
|
+
self._y1 = self._y1z # +self._height/self._scale
|
10744
|
+
self._scale = self._scalez
|
10745
|
+
|
10746
|
+
# midx=self._x0+self._panx*(self._x1-self._x0)
|
10747
|
+
# self._x0, self._x1= midx-(1/self._zoom)*(self._x1-self._x0)/2,midx+(1/self._zoom)*(self._x1-self._x0)/2
|
10748
|
+
|
10749
|
+
# midy=self._y0+self._pany*(self._y1-self._y0)
|
10750
|
+
# self._y0, self._y1 = midy-(1/self._zoom)*(self._y1-self._y0)/2, midy+(1/self._zoom)*(self._y1-self._y0)/2
|
10751
|
+
# self._scale = self._width / (self._x1 - self._x0)
|
10714
10752
|
|
10715
10753
|
def animation_post_tick(self, t: float) -> None:
|
10716
10754
|
"""
|
@@ -10723,7 +10761,12 @@ class Environment:
|
|
10723
10761
|
t : float
|
10724
10762
|
Current (animation) time.
|
10725
10763
|
"""
|
10726
|
-
|
10764
|
+
self._x0 = self._x0_org
|
10765
|
+
self._x1 = self._x1_org
|
10766
|
+
self._y0 = self._y0_org
|
10767
|
+
self._y1 = self._y1_org
|
10768
|
+
self._scale = self._scale_org
|
10769
|
+
self._last_scalez = self._scalez
|
10727
10770
|
|
10728
10771
|
def animation_pre_tick_sys(self, t: float) -> None:
|
10729
10772
|
for ao in self.sys_objects.copy(): # copy required as ao's may be removed due to keep
|
@@ -11248,6 +11291,61 @@ class Environment:
|
|
11248
11291
|
def on_closing(self):
|
11249
11292
|
self.an_quit()
|
11250
11293
|
|
11294
|
+
def on_mousewheel(self, event):
|
11295
|
+
x_mouse = self.root.winfo_pointerx() - self.root.winfo_rootx()
|
11296
|
+
y_mouse = self.height() - self.root.winfo_pointery() + self.root.winfo_rooty()
|
11297
|
+
x = (x_mouse / self._scale) + self._x0z
|
11298
|
+
y = (y_mouse / self._scale) + self._y0z
|
11299
|
+
|
11300
|
+
if Windows:
|
11301
|
+
delta = int(event.delta / 120) # normalize to ticks
|
11302
|
+
elif MacOS:
|
11303
|
+
delta = int(event.delta) # already small, usually ±1
|
11304
|
+
else:
|
11305
|
+
delta = 0 # fallback
|
11306
|
+
for _ in range(abs(delta)):
|
11307
|
+
if delta < 0:
|
11308
|
+
zoom_factor = self._zoom_factor
|
11309
|
+
|
11310
|
+
else:
|
11311
|
+
zoom_factor = 1 / self._zoom_factor
|
11312
|
+
|
11313
|
+
# min_zoom = min(
|
11314
|
+
# (self._x0 - x) / (self._x0z - x),
|
11315
|
+
# (self._x0 - x) / (self._x0z - x),
|
11316
|
+
# (self._x1 - x) / (self._x1z - x),
|
11317
|
+
# (self._y0 - y) / (self._y0z - y),
|
11318
|
+
# (self._y1 - y) / (self._y1z - y),
|
11319
|
+
# )
|
11320
|
+
|
11321
|
+
# zoom_factor = min(zoom_factor, min_zoom)
|
11322
|
+
|
11323
|
+
self._scalez /= zoom_factor
|
11324
|
+
self._x0z = x - (x - self._x0z) * zoom_factor
|
11325
|
+
self._y0z = y - (y - self._y0z) * zoom_factor
|
11326
|
+
self._x1z = x - (x - self._x1z) * zoom_factor
|
11327
|
+
self._y1z = y - (y - self._y1z) * zoom_factor
|
11328
|
+
|
11329
|
+
def start_pan(self, event):
|
11330
|
+
g.canvas.config(cursor="fleur") # Change cursor to "move" style
|
11331
|
+
self.lastx = event.x
|
11332
|
+
self.lasty = event.y
|
11333
|
+
self.lastx0 = self._x0z
|
11334
|
+
self.lasty0 = self._y0z
|
11335
|
+
|
11336
|
+
def do_pan(self, event):
|
11337
|
+
dx = -((event.x - self.lastx) / self._scale)
|
11338
|
+
dy = (event.y - self.lasty) / self._scale
|
11339
|
+
# self._x0z = max(self._x0,self.lastx0 + dx)
|
11340
|
+
# self._y0z = max(self._y0,self.lasty0 + dy)
|
11341
|
+
self._x0z = self.lastx0 + dx
|
11342
|
+
self._y0z = self.lasty0 + dy
|
11343
|
+
self._x1z = self._x0z + (self._x1 - self._x0)
|
11344
|
+
self._y1z = self._y0z + (self._y1 - self._y0)
|
11345
|
+
|
11346
|
+
def end_pan(self, event):
|
11347
|
+
g.canvas.config(cursor="") # Reset to default
|
11348
|
+
|
11251
11349
|
def animation_parameters(
|
11252
11350
|
self,
|
11253
11351
|
animate: Union[bool, str] = None,
|
@@ -11850,6 +11948,10 @@ class Environment:
|
|
11850
11948
|
self.root.bind("<space>", lambda self: g.animation_env.an_menu_go())
|
11851
11949
|
self.root.bind("s", lambda self: g.animation_env.an_single_step())
|
11852
11950
|
self.root.bind("<Control-c>", lambda self: g.animation_env.an_quit())
|
11951
|
+
self.root.bind("<MouseWheel>", self.on_mousewheel)
|
11952
|
+
self.root.bind("<ButtonPress-1>", self.start_pan)
|
11953
|
+
self.root.bind("<B1-Motion>", self.do_pan)
|
11954
|
+
self.root.bind("<ButtonRelease-1>", self.end_pan)
|
11853
11955
|
|
11854
11956
|
g.canvas = tkinter.Canvas(self.root, width=self._width, height=self._height)
|
11855
11957
|
g.canvas.configure(background=self.colorspec_to_hex("bg", False))
|
@@ -11857,6 +11959,11 @@ class Environment:
|
|
11857
11959
|
g.canvas_objects = []
|
11858
11960
|
g.canvas_object_overflow_image = None
|
11859
11961
|
|
11962
|
+
# g.canvas.move("all", 1, 1)
|
11963
|
+
# g.canvas.update()
|
11964
|
+
# g.canvas.move("all", -1, -1)
|
11965
|
+
# g.canvas.update()
|
11966
|
+
|
11860
11967
|
self.uninstall_uios() # this causes all ui objects to be (re)installed
|
11861
11968
|
|
11862
11969
|
if self._show_menu_buttons and not self._ui:
|
@@ -13313,6 +13420,12 @@ class Environment:
|
|
13313
13420
|
raise SimulationStopped
|
13314
13421
|
else:
|
13315
13422
|
self.root.after(0, self.simulate_and_animate_loop)
|
13423
|
+
self._x0z = self._x0
|
13424
|
+
self._y0z = self._y0
|
13425
|
+
self._x1z = self._x1
|
13426
|
+
self._y1z = self._y1
|
13427
|
+
|
13428
|
+
self._scalez = self._last_scalez = self._scale
|
13316
13429
|
self.root.mainloop()
|
13317
13430
|
if self._animate and self.running:
|
13318
13431
|
if self._video:
|
@@ -13822,19 +13935,19 @@ class Environment:
|
|
13822
13935
|
if screen_coordinates:
|
13823
13936
|
return 0
|
13824
13937
|
else:
|
13825
|
-
return self.
|
13938
|
+
return self._x0_org / scale
|
13826
13939
|
|
13827
13940
|
if xy_anchor in ("n", "c", "center", "s"):
|
13828
13941
|
if screen_coordinates:
|
13829
13942
|
return (width / 2) / scale
|
13830
13943
|
else:
|
13831
|
-
return ((self.
|
13944
|
+
return ((self._x0_org + self._x1_org) / 2) / scale
|
13832
13945
|
|
13833
13946
|
if xy_anchor in ("ne", "e", "se", ""):
|
13834
13947
|
if screen_coordinates:
|
13835
13948
|
return width / scale
|
13836
13949
|
else:
|
13837
|
-
return self.
|
13950
|
+
return self._x1_org / scale
|
13838
13951
|
|
13839
13952
|
raise ValueError("incorrect xy_anchor", xy_anchor)
|
13840
13953
|
|
@@ -13849,19 +13962,19 @@ class Environment:
|
|
13849
13962
|
if screen_coordinates:
|
13850
13963
|
return height / scale
|
13851
13964
|
else:
|
13852
|
-
return self.
|
13965
|
+
return self._y1_org / scale
|
13853
13966
|
|
13854
13967
|
if xy_anchor in ("w", "c", "center", "e"):
|
13855
13968
|
if screen_coordinates:
|
13856
13969
|
return (height / 2) / scale
|
13857
13970
|
else:
|
13858
|
-
return ((self.
|
13971
|
+
return ((self._y0_org + self._y1_org) / 2) / scale
|
13859
13972
|
|
13860
13973
|
if xy_anchor in ("sw", "s", "se", ""):
|
13861
13974
|
if screen_coordinates:
|
13862
13975
|
return 0
|
13863
13976
|
else:
|
13864
|
-
return self.
|
13977
|
+
return self._y0_org / scale
|
13865
13978
|
|
13866
13979
|
raise ValueError("incorrect xy_anchor", xy_anchor)
|
13867
13980
|
|
@@ -18180,6 +18293,7 @@ class AnimateQueue(DynamicClass):
|
|
18180
18293
|
if not self.keep(t):
|
18181
18294
|
self.remove()
|
18182
18295
|
return
|
18296
|
+
screen_coordinates = self.screen_coordinates
|
18183
18297
|
prev_aos = self.current_aos
|
18184
18298
|
self.current_aos = {}
|
18185
18299
|
xy_anchor = self.xy_anchor(t)
|
@@ -18201,8 +18315,8 @@ class AnimateQueue(DynamicClass):
|
|
18201
18315
|
titleoffsetx = self.titleoffsetx(t)
|
18202
18316
|
titleoffsety = self.titleoffsety(t)
|
18203
18317
|
|
18204
|
-
x += self._queue.env.xy_anchor_to_x(xy_anchor, screen_coordinates=
|
18205
|
-
y += self._queue.env.xy_anchor_to_y(xy_anchor, screen_coordinates=
|
18318
|
+
x += self._queue.env.xy_anchor_to_x(xy_anchor, screen_coordinates=screen_coordinates, over3d=self.over3d)
|
18319
|
+
y += self._queue.env.xy_anchor_to_y(xy_anchor, screen_coordinates=screen_coordinates, over3d=self.over3d)
|
18206
18320
|
|
18207
18321
|
if direction == "e":
|
18208
18322
|
self.x_t = x + (-25 if titleoffsetx is None else titleoffsetx)
|
@@ -18234,20 +18348,21 @@ class AnimateQueue(DynamicClass):
|
|
18234
18348
|
if ((max_length is not None) and n >= max_length) or not self.visible_t:
|
18235
18349
|
break
|
18236
18350
|
|
18237
|
-
if c
|
18238
|
-
nargs = c.animation_objects.__code__.co_argcount
|
18239
|
-
if nargs == 1:
|
18240
|
-
animation_objects = self.current_aos[c] = c.animation_objects()
|
18241
|
-
else:
|
18242
|
-
animation_objects = self.current_aos[c] = c.animation_objects(self.id(t))
|
18243
|
-
else:
|
18351
|
+
if c in prev_aos and self.env._scalez != self.env._last_scalez: # if scale changed (due to zooming), rerender the animation_objects
|
18244
18352
|
animation_objects = self.current_aos[c] = prev_aos[c]
|
18245
18353
|
del prev_aos[c]
|
18354
|
+
else:
|
18355
|
+
parameters = inspect.signature(c.animation_objects).parameters
|
18356
|
+
kwargs = {}
|
18357
|
+
if "id" in parameters:
|
18358
|
+
kwargs["id"] = self.id(t)
|
18359
|
+
if "screen_coordinates" in parameters:
|
18360
|
+
kwargs["screen_coordinates"] = self.screen_coordinates
|
18361
|
+
animation_objects = self.current_aos[c] = c.animation_objects(**kwargs)
|
18246
18362
|
|
18247
18363
|
dimx = _call(animation_objects[0], t, c)
|
18248
18364
|
dimy = _call(animation_objects[1], t, c)
|
18249
18365
|
for ao in animation_objects[2:]:
|
18250
|
-
ao.screen_coordinates = self.screen_coordinates
|
18251
18366
|
if isinstance(ao, AnimateClassic):
|
18252
18367
|
if direction == "t":
|
18253
18368
|
ao.x0 = xt + trajectory.x(t=x * 1.00, _t0=0)
|
@@ -18373,9 +18488,17 @@ class Animate3dQueue(DynamicClass):
|
|
18373
18488
|
if given, the animation object will be removed
|
18374
18489
|
automatically when the parent component is no longer accessible
|
18375
18490
|
|
18491
|
+
screen_coordinates : bool
|
18492
|
+
use screen_coordinates
|
18493
|
+
|
18494
|
+
if True (default), screen_coordinates will be used instead.
|
18495
|
+
|
18496
|
+
if False, all parameters are scaled for positioning and scaling
|
18497
|
+
objects.
|
18498
|
+
|
18376
18499
|
Note
|
18377
18500
|
----
|
18378
|
-
All parameters, apart from queue, id, arg and parent can be specified as:
|
18501
|
+
All parameters, apart from queue, id, arg, screen_coordinates and parent can be specified as:
|
18379
18502
|
|
18380
18503
|
- a scalar, like 10
|
18381
18504
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
salabim/DejaVuSansMono.ttf,sha256=Z_oIXp5yp1Zaw2y2p3vaxwHhjHpG0MFbmwhxSh4aIEI,335068
|
2
|
+
salabim/LICENSE.txt,sha256=eTPlcDJz4G0096Qv-wfMjm1Wxbd4ilDlsYg5rN4HjWQ,1106
|
3
|
+
salabim/__init__.py,sha256=r7qPLvlmX0dkZDyjuTo8Jo3ex3sD1L4pmK6K5ib9vyw,56
|
4
|
+
salabim/calibri.ttf,sha256=RWpf8Uo31RfvGGNaSt9-2sXSuN87AVE_NFMRsV3LhBk,1330156
|
5
|
+
salabim/mplus-1m-regular.ttf,sha256=EuFHr90BJjuAn_r5MleJFN-WfkeWJ4tf7DweI5zr8tU,289812
|
6
|
+
salabim/salabim.py,sha256=zcryC6kQgJSQizwS1gOkxHKqorHbFM2jOpf0jnPYejY,1126229
|
7
|
+
salabim-25.0.11.dist-info/METADATA,sha256=0lVnS6E5CEHalfeUwRRvypIxXXLa5zH4wkchdBEl3LU,3400
|
8
|
+
salabim-25.0.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
9
|
+
salabim-25.0.11.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
|
10
|
+
salabim-25.0.11.dist-info/RECORD,,
|
@@ -1,10 +0,0 @@
|
|
1
|
-
salabim/DejaVuSansMono.ttf,sha256=Z_oIXp5yp1Zaw2y2p3vaxwHhjHpG0MFbmwhxSh4aIEI,335068
|
2
|
-
salabim/LICENSE.txt,sha256=eTPlcDJz4G0096Qv-wfMjm1Wxbd4ilDlsYg5rN4HjWQ,1106
|
3
|
-
salabim/__init__.py,sha256=r7qPLvlmX0dkZDyjuTo8Jo3ex3sD1L4pmK6K5ib9vyw,56
|
4
|
-
salabim/calibri.ttf,sha256=RWpf8Uo31RfvGGNaSt9-2sXSuN87AVE_NFMRsV3LhBk,1330156
|
5
|
-
salabim/mplus-1m-regular.ttf,sha256=EuFHr90BJjuAn_r5MleJFN-WfkeWJ4tf7DweI5zr8tU,289812
|
6
|
-
salabim/salabim.py,sha256=hL-5b2WhppIVwwldm-O5-pCFOEHRoFt1DhoIhCHf9-w,1121320
|
7
|
-
salabim-25.0.9.post4.dist-info/METADATA,sha256=t2mmahEmxd0puFxYki_G4vcb1k05dVyw9F-IQuNjs2A,3405
|
8
|
-
salabim-25.0.9.post4.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
9
|
-
salabim-25.0.9.post4.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
|
10
|
-
salabim-25.0.9.post4.dist-info/RECORD,,
|
File without changes
|