bec-widgets 1.13.0__py3-none-any.whl → 1.14.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.
CHANGELOG.md CHANGED
@@ -1,6 +1,30 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v1.14.1 (2025-01-10)
5
+
6
+ ### Bug Fixes
7
+
8
+ - Cast spinner widget angle to int when using for arc
9
+ ([`fa9ecaf`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fa9ecaf43347f6a07f86075d7ea54463684344f1))
10
+
11
+
12
+ ## v1.14.0 (2025-01-09)
13
+
14
+ ### Documentation
15
+
16
+ - Add docs for games/minesweeper
17
+ ([`e2c7dc9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e2c7dc98d2f1c627fcc1aac045fa32dc94057bb0))
18
+
19
+ ### Features
20
+
21
+ - **widget**: Make Minesweeper into BEC widget
22
+ ([`507d46f`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/507d46f88bd06a3e77b1e60a6ce56c80f622cb6c))
23
+
24
+ - **widgets**: Added minesweeper widget
25
+ ([`57dc1a3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/57dc1a3afc60b6c27b42c258a6fd1ea1ddb24637))
26
+
27
+
4
28
  ## v1.13.0 (2025-01-09)
5
29
 
6
30
  ### Bug Fixes
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bec_widgets
3
- Version: 1.13.0
3
+ Version: 1.14.1
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
bec_widgets/cli/client.py CHANGED
@@ -31,6 +31,7 @@ class Widgets(str, enum.Enum):
31
31
  DeviceComboBox = "DeviceComboBox"
32
32
  DeviceLineEdit = "DeviceLineEdit"
33
33
  LMFitDialog = "LMFitDialog"
34
+ Minesweeper = "Minesweeper"
34
35
  PositionIndicator = "PositionIndicator"
35
36
  PositionerBox = "PositionerBox"
36
37
  PositionerControlLine = "PositionerControlLine"
