plopp 25.3.0__py3-none-any.whl → 25.4.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.
@@ -1,13 +1,12 @@
1
1
  # SPDX-License-Identifier: BSD-3-Clause
2
2
  # Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
3
3
 
4
- from collections.abc import Callable
5
4
  from html import escape
6
5
 
7
6
  import ipywidgets as ipw
8
7
 
9
8
 
10
- class Checkboxes(ipw.HBox):
9
+ class Checkboxes(ipw.HBox, ipw.ValueWidget):
11
10
  """
12
11
  Widget providing a list of checkboxes, along with a button to toggle them all.
13
12
 
@@ -19,20 +18,30 @@ class Checkboxes(ipw.HBox):
19
18
  Global description for all the checkboxes.
20
19
  value:
21
20
  Default value to set all the checkboxes to.
21
+ toggle_all_button:
22
+ Whether to add a button to toggle all checkboxes at once.
22
23
  """
23
24
 
24
- def __init__(self, entries: list[str], description: str = "", value: bool = True):
25
+ def __init__(
26
+ self,
27
+ entries: list[str],
28
+ description: str = "",
29
+ value: bool = True,
30
+ toggle_all_button: bool = True,
31
+ ):
25
32
  self.checkboxes = {}
26
33
  self._lock = False
27
34
  self.description = ipw.Label(value=description)
28
35
 
29
36
  for key in entries:
30
- self.checkboxes[key] = ipw.Checkbox(
37
+ chbx = ipw.Checkbox(
31
38
  value=value,
32
39
  description=f"{escape(key)}",
33
40
  indent=False,
34
41
  layout={"width": "initial"},
35
42
  )
43
+ chbx.observe(self._on_subwidget_change, names="value")
44
+ self.checkboxes[key] = chbx
36
45
 
37
46
  to_hbox = [
38
47
  self.description,
@@ -41,28 +50,29 @@ class Checkboxes(ipw.HBox):
41
50
  ),
42
51
  ]
43
52
 
44
- if len(self.checkboxes) > 1:
45
- # Add a master button to control all masks in one go
53
+ if len(self.checkboxes) > 1 and toggle_all_button:
54
+ # Add a master button to control all checkboxes in one go
46
55
  self.toggle_all_button = ipw.ToggleButton(
47
- value=value,
48
- description="Toggle all",
49
- disabled=False,
50
- button_style="",
51
- layout={"width": "initial"},
56
+ value=value, description="Toggle all", layout={"width": "initial"}
52
57
  )
53
- for cbox in self.checkboxes.values():
54
- ipw.jsdlink((self.toggle_all_button, 'value'), (cbox, 'value'))
58
+ self.toggle_all_button.observe(self._toggle_all, names="value")
55
59
  to_hbox.insert(1, self.toggle_all_button)
56
60
 
61
+ self._on_subwidget_change()
57
62
  super().__init__(to_hbox)
58
63
 
59
- def _plopp_observe_(self, callback: Callable, **kwargs):
64
+ def _toggle_all(self, change: dict):
65
+ self._lock = True
60
66
  for chbx in self.checkboxes.values():
61
- chbx.observe(callback, **kwargs)
67
+ chbx.value = change["new"]
68
+ self._lock = False
69
+ self._on_subwidget_change()
62
70
 
63
- @property
64
- def value(self) -> dict[str, bool]:
71
+ def _on_subwidget_change(self, _=None):
65
72
  """
66
- Returns a dict containing one entry per checkbox, giving the checkbox's value.
73
+ The value is a dict containing one entry per checkbox, giving the
74
+ checkbox's value.
67
75
  """
68
- return {key: chbx.value for key, chbx in self.checkboxes.items()}
76
+ if self._lock:
77
+ return
78
+ self.value = {key: chbx.value for key, chbx in self.checkboxes.items()}
plopp/widgets/slice.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: BSD-3-Clause
2
2
  # Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
3
3
 
4
- from collections.abc import Callable
4
+ from functools import partial
5
5
  from typing import Any
6
6
 
7
7
  import ipywidgets as ipw
@@ -12,8 +12,8 @@ from ..core.utils import coord_element_to_string
12
12
  from .box import VBar
13
13
 
14
14
 
15
- class _BaseSliceWidget(VBar):
16
- def __init__(self, da: sc.DataArray, dims: list[str], range: bool):
15
+ class _BaseSliceWidget(VBar, ipw.ValueWidget):
16
+ def __init__(self, da: sc.DataArray, dims: list[str], slider_constr: ipw.Widget):
17
17
  if isinstance(dims, str):
18
18
  dims = [dims]
19
19
  self._slider_dims = dims
@@ -32,22 +32,22 @@ class _BaseSliceWidget(VBar):
32
32
  'description': dim,
33
33
  'min': 0,
34
34
  'max': da.sizes[dim] - 1,
35
+ 'value': (da.sizes[dim] - 1) // 2
36
+ if slider_constr is ipw.IntSlider
37
+ else None,
35
38
  'continuous_update': True,
36
39
  'readout': False,
37
40
  'layout': {"width": "200px"},
38
41
  'style': {'description_width': 'initial'},
39
42
  }
40
- if range:
41
- slider = ipw.IntRangeSlider(**widget_args)
42
- else:
43
- slider = ipw.IntSlider(**widget_args)
43
+ slider = slider_constr(**widget_args)
44
44
  continuous_update = ipw.Checkbox(
45
45
  value=True,
46
46
  tooltip="Continuous update",
47
47
  indent=False,
48
48
  layout={"width": "20px"},
49
49
  )
50
- label = ipw.Label(value=coord_element_to_string(coord[dim, 0]))
50
+ label = ipw.Label(value=coord_element_to_string(coord[dim, slider.value]))
51
51
  ipw.jslink((continuous_update, 'value'), (slider, 'continuous_update'))
52
52
 
53
53
  self.controls[dim] = {
@@ -57,8 +57,10 @@ class _BaseSliceWidget(VBar):
57
57
  'coord': coord,
58
58
  }
59
59
  slider.observe(self._update_label, names='value')
60
+ slider.observe(self._on_subwidget_change, names='value')
60
61
  children.append(ipw.HBox([continuous_update, slider, label]))
61
62
 
63
+ self._on_subwidget_change()
62
64
  super().__init__(children)
63
65
 
64
66
  def _update_label(self, change: dict[str, Any]):
@@ -70,61 +72,47 @@ class _BaseSliceWidget(VBar):
70
72
  coord = self.controls[dim]['coord'][dim, change['new']]
71
73
  self.controls[dim]['label'].value = coord_element_to_string(coord)
72
74
 
73
- def _plopp_observe_(self, callback: Callable, **kwargs):
75
+ def _on_subwidget_change(self, _=None):
74
76
  """
75
- Special method which is used instead of the ``observe`` method of ``ipywidgets``
76
- because overriding the ``observe`` method of the ``VBox`` causes issues.
77
+ Update the value of the widget.
78
+ The value is a dict containing one entry per slider, giving the slider's value.
77
79
  """
78
- for dim in self.controls:
79
- self.controls[dim]['slider'].observe(callback, **kwargs)
80
-
81
- @property
82
- def value(self) -> dict[str, int | tuple[int]]:
83
- """
84
- The widget value, as a dict containing the dims as keys and the slider indices
85
- as values.
86
- """
87
- return {dim: self.controls[dim]['slider'].value for dim in self._slider_dims}
88
-
89
-
90
- class SliceWidget(_BaseSliceWidget):
91
- """
92
- Widgets containing a slider for each of the requested dimensions.
93
- The widget uses the input data array to determine the range each slider should have.
94
- Each slider also comes with a checkbox to toggle on and off the slider's continuous
95
- update.
96
-
97
- Parameters
98
- ----------
99
- da:
100
- The input data array.
101
- dims:
102
- The dimensions to make sliders for.
103
- """
104
-
105
- def __init__(self, da: sc.DataArray, dims: list[str]):
106
- super().__init__(da, dims, range=False)
107
-
108
-
109
- class RangeSliceWidget(_BaseSliceWidget):
110
- """
111
- Widgets containing a slider for each of the requested dimensions.
112
- The widget uses the input data array to determine the range each slider should have.
113
- Each slider also comes with a checkbox to toggle on and off the slider's continuous
114
- update.
115
-
116
- .. versionadded:: 24.04.0
117
-
118
- Parameters
119
- ----------
120
- da:
121
- The input data array.
122
- dims:
123
- The dimensions to make sliders for.
124
- """
125
-
126
- def __init__(self, da: sc.DataArray, dims: list[str]):
127
- super().__init__(da, dims, range=True)
80
+ self.value = {
81
+ dim: self.controls[dim]['slider'].value for dim in self._slider_dims
82
+ }
83
+
84
+
85
+ SliceWidget = partial(_BaseSliceWidget, slider_constr=ipw.IntSlider)
86
+ """
87
+ Widgets containing a slider for each of the requested dimensions.
88
+ The widget uses the input data array to determine the range each slider should have.
89
+ Each slider also comes with a checkbox to toggle on and off the slider's continuous
90
+ update.
91
+
92
+ Parameters
93
+ ----------
94
+ da:
95
+ The input data array.
96
+ dims:
97
+ The dimensions to make sliders for.
98
+ """
99
+
100
+ RangeSliceWidget = partial(_BaseSliceWidget, slider_constr=ipw.IntRangeSlider)
101
+ """
102
+ Widgets containing a slider for each of the requested dimensions.
103
+ The widget uses the input data array to determine the range each slider should have.
104
+ Each slider also comes with a checkbox to toggle on and off the slider's continuous
105
+ update.
106
+
107
+ .. versionadded:: 24.04.0
108
+
109
+ Parameters
110
+ ----------
111
+ da:
112
+ The input data array.
113
+ dims:
114
+ The dimensions to make sliders for.
115
+ """
128
116
 
