salabim 24.0.11.post1__py3-none-any.whl → 24.0.13__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 +277 -47
- {salabim-24.0.11.post1.dist-info → salabim-24.0.13.dist-info}/METADATA +1 -1
- salabim-24.0.13.dist-info/RECORD +10 -0
- {salabim-24.0.11.post1.dist-info → salabim-24.0.13.dist-info}/WHEEL +1 -1
- salabim-24.0.11.post1.dist-info/RECORD +0 -10
- {salabim-24.0.11.post1.dist-info → salabim-24.0.13.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__ = "24.0.
|
10
|
+
__version__ = "24.0.13"
|
11
11
|
|
12
12
|
import heapq
|
13
13
|
import random
|
@@ -60,7 +60,7 @@ PyDroid = sys.platform == "linux" and any("pydroid" in v for v in os.environ.val
|
|
60
60
|
PyPy = platform.python_implementation() == "PyPy"
|
61
61
|
Chromebook = "penguin" in platform.uname()
|
62
62
|
PythonInExcel = not ("__file__" in globals())
|
63
|
-
AnacondaCode = sys.platform=="emscripten"
|
63
|
+
AnacondaCode = sys.platform == "emscripten"
|
64
64
|
|
65
65
|
|
66
66
|
def a_log(*args):
|
@@ -154,8 +154,9 @@ nan = float("nan")
|
|
154
154
|
if Pythonista or AnacondaCode or PythonInExcel:
|
155
155
|
_yieldless = False
|
156
156
|
else:
|
157
|
-
_yieldless=True
|
158
|
-
|
157
|
+
_yieldless = True
|
158
|
+
|
159
|
+
|
159
160
|
class QueueFullError(Exception):
|
160
161
|
pass
|
161
162
|
|
@@ -4144,7 +4145,7 @@ if Pythonista:
|
|
4144
4145
|
try:
|
4145
4146
|
ims = scene.load_pil_image(capture_image)
|
4146
4147
|
except SystemError:
|
4147
|
-
im_file = "temp.png" # hack for Pythonista 3.4
|
4148
|
+
im_file = "temp.png" # hack for Pythonista 3.4
|
4148
4149
|
capture_image.save(im_file, "PNG")
|
4149
4150
|
ims = scene.load_image_file(im_file)
|
4150
4151
|
scene.image(ims, 0, 0, *capture_image.size)
|
@@ -5716,15 +5717,19 @@ class Queue:
|
|
5716
5717
|
|
5717
5718
|
|
5718
5719
|
class Store(Queue):
|
5719
|
-
def __init__(self, name: str = None, capacity:
|
5720
|
-
super().__init__(name=name, capacity=capacity, env=env, *args, **kwargs)
|
5720
|
+
def __init__(self, name: str = None, monitor: Any = True, fill: Iterable = None, capacity: float = inf, env: "Environment" = None, *args, **kwargs) -> None:
|
5721
|
+
super().__init__(name=name, monitor=monitor, fill=None, capacity=capacity, env=env, *args, **kwargs)
|
5722
|
+
|
5721
5723
|
with self.env.suppress_trace():
|
5722
5724
|
self._to_store_requesters = Queue(f"{name}.to_store_requesters", env=env)
|
5723
5725
|
self._to_store_requesters._isinternal = True
|
5724
5726
|
self._from_store_requesters = Queue(f"{name}.from_store_requesters", env=env)
|
5725
5727
|
self._from_store_requesters._isinternal = True
|
5726
5728
|
|
5727
|
-
|
5729
|
+
if fill is not None: # this cannot be done by Queue.__init__ as the requesters are not defined at that time
|
5730
|
+
with self.env.suppress_trace():
|
5731
|
+
for c in fill:
|
5732
|
+
c.enter(self)
|
5728
5733
|
|
5729
5734
|
def set_capacity(self, cap: float) -> None:
|
5730
5735
|
"""
|
@@ -7977,6 +7982,10 @@ by adding:
|
|
7977
7982
|
----
|
7978
7983
|
Only if yieldless is False: if to be used for the current component, use ``yield self.cancel()``.
|
7979
7984
|
"""
|
7985
|
+
if self.status.value == data:
|
7986
|
+
if self.env._trace:
|
7987
|
+
self.env.print_trace("", "", "cancel (on data component) " + self.name() + " " + self._modetxt())
|
7988
|
+
return
|
7980
7989
|
if self.status.value != current:
|
7981
7990
|
self._checkisnotdata()
|
7982
7991
|
self._remove()
|
@@ -9044,10 +9053,8 @@ by adding:
|
|
9044
9053
|
self.status._value = waiting
|
9045
9054
|
self._reschedule(scheduled_time, schedule_priority, urgent, "wait", cap_now)
|
9046
9055
|
else:
|
9047
|
-
return
|
9048
|
-
|
9049
|
-
if self is self.env._current_component:
|
9050
|
-
self.env._glet.switch()
|
9056
|
+
return
|
9057
|
+
|
9051
9058
|
|
9052
9059
|
def _trywait(self):
|
9053
9060
|
if self.status.value == interrupted:
|
@@ -9996,6 +10003,211 @@ by adding:
|
|
9996
10003
|
return None
|
9997
10004
|
|
9998
10005
|
|
10006
|
+
class Event(Component):
|
10007
|
+
"""
|
10008
|
+
Event object
|
10009
|
+
|
10010
|
+
An event object is a specialized Component that is usually not subclassed.
|
10011
|
+
|
10012
|
+
Apart from the usual Component parameters it has an action parameter, to specifies what should
|
10013
|
+
happen after becoming active. This action is usually a lambda function.
|
10014
|
+
|
10015
|
+
Parameters
|
10016
|
+
----------
|
10017
|
+
action : callable
|
10018
|
+
function called when the component becomes current.
|
10019
|
+
|
10020
|
+
action_string : str
|
10021
|
+
string to be printed in trace when action gets executed (default: "action")
|
10022
|
+
|
10023
|
+
name : str
|
10024
|
+
name of the component.
|
10025
|
+
|
10026
|
+
if the name ends with a period (.),
|
10027
|
+
auto serializing will be applied
|
10028
|
+
|
10029
|
+
if the name end with a comma,
|
10030
|
+
auto serializing starting at 1 will be applied
|
10031
|
+
|
10032
|
+
if omitted, the name will be derived from the class
|
10033
|
+
it is defined in (lowercased)
|
10034
|
+
|
10035
|
+
at : float or distribution
|
10036
|
+
schedule time
|
10037
|
+
|
10038
|
+
if omitted, now is used
|
10039
|
+
|
10040
|
+
if distribution, the distribution is sampled
|
10041
|
+
|
10042
|
+
delay : float or distributiom
|
10043
|
+
schedule with a delay
|
10044
|
+
|
10045
|
+
if omitted, no delay
|
10046
|
+
|
10047
|
+
if distribution, the distribution is sampled
|
10048
|
+
|
10049
|
+
priority : float
|
10050
|
+
priority
|
10051
|
+
|
10052
|
+
default: 0
|
10053
|
+
|
10054
|
+
if a component has the same time on the event list, this component is sorted accoring to
|
10055
|
+
the priority.
|
10056
|
+
|
10057
|
+
urgent : bool
|
10058
|
+
urgency indicator
|
10059
|
+
|
10060
|
+
if False (default), the component will be scheduled
|
10061
|
+
behind all other components scheduled
|
10062
|
+
for the same time and priority
|
10063
|
+
|
10064
|
+
if True, the component will be scheduled
|
10065
|
+
in front of all components scheduled
|
10066
|
+
for the same time and priority
|
10067
|
+
|
10068
|
+
suppress_trace : bool
|
10069
|
+
suppress_trace indicator
|
10070
|
+
|
10071
|
+
if True, this component will be excluded from the trace
|
10072
|
+
|
10073
|
+
If False (default), the component will be traced
|
10074
|
+
|
10075
|
+
Can be queried or set later with the suppress_trace method.
|
10076
|
+
|
10077
|
+
suppress_pause_at_step : bool
|
10078
|
+
suppress_pause_at_step indicator
|
10079
|
+
|
10080
|
+
if True, if this component becomes current, do not pause when stepping
|
10081
|
+
|
10082
|
+
If False (default), the component will be paused when stepping
|
10083
|
+
|
10084
|
+
Can be queried or set later with the suppress_pause_at_step method.
|
10085
|
+
|
10086
|
+
skip_standby : bool
|
10087
|
+
skip_standby indicator
|
10088
|
+
|
10089
|
+
if True, after this component became current, do not activate standby components
|
10090
|
+
|
10091
|
+
If False (default), after the component became current activate standby components
|
10092
|
+
|
10093
|
+
Can be queried or set later with the skip_standby method.
|
10094
|
+
|
10095
|
+
mode : str preferred
|
10096
|
+
mode
|
10097
|
+
|
10098
|
+
will be used in trace and can be used in animations
|
10099
|
+
|
10100
|
+
if omitted, the mode will be "".
|
10101
|
+
|
10102
|
+
also mode_time will be set to now.
|
10103
|
+
|
10104
|
+
cap_now : bool
|
10105
|
+
indicator whether times (at, delay) in the past are allowed. If, so now() will be used.
|
10106
|
+
default: sys.default_cap_now(), usualy False
|
10107
|
+
|
10108
|
+
env : Environment
|
10109
|
+
environment where the component is defined
|
10110
|
+
|
10111
|
+
if omitted, default_env will be used
|
10112
|
+
"""
|
10113
|
+
|
10114
|
+
def __init__(
|
10115
|
+
self,
|
10116
|
+
action: Callable,
|
10117
|
+
action_string="action",
|
10118
|
+
name: str = None,
|
10119
|
+
at: Union[float, Callable] = None,
|
10120
|
+
delay: Union[float, Callable] = None,
|
10121
|
+
priority: float = None,
|
10122
|
+
urgent: bool = None,
|
10123
|
+
suppress_trace: bool = False,
|
10124
|
+
suppress_pause_at_step: bool = False,
|
10125
|
+
skip_standby: bool = False,
|
10126
|
+
mode: str = "",
|
10127
|
+
cap_now: bool = None,
|
10128
|
+
env: "Environment" = None,
|
10129
|
+
**kwargs,
|
10130
|
+
):
|
10131
|
+
self._action = action
|
10132
|
+
self._action_string = action_string
|
10133
|
+
self._action_taken = False
|
10134
|
+
if env is None:
|
10135
|
+
env = g.default_env
|
10136
|
+
super().__init__(
|
10137
|
+
name=name,
|
10138
|
+
at=at,
|
10139
|
+
delay=delay,
|
10140
|
+
priority=priority,
|
10141
|
+
urgent=urgent,
|
10142
|
+
suppress_trace=suppress_trace,
|
10143
|
+
suppress_pause_at_step=suppress_pause_at_step,
|
10144
|
+
skip_standby=skip_standby,
|
10145
|
+
mode=mode,
|
10146
|
+
cap_now=cap_now,
|
10147
|
+
env=env,
|
10148
|
+
process="process" if env._yieldless else "process_yield",
|
10149
|
+
**kwargs,
|
10150
|
+
)
|
10151
|
+
|
10152
|
+
def process_yield(self):
|
10153
|
+
self.env.print_trace("", "", self._action_string, "")
|
10154
|
+
self._action()
|
10155
|
+
self._action_taken = True
|
10156
|
+
return
|
10157
|
+
yield 1 # just to make it a generator
|
10158
|
+
|
10159
|
+
def process(self):
|
10160
|
+
self.env.print_trace("", "", self._action_string, "")
|
10161
|
+
self._action()
|
10162
|
+
self._action_taken = True
|
10163
|
+
|
10164
|
+
def action(self, value=None):
|
10165
|
+
"""
|
10166
|
+
action
|
10167
|
+
|
10168
|
+
Parameters
|
10169
|
+
----------
|
10170
|
+
value : callable
|
10171
|
+
new action callable
|
10172
|
+
|
10173
|
+
Returns
|
10174
|
+
-------
|
10175
|
+
current action : callable
|
10176
|
+
"""
|
10177
|
+
if value is not None:
|
10178
|
+
self._action = value
|
10179
|
+
return self._action
|
10180
|
+
|
10181
|
+
def action_string(self, value=None):
|
10182
|
+
"""
|
10183
|
+
action_string
|
10184
|
+
|
10185
|
+
Parameters
|
10186
|
+
----------
|
10187
|
+
value : string
|
10188
|
+
new action_string
|
10189
|
+
|
10190
|
+
Returns
|
10191
|
+
-------
|
10192
|
+
current action_string : string
|
10193
|
+
"""
|
10194
|
+
|
10195
|
+
if value is not None:
|
10196
|
+
self._action_string = value
|
10197
|
+
return self._action_string
|
10198
|
+
|
10199
|
+
def action_taken(self):
|
10200
|
+
"""
|
10201
|
+
action_taken
|
10202
|
+
|
10203
|
+
Returns
|
10204
|
+
-------
|
10205
|
+
action taken: bool
|
10206
|
+
True if action has been taken, False if not
|
10207
|
+
"""
|
10208
|
+
return self._action_taken
|
10209
|
+
|
10210
|
+
|
9999
10211
|
class Environment:
|
10000
10212
|
"""
|
10001
10213
|
environment object
|
@@ -10787,7 +10999,7 @@ class Environment:
|
|
10787
10999
|
if c.overridden_lineno:
|
10788
11000
|
self.print_trace(self.time_to_str(self._now - self._offset), c.name(), "current", s0=un_na(c.overridden_lineno))
|
10789
11001
|
else:
|
10790
|
-
self.print_trace(self.time_to_str(self._now - self._offset), c.name(), "current", s0=un_na(c.lineno_txt()))
|
11002
|
+
self.print_trace(self.time_to_str(self._now - self._offset), c.name(), "current", s0=un_na(c.lineno_txt()))
|
10791
11003
|
if c == self._main:
|
10792
11004
|
self.running = False
|
10793
11005
|
return
|
@@ -11502,7 +11714,7 @@ class Environment:
|
|
11502
11714
|
if self._video_pingpong:
|
11503
11715
|
self._images.extend(self._images[::-1])
|
11504
11716
|
if self._video_repeat == 1: # in case of repeat == 1, loop should not be specified (otherwise, it might show twice)
|
11505
|
-
if PythonInExcel or AnacondaCode:
|
11717
|
+
if PythonInExcel or AnacondaCode:
|
11506
11718
|
with b64_file_handler(self._video_name, mode="b", result=_pie_result) as f:
|
11507
11719
|
self._images[0].save(
|
11508
11720
|
f,
|
@@ -11523,7 +11735,7 @@ class Environment:
|
|
11523
11735
|
optimize=False,
|
11524
11736
|
)
|
11525
11737
|
else:
|
11526
|
-
if PythonInExcel or AnacondaCode:
|
11738
|
+
if PythonInExcel or AnacondaCode:
|
11527
11739
|
with b64_file_handler(self._video_name, mode="b", result=_pie_result) as f:
|
11528
11740
|
self._images[0].save(
|
11529
11741
|
f,
|
@@ -15308,8 +15520,6 @@ class Animate2dBase(DynamicClass):
|
|
15308
15520
|
|
15309
15521
|
if not self.screen_coordinates:
|
15310
15522
|
fontsize = fontsize * self.env._scale
|
15311
|
-
# offsetx = offsetx * self.env._scale # ***
|
15312
|
-
# offsety = offsety * self.env._scale # ***
|
15313
15523
|
text_anchor = self.text_anchor(t)
|
15314
15524
|
|
15315
15525
|
if self.attached_to:
|
@@ -15343,6 +15553,7 @@ class Animate2dBase(DynamicClass):
|
|
15343
15553
|
qx = (x - self.env._x0) * self.env._scale
|
15344
15554
|
qy = (y - self.env._y0) * self.env._scale
|
15345
15555
|
max_lines = self.max_lines(t)
|
15556
|
+
|
15346
15557
|
self._image_ident = (text, fontname, fontsize, angle, textcolor, max_lines)
|
15347
15558
|
if self._image_ident != self._image_ident_prev:
|
15348
15559
|
font, heightA = getfont(fontname, fontsize)
|
@@ -19818,6 +20029,13 @@ class ComponentGenerator(Component):
|
|
19818
20029
|
|
19819
20030
|
e.g. env.main().activate()
|
19820
20031
|
|
20032
|
+
moments : iterable
|
20033
|
+
specifies the moments when the components have to be generated. It is not required that these are sorted.
|
20034
|
+
|
20035
|
+
note that the moments are specified in the current time unit
|
20036
|
+
|
20037
|
+
cannot be used together with at, delay, till, duration, number, iat,force_at, force_till, disturbance or equidistant
|
20038
|
+
|
19821
20039
|
env : Environment
|
19822
20040
|
environment where the component is defined
|
19823
20041
|
|
@@ -19846,6 +20064,7 @@ class ComponentGenerator(Component):
|
|
19846
20064
|
disturbance: Callable = None,
|
19847
20065
|
equidistant: bool = False,
|
19848
20066
|
at_end: Callable = None,
|
20067
|
+
moments: Iterable = None,
|
19849
20068
|
env: "Environment" = None,
|
19850
20069
|
**kwargs,
|
19851
20070
|
):
|
@@ -19863,6 +20082,15 @@ class ComponentGenerator(Component):
|
|
19863
20082
|
|
19864
20083
|
if not callable(component_class):
|
19865
20084
|
raise ValueError("component_class must be a callable")
|
20085
|
+
if moments is not None:
|
20086
|
+
if any(prop for prop in (at, delay, till, duration, number, iat, force_at, force_till, disturbance, equidistant)):
|
20087
|
+
raise ValueError(
|
20088
|
+
"specifying at, delay, till,duration, number, iat,force_at, force_till, disturbance or equidistant is not allowed, if moments is specified"
|
20089
|
+
)
|
20090
|
+
if callable(moments):
|
20091
|
+
moments = moments()
|
20092
|
+
moments = sorted([env.spec_to_time(moment) for moment in moments])
|
20093
|
+
|
19866
20094
|
self.component_class = component_class
|
19867
20095
|
self.iat = iat
|
19868
20096
|
self.disturbance = disturbance
|
@@ -19905,25 +20133,26 @@ class ComponentGenerator(Component):
|
|
19905
20133
|
at = None
|
19906
20134
|
process = ""
|
19907
20135
|
else:
|
19908
|
-
if self.iat is None and not equidistant:
|
19909
|
-
if
|
19910
|
-
|
19911
|
-
|
19912
|
-
|
19913
|
-
|
19914
|
-
|
19915
|
-
|
19916
|
-
if
|
19917
|
-
if
|
19918
|
-
|
19919
|
-
|
19920
|
-
|
19921
|
-
|
19922
|
-
|
19923
|
-
|
19924
|
-
|
19925
|
-
|
19926
|
-
|
20136
|
+
if (self.iat is None and not equidistant) or moments:
|
20137
|
+
if not moments:
|
20138
|
+
if till == inf or self.number == inf:
|
20139
|
+
raise ValueError("iat not specified --> till and number need to be specified")
|
20140
|
+
if disturbance is not None:
|
20141
|
+
raise ValueError("iat not specified --> disturbance not allowed")
|
20142
|
+
|
20143
|
+
moments = sorted([Uniform(at, till)() for _ in range(self.number)])
|
20144
|
+
if force_at or force_till:
|
20145
|
+
if number == 1:
|
20146
|
+
if force_at and force_till:
|
20147
|
+
raise ValueError("force_at and force_till does not allow number=1")
|
20148
|
+
moments = [at] if force_at else [till]
|
20149
|
+
else:
|
20150
|
+
v_at = at if force_at else moments[0]
|
20151
|
+
v_till = till if force_till else moments[-1]
|
20152
|
+
min_moment = moments[0]
|
20153
|
+
max_moment = moments[-1]
|
20154
|
+
moments = [interpolate(moment, min_moment, max_moment, v_at, v_till) for moment in moments]
|
20155
|
+
self.intervals = [t1 - t0 for t0, t1 in zip([0] + moments, moments)]
|
19927
20156
|
at = self.intervals[0]
|
19928
20157
|
self.intervals[0] = 0
|
19929
20158
|
process = "do_spread_yieldless" if env._yieldless else "do_spread"
|
@@ -26312,7 +26541,7 @@ def fonts():
|
|
26312
26541
|
|
26313
26542
|
for dir, recursive in dir_recursives:
|
26314
26543
|
for file_path in dir.glob("**/*.*" if recursive else "*.*"):
|
26315
|
-
if file_path.suffix.lower() == ".ttf":
|
26544
|
+
if file_path.suffix.lower() == ".ttf":
|
26316
26545
|
file = str(file_path)
|
26317
26546
|
fn = os.path.basename(file).split(".")[0]
|
26318
26547
|
if "_std_fonts" in globals() and fn in _std_fonts(): # test for availabiitly, because of minimized version
|
@@ -26372,7 +26601,8 @@ def getfont(fontname, fontsize):
|
|
26372
26601
|
return getfont.lookup[(fontname, fontsize)]
|
26373
26602
|
else:
|
26374
26603
|
getfont.lookup = {}
|
26375
|
-
|
26604
|
+
if fontname=="":
|
26605
|
+
a=1
|
26376
26606
|
if isinstance(fontname, str):
|
26377
26607
|
fontlist1 = [fontname]
|
26378
26608
|
else:
|
@@ -26405,7 +26635,8 @@ def getfont(fontname, fontsize):
|
|
26405
26635
|
result = ImageFont.truetype(filename, size=int(fontsize))
|
26406
26636
|
else:
|
26407
26637
|
# refer to https://github.com/python-pillow/Pillow/issues/3730 for explanation (in order to load >= 500 fonts)
|
26408
|
-
|
26638
|
+
with open(filename, "rb") as f:
|
26639
|
+
result = ImageFont.truetype(font=io.BytesIO(f.read()), size=int(fontsize))
|
26409
26640
|
break
|
26410
26641
|
except Exception:
|
26411
26642
|
raise
|
@@ -26798,7 +27029,7 @@ class ImageContainer:
|
|
26798
27029
|
if not (0 <= t_from < t_to):
|
26799
27030
|
raise ValueError(f"animation_from={t_from} not with 0 and animation_to={t_to}")
|
26800
27031
|
if t_to > self._duration:
|
26801
|
-
raise ValueError(f"animation_to={t_to} > duration={
|
27032
|
+
raise ValueError(f"animation_to={t_to} > duration={self._duration}")
|
26802
27033
|
if pingpong:
|
26803
27034
|
interval = 2 * (t_to - t_from)
|
26804
27035
|
else:
|
@@ -26944,7 +27175,7 @@ def reset() -> None:
|
|
26944
27175
|
g.tkinter_loaded = "?"
|
26945
27176
|
g.image_container_cache = {}
|
26946
27177
|
g._default_cap_now = False
|
26947
|
-
g._captured_stdout=[]
|
27178
|
+
g._captured_stdout = []
|
26948
27179
|
|
26949
27180
|
random_seed() # always start with seed 1234567
|
26950
27181
|
|
@@ -27177,7 +27408,6 @@ reset()
|
|
27177
27408
|
set_environment_aliases()
|
27178
27409
|
|
27179
27410
|
if __name__ == "__main__":
|
27180
|
-
|
27181
27411
|
sys.path.insert(0, str(Path(__file__).parent / ".." / "misc"))
|
27182
27412
|
try:
|
27183
27413
|
import salabim_exp
|
@@ -0,0 +1,10 @@
|
|
1
|
+
salabim/DejaVuSansMono.ttf,sha256=Z_oIXp5yp1Zaw2y2p3vaxwHhjHpG0MFbmwhxSh4aIEI,335068
|
2
|
+
salabim/LICENSE.txt,sha256=qHlBa-POyexatCxDTjSKMlYtkBFQDn9lu-YV_1L6V0U,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=NzhLkqRi8niqF9eQQPZRxJueQBROP0084q6qHrY6Qzc,1103953
|
7
|
+
salabim-24.0.13.dist-info/METADATA,sha256=-xWemNdEOZ-EbstXw49IqGKhr97mg85QxyuDLa2LtGA,3450
|
8
|
+
salabim-24.0.13.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
9
|
+
salabim-24.0.13.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
|
10
|
+
salabim-24.0.13.dist-info/RECORD,,
|
@@ -1,10 +0,0 @@
|
|
1
|
-
salabim/DejaVuSansMono.ttf,sha256=Z_oIXp5yp1Zaw2y2p3vaxwHhjHpG0MFbmwhxSh4aIEI,335068
|
2
|
-
salabim/LICENSE.txt,sha256=qHlBa-POyexatCxDTjSKMlYtkBFQDn9lu-YV_1L6V0U,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=8dANioKbD1covX06fZohLeNttQVbalrN6q8eODdZYTU,1097286
|
7
|
-
salabim-24.0.11.post1.dist-info/METADATA,sha256=g39m6E1GfEa8lmL3Ji7vWbz2MpGvYClI1oedRWT2zQc,3456
|
8
|
-
salabim-24.0.11.post1.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
|
9
|
-
salabim-24.0.11.post1.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
|
10
|
-
salabim-24.0.11.post1.dist-info/RECORD,,
|
File without changes
|