plopp 25.6.1__py3-none-any.whl → 25.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.
- plopp/core/graph.py +2 -2
- plopp/core/helpers.py +1 -1
- plopp/core/node_class.py +3 -3
- plopp/plotting/common.py +3 -3
- plopp/plotting/slicer.py +10 -1
- plopp/widgets/drawing.py +2 -2
- plopp/widgets/linesave.py +1 -1
- plopp/widgets/slice.py +97 -46
- {plopp-25.6.1.dist-info → plopp-25.7.0.dist-info}/METADATA +2 -2
- {plopp-25.6.1.dist-info → plopp-25.7.0.dist-info}/RECORD +13 -13
- {plopp-25.6.1.dist-info → plopp-25.7.0.dist-info}/WHEEL +0 -0
- {plopp-25.6.1.dist-info → plopp-25.7.0.dist-info}/licenses/LICENSE +0 -0
- {plopp-25.6.1.dist-info → plopp-25.7.0.dist-info}/top_level.txt +0 -0
plopp/core/graph.py
CHANGED
|
@@ -23,8 +23,8 @@ def _make_graphviz_digraph(*args, **kwargs):
|
|
|
23
23
|
def _walk_graph(start, nodes, edges, views, labels):
|
|
24
24
|
label = (
|
|
25
25
|
escape(str(start.func)) + '\nid = ' + start.id
|
|
26
|
-
if start.
|
|
27
|
-
else escape(start.
|
|
26
|
+
if start.pretty_name is None
|
|
27
|
+
else escape(start.pretty_name)
|
|
28
28
|
)
|
|
29
29
|
nodes[start.id] = label
|
|
30
30
|
for child in start.children:
|
plopp/core/helpers.py
CHANGED
|
@@ -38,6 +38,6 @@ def widget_node(widget) -> Node:
|
|
|
38
38
|
``ipywidgets`` library, or a custom widget.
|
|
39
39
|
"""
|
|
40
40
|
n = Node(func=lambda: widget.value)
|
|
41
|
-
n.
|
|
41
|
+
n.pretty_name = f'Widget <{type(widget).__name__}: {type(widget.value).__name__}>'
|
|
42
42
|
widget.observe(n.notify_children, names="value")
|
|
43
43
|
return n
|
plopp/core/node_class.py
CHANGED
|
@@ -64,10 +64,10 @@ class Node:
|
|
|
64
64
|
)
|
|
65
65
|
)
|
|
66
66
|
fname = getattr(self.func, "__name__", str(self.func))
|
|
67
|
-
self.
|
|
67
|
+
self.pretty_name = f'{fname}({args_string})'
|
|
68
68
|
else:
|
|
69
69
|
val_str = f'={func!r}' if isinstance(func, int | float | str) else ""
|
|
70
|
-
self.
|
|
70
|
+
self.pretty_name = f'Input <{type(func).__name__}{val_str}>'
|
|
71
71
|
|
|
72
72
|
# Attempt to set children after setting name in case error message is needed
|
|
73
73
|
for parent in chain(self.parents, self.kwparents.values()):
|
|
@@ -194,7 +194,7 @@ class Node:
|
|
|
194
194
|
return self.id == other.id
|
|
195
195
|
|
|
196
196
|
def __repr__(self) -> str:
|
|
197
|
-
return f"Node(name={self.
|
|
197
|
+
return f"Node(name={self.pretty_name})"
|
|
198
198
|
|
|
199
199
|
def __add__(self, other: Node | Any) -> Node:
|
|
200
200
|
return Node(lambda x, y: x + y, self, other)
|
plopp/plotting/common.py
CHANGED
|
@@ -285,7 +285,7 @@ def preprocess(
|
|
|
285
285
|
check_not_binned(out)
|
|
286
286
|
check_allowed_dtypes(out)
|
|
287
287
|
if name is not None:
|
|
288
|
-
out.name = name
|
|
288
|
+
out.name = str(name)
|
|
289
289
|
if not ignore_size:
|
|
290
290
|
_check_size(out)
|
|
291
291
|
if coords is not None:
|
|
@@ -316,9 +316,9 @@ def input_to_nodes(obj: PlottableMulti, processor: Callable) -> list[Node]:
|
|
|
316
316
|
nodes = [Node(processor, inp, name=name) for name, inp in to_nodes]
|
|
317
317
|
for node in nodes:
|
|
318
318
|
if hasattr(processor, 'func'):
|
|
319
|
-
node.
|
|
319
|
+
node.pretty_name = processor.func.__name__
|
|
320
320
|
else:
|
|
321
|
-
node.
|
|
321
|
+
node.pretty_name = 'Preprocess data'
|
|
322
322
|
return nodes
|
|
323
323
|
|
|
324
324
|
|
plopp/plotting/slicer.py
CHANGED
|
@@ -60,6 +60,7 @@ class Slicer:
|
|
|
60
60
|
vmin: VariableLike | float = None,
|
|
61
61
|
vmax: VariableLike | float = None,
|
|
62
62
|
cbar: bool = True,
|
|
63
|
+
enable_player: bool = False,
|
|
63
64
|
**kwargs,
|
|
64
65
|
):
|
|
65
66
|
nodes = input_to_nodes(
|
|
@@ -98,7 +99,9 @@ class Slicer:
|
|
|
98
99
|
from ..widgets import SliceWidget, slice_dims
|
|
99
100
|
|
|
100
101
|
self.slider = SliceWidget(
|
|
101
|
-
nodes[0](),
|
|
102
|
+
nodes[0](),
|
|
103
|
+
dims=[dim for dim in dims if dim not in keep],
|
|
104
|
+
enable_player=enable_player,
|
|
102
105
|
)
|
|
103
106
|
self.slider_node = widget_node(self.slider)
|
|
104
107
|
self.slice_nodes = [slice_dims(node, self.slider_node) for node in nodes]
|
|
@@ -130,6 +133,7 @@ def slicer(
|
|
|
130
133
|
vmin: VariableLike | float = None,
|
|
131
134
|
vmax: VariableLike | float = None,
|
|
132
135
|
cbar: bool = True,
|
|
136
|
+
enable_player: bool = False,
|
|
133
137
|
**kwargs,
|
|
134
138
|
) -> FigureLike:
|
|
135
139
|
"""
|
|
@@ -156,6 +160,10 @@ def slicer(
|
|
|
156
160
|
The maximum value of the y-axis (1d plots) or color range (2d plots).
|
|
157
161
|
cbar:
|
|
158
162
|
Whether to display a colorbar for 2D plots.
|
|
163
|
+
enable_player:
|
|
164
|
+
Add a play button to animate the sliders if True. Defaults to False.
|
|
165
|
+
|
|
166
|
+
.. versionadded:: 25.07.0
|
|
159
167
|
**kwargs:
|
|
160
168
|
See :py:func:`plopp.plot` for the full list of figure customization arguments.
|
|
161
169
|
"""
|
|
@@ -167,5 +175,6 @@ def slicer(
|
|
|
167
175
|
vmax=vmax,
|
|
168
176
|
coords=coords,
|
|
169
177
|
cbar=cbar,
|
|
178
|
+
enable_player=enable_player,
|
|
170
179
|
**kwargs,
|
|
171
180
|
).figure
|
plopp/widgets/drawing.py
CHANGED
|
@@ -86,12 +86,12 @@ class DrawingTool(ToggleTool):
|
|
|
86
86
|
|
|
87
87
|
def make_node(self, artist):
|
|
88
88
|
draw_node = Node(self._get_artist_info(artist=artist, figure=self._figure))
|
|
89
|
-
draw_node.
|
|
89
|
+
draw_node.pretty_name = f'Draw node {len(self._draw_nodes)}'
|
|
90
90
|
nodeid = draw_node.id
|
|
91
91
|
self._draw_nodes[nodeid] = draw_node
|
|
92
92
|
artist.nodeid = nodeid
|
|
93
93
|
output_node = node(self._func)(self._input_node, draw_node)
|
|
94
|
-
output_node.
|
|
94
|
+
output_node.pretty_name = f'Output node {len(self._output_nodes)}'
|
|
95
95
|
self._output_nodes[nodeid] = output_node
|
|
96
96
|
if self._destination_is_fig:
|
|
97
97
|
output_node.add_view(self._destination.view)
|
plopp/widgets/linesave.py
CHANGED
|
@@ -45,7 +45,7 @@ class LineSaveTool(VBar):
|
|
|
45
45
|
|
|
46
46
|
data = self._data_node.request_data()
|
|
47
47
|
node = Node(data)
|
|
48
|
-
node.
|
|
48
|
+
node.pretty_name = f'Save node {len(self._lines)}'
|
|
49
49
|
line_id = node._id
|
|
50
50
|
node.add_view(self._fig.view)
|
|
51
51
|
self._fig.view.render()
|
plopp/widgets/slice.py
CHANGED
|
@@ -12,74 +12,121 @@ from ..core.utils import coord_element_to_string
|
|
|
12
12
|
from .box import VBar
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
class DimSlicer(ipw.VBox):
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
dim: str,
|
|
19
|
+
size: int,
|
|
20
|
+
coord: sc.Variable,
|
|
21
|
+
slider_constr: type[ipw.Widget],
|
|
22
|
+
enable_player: bool = False,
|
|
23
|
+
):
|
|
24
|
+
if enable_player and not issubclass(slider_constr, ipw.IntSlider):
|
|
25
|
+
raise TypeError(
|
|
26
|
+
"Player can only be enabled for IntSlider, not for IntRangeSlider."
|
|
27
|
+
)
|
|
28
|
+
widget_args = {
|
|
29
|
+
'step': 1,
|
|
30
|
+
'description': dim,
|
|
31
|
+
'min': 0,
|
|
32
|
+
'max': size - 1,
|
|
33
|
+
'value': (size - 1) // 2 if slider_constr is ipw.IntSlider else None,
|
|
34
|
+
'continuous_update': True,
|
|
35
|
+
'readout': False,
|
|
36
|
+
'layout': {"width": "200px", "margin": "0px 0px 0px 10px"},
|
|
37
|
+
'style': {'description_width': 'initial'},
|
|
38
|
+
}
|
|
39
|
+
self.slider = slider_constr(**widget_args)
|
|
40
|
+
self.continuous_update = ipw.Checkbox(
|
|
41
|
+
value=True,
|
|
42
|
+
tooltip="Continuous update",
|
|
43
|
+
indent=False,
|
|
44
|
+
layout={"width": "20px"},
|
|
45
|
+
)
|
|
46
|
+
self.label = ipw.Label(
|
|
47
|
+
value=coord_element_to_string(coord[dim, self.slider.value])
|
|
48
|
+
)
|
|
49
|
+
ipw.jslink(
|
|
50
|
+
(self.continuous_update, 'value'), (self.slider, 'continuous_update')
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
children = [self.slider, self.continuous_update, self.label]
|
|
54
|
+
if enable_player:
|
|
55
|
+
self.player = ipw.Play(
|
|
56
|
+
value=self.slider.value,
|
|
57
|
+
min=self.slider.min,
|
|
58
|
+
max=self.slider.max,
|
|
59
|
+
step=self.slider.step,
|
|
60
|
+
interval=100,
|
|
61
|
+
description='Play',
|
|
62
|
+
)
|
|
63
|
+
ipw.jslink((self.player, 'value'), (self.slider, 'value'))
|
|
64
|
+
children.insert(0, self.player)
|
|
65
|
+
|
|
66
|
+
self.dim = dim
|
|
67
|
+
self.coord = coord
|
|
68
|
+
self.slider.observe(self._update_label, names='value')
|
|
69
|
+
|
|
70
|
+
super().__init__([ipw.HBox(children)])
|
|
71
|
+
|
|
72
|
+
def _update_label(self, change: dict[str, Any]):
|
|
73
|
+
"""
|
|
74
|
+
Update the readout label with the coordinate value, instead of the integer
|
|
75
|
+
readout index.
|
|
76
|
+
"""
|
|
77
|
+
self.label.value = coord_element_to_string(self.coord[self.dim, change['new']])
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def value(self) -> int | tuple[int, int]:
|
|
81
|
+
"""
|
|
82
|
+
The value of the slider.
|
|
83
|
+
"""
|
|
84
|
+
return self.slider.value
|
|
85
|
+
|
|
86
|
+
@value.setter
|
|
87
|
+
def value(self, value: int | tuple[int, int]):
|
|
88
|
+
self.slider.value = value
|
|
89
|
+
|
|
90
|
+
|
|
15
91
|
class _BaseSliceWidget(VBar, ipw.ValueWidget):
|
|
16
|
-
def __init__(
|
|
92
|
+
def __init__(
|
|
93
|
+
self,
|
|
94
|
+
da: sc.DataArray,
|
|
95
|
+
dims: list[str],
|
|
96
|
+
slider_constr: ipw.Widget,
|
|
97
|
+
enable_player: bool = False,
|
|
98
|
+
):
|
|
17
99
|
if isinstance(dims, str):
|
|
18
100
|
dims = [dims]
|
|
19
|
-
self._slider_dims = dims
|
|
20
101
|
self.controls = {}
|
|
21
102
|
self.view = None
|
|
22
103
|
children = []
|
|
23
104
|
|
|
24
|
-
for dim in
|
|
105
|
+
for dim in dims:
|
|
25
106
|
coord = (
|
|
26
107
|
da.coords[dim]
|
|
27
108
|
if dim in da.coords
|
|
28
109
|
else sc.arange(dim, da.sizes[dim], unit=None)
|
|
29
110
|
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if slider_constr is ipw.IntSlider
|
|
37
|
-
else None,
|
|
38
|
-
'continuous_update': True,
|
|
39
|
-
'readout': False,
|
|
40
|
-
'layout': {"width": "200px"},
|
|
41
|
-
'style': {'description_width': 'initial'},
|
|
42
|
-
}
|
|
43
|
-
slider = slider_constr(**widget_args)
|
|
44
|
-
continuous_update = ipw.Checkbox(
|
|
45
|
-
value=True,
|
|
46
|
-
tooltip="Continuous update",
|
|
47
|
-
indent=False,
|
|
48
|
-
layout={"width": "20px"},
|
|
111
|
+
self.controls[dim] = DimSlicer(
|
|
112
|
+
dim=dim,
|
|
113
|
+
size=da.sizes[dim],
|
|
114
|
+
coord=coord,
|
|
115
|
+
slider_constr=slider_constr,
|
|
116
|
+
enable_player=enable_player,
|
|
49
117
|
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
self.controls[dim] = {
|
|
54
|
-
'continuous': continuous_update,
|
|
55
|
-
'slider': slider,
|
|
56
|
-
'label': label,
|
|
57
|
-
'coord': coord,
|
|
58
|
-
}
|
|
59
|
-
slider.observe(self._update_label, names='value')
|
|
60
|
-
slider.observe(self._on_subwidget_change, names='value')
|
|
61
|
-
children.append(ipw.HBox([continuous_update, slider, label]))
|
|
118
|
+
self.controls[dim].slider.observe(self._on_subwidget_change, names='value')
|
|
119
|
+
children.append(self.controls[dim])
|
|
62
120
|
|
|
63
121
|
self._on_subwidget_change()
|
|
64
122
|
super().__init__(children)
|
|
65
123
|
|
|
66
|
-
def _update_label(self, change: dict[str, Any]):
|
|
67
|
-
"""
|
|
68
|
-
Update the readout label with the coordinate value, instead of the integer
|
|
69
|
-
readout index.
|
|
70
|
-
"""
|
|
71
|
-
dim = change['owner'].description
|
|
72
|
-
coord = self.controls[dim]['coord'][dim, change['new']]
|
|
73
|
-
self.controls[dim]['label'].value = coord_element_to_string(coord)
|
|
74
|
-
|
|
75
124
|
def _on_subwidget_change(self, _=None):
|
|
76
125
|
"""
|
|
77
126
|
Update the value of the widget.
|
|
78
127
|
The value is a dict containing one entry per slider, giving the slider's value.
|
|
79
128
|
"""
|
|
80
|
-
self.value = {
|
|
81
|
-
dim: self.controls[dim]['slider'].value for dim in self._slider_dims
|
|
82
|
-
}
|
|
129
|
+
self.value = {dim: slicer.slider.value for dim, slicer in self.controls.items()}
|
|
83
130
|
|
|
84
131
|
|
|
85
132
|
SliceWidget = partial(_BaseSliceWidget, slider_constr=ipw.IntSlider)
|
|
@@ -95,6 +142,10 @@ da:
|
|
|
95
142
|
The input data array.
|
|
96
143
|
dims:
|
|
97
144
|
The dimensions to make sliders for.
|
|
145
|
+
enable_player:
|
|
146
|
+
Add a play button to animate the slider if True. Defaults to False.
|
|
147
|
+
|
|
148
|
+
.. versionadded:: 25.07.0
|
|
98
149
|
"""
|
|
99
150
|
|
|
100
151
|
RangeSliceWidget = partial(_BaseSliceWidget, slider_constr=ipw.IntRangeSlider)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plopp
|
|
3
|
-
Version: 25.
|
|
3
|
+
Version: 25.7.0
|
|
4
4
|
Summary: Visualization library for Scipp
|
|
5
5
|
Author: Scipp contributors
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -84,7 +84,7 @@ Dynamic: license-file
|
|
|
84
84
|
|
|
85
85
|
[](CODE_OF_CONDUCT.md)
|
|
86
86
|
[](https://pypi.python.org/pypi/plopp)
|
|
87
|
-
[](https://anaconda.org/conda-forge/plopp)
|
|
88
88
|
[](https://scipp.github.io/plopp/)
|
|
89
89
|
[](LICENSE)
|
|
90
90
|
[](https://zenodo.org/badge/latestdoi/528859752)
|
|
@@ -25,10 +25,10 @@ plopp/backends/pythreejs/outline.py,sha256=WUqtUj8GMAUzUqOocFjdT8F7WBeV9jgMSYmXD
|
|
|
25
25
|
plopp/backends/pythreejs/scatter3d.py,sha256=Z8D0l3hBJ2qlC4BIAAoHCAa97uf6IViFNt23f9wzFFI,7049
|
|
26
26
|
plopp/core/__init__.py,sha256=s25RIbKplHSRn0jjtLADPQl72JLf_KLRMRCfeMDI_UA,205
|
|
27
27
|
plopp/core/__init__.pyi,sha256=FU5U5nymhzbgBRolZSh1tqYDJ3M2djUv71mriWHD1hI,294
|
|
28
|
-
plopp/core/graph.py,sha256=
|
|
29
|
-
plopp/core/helpers.py,sha256=
|
|
28
|
+
plopp/core/graph.py,sha256=dTJa1QIQDEuDUYZIwF7NT444wkuXxb0wwBrx311vTT8,3855
|
|
29
|
+
plopp/core/helpers.py,sha256=BVunzkcYOXoYjawutFtKP8WbWN1h1OlRrSd_i9TY090,1200
|
|
30
30
|
plopp/core/limits.py,sha256=ojb3MTxlWNz2ibHXu9P-agzYV8HxPCGSB2D0oxoO9RQ,3572
|
|
31
|
-
plopp/core/node_class.py,sha256=
|
|
31
|
+
plopp/core/node_class.py,sha256=Vzjf0f7UTiCVZC8m_dwh2gGPwnJqD0HOR8HuUX5TsDI,7483
|
|
32
32
|
plopp/core/typing.py,sha256=JL_mMdFq2dNu6LuZYSBfOXGZSEn0VIJK_lr-LbC11t4,2903
|
|
33
33
|
plopp/core/utils.py,sha256=qxdOLRODgv3b0dDywT0JomsVrgifS_siC-ZpzJqgblo,7120
|
|
34
34
|
plopp/core/view.py,sha256=9WulgLHg8aPjePz967WLWieTM40dvqlgJitu-AS3WdM,1972
|
|
@@ -47,13 +47,13 @@ plopp/graphics/graphicalview.py,sha256=07xpJVnvuNlaWGsJshg_wL81jG57JhRxI23E7_WYI
|
|
|
47
47
|
plopp/graphics/tiled.py,sha256=gXYZVAs6wRFKezzN3VlEvm7_z2zx3IDYfGZQZqrpL80,1386
|
|
48
48
|
plopp/plotting/__init__.py,sha256=s25RIbKplHSRn0jjtLADPQl72JLf_KLRMRCfeMDI_UA,205
|
|
49
49
|
plopp/plotting/__init__.pyi,sha256=95wYGfM5PT0Y0Ov_ue7rBrHvHxrtex-2WEYtfFzBvE0,475
|
|
50
|
-
plopp/plotting/common.py,sha256=
|
|
50
|
+
plopp/plotting/common.py,sha256=dwtOpmMNY8deLWskiByKXficZUqX1pPGrkT_ieDN36c,10984
|
|
51
51
|
plopp/plotting/inspector.py,sha256=fT4v342pqTzihKaweoGD4WaQ5eDdyngK7W451Mh2Ffw,3586
|
|
52
52
|
plopp/plotting/mesh3d.py,sha256=KjAtlVlLYslwgP_uE067WtJRgNURkhaz0PPUuYLlJyw,2778
|
|
53
53
|
plopp/plotting/plot.py,sha256=WQzw1vHGljWY1tQU1InQWe2-M-vCW2IRiL-v7cnw46w,3886
|
|
54
54
|
plopp/plotting/scatter.py,sha256=ybPWFHFwxt_Bzv3Dy-yAFCRHW5HQEggcNihpzWduH7A,3161
|
|
55
55
|
plopp/plotting/scatter3d.py,sha256=oizd-BCgmvNu_fSV6FQt9oe7lPn4h2Zc1ohKmor-d78,3819
|
|
56
|
-
plopp/plotting/slicer.py,sha256=
|
|
56
|
+
plopp/plotting/slicer.py,sha256=ym20mXJtp_msGOet18wr0mb4TL0z4ti6W9uFo_5cvKc,6169
|
|
57
57
|
plopp/plotting/superplot.py,sha256=0EnzgSmNrdPHXooqj6GNR0IAApEHyfjgxYIPgPVO_5o,1416
|
|
58
58
|
plopp/plotting/xyplot.py,sha256=zi-RcsgonnR747aH3zp75at4ntgZ0t0rSdKEeVlReMI,1641
|
|
59
59
|
plopp/widgets/__init__.py,sha256=s25RIbKplHSRn0jjtLADPQl72JLf_KLRMRCfeMDI_UA,205
|
|
@@ -62,14 +62,14 @@ plopp/widgets/box.py,sha256=v5Gd3sY0WXcc3UfkcXxZboPG02sfOMXIo50tmpxPwVs,1806
|
|
|
62
62
|
plopp/widgets/checkboxes.py,sha256=52yJryEu1upYafFxqoTOdAZmHeKzCI_CJiCWSezCtRA,2430
|
|
63
63
|
plopp/widgets/clip3d.py,sha256=L90HUd3bjEU3BaPdK8DnUbeeFNqfFyBWDEwaG9nP-M8,14602
|
|
64
64
|
plopp/widgets/debounce.py,sha256=V5aIcnb465oqXZX-UG_DR7GjvoG6D_C2jjEUBmguGDA,1292
|
|
65
|
-
plopp/widgets/drawing.py,sha256=
|
|
66
|
-
plopp/widgets/linesave.py,sha256=
|
|
67
|
-
plopp/widgets/slice.py,sha256=
|
|
65
|
+
plopp/widgets/drawing.py,sha256=Pcozffq7I5H9x57GNBJVvkCjVR6eaPBuxyHlFkEEjzQ,6252
|
|
66
|
+
plopp/widgets/linesave.py,sha256=s5QcY-31x7Hvf9iLHmzfFIzodXTD9BX0Av3NlG8GS88,2458
|
|
67
|
+
plopp/widgets/slice.py,sha256=hG1QzLsjmxjY4fjQwtlu8GxK6zzalrZsZxZzhwIaskg,5499
|
|
68
68
|
plopp/widgets/style.py,sha256=Fw4S8te0xDyT8-kWu4Ut35aLgyr98qMlWZRbXbd1-dk,184
|
|
69
69
|
plopp/widgets/toolbar.py,sha256=ueNeOZSC2suAG7nCJzqwl8DmtWD5c2J8VkuP-XzJRwI,4683
|
|
70
70
|
plopp/widgets/tools.py,sha256=9l7LmB8qG0OTt5ZJihJzqRna1ouxJthO_Ahnq7WKTtY,7172
|
|
71
|
-
plopp-25.
|
|
72
|
-
plopp-25.
|
|
73
|
-
plopp-25.
|
|
74
|
-
plopp-25.
|
|
75
|
-
plopp-25.
|
|
71
|
+
plopp-25.7.0.dist-info/licenses/LICENSE,sha256=fCqnkzCwkGneGtgOidkO2b3ed6SGZT0yhuworuJG0K0,1553
|
|
72
|
+
plopp-25.7.0.dist-info/METADATA,sha256=ORDD8s280azbvWqw84HVSpZ9uZ1HoGB8L13Uf7LTyVg,4545
|
|
73
|
+
plopp-25.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
74
|
+
plopp-25.7.0.dist-info/top_level.txt,sha256=Lk_GLFh37eX-3PO3c6bPkDpir7GjJmbQHYza3IpIphc,6
|
|
75
|
+
plopp-25.7.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|