@@ -3181,6 +3182,9 @@ class LMFitDialog(RPCBase):
3181
3182
  """
3182
3183
 
3183
3184
 
3185
+ class Minesweeper(RPCBase): ...
3186
+
3187
+
3184
3188
  class PositionIndicator(RPCBase):
3185
3189
  @rpc_call
3186
3190
  def set_value(self, position: float):
@@ -0,0 +1,3 @@
1
+ from bec_widgets.widgets.games.minesweeper import Minesweeper
2
+
3
+ __ALL__ = ["Minesweeper"]
@@ -0,0 +1,413 @@
1
+ import enum
2
+ import random
3
+ import time
4
+
5
+ from bec_qthemes import material_icon
6
+ from qtpy.QtCore import QSize, Qt, QTimer, Signal, Slot
7
+ from qtpy.QtGui import QBrush, QColor, QPainter, QPen
8
+ from qtpy.QtWidgets import (
9
+ QApplication,
10
+ QComboBox,
11
+ QGridLayout,
12
+ QHBoxLayout,
13
+ QLabel,
14
+ QPushButton,
15
+ QVBoxLayout,
16
+ QWidget,
17
+ )
18
+
19
+ from bec_widgets.utils.bec_widget import BECWidget
20
+
21
+ NUM_COLORS = {
22
+ 1: QColor("#f44336"),
23
+ 2: QColor("#9C27B0"),
24
+ 3: QColor("#3F51B5"),
25
+ 4: QColor("#03A9F4"),
26
+ 5: QColor("#00BCD4"),
27
+ 6: QColor("#4CAF50"),
28
+ 7: QColor("#E91E63"),
29
+ 8: QColor("#FF9800"),
30
+ }
31
+
32
+ LEVELS: dict[str, tuple[int, int]] = {"1": (8, 10), "2": (16, 40), "3": (24, 99)}
33
+
34
+
35
+ class GameStatus(enum.Enum):
36
+ READY = 0
37
+ PLAYING = 1
38
+ FAILED = 2
39
+ SUCCESS = 3
40
+
41
+
42
+ class Pos(QWidget):
43
+ expandable = Signal(int, int)
44
+ clicked = Signal()
45
+ ohno = Signal()
46
+
47
+ def __init__(self, x, y, *args, **kwargs):
48
+ super().__init__(*args, **kwargs)
49
+
50
+ self.setFixedSize(QSize(20, 20))
51
+
52
+ self.x = x
53
+ self.y = y
54
+ self.is_start = False
55
+ self.is_mine = False
56
+ self.adjacent_n = 0
57
+ self.is_revealed = False
58
+ self.is_flagged = False
59
+
60
+ def reset(self):
61
+ """Restore the tile to its original state before mine status is assigned"""
62
+ self.is_start = False
63
+ self.is_mine = False
64
+ self.adjacent_n = 0
65
+
66
+ self.is_revealed = False
67
+ self.is_flagged = False
68
+
69
+ self.update()
70
+
71
+ def paintEvent(self, event):
72
+ p = QPainter(self)
73
+
74
+ r = event.rect()
75
+
76
+ if self.is_revealed:
77
+ color = self.palette().base().color()
78
+ outer, inner = color, color
79
+ else:
80
+ outer, inner = (self.palette().highlightedText().color(), self.palette().text().color())
81
+
82
+ p.fillRect(r, QBrush(inner))
83
+ pen = QPen(outer)
84
+ pen.setWidth(1)
85
+ p.setPen(pen)
86
+ p.drawRect(r)
87
+
88
+ if self.is_revealed:
89
+ if self.is_mine:
90
+ p.drawPixmap(r, material_icon("experiment", convert_to_pixmap=True, filled=True))
91
+
92
+ elif self.adjacent_n > 0:
93
+ pen = QPen(NUM_COLORS[self.adjacent_n])
94
+ p.setPen(pen)
95
+ f = p.font()
96
+ f.setBold(True)
97
+ p.setFont(f)
98
+ p.drawText(r, Qt.AlignHCenter | Qt.AlignVCenter, str(self.adjacent_n))
99
+
100
+ elif self.is_flagged:
101
+ p.drawPixmap(
102
+ r,
103
+ material_icon(
104
+ "flag",
105
+ size=(50, 50),
106
+ convert_to_pixmap=True,
107
+ filled=True,
108
+ color=self.palette().base().color(),
109
+ ),
110
+ )
111
+ p.end()
112
+
113
+ def flag(self):
114
+ self.is_flagged = not self.is_flagged
115
+ self.update()
116
+
117
+ self.clicked.emit()
118
+
119
+ def reveal(self):
120
+ self.is_revealed = True
121
+ self.update()
122
+
123
+ def click(self):
124
+ if not self.is_revealed:
125
+ self.reveal()
126
+ if self.adjacent_n == 0:
127
+ self.expandable.emit(self.x, self.y)
128
+
129
+ self.clicked.emit()
130
+
131
+ def mouseReleaseEvent(self, event):
132
+ if event.button() == Qt.MouseButton.RightButton and not self.is_revealed:
133
+ self.flag()
134
+ return
135
+
136
+ if event.button() == Qt.MouseButton.LeftButton:
137
+ self.click()
138
+ if self.is_mine:
139
+ self.ohno.emit()
140
+
141
+
142
+ class Minesweeper(BECWidget, QWidget):
143
+
144
+ PLUGIN = True
145
+ ICON_NAME = "videogame_asset"
146
+ USER_ACCESS = []
147
+
148
+ def __init__(self, parent=None, *args, **kwargs):
149
+ super().__init__(*args, **kwargs)
150
+ QWidget.__init__(self, parent=parent)
151
+
152
+ self._ui_initialised = False
153
+ self._timer_start_num_seconds = 0
154
+ self._set_level_params(LEVELS["1"])
155
+
156
+ self._init_ui()
157
+ self._init_map()
158
+
159
+ self.update_status(GameStatus.READY)
160
+ self.reset_map()
161
+ self.update_status(GameStatus.READY)
162
+
163
+ def _init_ui(self):
164
+ if self._ui_initialised:
165
+ return
166
+ self._ui_initialised = True
167
+
168
+ status_hb = QHBoxLayout()
169
+ self.mines = QLabel()
170
+ self.mines.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
171
+ f = self.mines.font()
172
+ f.setPointSize(24)
173
+ self.mines.setFont(f)
174
+
175
+ self.reset_button = QPushButton()
176
+ self.reset_button.setFixedSize(QSize(32, 32))
177
+ self.reset_button.setIconSize(QSize(32, 32))
178
+ self.reset_button.setFlat(True)
179
+ self.reset_button.pressed.connect(self.reset_button_pressed)
180
+
181
+ self.clock = QLabel()
182
+ self.clock.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
183
+ self.clock.setFont(f)
184
+ self._timer = QTimer()
185
+ self._timer.timeout.connect(self.update_timer)
186
+ self._timer.start(1000) # 1 second timer
187
+ self.mines.setText(f"{self.num_mines:03d}")
188
+ self.clock.setText("000")
189
+
190
+ status_hb.addWidget(self.mines)
191
+ status_hb.addWidget(self.reset_button)
192
+ status_hb.addWidget(self.clock)
193
+
194
+ level_hb = QHBoxLayout()
195
+ self.level_selector = QComboBox()
196
+ self.level_selector.addItems(list(LEVELS.keys()))
197
+ level_hb.addWidget(QLabel("Level: "))
198
+ level_hb.addWidget(self.level_selector)
199
+ self.level_selector.currentTextChanged.connect(self.change_level)
200
+
201
+ vb = QVBoxLayout()
202
+ vb.addLayout(level_hb)
203
+ vb.addLayout(status_hb)
204
+
205
+ self.grid = QGridLayout()
206
+ self.grid.setSpacing(5)
207
+
208
+ vb.addLayout(self.grid)
209
+ self.setLayout(vb)
210
+
211
+ def _init_map(self):
212
+ """Redraw the grid of mines"""
213
+
214
+ # Remove any previous grid items and reset the grid
215
+ for i in reversed(range(self.grid.count())):
216
+ w: Pos = self.grid.itemAt(i).widget()
217
+ w.clicked.disconnect(self.on_click)
218
+ w.expandable.disconnect(self.expand_reveal)
219
+ w.ohno.disconnect(self.game_over)
220
+ w.setParent(None)
221
+ w.deleteLater()
222
+
223
+ # Add positions to the map
224
+ for x in range(0, self.b_size):
225
+ for y in range(0, self.b_size):
226
+ w = Pos(x, y)
227
+ self.grid.addWidget(w, y, x)
228
+ # Connect signal to handle expansion.
229
+ w.clicked.connect(self.on_click)
230
+ w.expandable.connect(self.expand_reveal)
231
+ w.ohno.connect(self.game_over)
232
+
233
+ def reset_map(self):
234
+ """
235
+ Reset the map and add new mines.
236
+ """
237
+ # Clear all mine positions
238
+ for x in range(0, self.b_size):
239
+ for y in range(0, self.b_size):
240
+ w = self.grid.itemAtPosition(y, x).widget()
241
+ w.reset()
242
+
243
+ # Add mines to the positions
244
+ positions = []
245
+ while len(positions) < self.num_mines:
246
+ x, y = (random.randint(0, self.b_size - 1), random.randint(0, self.b_size - 1))
247
+ if (x, y) not in positions:
248
+ w = self.grid.itemAtPosition(y, x).widget()
249
+ w.is_mine = True
250
+ positions.append((x, y))
251
+
252
+ def get_adjacency_n(x, y):
253
+ positions = self.get_surrounding(x, y)
254
+ num_mines = sum(1 if w.is_mine else 0 for w in positions)
255
+
256
+ return num_mines
257
+
258
+ # Add adjacencies to the positions
259
+ for x in range(0, self.b_size):
260
+ for y in range(0, self.b_size):
261
+ w = self.grid.itemAtPosition(y, x).widget()
262
+ w.adjacent_n = get_adjacency_n(x, y)
263
+
264
+ # Place starting marker
265
+ while True:
266
+ x, y = (random.randint(0, self.b_size - 1), random.randint(0, self.b_size - 1))
267
+ w = self.grid.itemAtPosition(y, x).widget()
268
+ # We don't want to start on a mine.
269
+ if (x, y) not in positions:
270
+ w = self.grid.itemAtPosition(y, x).widget()
271
+ w.is_start = True
272
+
273
+ # Reveal all positions around this, if they are not mines either.
274
+ for w in self.get_surrounding(x, y):
275
+ if not w.is_mine:
276
+ w.click()
277
+ break
278
+
279
+ def get_surrounding(self, x, y):
280
+ positions = []
281
+ for xi in range(max(0, x - 1), min(x + 2, self.b_size)):
282
+ for yi in range(max(0, y - 1), min(y + 2, self.b_size)):
283
+ positions.append(self.grid.itemAtPosition(yi, xi).widget())
284
+ return positions
285
+
286
+ def get_num_hidden(self) -> int:
287
+ """
288
+ Get the number of hidden positions.
289
+ """
290
+ return sum(
291
+ 1
292
+ for x in range(0, self.b_size)
293
+ for y in range(0, self.b_size)
294
+ if not self.grid.itemAtPosition(y, x).widget().is_revealed
295
+ )
296
+
297
+ def get_num_remaining_flags(self) -> int:
298
+ """
299
+ Get the number of remaining flags.
300
+ """
301
+ return self.num_mines - sum(
302
+ 1
303
+ for x in range(0, self.b_size)
304
+ for y in range(0, self.b_size)
305
+ if self.grid.itemAtPosition(y, x).widget().is_flagged
306
+ )
307
+
308
+ def reset_button_pressed(self):
309
+ match self.status:
310
+ case GameStatus.PLAYING:
311
+ self.game_over()
312
+ case GameStatus.FAILED | GameStatus.SUCCESS:
313
+ self.reset_map()
314
+
315
+ def reveal_map(self):
316
+ for x in range(0, self.b_size):
317
+ for y in range(0, self.b_size):
318
+ w = self.grid.itemAtPosition(y, x).widget()
319
+ w.reveal()
320
+
321
+ @Slot(str)
322
+ def change_level(self, level: str):
323
+ self._set_level_params(LEVELS[level])
324
+ self._init_map()
325
+ self.reset_map()
326
+
327
+ @Slot(int, int)
328
+ def expand_reveal(self, x, y):
329
+ """
330
+ Expand the reveal to the surrounding
331
+
332
+ Args:
333
+ x (int): The x position.
334
+ y (int): The y position.
335
+ """
336
+ for xi in range(max(0, x - 1), min(x + 2, self.b_size)):
337
+ for yi in range(max(0, y - 1), min(y + 2, self.b_size)):
338
+ w = self.grid.itemAtPosition(yi, xi).widget()
339
+ if not w.is_mine:
340
+ w.click()
341
+
342
+ @Slot()
343
+ def on_click(self):
344
+ """
345
+ Handle the click event. If the game is not started, start the game.
346
+ """
347
+ self.update_available_flags()
348
+ if self.status != GameStatus.PLAYING:
349
+ # First click.
350
+ self.update_status(GameStatus.PLAYING)
351
+ # Start timer.
352
+ self._timer_start_num_seconds = int(time.time())
353
+ return
354
+ self.check_win()
355
+
356
+ def update_available_flags(self):
357
+ """
358
+ Update the number of available flags.
359
+ """
360
+ self.mines.setText(f"{self.get_num_remaining_flags():03d}")
361
+
362
+ def check_win(self):
363
+ """
364
+ Check if the game is won.
365
+ """
366
+ if self.get_num_hidden() == self.num_mines:
367
+ self.update_status(GameStatus.SUCCESS)
368
+
369
+ def update_status(self, status: GameStatus):
370
+ """
371
+ Update the status of the game.
372
+
373
+ Args:
374
+ status (GameStatus): The status of the game.
375
+ """
376
+ self.status = status
377
+ match status:
378
+ case GameStatus.READY:
379
+ icon = material_icon(icon_name="add", convert_to_pixmap=False)
380
+ case GameStatus.PLAYING:
381
+ icon = material_icon(icon_name="smart_toy", convert_to_pixmap=False)
382
+ case GameStatus.FAILED:
383
+ icon = material_icon(icon_name="error", convert_to_pixmap=False)
384
+ case GameStatus.SUCCESS:
385
+ icon = material_icon(icon_name="celebration", convert_to_pixmap=False)
386
+ self.reset_button.setIcon(icon)
387
+
388
+ def update_timer(self):
389
+ """
390
+ Update the timer.
391
+ """
392
+ if self.status == GameStatus.PLAYING:
393
+ num_seconds = int(time.time()) - self._timer_start_num_seconds
394
+ self.clock.setText(f"{num_seconds:03d}")
395
+
396
+ def game_over(self):
397
+ """Cause the game to end early"""
398
+ self.reveal_map()
399
+ self.update_status(GameStatus.FAILED)
400
+
401
+ def _set_level_params(self, level: tuple[int, int]):
402
+ self.b_size, self.num_mines = level
403
+
404
+
405
+ if __name__ == "__main__":
406
+ from bec_widgets.utils.colors import set_theme
407
+
408
+ app = QApplication([])
409
+ set_theme("light")
410
+ widget = Minesweeper()
411
+ widget.show()
412
+
413
+ app.exec_()
@@ -0,0 +1 @@
1
+ {'files': ['minesweeper.py']}
@@ -0,0 +1,54 @@
1
+ # Copyright (C) 2022 The Qt Company Ltd.
2
+ # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3
+
4
+ from qtpy.QtDesigner import QDesignerCustomWidgetInterface
5
+
6
+ from bec_widgets.utils.bec_designer import designer_material_icon
7
+ from bec_widgets.widgets.games.minesweeper import Minesweeper
8
+
9
+ DOM_XML = """
10
+ <ui language='c++'>
11
+ <widget class='Minesweeper' name='minesweeper'>
12
+ </widget>
13
+ </ui>
14
+ """
15
+
16
+
17
+ class MinesweeperPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
18
+ def __init__(self):
19
+ super().__init__()
20
+ self._form_editor = None
21
+
22
+ def createWidget(self, parent):
23
+ t = Minesweeper(parent)
24
+ return t
25
+
26
+ def domXml(self):
27
+ return DOM_XML
28
+
29
+ def group(self):
30
+ return "BEC Games"
31
+
32
+ def icon(self):
33
+ return designer_material_icon(Minesweeper.ICON_NAME)
34
+
35
+ def includeFile(self):
36
+ return "minesweeper"
37
+
38
+ def initialize(self, form_editor):
39
+ self._form_editor = form_editor
40
+
41
+ def isContainer(self):
42
+ return False
43
+
44
+ def isInitialized(self):
45
+ return self._form_editor is not None
46
+
47
+ def name(self):
48
+ return "Minesweeper"
49
+
50
+ def toolTip(self):
51
+ return "Minesweeper"
52
+
53
+ def whatsThis(self):
54
+ return self.toolTip()
@@ -0,0 +1,15 @@
1
+ def main(): # pragma: no cover
2
+ from qtpy import PYSIDE6
3
+
4
+ if not PYSIDE6:
5
+ print("PYSIDE6 is not available in the environment. Cannot patch designer.")
6
+ return
7
+ from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
8
+
9
+ from bec_widgets.widgets.games.minesweeper_plugin import MinesweeperPlugin
10
+
11
+ QPyDesignerCustomWidgetCollection.addCustomWidget(MinesweeperPlugin())
12
+
13
+
14
+ if __name__ == "__main__": # pragma: no cover
15
+ main()
@@ -75,7 +75,7 @@ class SpinnerWidget(QWidget):
75
75
  proportion = 1 / 4
76
76
  angle_span = int(proportion * 360 * 16)
77
77
  angle_span += angle_span * ease_in_out_sine(self.time / self.duration)
78
- painter.drawArc(adjusted_rect, self.angle * 16, int(angle_span))
78
+ painter.drawArc(adjusted_rect, int(self.angle * 16), int(angle_span))
79
79
  painter.end()
80
80
 
81
81
  def closeEvent(self, event):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bec_widgets
3
- Version: 1.13.0
3
+ Version: 1.14.1
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=CLlFGYRGKp4FxCPTkyF9p-7qx67KmbM9Yok9JQEU_Ls,8677
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=b62pnNgeQvzhGnSiNMjZoGQWAAO_bNQmWcZFLotYG4M,220277
5
+ CHANGELOG.md,sha256=FFvwVqBUD_q2IiMmx4HdvyGB5NKM2DG0Tkcfcy_9reE,220975
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=hTH9uddiO3VSWkLCtNU5JlJuoCl-ihuNT-n54_8jKtk,1339
7
+ PKG-INFO,sha256=NtdzzO4MGjNTXBbNulluYh__nOLWcQX820P88EixW30,1339
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=GHl8yujnK76K4FPByP17M0FJi-2engw6lRkP5l2rKwA,2596
9
+ pyproject.toml,sha256=a_6QuEHoaPGQEUAHvY24XelSuVDR_Df6wf0IAftbEvg,2596
10
10
  .git_hooks/pre-commit,sha256=n3RofIZHJl8zfJJIUomcMyYGFi_rwq4CC19z0snz3FI,286
11
11
  .gitlab/issue_templates/bug_report_template.md,sha256=gAuyEwl7XlnebBrkiJ9AqffSNOywmr8vygUFWKTuQeI,386
12
12
  .gitlab/issue_templates/documentation_update_template.md,sha256=FHLdb3TS_D9aL4CYZCjyXSulbaW5mrN2CmwTaeLPbNw,860
@@ -24,7 +24,7 @@ bec_widgets/assets/app_icons/alignment_1d.png,sha256=5VouaWieb4lVv3wUBNHaO5ovUW2
24
24
  bec_widgets/assets/app_icons/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqgdX7a00nM3igZdc20pkYM,1747017
25
25
  bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
26
26
  bec_widgets/cli/auto_updates.py,sha256=Pj8OHlSlKN3JOAmuuBC5oUMzdfC8TYRY7QKT5BQ2cZo,5171
27
- bec_widgets/cli/client.py,sha256=Mwt3Lw3iy_uW-MXUKSJ3ci8St-4gOp-qL4OmjLeRbWk,98767
27
+ bec_widgets/cli/client.py,sha256=8JLY18GiUYMlIw4I4WXnNWiGmJ40P5TylrbyUAIv3ik,98833
28
28
  bec_widgets/cli/client_utils.py,sha256=DXHHw1LNkKVCApbWmOAdZqU_qdvvqx28QiWV-Uf-jos,12207
29
29
  bec_widgets/cli/generate_cli.py,sha256=2BFNgxM_0XLy2OXxG_SX0rgPHFc27oq0_yoOI2h2Rgw,6605
30
30
  bec_widgets/cli/server.py,sha256=j5S3-HUCcKE_rip4PDP7nNBAMObO6Ja6D66zhYxXmsE,10693
@@ -225,6 +225,11 @@ bec_widgets/widgets/editors/website/register_website_widget.py,sha256=VSVrZRCZoI
225
225
  bec_widgets/widgets/editors/website/website.py,sha256=VFFdrFX3P0Pf1V21oXrjGyCNrNp7fCsfbWPuRp9xEd8,3030
226
226
  bec_widgets/widgets/editors/website/website_widget.pyproject,sha256=scOiV3cV1_BjbzpPzy2N8rIJL5P2qIZz8ObTJ-Uvdtg,25
227
227
  bec_widgets/widgets/editors/website/website_widget_plugin.py,sha256=-YezP8dDqWZ9Xjjl-e5QTZuBPxxKyY4Lqcs7iaetIa8,1349
228
+ bec_widgets/widgets/games/__init__.py,sha256=jWW-3K3f3gqYM48Tp8rBxPebwPqxAcb7Q4dm_eE7FwI,89
229
+ bec_widgets/widgets/games/minesweeper.py,sha256=WQpyKwkNLCcH0t8InnFLM9TOiQSkbfOKp1uq3wwsPFo,12373
230
+ bec_widgets/widgets/games/minesweeper.pyproject,sha256=wHrLKY3H8uNiVgb9BIrj4S0Jeet9fjoR0BTnKzpx-vY,29
231
+ bec_widgets/widgets/games/minesweeper_plugin.py,sha256=oPEjSTpdIIkvuGThHxhVS8Rp47DWiaXHROtm8NJWYwo,1255
232
+ bec_widgets/widgets/games/register_minesweeper.py,sha256=8fgMBD3yB-5_eGqhG_qxpj3igXDK9WZfHrdYcA1aqz8,467
228
233
  bec_widgets/widgets/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
229
234
  bec_widgets/widgets/plots/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
230
235
  bec_widgets/widgets/plots/image/bec_image_widget.pyproject,sha256=PHisdBo5_5UCApd27GkizzqgfdjsDx2bFZa_p9LiSW8,30
@@ -291,7 +296,7 @@ bec_widgets/widgets/services/device_browser/device_item/device_item.py,sha256=u3
291
296
  bec_widgets/widgets/utility/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
292
297
  bec_widgets/widgets/utility/spinner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
293
298
  bec_widgets/widgets/utility/spinner/register_spinner_widget.py,sha256=96A13dEcyTgXfc9G0sTdlXYCDcVav8Z2P2eDC95bESQ,484
294
- bec_widgets/widgets/utility/spinner/spinner.py,sha256=FRsaHkaoye_4ulNDdbn6a4EaXkO3lYZONB74IXQ2mdQ,2646
299
+ bec_widgets/widgets/utility/spinner/spinner.py,sha256=6c0fN7mdGzELg4mf_yG08ubses3svb6w0EqMeHDFkIw,2651
295
300
  bec_widgets/widgets/utility/spinner/spinner_widget.pyproject,sha256=zzLajGB3DTgVnrSqMey2jRpBlxTq9cBXZL9tWJCKe-I,25
296
301
  bec_widgets/widgets/utility/spinner/spinner_widget_plugin.py,sha256=kRQCOwxPQsFOrJIkSoqq7xdF_VtoRo_b2vOZEr5eXrA,1363
297
302
  bec_widgets/widgets/utility/toggle/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -320,8 +325,8 @@ bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py,sha256=Z
320
325
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.pyproject,sha256=Lbi9zb6HNlIq14k6hlzR-oz6PIFShBuF7QxE6d87d64,34
321
326
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button_plugin.py,sha256=CzChz2SSETYsR8-36meqWnsXCT-FIy_J_xeU5coWDY8,1350
322
327
  bec_widgets/widgets/utility/visual/dark_mode_button/register_dark_mode_button.py,sha256=rMpZ1CaoucwobgPj1FuKTnt07W82bV1GaSYdoqcdMb8,521
323
- bec_widgets-1.13.0.dist-info/METADATA,sha256=hTH9uddiO3VSWkLCtNU5JlJuoCl-ihuNT-n54_8jKtk,1339
324
- bec_widgets-1.13.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
325
- bec_widgets-1.13.0.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
326
- bec_widgets-1.13.0.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
327
- bec_widgets-1.13.0.dist-info/RECORD,,
328
+ bec_widgets-1.14.1.dist-info/METADATA,sha256=NtdzzO4MGjNTXBbNulluYh__nOLWcQX820P88EixW30,1339
329
+ bec_widgets-1.14.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
330
+ bec_widgets-1.14.1.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
331
+ bec_widgets-1.14.1.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
332
+ bec_widgets-1.14.1.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "1.13.0"
7
+ version = "1.14.1"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [