e2D 1.3.8__py3-none-any.whl → 1.3.9__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.
- e2D/envs.py +1 -1
- e2D/plots.py +110 -51
- {e2D-1.3.8.dist-info → e2D-1.3.9.dist-info}/METADATA +1 -1
- e2D-1.3.9.dist-info/RECORD +9 -0
- e2D-1.3.8.dist-info/RECORD +0 -9
- {e2D-1.3.8.dist-info → e2D-1.3.9.dist-info}/LICENSE +0 -0
- {e2D-1.3.8.dist-info → e2D-1.3.9.dist-info}/WHEEL +0 -0
- {e2D-1.3.8.dist-info → e2D-1.3.9.dist-info}/top_level.txt +0 -0
e2D/envs.py
CHANGED
|
@@ -25,7 +25,7 @@ pg.font.init()
|
|
|
25
25
|
font_arial_16 = pg.font.SysFont("Arial", 16)
|
|
26
26
|
font_arial_32 = pg.font.SysFont("Arial", 32)
|
|
27
27
|
font_arial_64 = pg.font.SysFont("Arial", 64)
|
|
28
|
-
|
|
28
|
+
create_arial_font_size = lambda size: pg.font.SysFont("Arial", size)
|
|
29
29
|
|
|
30
30
|
TEXT_FIXED_SIDES_TOP_LEFT = 0
|
|
31
31
|
TEXT_FIXED_SIDES_TOP_MIDDLE = 1
|
e2D/plots.py
CHANGED
|
@@ -9,7 +9,7 @@ def no_error_complex_function(function, args) -> V2|Vector2D:
|
|
|
9
9
|
sign = lambda value: -1 if value < 0 else (1 if value > 0 else 0)
|
|
10
10
|
|
|
11
11
|
class Function:
|
|
12
|
-
def __init__(self, function, color) -> None:
|
|
12
|
+
def __init__(self, function, color:list[float]|tuple[float,float,float]=(255,255,255)) -> None:
|
|
13
13
|
self.plot : Plot
|
|
14
14
|
self.color = color
|
|
15
15
|
self.function = function
|
|
@@ -28,9 +28,11 @@ class Function:
|
|
|
28
28
|
self.points = self.get_points()
|
|
29
29
|
self.render()
|
|
30
30
|
|
|
31
|
+
def get_derivative(self, delta:float=.01, color:None|list[float]|tuple[float,float,float]=None) -> Function:
|
|
32
|
+
return Function(lambda x,y: (self.function(x + delta, y) - self.function(x,y))/delta - y, color if color != None else self.color)
|
|
33
|
+
|
|
31
34
|
def render(self) -> None:
|
|
32
35
|
self.__layer_surface__.fill((0,0,0,0))
|
|
33
|
-
# print(self.plot.dra)
|
|
34
36
|
offset = self.plot.dragging - self.plot.start_dragging if (self.plot.dragging != None) and (not self.plot.settings.get("use_real_time_rendering")) else V2z
|
|
35
37
|
if any(x < 1 for x in self.plot.scale):
|
|
36
38
|
# draw rects
|
|
@@ -85,34 +87,56 @@ class __PlotSettings__:
|
|
|
85
87
|
def __init__(self, plot:Plot) -> None:
|
|
86
88
|
self.plot = plot
|
|
87
89
|
self.settings :dict= {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
90
|
+
# axes
|
|
91
|
+
"distance_to_axis_for_scalar_zoom" : 10,
|
|
92
|
+
|
|
93
|
+
# cursor
|
|
94
|
+
"show_cursor_coords" : False,
|
|
95
|
+
"zoom_on_center" : False,
|
|
96
|
+
|
|
97
|
+
# plot visual options
|
|
98
|
+
# plot system
|
|
99
|
+
"use_inter_pixel_correction" : True,
|
|
100
|
+
"use_real_time_rendering" : True,
|
|
101
|
+
|
|
102
|
+
# axes
|
|
103
|
+
"change_axes_colors_on_mouse_hover" : True,
|
|
104
|
+
"mouse_hover_axes_color" : rgb(200, 200, 200),
|
|
105
|
+
"show_axes" : True,
|
|
106
|
+
"show_x_axis" : True,
|
|
107
|
+
"show_y_axis" : True,
|
|
108
|
+
"axes_default_color" : rgb(100, 100, 100),
|
|
109
|
+
"x_axis_color" : None,
|
|
110
|
+
"y_axis_color" : None,
|
|
111
|
+
"axes_default_width" : 5,
|
|
112
|
+
"x_axis_width" : None,
|
|
113
|
+
"y_axis_width" : None,
|
|
114
|
+
"render_axes_on_top" : False,
|
|
115
|
+
|
|
116
|
+
# grid
|
|
117
|
+
"show_grid" : True,
|
|
118
|
+
"grid_step" : V2(PI, 1),
|
|
119
|
+
"grid_color" : rgb(17, 65, 68),
|
|
120
|
+
"grid_width" : 1,
|
|
121
|
+
|
|
122
|
+
# pointer
|
|
123
|
+
"show_pointer" : True,
|
|
124
|
+
"pointer_radius" : 15,
|
|
125
|
+
"pointer_color" : rgb(255, 255, 255),
|
|
126
|
+
|
|
127
|
+
#rect
|
|
128
|
+
"render_bg" : True,
|
|
129
|
+
"bg_color" : rgb(28, 29, 34),
|
|
130
|
+
"draw_rect" : True,
|
|
131
|
+
"rect_color" : rgb(255, 255, 255),
|
|
132
|
+
"rect_width" : 5,
|
|
133
|
+
"show_corners_coords" : True,
|
|
134
|
+
|
|
135
|
+
# info options
|
|
136
|
+
"show_zoom_info": True,
|
|
137
|
+
"top_left_info_position" : self.plot.position + V2(20, 100),
|
|
138
|
+
"info_interline_space" : V2(0, 32),
|
|
139
|
+
"info_precision" : 2,
|
|
116
140
|
}
|
|
117
141
|
|
|
118
142
|
def print_current_settings(self) -> None:
|
|
@@ -136,9 +160,8 @@ class __PlotSettings__:
|
|
|
136
160
|
if not (key in self.settings): raise ValueError(f"The key [{key}] does not exist...")
|
|
137
161
|
self.settings[key] = new_value
|
|
138
162
|
|
|
139
|
-
def multiple_set(self,
|
|
140
|
-
|
|
141
|
-
self.set(key, new_value)
|
|
163
|
+
def multiple_set(self, new_key_and_values_dict:dict) -> None:
|
|
164
|
+
self.settings.update(new_key_and_values_dict)
|
|
142
165
|
|
|
143
166
|
def get(self, key:str) -> bool|V2|Vector2D|int|float:
|
|
144
167
|
return self.settings[key]
|
|
@@ -147,8 +170,7 @@ class __PlotSettings__:
|
|
|
147
170
|
return [self.get(key) for key in keys]
|
|
148
171
|
|
|
149
172
|
class Plot:
|
|
150
|
-
|
|
151
|
-
__bottom_right_multiplier__ = V2(1, -1)
|
|
173
|
+
__y_axis_multiplier__ = V2(1, -1)
|
|
152
174
|
def __init__(self, rootEnv:"RootEnv", plot_position:V2|Vector2D, plot_size:V2|Vector2D, top_left_plot_coord:V2|Vector2D, bottom_right_plot_coord: V2|Vector2D, scale:V2|Vector2D=V2one) -> None:
|
|
153
175
|
self.rootEnv = rootEnv
|
|
154
176
|
|
|
@@ -167,15 +189,15 @@ class Plot:
|
|
|
167
189
|
|
|
168
190
|
self.functions :list[Function]= []
|
|
169
191
|
|
|
170
|
-
self.canvas = pg.Surface(self.size())
|
|
192
|
+
self.canvas = pg.Surface(self.size(), pg.SRCALPHA, 32).convert_alpha()
|
|
171
193
|
self.dragging = None
|
|
172
194
|
self.start_dragging = V2z
|
|
173
195
|
self.is_mouse_in_rect = False
|
|
174
196
|
self.mouse_scalar = V2one.copy()
|
|
175
197
|
|
|
176
198
|
def set_borders_by_position_and_zoom(self) -> None:
|
|
177
|
-
self.top_left_plot_coord = self.current_offset - (.5**(.1*self.current_zoom)) * self.
|
|
178
|
-
self.bottom_right_plot_coord = self.current_offset + (.5**(.1*self.current_zoom)) * self.
|
|
199
|
+
self.top_left_plot_coord = self.current_offset - (.5**(.1*self.current_zoom)) * self.__y_axis_multiplier__
|
|
200
|
+
self.bottom_right_plot_coord = self.current_offset + (.5**(.1*self.current_zoom)) * self.__y_axis_multiplier__
|
|
179
201
|
self.top_left_x, self.top_left_y = self.top_left_plot_coord
|
|
180
202
|
self.bottom_right_x, self.bottom_right_y = self.bottom_right_plot_coord
|
|
181
203
|
|
|
@@ -202,17 +224,35 @@ class Plot:
|
|
|
202
224
|
return (real_position - self.position) * (self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size + self.top_left_plot_coord
|
|
203
225
|
|
|
204
226
|
def render(self) -> None:
|
|
205
|
-
|
|
206
|
-
|
|
227
|
+
# fill canvas with alpha zero color
|
|
228
|
+
self.canvas.fill((0,0,0,0))
|
|
229
|
+
|
|
230
|
+
# draw grid
|
|
231
|
+
if self.settings.get("show_grid"):
|
|
232
|
+
grid_step = self.settings.get("grid_step")
|
|
233
|
+
grid_color = self.settings.get("grid_color")
|
|
234
|
+
grid_width = self.settings.get("grid_width")
|
|
235
|
+
clamped_top_left = grid_step * (self.top_left_plot_coord / grid_step).__ceil__()
|
|
236
|
+
clamped_bottom_right = grid_step * (self.bottom_right_plot_coord / grid_step).__ceil__()
|
|
237
|
+
for x_value in np.arange(clamped_top_left.x, clamped_bottom_right.x, grid_step.x):
|
|
238
|
+
pg.draw.line( self.canvas, grid_color, self.__plot2real__((x_value, self.top_left_y))(), self.__plot2real__((x_value, self.bottom_right_y))(), grid_width)
|
|
239
|
+
for y_value in np.arange(clamped_bottom_right.y, clamped_top_left.y, grid_step.y):
|
|
240
|
+
pg.draw.line(self.canvas, grid_color, self.__plot2real__((self.top_left_x, y_value))(), self.__plot2real__((self.bottom_right_x, y_value))(), grid_width)
|
|
241
|
+
|
|
242
|
+
# draw functions
|
|
207
243
|
for function in self.functions: function.draw()
|
|
208
244
|
|
|
209
|
-
|
|
245
|
+
# draw rect, pointer and corner coords
|
|
246
|
+
if self.settings.get("draw_rect"):
|
|
247
|
+
pg.draw.rect(self.canvas, self.settings.get("rect_color"), V2z() + self.size(), self.settings.get("rect_width"))
|
|
210
248
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
249
|
+
if self.settings.get("show_pointer"):
|
|
250
|
+
center = self.size * .5
|
|
251
|
+
aimer_radius = self.settings.get("pointer_radius")
|
|
252
|
+
pointer_color = self.settings.get("pointer_color")
|
|
253
|
+
pg.draw.line(self.canvas, pointer_color, (center + aimer_radius)(), (center - aimer_radius)(), 1)
|
|
254
|
+
pg.draw.line(self.canvas, pointer_color, (center + self.__y_axis_multiplier__ * aimer_radius)(), (center - self.__y_axis_multiplier__ * aimer_radius)(), 1)
|
|
255
|
+
pg.draw.circle(self.canvas, pointer_color, (self.size * .5)(), 15, 1)
|
|
216
256
|
|
|
217
257
|
if self.settings.get("show_corners_coords"):
|
|
218
258
|
self.rootEnv.print(str(self.top_left_plot_coord), V2z.copy(), bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
@@ -221,12 +261,14 @@ class Plot:
|
|
|
221
261
|
self.rootEnv.print(str(V2(self.bottom_right_plot_coord.x, self.top_left_plot_coord.y)), self.size * V2(1, 0), fixed_sides=TEXT_FIXED_SIDES_TOP_RIGHT, bg_color=(0,0,0), border_color=(255,255,255), border_width=2, border_radius=15, margin=V2(10,10), personalized_surface=self.canvas)
|
|
222
262
|
|
|
223
263
|
def update(self) -> None:
|
|
264
|
+
# update mouse and center positions
|
|
224
265
|
self.plot_mouse_position = self.__real2plot__(self.rootEnv.mouse.position)
|
|
225
266
|
self.plot_center_real_position = self.__plot2real__(V2z) + self.position
|
|
226
267
|
|
|
227
268
|
self.is_mouse_in_rect = self.position.x < self.rootEnv.mouse.position.x < self.position.x + self.size.x and \
|
|
228
269
|
self.position.y < self.rootEnv.mouse.position.y < self.position.y + self.size.y
|
|
229
270
|
|
|
271
|
+
# render the functions when i stop dragging (when i release the left mouse key)
|
|
230
272
|
if self.rootEnv.mouse.just_released[0] and self.dragging != None:
|
|
231
273
|
self.dragging = None
|
|
232
274
|
self.update_grid(True)
|
|
@@ -235,15 +277,19 @@ class Plot:
|
|
|
235
277
|
self.render()
|
|
236
278
|
|
|
237
279
|
if self.is_mouse_in_rect:
|
|
280
|
+
# mouse scalar is needed for checking if the mouse is hovering an axis, in case it is the opposite one zoom value has to be multiplied by 0 so nullifying it.
|
|
238
281
|
self.mouse_scalar = V2(0 if abs(self.plot_center_real_position.x - self.rootEnv.mouse.position.x) < self.settings.get("distance_to_axis_for_scalar_zoom") else 1, 0 if abs(self.plot_center_real_position.y - self.rootEnv.mouse.position.y) < self.settings.get("distance_to_axis_for_scalar_zoom") else 1) #type: ignore
|
|
239
282
|
if self.mouse_scalar.x == self.mouse_scalar.y == 0: self.mouse_scalar = V2one
|
|
240
283
|
for event in self.rootEnv.events:
|
|
241
284
|
if event.type == pg.MOUSEWHEEL:
|
|
242
285
|
if self.settings.get("zoom_on_center"):
|
|
286
|
+
# this will always zoom exactly in the middle of the canvas, according to the current plot offset
|
|
243
287
|
self.current_zoom += event.y * self.mouse_scalar
|
|
244
288
|
else:
|
|
289
|
+
# this will get the pre plot mouse position, calculate the zoom and with the "after" mouse position calculate the offset that i will add to the current plot offset
|
|
245
290
|
pre = self.__real2plot__(self.rootEnv.mouse.position)
|
|
246
291
|
self.current_zoom += event.y * self.mouse_scalar
|
|
292
|
+
# i have to update the corners of the plot here to use the real2plot function correctly (i cant use shortcuts)
|
|
247
293
|
self.update_grid(False)
|
|
248
294
|
self.current_offset += pre - self.__real2plot__(self.rootEnv.mouse.position)
|
|
249
295
|
self.update_grid(True)
|
|
@@ -251,15 +297,18 @@ class Plot:
|
|
|
251
297
|
function.update_points()
|
|
252
298
|
self.render()
|
|
253
299
|
|
|
300
|
+
# start dragging whenever mouse left button is just pressed
|
|
254
301
|
if self.rootEnv.mouse.just_pressed[0] and self.dragging == None:
|
|
255
302
|
self.dragging = self.rootEnv.mouse.position.copy()
|
|
256
303
|
self.start_dragging = self.dragging.copy()
|
|
257
304
|
|
|
305
|
+
# update the canvas if im dragging
|
|
258
306
|
if self.dragging:
|
|
259
307
|
offset = (self.dragging - self.rootEnv.mouse.position)* V2(1, -1) * (abs(self.bottom_right_plot_coord - self.top_left_plot_coord) / self.size)
|
|
260
308
|
self.dragging = self.rootEnv.mouse.position.copy()
|
|
261
309
|
self.current_offset += offset
|
|
262
310
|
|
|
311
|
+
# with real time rendering i update the function render each frame whnever im dragging the canvs around
|
|
263
312
|
if self.settings.get("use_real_time_rendering"):
|
|
264
313
|
self.update_grid(True)
|
|
265
314
|
for function in self.functions: function.update_points()
|
|
@@ -268,22 +317,32 @@ class Plot:
|
|
|
268
317
|
self.render()
|
|
269
318
|
|
|
270
319
|
def draw(self) -> None:
|
|
271
|
-
|
|
272
|
-
if self.
|
|
320
|
+
# fill canvas with bg color
|
|
321
|
+
if self.settings.get("render_bg"):
|
|
322
|
+
self.rootEnv.screen.fill(self.settings.get("bg_color"), self.position() + self.size())
|
|
323
|
+
|
|
324
|
+
# render functions before axes
|
|
325
|
+
if render_axes_on_top:=self.settings.get("render_axes_on_top"): self.rootEnv.screen.blit(self.canvas, self.position())
|
|
326
|
+
|
|
327
|
+
# render axes
|
|
328
|
+
if self.top_left_x < 0 < self.bottom_right_x and (self.settings.get("show_x_axis") and self.settings.get("show_axes")):
|
|
273
329
|
pg.draw.line(self.rootEnv.screen,
|
|
274
330
|
(self.settings.get("axes_default_color") if (x_color:=self.settings.get("x_axis_color"))==None else x_color) if self.mouse_scalar.x else (self.settings.get("mouse_hover_axes_color")),
|
|
275
331
|
(self.__plot2real__(V2(0, self.top_left_y)) + self.position)(),
|
|
276
332
|
(self.__plot2real__(V2(0, self.bottom_right_y)) + self.position)(),
|
|
277
333
|
self.settings.get("axes_default_width") if (x_width:=self.settings.get("x_axis_width"))==None else x_width) #type: ignore
|
|
278
|
-
if self.bottom_right_y < 0 < self.top_left_y and self.settings.get("show_y_axis"):
|
|
334
|
+
if self.bottom_right_y < 0 < self.top_left_y and (self.settings.get("show_y_axis") and self.settings.get("show_axes")):
|
|
279
335
|
pg.draw.line(self.rootEnv.screen,
|
|
280
336
|
(self.settings.get("axes_default_color") if (y_color:=self.settings.get("y_axis_color"))==None else y_color) if self.mouse_scalar.y else (self.settings.get("mouse_hover_axes_color")),
|
|
281
337
|
(self.__plot2real__(V2(self.top_left_x, 0)) + self.position)(),
|
|
282
338
|
(self.__plot2real__(V2(self.bottom_right_x, 0)) + self.position)(),
|
|
283
339
|
self.settings.get("axes_default_width") if (y_width:=self.settings.get("y_axis_width"))==None else y_width) #type: ignore
|
|
340
|
+
|
|
341
|
+
# render functions after axes
|
|
342
|
+
if not render_axes_on_top: self.rootEnv.screen.blit(self.canvas, self.position())
|
|
284
343
|
|
|
285
344
|
if self.is_mouse_in_rect and self.settings.get("show_cursor_coords"):
|
|
286
|
-
self.rootEnv.print(str(
|
|
345
|
+
self.rootEnv.print(str(self.plot_mouse_position), self.rootEnv.mouse.position, fixed_sides=TEXT_FIXED_SIDES_BOTTOM_MIDDLE) #type: ignore
|
|
287
346
|
|
|
288
347
|
data = [
|
|
289
348
|
[f"ZOOM:", TEXT_FIXED_SIDES_TOP_LEFT, self.settings.get("show_zoom_info")],
|
|
@@ -293,4 +352,4 @@ class Plot:
|
|
|
293
352
|
|
|
294
353
|
for i, (d, fixed_side, show) in enumerate(data):
|
|
295
354
|
if show:
|
|
296
|
-
self.rootEnv.print(d, self.settings.get("top_left_info_position") + self.settings.get("
|
|
355
|
+
self.rootEnv.print(d, self.settings.get("top_left_info_position") + self.settings.get("info_interline_space") * i, fixed_sides=fixed_side) #type: ignore
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: e2D
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.9
|
|
4
4
|
Summary: Python library for 2D games. Streamlines dev with keyboard/mouse input, vector calculations, color manipulation, and collision detection. Simplify game creation and unleash creativity!
|
|
5
5
|
Home-page: https://github.com/marick-py/e2D
|
|
6
6
|
Author: Riccardo Mariani
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
e2D/__init__.py,sha256=L4wmmedzo_SQUIcCwPYTMJTuqYi_lASRdCwL1q0Q2rw,56327
|
|
2
|
+
e2D/envs.py,sha256=myRralRCZeuadguczadi7lXUPOZdNwlnTw0M3oNpNFE,3933
|
|
3
|
+
e2D/plots.py,sha256=WCANUHZQE0vmUR4rg9gQVShbljxZ-Dz6ae3VhNO6PSo,20418
|
|
4
|
+
e2D/utils.py,sha256=sq9efoNnSlJAfjvf18qDQpvO1jyz-9-mWBW3P4WMkD4,5368
|
|
5
|
+
e2D-1.3.9.dist-info/LICENSE,sha256=wymkNVDvj3qmjdO_rAhkRPM4t5y3_SqffGsFdgfvznU,1066
|
|
6
|
+
e2D-1.3.9.dist-info/METADATA,sha256=ZVXNZs-NxLBNIDlB8rBIc3HQEfeCUeC7Yu5e1yLWYb0,9608
|
|
7
|
+
e2D-1.3.9.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
8
|
+
e2D-1.3.9.dist-info/top_level.txt,sha256=3vKZ-CGzNlTCpzVMmM0Ht76krCofKw7hZ0wBf-dnKdM,4
|
|
9
|
+
e2D-1.3.9.dist-info/RECORD,,
|
e2D-1.3.8.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
e2D/__init__.py,sha256=L4wmmedzo_SQUIcCwPYTMJTuqYi_lASRdCwL1q0Q2rw,56327
|
|
2
|
-
e2D/envs.py,sha256=mhq3SI2EmckXp9h6RYKzTGSKkvzlH-SyMTBhl3yDVZU,3929
|
|
3
|
-
e2D/plots.py,sha256=VvxODi_kP92DeoAMZ2UCXdmeZiOeyqID2gLCY8XnRYA,16345
|
|
4
|
-
e2D/utils.py,sha256=sq9efoNnSlJAfjvf18qDQpvO1jyz-9-mWBW3P4WMkD4,5368
|
|
5
|
-
e2D-1.3.8.dist-info/LICENSE,sha256=wymkNVDvj3qmjdO_rAhkRPM4t5y3_SqffGsFdgfvznU,1066
|
|
6
|
-
e2D-1.3.8.dist-info/METADATA,sha256=_8qvIkMK6qheCxzwtGfnrfGXHG5b_FDMq6gjE4QE9rY,9608
|
|
7
|
-
e2D-1.3.8.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
8
|
-
e2D-1.3.8.dist-info/top_level.txt,sha256=3vKZ-CGzNlTCpzVMmM0Ht76krCofKw7hZ0wBf-dnKdM,4
|
|
9
|
-
e2D-1.3.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|