129
117
 
130
118
  @node
plopp/widgets/toolbar.py CHANGED
@@ -62,10 +62,12 @@ def make_toolbar_canvas2d(view: GraphicalView) -> Toolbar:
62
62
  def logx() -> None:
63
63
  view.canvas.logx()
64
64
  view.autoscale()
65
+ view.canvas.draw()
65
66
 
66
67
  def logy() -> None:
67
68
  view.canvas.logy()
68
69
  view.autoscale()
70
+ view.canvas.draw()
69
71
 
70
72
  def autoscale_axes() -> None:
71
73
  view.autoscale()
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: plopp
3
- Version: 25.3.0
3
+ Version: 25.4.1
4
4
  Summary: Visualization library for Scipp
5
5
  Author: Scipp contributors
6
6
  License: BSD 3-Clause License
@@ -78,6 +78,7 @@ Requires-Dist: scipp; extra == "test"
78
78
  Requires-Dist: scipy; extra == "test"
79
79
  Requires-Dist: xarray; extra == "test"
80
80
  Requires-Dist: anywidget; extra == "test"
81
+ Dynamic: license-file
81
82
 
82
83
  <img src="docs/_static/logo.svg" width="50%" />
83
84
 
@@ -2,53 +2,55 @@ plopp/__init__.py,sha256=gyb7FdEP0biNaLQEBZFJKTQSf2pAghTK051eN-yJLxM,1084
2
2
  plopp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  plopp/utils.py,sha256=YPcwwMN949UhUR2d-deHJ_-URI1PPRQmVxcNS-ZgyPY,700
4
4
  plopp/backends/__init__.py,sha256=hMvOWD3ua_34nUgcb_jITMnRvjRUUqHSUYuXxkxSIMM,1491
5
- plopp/backends/common.py,sha256=yAgWHsD2TiqPC-SKFrAN4THfhj53Qq5pCCDT3sMwjKo,3481
5
+ plopp/backends/common.py,sha256=xz4iMmgE4UtRzQJQlX4Sc9sbTCmjPrd7b4dnpCbWuQs,3422
6
6
  plopp/backends/matplotlib/__init__.py,sha256=QNPZgWV3wO8psaMkSB-GtTOP-OIe9jSfwDdEt2xgbZg,107
7
7
  plopp/backends/matplotlib/canvas.py,sha256=aAiDC2PfirZlffX671Xzs7GswtOfJjywf_nCh7irGOw,14702
8
+ plopp/backends/matplotlib/fast_image.py,sha256=1tF4G8kTmgmiybdD-KPIatU2dWwv0dgv4r8IMDQTTGE,6532
8
9
  plopp/backends/matplotlib/figure.py,sha256=Emj8KCIFvesEfAoKIWn4M4TcgZhq6zFTfRTFnLZHGxE,5515
9
- plopp/backends/matplotlib/image.py,sha256=hPh44hid0qRcIn9A9Ibrtiebt5wMyvJOh1i7A-nJmfk,8312
10
- plopp/backends/matplotlib/line.py,sha256=MMYiY_6V_FSwDfPfczy9zcZkpLkFDAHJFpJmFFwXx0Q,7542
11
- plopp/backends/matplotlib/scatter.py,sha256=YWr9ku7t6YibVVzxBHLcpYxGzpugvj_5uoTB3LUc-ho,6117
10
+ plopp/backends/matplotlib/image.py,sha256=YnczwdxsGmh0Nvrk1A8xL93ap2rzKI-0G428OCQmSCc,974
11
+ plopp/backends/matplotlib/line.py,sha256=xWZx_3j7_O1IoNjVOu-KM4Ue9haQ5IqHjRsY-VhyKak,8779
12
+ plopp/backends/matplotlib/mesh_image.py,sha256=4ndrauA71asWJdA6ZDkh6iPnQPk07kNd3m1h0_bTM6U,8542
13
+ plopp/backends/matplotlib/scatter.py,sha256=NuYi9G4csQTklUjB7WXSjothrH77C0NY0KHiMPHBqcw,6739
12
14
  plopp/backends/matplotlib/tiled.py,sha256=BfFHNQ-or19X44N-XaaUf9A3trdSSaCfC2CIAR1WTPg,6127
13
15
  plopp/backends/matplotlib/utils.py,sha256=24gmT2sBHS_wUitUThSLavwSK95uqbLAhadNdxC19I0,3479
14
16
  plopp/backends/plotly/__init__.py,sha256=QNPZgWV3wO8psaMkSB-GtTOP-OIe9jSfwDdEt2xgbZg,107
15
17
  plopp/backends/plotly/canvas.py,sha256=JQXl8c23Ju-DTame2rZ4T_lgrArgH1WElUGJIaGyEbU,8943
16
18
  plopp/backends/plotly/figure.py,sha256=60QsXUFjr3CqXjxVpAbvd1c-wtq7T5fptotwybgUEcI,1356
17
- plopp/backends/plotly/line.py,sha256=3FSRP6EwWv3GUl4FpXfxWMdo5PSLHsPfA0IV1DjWwfk,8279
19
+ plopp/backends/plotly/line.py,sha256=yVpJW-xWa0Wy_oMdmvDn2ESIJymT9Fg6wN7RhIRK6Dw,9533
18
20
  plopp/backends/pythreejs/__init__.py,sha256=XvSD58Tj5WBrrOjkePcCrRW6RbbyrvhhWI_S8-AR92U,107
19
21
  plopp/backends/pythreejs/canvas.py,sha256=yn6iz4BcaNpJZa-lUlyQ5BnYTThb3zYTUv7zWohhaMo,11942
20
22
  plopp/backends/pythreejs/figure.py,sha256=n9R1YokZMRPGA2XP9qeMIGGe-wcTt91vAiexVf7YRnc,2022
21
- plopp/backends/pythreejs/mesh3d.py,sha256=Oij0OeKXdte_bADgGlAtlRxu3LnLi8ctDAskaimYhjg,6650
23
+ plopp/backends/pythreejs/mesh3d.py,sha256=UdaHJ7ssqMaa_U1bDtYWfkz0tvahdIpWKNY0K1AEOEI,6979
22
24
  plopp/backends/pythreejs/outline.py,sha256=WUqtUj8GMAUzUqOocFjdT8F7WBeV9jgMSYmXD157igI,4913
23
- plopp/backends/pythreejs/scatter3d.py,sha256=FGGO9Ih0k1g5VtrWW-OSNVHd3ca0BdpuxGoJxV_Wk4c,6849
25
+ plopp/backends/pythreejs/scatter3d.py,sha256=Z8D0l3hBJ2qlC4BIAAoHCAa97uf6IViFNt23f9wzFFI,7049
24
26
  plopp/core/__init__.py,sha256=s25RIbKplHSRn0jjtLADPQl72JLf_KLRMRCfeMDI_UA,205
25
27
  plopp/core/__init__.pyi,sha256=FU5U5nymhzbgBRolZSh1tqYDJ3M2djUv71mriWHD1hI,294
26
28
  plopp/core/graph.py,sha256=beHDxqF4C-6wd18TkYue3KqYutEYJ2EwoEBbWIqWQNs,3841
27
- plopp/core/helpers.py,sha256=sHJ2tDsTeHGheAvXiX-uWojcVP6SxvcqGmPElWRq1I4,1512
28
- plopp/core/limits.py,sha256=DcOCWK-5lBynHMZcH7eCx-M_GAxMpM5ODxBvHdCabb4,3329
29
+ plopp/core/helpers.py,sha256=Dua9KWOk2cCpDyWPUrak6kymUx7QvjRI2LNJRoGDMcY,1193
30
+ plopp/core/limits.py,sha256=ojb3MTxlWNz2ibHXu9P-agzYV8HxPCGSB2D0oxoO9RQ,3572
29
31
  plopp/core/node_class.py,sha256=5SnVELRZSzcTD1ku8hDkWygCWsDMpedvcyYGZV-CHlw,7462
30
32
  plopp/core/typing.py,sha256=JL_mMdFq2dNu6LuZYSBfOXGZSEn0VIJK_lr-LbC11t4,2903
31
33
  plopp/core/utils.py,sha256=qxdOLRODgv3b0dDywT0JomsVrgifS_siC-ZpzJqgblo,7120
32
34
  plopp/core/view.py,sha256=9WulgLHg8aPjePz967WLWieTM40dvqlgJitu-AS3WdM,1972
33
35
  plopp/data/__init__.py,sha256=sOTLyBuiH-dxmpiVsZxd7L7YTkFMfAQUvah1g04AiQk,581
34
36
  plopp/data/examples.py,sha256=ysXNnZRywZUU9xDrACaFNK-8UCY_v70ZB169XXvToF4,3726
35
- plopp/data/factory.py,sha256=Q4zvWuPam9j4Uzu-kPnSnuhUbkL5q7SVjhpSCXxVDVs,6803
37
+ plopp/data/factory.py,sha256=A9plNosKSdKFfQdeY538EHcjK7IU4yqsSoj9p1-5Q-k,7026
36
38
  plopp/data/testing.py,sha256=g1PT5o7omwucdtRp37ep1fjr__kVBjpMkP4fz5xC2So,430
37
39
  plopp/graphics/__init__.py,sha256=s25RIbKplHSRn0jjtLADPQl72JLf_KLRMRCfeMDI_UA,205
38
40
  plopp/graphics/__init__.pyi,sha256=yZQkWxUfP9eKHSP47WjrBiu59Z-uhP5gE2eUrPDa6jU,630
39
41
  plopp/graphics/basefig.py,sha256=N5gBQE8w2968biRV7a3wkxxq-BM14ncfX52y5HziWiQ,824
40
42
  plopp/graphics/bbox.py,sha256=3WeMgu5LgWIXLJTYVT7_USwaAcS7cQPNCk6B0gvuNGo,3596
41
43
  plopp/graphics/camera.py,sha256=fXc1YH7Tp-rwKkcYeE-mHrxMz3SKauj5xJCRuKv-QPs,5323
42
- plopp/graphics/colormapper.py,sha256=4ZF6933BrYEr4YasRcAhzPt9TNepmWPBbS4bMKLQKsU,9611
44
+ plopp/graphics/colormapper.py,sha256=u5cADKU9lrRkJ_a969i_5z-mdT0-lBnEonc0PW_xSXA,9643
43
45
  plopp/graphics/figures.py,sha256=PLWQLnQNWz8epubYlK7HLSkvPGJmTAmHjJM2DqpvLe8,2735
44
46
  plopp/graphics/graphicalview.py,sha256=uX6KLMy5r0yqbFVSE3y0T7kW7oAg8CVuioIBOtTNVTc,9183
45
47
  plopp/graphics/tiled.py,sha256=gXYZVAs6wRFKezzN3VlEvm7_z2zx3IDYfGZQZqrpL80,1386
46
48
  plopp/plotting/__init__.py,sha256=s25RIbKplHSRn0jjtLADPQl72JLf_KLRMRCfeMDI_UA,205
47
49
  plopp/plotting/__init__.pyi,sha256=95wYGfM5PT0Y0Ov_ue7rBrHvHxrtex-2WEYtfFzBvE0,475
48
- plopp/plotting/common.py,sha256=htVveCgq8iUa7CTwoYrCbEB-GvgH4AQ_95fasix9Qis,8184
50
+ plopp/plotting/common.py,sha256=ZEFJ8dZC0aQ_Ucrvu7JXiwaKZ6YT7qfdg8pMZVpX62Y,8696
49
51
  plopp/plotting/inspector.py,sha256=fT4v342pqTzihKaweoGD4WaQ5eDdyngK7W451Mh2Ffw,3586
50
52
  plopp/plotting/mesh3d.py,sha256=KjAtlVlLYslwgP_uE067WtJRgNURkhaz0PPUuYLlJyw,2778
51
- plopp/plotting/plot.py,sha256=S3Af6PQb7Eu0_t7qoKMMkS6hyt6iah-Hm1RWGi5PnEA,3934
53
+ plopp/plotting/plot.py,sha256=WQzw1vHGljWY1tQU1InQWe2-M-vCW2IRiL-v7cnw46w,3886
52
54
  plopp/plotting/scatter.py,sha256=ybPWFHFwxt_Bzv3Dy-yAFCRHW5HQEggcNihpzWduH7A,3161
53
55
  plopp/plotting/scatter3d.py,sha256=oizd-BCgmvNu_fSV6FQt9oe7lPn4h2Zc1ohKmor-d78,3819
54
56
  plopp/plotting/slicer.py,sha256=A3g26czD6GM3vBlVS-IBOnCOlpaERqUhjT-_POYJEHQ,5877
@@ -57,17 +59,17 @@ plopp/plotting/xyplot.py,sha256=t_0GC2TlC6QZPKN4tfgLRUUBDhJ5zoNJjsRyYxLX_xI,1448
57
59
  plopp/widgets/__init__.py,sha256=s25RIbKplHSRn0jjtLADPQl72JLf_KLRMRCfeMDI_UA,205
58
60
  plopp/widgets/__init__.pyi,sha256=4hVX7I3VEjE3oy2AGVvguYsIgg7cVrhKGpX7xVgGe9Y,844
59
61
  plopp/widgets/box.py,sha256=v5Gd3sY0WXcc3UfkcXxZboPG02sfOMXIo50tmpxPwVs,1806
60
- plopp/widgets/checkboxes.py,sha256=KeeskJP73NAs-38XI0g3KPkzxB3FPOcmetLoZGc2ge4,2166
62
+ plopp/widgets/checkboxes.py,sha256=52yJryEu1upYafFxqoTOdAZmHeKzCI_CJiCWSezCtRA,2430
61
63
  plopp/widgets/clip3d.py,sha256=L90HUd3bjEU3BaPdK8DnUbeeFNqfFyBWDEwaG9nP-M8,14602
62
64
  plopp/widgets/debounce.py,sha256=V5aIcnb465oqXZX-UG_DR7GjvoG6D_C2jjEUBmguGDA,1292
63
65
  plopp/widgets/drawing.py,sha256=3aWEYUXsNNBJFey-7cPXbQ4bLQpDbIJe-kSNB2yonbE,6238
64
66
  plopp/widgets/linesave.py,sha256=FAM1toc71fg3SfRrU-r_KXjHKBOJU4qKXs5bebReNiU,2451
65
- plopp/widgets/slice.py,sha256=cd-DOs03xdNolajOaDdpjyo6Kcyti5yDGWea0z5qhB8,4626
67
+ plopp/widgets/slice.py,sha256=ihiGEGGva_2WZIug-kizg1I5SFdMzu4_8DDzuHWIKeA,4212
66
68
  plopp/widgets/style.py,sha256=Fw4S8te0xDyT8-kWu4Ut35aLgyr98qMlWZRbXbd1-dk,184
67
- plopp/widgets/toolbar.py,sha256=5hZA32UZLtU8gQzK_7ol_E0go2iHVc2psqIJ4aMSnWc,4629
69
+ plopp/widgets/toolbar.py,sha256=ueNeOZSC2suAG7nCJzqwl8DmtWD5c2J8VkuP-XzJRwI,4683
68
70
  plopp/widgets/tools.py,sha256=9l7LmB8qG0OTt5ZJihJzqRna1ouxJthO_Ahnq7WKTtY,7172
69
- plopp-25.3.0.dist-info/LICENSE,sha256=fCqnkzCwkGneGtgOidkO2b3ed6SGZT0yhuworuJG0K0,1553
70
- plopp-25.3.0.dist-info/METADATA,sha256=vyaGzlYfOEBTBbKwdRZGO9JZLTqaBLPpx-Lef6wrIYA,4511
71
- plopp-25.3.0.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
72
- plopp-25.3.0.dist-info/top_level.txt,sha256=Lk_GLFh37eX-3PO3c6bPkDpir7GjJmbQHYza3IpIphc,6
73
- plopp-25.3.0.dist-info/RECORD,,
71
+ plopp-25.4.1.dist-info/licenses/LICENSE,sha256=fCqnkzCwkGneGtgOidkO2b3ed6SGZT0yhuworuJG0K0,1553
72
+ plopp-25.4.1.dist-info/METADATA,sha256=ldO8vURvNcAl2TRMrj6JGatMte8GybEgq-d0lf7vwDo,4533
73
+ plopp-25.4.1.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
74
+ plopp-25.4.1.dist-info/top_level.txt,sha256=Lk_GLFh37eX-3PO3c6bPkDpir7GjJmbQHYza3IpIphc,6
75
+ plopp-25.4.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.0.0)
2
+ Generator: setuptools (79.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5