talos-bar 0.0.1__tar.gz
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.
- talos_bar-0.0.1/.gitignore +3 -0
- talos_bar-0.0.1/LICENSE +29 -0
- talos_bar-0.0.1/PKG-INFO +42 -0
- talos_bar-0.0.1/README.md +32 -0
- talos_bar-0.0.1/docs/DESIGN.md +144 -0
- talos_bar-0.0.1/docs/MIGRATION.md +87 -0
- talos_bar-0.0.1/pyproject.toml +35 -0
- talos_bar-0.0.1/src/talos_bar/__init__.py +0 -0
- talos_bar-0.0.1/src/talos_bar/__main__.py +6 -0
- talos_bar-0.0.1/src/talos_bar/app.py +138 -0
- talos_bar-0.0.1/src/talos_bar/glue/__init__.py +115 -0
- talos_bar-0.0.1/src/talos_bar/glue/builtin/clock.py +29 -0
- talos_bar-0.0.1/src/talos_bar/glue/builtin/hello.py +15 -0
- talos_bar-0.0.1/src/talos_bar/platform/__init__.py +27 -0
- talos_bar-0.0.1/src/talos_bar/qml/Bar.qml +37 -0
- talos_bar-0.0.1/tests/test_glue.py +22 -0
- talos_bar-0.0.1/uv.lock +264 -0
talos_bar-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Zackees
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
10
|
+
this list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
talos_bar-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: talos-bar
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Cross-platform desktop bar (PySide6 + QML) extended with Python glue
|
|
5
|
+
License-Expression: BSD-3-Clause
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: pyside6-essentials>=6.7
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# talos-bar
|
|
12
|
+
|
|
13
|
+
A cross-platform desktop bar (Linux, Windows, macOS) for the Talos HQ setup.
|
|
14
|
+
It replaces the KDE Plasma top panel defined in `~/dev/nixos`, so the same
|
|
15
|
+
bar follows us onto any machine.
|
|
16
|
+
|
|
17
|
+
- UI: PySide6 (Qt 6, LGPLv3) + QML, GPU-rendered by Qt Quick
|
|
18
|
+
- Logic: plain Python, so agents can iterate without a compile step
|
|
19
|
+
- Glue: drop a Python file in `glue/` to add bar items, timers and click
|
|
20
|
+
handlers, with hot reload. This is the main way agents extend the bar.
|
|
21
|
+
- Platform docking: one small module per OS (layer-shell, AppBar, NSPanel)
|
|
22
|
+
|
|
23
|
+
Status: design phase. See:
|
|
24
|
+
|
|
25
|
+
- [docs/DESIGN.md](docs/DESIGN.md) — architecture and decisions
|
|
26
|
+
- [docs/MIGRATION.md](docs/MIGRATION.md) — moving the NixOS panel widgets here
|
|
27
|
+
|
|
28
|
+
## Development
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
uv sync
|
|
32
|
+
uv run talos-bar # run the bar
|
|
33
|
+
uv run ruff check . && uv run ruff format --check .
|
|
34
|
+
uv run basedpyright # strict mode
|
|
35
|
+
uv run pytest
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Glue lives in `src/talos_bar/glue/builtin/` and `~/.config/talos-bar/glue/`.
|
|
39
|
+
Edit a glue file while the bar runs and it reloads.
|
|
40
|
+
|
|
41
|
+
On NixOS the PyPI PySide6 wheel needs system libraries (libstdc++, zlib,
|
|
42
|
+
krb5, xcb-*) on `LD_LIBRARY_PATH`; a Nix dev shell for this is still to do.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# talos-bar
|
|
2
|
+
|
|
3
|
+
A cross-platform desktop bar (Linux, Windows, macOS) for the Talos HQ setup.
|
|
4
|
+
It replaces the KDE Plasma top panel defined in `~/dev/nixos`, so the same
|
|
5
|
+
bar follows us onto any machine.
|
|
6
|
+
|
|
7
|
+
- UI: PySide6 (Qt 6, LGPLv3) + QML, GPU-rendered by Qt Quick
|
|
8
|
+
- Logic: plain Python, so agents can iterate without a compile step
|
|
9
|
+
- Glue: drop a Python file in `glue/` to add bar items, timers and click
|
|
10
|
+
handlers, with hot reload. This is the main way agents extend the bar.
|
|
11
|
+
- Platform docking: one small module per OS (layer-shell, AppBar, NSPanel)
|
|
12
|
+
|
|
13
|
+
Status: design phase. See:
|
|
14
|
+
|
|
15
|
+
- [docs/DESIGN.md](docs/DESIGN.md) — architecture and decisions
|
|
16
|
+
- [docs/MIGRATION.md](docs/MIGRATION.md) — moving the NixOS panel widgets here
|
|
17
|
+
|
|
18
|
+
## Development
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
uv sync
|
|
22
|
+
uv run talos-bar # run the bar
|
|
23
|
+
uv run ruff check . && uv run ruff format --check .
|
|
24
|
+
uv run basedpyright # strict mode
|
|
25
|
+
uv run pytest
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Glue lives in `src/talos_bar/glue/builtin/` and `~/.config/talos-bar/glue/`.
|
|
29
|
+
Edit a glue file while the bar runs and it reloads.
|
|
30
|
+
|
|
31
|
+
On NixOS the PyPI PySide6 wheel needs system libraries (libstdc++, zlib,
|
|
32
|
+
krb5, xcb-*) on `LD_LIBRARY_PATH`; a Nix dev shell for this is still to do.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# talos-bar design
|
|
2
|
+
|
|
3
|
+
## Goals
|
|
4
|
+
|
|
5
|
+
1. One bar that runs on Linux (Wayland and X11), Windows 10/11 and macOS.
|
|
6
|
+
2. Fast to appear and smooth to draw: GPU rendering, no webview.
|
|
7
|
+
3. Easy for an agent to change: Python + QML, edit and relaunch, no compile.
|
|
8
|
+
4. Licensing that permits closed or commercial distribution.
|
|
9
|
+
|
|
10
|
+
Non-goals: being a full desktop shell (task manager, launcher dock, pager).
|
|
11
|
+
Those stay with the host desktop.
|
|
12
|
+
|
|
13
|
+
## Stack decision
|
|
14
|
+
|
|
15
|
+
| Choice | Decision | Why |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Toolkit | **PySide6** (Qt 6) | Official Qt for Python, **LGPLv3**: closed apps are fine with dynamic linking. PyQt6 is GPL/commercial, so it is rejected. |
|
|
18
|
+
| UI language | **QML / Qt Quick** | GPU scene graph (Vulkan/Metal/D3D11/OpenGL); Python only drives state. Reuses the existing plasmoid QML. |
|
|
19
|
+
| Rust native core | Not in v1 | `kernal-api`'s Python package is only a compatibility stub today. Bindings (PyO3) come later, only if needed. |
|
|
20
|
+
| Packaging | `uv` for dev; Nuitka (or PyInstaller) per-OS for release | Nuitka also improves cold start. |
|
|
21
|
+
|
|
22
|
+
## Architecture
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
talos_bar/
|
|
26
|
+
__main__.py # entry: python -m talos_bar
|
|
27
|
+
app.py # QGuiApplication, QQmlApplicationEngine, per-screen bars
|
|
28
|
+
config.py # TOML config (~/.config/talos-bar/config.toml)
|
|
29
|
+
platform/
|
|
30
|
+
__init__.py # dock(window, edge, height) -> picks backend
|
|
31
|
+
wayland.py # LayerShellQt: anchor, exclusive zone, layer=top
|
|
32
|
+
x11.py # _NET_WM_STRUT_PARTIAL + _NET_WM_WINDOW_TYPE_DOCK
|
|
33
|
+
windows.py # ctypes SHAppBarMessage (ABM_NEW/ABM_SETPOS), Mica/Acrylic via DWM
|
|
34
|
+
macos.py # pyobjc: NSPanel, NSStatusWindowLevel, NSVisualEffectView
|
|
35
|
+
widgets/ # one Python "model" per widget, exposed to QML
|
|
36
|
+
clock.py # multi-time-zone clock
|
|
37
|
+
agenda.py # wraps calendar-py
|
|
38
|
+
tasks.py # wraps tasks_cli (GitHub-synced checklist)
|
|
39
|
+
qml/
|
|
40
|
+
Bar.qml # the strip: blur/opacity background, widget row
|
|
41
|
+
Clock.qml
|
|
42
|
+
Agenda.qml # popup list
|
|
43
|
+
Tasks.qml # popup checklist
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Data flow
|
|
47
|
+
|
|
48
|
+
- Each widget is a `QObject` with `Property`/`Signal`s registered to QML.
|
|
49
|
+
- Slow work (calendar sync, GitHub calls) runs in a worker thread or
|
|
50
|
+
`asyncio` via `qasync`. It never runs on the GUI thread.
|
|
51
|
+
- QML binds to properties only. No business logic in QML, so the backends can
|
|
52
|
+
be tested headless with pytest.
|
|
53
|
+
|
|
54
|
+
### Glue layer (the main extension point)
|
|
55
|
+
|
|
56
|
+
The current panel is held together by small scripts: plasmoid
|
|
57
|
+
`executable` DataSources, qdbus calls, KWin scripts and Python helpers.
|
|
58
|
+
talos-bar makes that kind of glue a supported feature. **Glue is written in
|
|
59
|
+
Python**, and an agent adds it by dropping in one file. The agent does not
|
|
60
|
+
edit the bar or write QML.
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
talos_bar/glue/ # glue that ships with the repo
|
|
64
|
+
~/.config/talos-bar/glue/ # personal or machine-local glue, same API
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
A glue module is ordinary Python and uses a small decorator API:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from talos_bar.glue import item, every, on_click, run, notify
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@item("standup", label="Standup") # adds a text/icon slot to the bar
|
|
74
|
+
@every(seconds=60) # how often refresh runs (off the GUI thread)
|
|
75
|
+
def refresh(ctx):
|
|
76
|
+
nxt = ctx.backends.agenda.next_event()
|
|
77
|
+
return f"{nxt.title} in {nxt.minutes_until}m" if nxt else ""
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@on_click("standup")
|
|
81
|
+
def open_meeting(ctx):
|
|
82
|
+
run(["xdg-open", ctx.backends.agenda.next_event().url])
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The API covers:
|
|
86
|
+
|
|
87
|
+
- `item` / `popup`: a text/icon slot or a list popup, rendered by built-in QML.
|
|
88
|
+
Glue can't break the layout.
|
|
89
|
+
- `every`, `on_event` (screen change, wake, fullscreen), `on_click`, `on_scroll`.
|
|
90
|
+
- `run` (subprocess, with a timeout), `notify`, `ctx.config`, `ctx.cache`,
|
|
91
|
+
and `ctx.platform` (open a URL, focus an app, OS name), all cross-platform.
|
|
92
|
+
- `ctx.backends.*`: the agenda and tasks backends, so glue can reuse them.
|
|
93
|
+
|
|
94
|
+
Rules that keep the glue safe to change:
|
|
95
|
+
|
|
96
|
+
- **Hot reload:** a file watcher reloads a module when it changes. No restart.
|
|
97
|
+
- **Isolation:** each glue module runs in a worker thread with a timeout. An
|
|
98
|
+
exception shows a red dot on that item and goes to the log. The bar keeps running.
|
|
99
|
+
- **OS-specific glue:** use `@item(..., platforms={"linux"})`, or branch on
|
|
100
|
+
`ctx.platform.os`. Glue that needs qdbus/KWin stays Linux-only. Everything
|
|
101
|
+
else should work on every OS.
|
|
102
|
+
- **Testing:** `talos-bar glue test <file>` runs a module headless against
|
|
103
|
+
fake backends, so agents can check their changes without a display.
|
|
104
|
+
|
|
105
|
+
### Platform docking contract
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
def dock(window: QQuickWindow, screen: QScreen, edge: Edge, thickness: int) -> Docking
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`Docking` exposes `reserve(bool)` (take screen space or float) and `close()`.
|
|
112
|
+
Behaviour per OS:
|
|
113
|
+
|
|
114
|
+
| OS | Reserves space | Notes |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| Wayland (KWin, Hyprland, Sway) | yes, exclusive zone | Needs the compositor to support `wlr-layer-shell`. GNOME does not, so GNOME falls back to a floating window. |
|
|
117
|
+
| X11 | yes, strut | |
|
|
118
|
+
| Windows | yes, AppBar | Handle `ABN_FULLSCREENAPP` to hide under fullscreen apps. |
|
|
119
|
+
| macOS | **no** | The system menu bar owns the top edge. Float an NSPanel just below it, or use a bottom edge. |
|
|
120
|
+
|
|
121
|
+
### Look
|
|
122
|
+
|
|
123
|
+
- Background: 70% opacity plus shadow, matching the current panel colorizer setting.
|
|
124
|
+
- Blur: KWin blur protocol on Linux, `DWMWA_SYSTEMBACKDROP_TYPE` on Windows,
|
|
125
|
+
`NSVisualEffectView` on macOS. Fall back to plain translucency.
|
|
126
|
+
- Height 36 logical px, centered, sized to contents (matches today's panel).
|
|
127
|
+
- Follows each screen's DPI; one bar per screen, configurable.
|
|
128
|
+
|
|
129
|
+
## Performance budget
|
|
130
|
+
|
|
131
|
+
| Metric | Target |
|
|
132
|
+
|---|---|
|
|
133
|
+
| Cold start to visible bar | under 800 ms (Nuitka build), under 1.5 s (`uv run`) |
|
|
134
|
+
| Idle CPU | about 0% (clock ticks once per second, or per minute without seconds) |
|
|
135
|
+
| Resident memory | under 150 MB |
|
|
136
|
+
|
|
137
|
+
Measure these early. If cold start misses its target, use Nuitka and
|
|
138
|
+
precompiled QML (`qmlcachegen`) before changing the architecture.
|
|
139
|
+
|
|
140
|
+
## Open questions
|
|
141
|
+
|
|
142
|
+
- macOS: a bar below the menu bar, or `NSStatusItem` menu extras instead?
|
|
143
|
+
- Should talos-bar also absorb the bottom dock's custom launchers later?
|
|
144
|
+
- When should `kernal-api` get PyO3 bindings, and which modules first (process, http, tray)?
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Migrating the NixOS top panel into talos-bar
|
|
2
|
+
|
|
3
|
+
## Starting point
|
|
4
|
+
|
|
5
|
+
The NixOS top panel is declared in `~/dev/nixos/system/configuration.nix`
|
|
6
|
+
(around line 3190): `location = "top"`, screen 0, centered, `lengthMode = "fit"`,
|
|
7
|
+
height 36, `hiding = "windowsgobelow"`. It holds:
|
|
8
|
+
|
|
9
|
+
| Current widget | Source | Moves to |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| `luisbocanegra.panel.colorizer` (70% opacity, shadow) | third-party plasmoid | `qml/Bar.qml` background, plus blur in `platform/*` |
|
|
12
|
+
| `digitalClock`, 9 zones (Local, New York, Chicago, Denver, Sydney, Luxembourg, Moscow, Tokyo, UTC), city format | stock Plasma | `widgets/clock.py` + `qml/Clock.qml`; zones in config.toml |
|
|
13
|
+
| `org.niteris.calendar-agenda` | `nixos/system/calendar-agenda/` (483-line QML) + `nixos/system/calendar-py/` | `widgets/agenda.py` imports calendar-py; QML ported |
|
|
14
|
+
| `org.niteris.tasks` | `nixos/system/tasks/` (applet + `tasks_cli.py`) | `widgets/tasks.py` imports tasks_cli; QML ported |
|
|
15
|
+
|
|
16
|
+
Out of scope: the bottom dock (launchers, pager, task manager) stays in Plasma.
|
|
17
|
+
|
|
18
|
+
## Phase 0: scaffold (about 1 day)
|
|
19
|
+
|
|
20
|
+
- `pyproject.toml` (uv), PySide6, pytest, ruff.
|
|
21
|
+
- `python -m talos_bar` opens an undecorated 36 px window with a clock.
|
|
22
|
+
|
|
23
|
+
## Phase 1: Linux parity, side by side with Plasma (about 3–5 days)
|
|
24
|
+
|
|
25
|
+
1. Wayland docking via LayerShellQt (in nixpkgs as `kdePackages.layer-shell-qt`).
|
|
26
|
+
2. Clock widget with the nine zones.
|
|
27
|
+
3. **Backends:** move `calendar-py` and `tasks_cli.py` into this repo as
|
|
28
|
+
`talos_bar/backends/` (keep their tests). Until the move, depend on them
|
|
29
|
+
by path. Drop the `Plasma5Support.DataSource { engine: "executable" }`
|
|
30
|
+
subprocess bridge and call the Python functions directly.
|
|
31
|
+
4. **QML port:** replace `org.kde.plasma.*`, `Plasma5Support` and Kirigami
|
|
32
|
+
imports with `QtQuick.Controls`. Replace `plasmoid.*` config with
|
|
33
|
+
properties from `config.py`. Keep the layout and behaviour as they are.
|
|
34
|
+
5. Run talos-bar next to the Plasma panel on another screen or edge until it
|
|
35
|
+
matches.
|
|
36
|
+
|
|
37
|
+
## Phase 1b: convert existing glue into Python glue modules (ongoing)
|
|
38
|
+
|
|
39
|
+
Go through every ad-hoc bridge that feeds the panel and rewrite it as a
|
|
40
|
+
`talos_bar/glue/*.py` module (see "Glue layer" in DESIGN.md):
|
|
41
|
+
|
|
42
|
+
- Plasmoid `executable` DataSources and the shell strings they run.
|
|
43
|
+
- `qdbus` / KWin-script snippets in `configuration.nix` that the panel uses
|
|
44
|
+
(Overview button, desktop moves). These become Linux-only glue.
|
|
45
|
+
- Python helpers wired to the bar (e.g. `launch-origin/kitty_bridge.py`,
|
|
46
|
+
`voxtype-popup.py`) if they surface state on the bar.
|
|
47
|
+
|
|
48
|
+
Do one conversion per commit, and record each in the table below. Once a
|
|
49
|
+
piece of glue is a module, an agent can change it without touching Nix.
|
|
50
|
+
|
|
51
|
+
| Old glue | New module | Platforms | Done |
|
|
52
|
+
|---|---|---|---|
|
|
53
|
+
| | | | |
|
|
54
|
+
|
|
55
|
+
## Phase 2: switch over on NixOS (about 1 day)
|
|
56
|
+
|
|
57
|
+
- Package talos-bar in `~/dev/nixos` (a `buildPythonApplication` in
|
|
58
|
+
`system/pkgs/talos-bar/`) and start it with a systemd user service.
|
|
59
|
+
- Remove the top panel block from `configuration.nix`, and remove the
|
|
60
|
+
agenda/tasks plasmoid wiring in `calendar.nix` and `tasks.nix` (keep the
|
|
61
|
+
sync services those widgets rely on).
|
|
62
|
+
- Keep the old panel block in git history as the rollback.
|
|
63
|
+
|
|
64
|
+
## Phase 3: Windows and macOS (about 1.5–2 weeks)
|
|
65
|
+
|
|
66
|
+
- `platform/windows.py`: AppBar registration, work-area reservation,
|
|
67
|
+
fullscreen hiding, Mica backdrop.
|
|
68
|
+
- `platform/macos.py`: NSPanel at status level below the menu bar,
|
|
69
|
+
vibrancy, no Dock icon (`LSUIElement`).
|
|
70
|
+
- Check that the calendar and tasks backends have no Linux-only paths (XDG
|
|
71
|
+
directories, `notify-send`, etc.). Use `platformdirs` for paths.
|
|
72
|
+
|
|
73
|
+
## Phase 4: packaging and polish (about 1 week)
|
|
74
|
+
|
|
75
|
+
- Nuitka builds per OS in CI (add workflows only when asked).
|
|
76
|
+
- Autostart: systemd user unit, Windows Startup shortcut / Run key, macOS LaunchAgent.
|
|
77
|
+
- Multi-monitor (one bar per screen, or primary only) and per-screen DPI.
|
|
78
|
+
- Measure against the performance budget in DESIGN.md.
|
|
79
|
+
|
|
80
|
+
## Risks
|
|
81
|
+
|
|
82
|
+
| Risk | Mitigation |
|
|
83
|
+
|---|---|
|
|
84
|
+
| GNOME has no layer-shell | Floating window fallback; document the limitation |
|
|
85
|
+
| Python + Qt cold start | Nuitka + `qmlcachegen`; it is a login-once process |
|
|
86
|
+
| calendar-py assumes Linux | Audit in Phase 3; `platformdirs` |
|
|
87
|
+
| macOS cannot reserve the top edge | Accept a floating bar, or go to `NSStatusItem` |
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "talos-bar"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "Cross-platform desktop bar (PySide6 + QML) extended with Python glue"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "BSD-3-Clause"
|
|
7
|
+
requires-python = ">=3.10"
|
|
8
|
+
dependencies = ["PySide6-Essentials>=6.7"]
|
|
9
|
+
|
|
10
|
+
[project.scripts]
|
|
11
|
+
talos-bar = "talos_bar.__main__:main"
|
|
12
|
+
|
|
13
|
+
[dependency-groups]
|
|
14
|
+
dev = ["pytest>=8", "ruff>=0.6", "basedpyright>=1.20"]
|
|
15
|
+
|
|
16
|
+
[build-system]
|
|
17
|
+
requires = ["hatchling>=1.26"]
|
|
18
|
+
build-backend = "hatchling.build"
|
|
19
|
+
|
|
20
|
+
[tool.hatch.build.targets.wheel]
|
|
21
|
+
packages = ["src/talos_bar"]
|
|
22
|
+
|
|
23
|
+
[tool.ruff]
|
|
24
|
+
line-length = 110
|
|
25
|
+
target-version = "py310"
|
|
26
|
+
src = ["src", "tests"]
|
|
27
|
+
|
|
28
|
+
[tool.ruff.lint]
|
|
29
|
+
select = ["E", "F", "W", "I", "UP", "B", "SIM", "RUF", "ANN"]
|
|
30
|
+
|
|
31
|
+
[tool.basedpyright]
|
|
32
|
+
include = ["src", "tests"]
|
|
33
|
+
pythonVersion = "3.10"
|
|
34
|
+
typeCheckingMode = "strict"
|
|
35
|
+
reportMissingTypeStubs = false
|
|
File without changes
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Bar application: loads glue, runs it off the GUI thread, feeds QML."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
import traceback
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import cast
|
|
9
|
+
|
|
10
|
+
from PySide6.QtCore import (
|
|
11
|
+
Property,
|
|
12
|
+
QFileSystemWatcher,
|
|
13
|
+
QObject,
|
|
14
|
+
QRunnable,
|
|
15
|
+
QThreadPool,
|
|
16
|
+
QTimer,
|
|
17
|
+
QUrl,
|
|
18
|
+
Signal,
|
|
19
|
+
Slot,
|
|
20
|
+
)
|
|
21
|
+
from PySide6.QtGui import QGuiApplication, QWindow
|
|
22
|
+
from PySide6.QtQml import QQmlApplicationEngine
|
|
23
|
+
|
|
24
|
+
from talos_bar import glue, platform
|
|
25
|
+
|
|
26
|
+
QML = Path(__file__).parent / "qml" / "Bar.qml"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class _Job(QRunnable):
|
|
30
|
+
def __init__(self, bar: Bar, item: glue.Item, fn: glue.RefreshFn) -> None:
|
|
31
|
+
super().__init__()
|
|
32
|
+
self.bar, self.item, self.fn = bar, item, fn
|
|
33
|
+
|
|
34
|
+
def run(self) -> None:
|
|
35
|
+
try:
|
|
36
|
+
out = self.fn(self.bar.ctx)
|
|
37
|
+
self.bar.result.emit(self.item.id, out if out is not None else "", False)
|
|
38
|
+
except Exception:
|
|
39
|
+
traceback.print_exc()
|
|
40
|
+
self.bar.result.emit(self.item.id, "", True)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Bar(QObject):
|
|
44
|
+
itemsChanged = Signal()
|
|
45
|
+
result = Signal(str, object, bool)
|
|
46
|
+
|
|
47
|
+
def __init__(self) -> None:
|
|
48
|
+
super().__init__()
|
|
49
|
+
self.ctx = glue.Context()
|
|
50
|
+
self._items: dict[str, glue.Item] = {}
|
|
51
|
+
self._view: dict[str, dict[str, object]] = {}
|
|
52
|
+
self._timers: dict[str, QTimer] = {}
|
|
53
|
+
self._pool = QThreadPool.globalInstance()
|
|
54
|
+
self.result.connect(self._on_result)
|
|
55
|
+
self._watch = QFileSystemWatcher(self)
|
|
56
|
+
self._watch.directoryChanged.connect(self._changed)
|
|
57
|
+
self._watch.fileChanged.connect(self._changed)
|
|
58
|
+
self.reload()
|
|
59
|
+
|
|
60
|
+
@Property(list, notify=itemsChanged) # pyright: ignore[reportArgumentType]
|
|
61
|
+
def items(self) -> list[dict[str, object]]:
|
|
62
|
+
return [self._view[i] for i in self._items]
|
|
63
|
+
|
|
64
|
+
@Slot(str)
|
|
65
|
+
def _changed(self, _path: str) -> None:
|
|
66
|
+
self.reload()
|
|
67
|
+
|
|
68
|
+
@Slot()
|
|
69
|
+
def reload(self) -> None:
|
|
70
|
+
for t in self._timers.values():
|
|
71
|
+
t.stop()
|
|
72
|
+
self._timers.clear()
|
|
73
|
+
self._items.clear()
|
|
74
|
+
files: list[Path] = []
|
|
75
|
+
for d in glue.glue_dirs():
|
|
76
|
+
if d.is_dir():
|
|
77
|
+
files += sorted(p for p in d.glob("*.py") if not p.name.startswith("_"))
|
|
78
|
+
self._watch.addPath(str(d))
|
|
79
|
+
for f in files:
|
|
80
|
+
self._watch.addPath(str(f))
|
|
81
|
+
for it in glue.load_file(f):
|
|
82
|
+
self._items[it.id] = it
|
|
83
|
+
self._view.setdefault(it.id, {"id": it.id, "text": it.label, "tooltip": "", "error": False})
|
|
84
|
+
self._schedule(it)
|
|
85
|
+
self.itemsChanged.emit()
|
|
86
|
+
|
|
87
|
+
def _schedule(self, it: glue.Item) -> None:
|
|
88
|
+
if not it.refresh:
|
|
89
|
+
return
|
|
90
|
+
t = QTimer(self)
|
|
91
|
+
t.setInterval(int(it.interval * 1000))
|
|
92
|
+
refresh = it.refresh
|
|
93
|
+
t.timeout.connect(lambda: self._pool.start(_Job(self, it, refresh)))
|
|
94
|
+
t.start()
|
|
95
|
+
self._timers[it.id] = t
|
|
96
|
+
self._pool.start(_Job(self, it, refresh))
|
|
97
|
+
|
|
98
|
+
@Slot(str, object, bool)
|
|
99
|
+
def _on_result(self, item_id: str, out: object, error: bool) -> None:
|
|
100
|
+
if item_id not in self._view:
|
|
101
|
+
return
|
|
102
|
+
v = self._view[item_id]
|
|
103
|
+
v["error"] = error
|
|
104
|
+
if isinstance(out, dict):
|
|
105
|
+
rich = cast("glue.Rich", out)
|
|
106
|
+
v["text"] = rich.get("text", str(v["text"]))
|
|
107
|
+
v["tooltip"] = rich.get("tooltip", "")
|
|
108
|
+
elif not error:
|
|
109
|
+
v["text"] = str(out)
|
|
110
|
+
self.itemsChanged.emit()
|
|
111
|
+
|
|
112
|
+
@Slot(str)
|
|
113
|
+
def click(self, item_id: str) -> None:
|
|
114
|
+
it = self._items.get(item_id)
|
|
115
|
+
if it is None or it.click is None:
|
|
116
|
+
return
|
|
117
|
+
on_click, refresh = it.click, it.refresh
|
|
118
|
+
|
|
119
|
+
def clicked(ctx: glue.Context) -> glue.Output:
|
|
120
|
+
on_click(ctx)
|
|
121
|
+
return refresh(ctx) if refresh else None
|
|
122
|
+
|
|
123
|
+
self._pool.start(_Job(self, it, clicked))
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def main(argv: list[str] | None = None) -> int:
|
|
127
|
+
app = QGuiApplication(argv or sys.argv)
|
|
128
|
+
app.setApplicationName("talos-bar")
|
|
129
|
+
bar = Bar()
|
|
130
|
+
engine = QQmlApplicationEngine()
|
|
131
|
+
engine.rootContext().setContextProperty("bar", bar)
|
|
132
|
+
engine.load(QUrl.fromLocalFile(str(QML)))
|
|
133
|
+
if not engine.rootObjects():
|
|
134
|
+
return 1
|
|
135
|
+
root = engine.rootObjects()[0]
|
|
136
|
+
assert isinstance(root, QWindow)
|
|
137
|
+
platform.dock(root, height=36)
|
|
138
|
+
return app.exec()
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""Glue API: drop a Python file in a glue directory to add items to the bar.
|
|
2
|
+
|
|
3
|
+
from talos_bar.glue import Context, Output, every, item, on_click
|
|
4
|
+
|
|
5
|
+
@item("hello", label="Hello")
|
|
6
|
+
@every(seconds=5)
|
|
7
|
+
def refresh(ctx: Context) -> Output:
|
|
8
|
+
return "hi"
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import importlib.util
|
|
14
|
+
import subprocess
|
|
15
|
+
import sys
|
|
16
|
+
import traceback
|
|
17
|
+
from collections.abc import Callable
|
|
18
|
+
from dataclasses import dataclass, field
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any, TypedDict
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Rich(TypedDict, total=False):
|
|
24
|
+
text: str
|
|
25
|
+
tooltip: str
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Output = str | Rich | None
|
|
29
|
+
RefreshFn = Callable[["Context"], Output]
|
|
30
|
+
ClickFn = Callable[["Context"], None]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class Item:
|
|
35
|
+
id: str
|
|
36
|
+
label: str
|
|
37
|
+
refresh: RefreshFn | None = None
|
|
38
|
+
interval: float = 60.0
|
|
39
|
+
click: ClickFn | None = None
|
|
40
|
+
platforms: frozenset[str] | None = None
|
|
41
|
+
source: Path | None = None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass
|
|
45
|
+
class Context:
|
|
46
|
+
os: str = sys.platform
|
|
47
|
+
cache: dict[str, Any] = field(default_factory=dict[str, Any])
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# Filled while a glue module is imported; read back by load_file().
|
|
51
|
+
_registry: dict[str, Item] = {}
|
|
52
|
+
_intervals: dict[int, float] = {}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def item(id: str, label: str = "", platforms: set[str] | None = None) -> Callable[[RefreshFn], RefreshFn]:
|
|
56
|
+
def deco(fn: RefreshFn) -> RefreshFn:
|
|
57
|
+
it = _registry.setdefault(id, Item(id=id, label=label or id))
|
|
58
|
+
it.refresh = fn
|
|
59
|
+
it.interval = _intervals.get(id_of(fn), it.interval)
|
|
60
|
+
it.platforms = frozenset(platforms) if platforms else None
|
|
61
|
+
return fn
|
|
62
|
+
|
|
63
|
+
return deco
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def every(seconds: float) -> Callable[[RefreshFn], RefreshFn]:
|
|
67
|
+
"""Refresh interval; place it below @item."""
|
|
68
|
+
|
|
69
|
+
def deco(fn: RefreshFn) -> RefreshFn:
|
|
70
|
+
_intervals[id_of(fn)] = seconds
|
|
71
|
+
return fn
|
|
72
|
+
|
|
73
|
+
return deco
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def on_click(id: str) -> Callable[[ClickFn], ClickFn]:
|
|
77
|
+
def deco(fn: ClickFn) -> ClickFn:
|
|
78
|
+
_registry.setdefault(id, Item(id=id, label=id)).click = fn
|
|
79
|
+
return fn
|
|
80
|
+
|
|
81
|
+
return deco
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def run(cmd: list[str], timeout: float = 10.0) -> str:
|
|
85
|
+
return subprocess.run(cmd, capture_output=True, text=True, timeout=timeout, check=False).stdout
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def id_of(fn: object) -> int:
|
|
89
|
+
return id(fn)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def load_file(path: Path) -> list[Item]:
|
|
93
|
+
"""Import one glue file and return the items it registered (empty on error)."""
|
|
94
|
+
_registry.clear()
|
|
95
|
+
_intervals.clear()
|
|
96
|
+
spec = importlib.util.spec_from_file_location(f"talos_glue_{path.stem}", path)
|
|
97
|
+
if spec is None or spec.loader is None:
|
|
98
|
+
return []
|
|
99
|
+
try:
|
|
100
|
+
spec.loader.exec_module(importlib.util.module_from_spec(spec))
|
|
101
|
+
except Exception:
|
|
102
|
+
traceback.print_exc()
|
|
103
|
+
return []
|
|
104
|
+
items = [i for i in _registry.values() if i.platforms is None or os_key() in i.platforms]
|
|
105
|
+
for i in items:
|
|
106
|
+
i.source = path
|
|
107
|
+
return items
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def glue_dirs() -> list[Path]:
|
|
111
|
+
return [Path(__file__).parent / "builtin", Path.home() / ".config" / "talos-bar" / "glue"]
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def os_key() -> str:
|
|
115
|
+
return {"win32": "windows", "darwin": "macos"}.get(sys.platform, "linux")
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""World clock: local time, with other zones in the tooltip."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from zoneinfo import ZoneInfo
|
|
5
|
+
|
|
6
|
+
from talos_bar.glue import Context, Output, every, item
|
|
7
|
+
|
|
8
|
+
ZONES = [
|
|
9
|
+
"America/New_York",
|
|
10
|
+
"America/Chicago",
|
|
11
|
+
"America/Denver",
|
|
12
|
+
"Australia/Sydney",
|
|
13
|
+
"Europe/Luxembourg",
|
|
14
|
+
"Europe/Moscow",
|
|
15
|
+
"Asia/Tokyo",
|
|
16
|
+
"UTC",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _city(zone: str) -> str:
|
|
21
|
+
return zone.split("/")[-1].replace("_", " ")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@item("clock", label="Clock")
|
|
25
|
+
@every(seconds=1)
|
|
26
|
+
def refresh(ctx: Context) -> Output:
|
|
27
|
+
now = datetime.now().astimezone()
|
|
28
|
+
tip = "\n".join(f"{_city(z)}: {now.astimezone(ZoneInfo(z)):%H:%M}" for z in ZONES)
|
|
29
|
+
return {"text": f"{now:%a %d %b %H:%M:%S}", "tooltip": tip}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Example glue: edit this file while the bar runs and it reloads."""
|
|
2
|
+
|
|
3
|
+
from talos_bar.glue import Context, Output, every, item, on_click
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@item("hello", label="Hello")
|
|
7
|
+
@every(seconds=5)
|
|
8
|
+
def refresh(ctx: Context) -> Output:
|
|
9
|
+
clicks: int = ctx.cache.get("clicks", 0)
|
|
10
|
+
return f"glue ok ({clicks} clicks)"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@on_click("hello")
|
|
14
|
+
def click(ctx: Context) -> None:
|
|
15
|
+
ctx.cache["clicks"] = ctx.cache.get("clicks", 0) + 1
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Edge docking. The spike only floats the bar at the top centre of the
|
|
2
|
+
primary screen; real space reservation (layer-shell, X11 strut, AppBar,
|
|
3
|
+
NSPanel) lands per OS as described in docs/DESIGN.md."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from PySide6.QtCore import Qt
|
|
8
|
+
from PySide6.QtGui import QGuiApplication, QWindow
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def dock(window: QWindow, height: int) -> None:
|
|
12
|
+
window.setFlags(
|
|
13
|
+
Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint | Qt.WindowType.Tool
|
|
14
|
+
)
|
|
15
|
+
geo = QGuiApplication.primaryScreen().availableGeometry()
|
|
16
|
+
|
|
17
|
+
def place() -> None:
|
|
18
|
+
window.setY(geo.y())
|
|
19
|
+
window.setX(geo.x() + (geo.width() - window.width()) // 2)
|
|
20
|
+
|
|
21
|
+
def on_width(_w: int) -> None:
|
|
22
|
+
place()
|
|
23
|
+
|
|
24
|
+
window.widthChanged.connect(on_width)
|
|
25
|
+
window.setHeight(height)
|
|
26
|
+
place()
|
|
27
|
+
window.show()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import QtQuick.Controls
|
|
3
|
+
|
|
4
|
+
Window {
|
|
5
|
+
id: root
|
|
6
|
+
visible: false
|
|
7
|
+
color: "transparent"
|
|
8
|
+
width: row.implicitWidth + 32
|
|
9
|
+
height: 36
|
|
10
|
+
|
|
11
|
+
Rectangle {
|
|
12
|
+
anchors.fill: parent
|
|
13
|
+
radius: 8
|
|
14
|
+
color: Qt.rgba(0.08, 0.09, 0.11, 0.7)
|
|
15
|
+
border.color: Qt.rgba(1, 1, 1, 0.08)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Row {
|
|
19
|
+
id: row
|
|
20
|
+
anchors.centerIn: parent
|
|
21
|
+
spacing: 20
|
|
22
|
+
|
|
23
|
+
Repeater {
|
|
24
|
+
model: bar.items
|
|
25
|
+
delegate: Label {
|
|
26
|
+
required property var modelData
|
|
27
|
+
text: modelData.text
|
|
28
|
+
color: modelData.error ? "#ff6b6b" : "#e8e8ea"
|
|
29
|
+
font.pixelSize: 14
|
|
30
|
+
ToolTip.visible: modelData.tooltip !== "" && hover.hovered
|
|
31
|
+
ToolTip.text: modelData.tooltip
|
|
32
|
+
HoverHandler { id: hover }
|
|
33
|
+
TapHandler { onTapped: bar.click(modelData.id) }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from talos_bar import glue
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_builtin_glue_loads_and_refreshes() -> None:
|
|
7
|
+
builtin = glue.glue_dirs()[0]
|
|
8
|
+
ids: dict[str, glue.Item] = {}
|
|
9
|
+
for f in sorted(builtin.glob("*.py")):
|
|
10
|
+
for it in glue.load_file(f):
|
|
11
|
+
ids[it.id] = it
|
|
12
|
+
assert {"clock", "hello"} <= ids.keys()
|
|
13
|
+
assert ids["clock"].interval == 1
|
|
14
|
+
ctx = glue.Context()
|
|
15
|
+
assert ids["clock"].refresh is not None
|
|
16
|
+
assert "text" in ids["clock"].refresh(ctx) # type: ignore[operator]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_broken_glue_is_isolated(tmp_path: Path) -> None:
|
|
20
|
+
bad = tmp_path / "bad.py"
|
|
21
|
+
bad.write_text("raise RuntimeError('boom')\n")
|
|
22
|
+
assert glue.load_file(bad) == []
|
talos_bar-0.0.1/uv.lock
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 5
|
|
3
|
+
requires-python = ">=3.10"
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "basedpyright"
|
|
7
|
+
version = "1.40.2"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
dependencies = [
|
|
10
|
+
{ name = "nodejs-wheel-binaries" },
|
|
11
|
+
]
|
|
12
|
+
sdist = { url = "https://files.pythonhosted.org/packages/3a/36/1cf637b15704e4c1f09f8bcc48ab3bfaff089e7466565bd34d8d1dcc03e9/basedpyright-1.40.2.tar.gz", hash = "sha256:d4db36d095230379acc66c7e5fba7e4b50ca902f6e803d696782dd031cb8d7d7", size = 25559682, upload-time = "2026-10-04T11:28:30.415Z" }
|
|
13
|
+
wheels = [
|
|
14
|
+
{ url = "https://files.pythonhosted.org/packages/de/53/0031b22e118264a57a3b64dfc0c8f0659b81af5bccd419ac62933013c601/basedpyright-1.40.2-py3-none-any.whl", hash = "sha256:3a53aeb93a86675ded0e12bc27bd8476c1742356de07ad8cab67bff18110c690", size = 13694487, upload-time = "2026-10-04T11:28:26.271Z" },
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "colorama"
|
|
19
|
+
version = "0.4.6"
|
|
20
|
+
source = { registry = "https://pypi.org/simple" }
|
|
21
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
22
|
+
wheels = [
|
|
23
|
+
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[[package]]
|
|
27
|
+
name = "exceptiongroup"
|
|
28
|
+
version = "1.3.1"
|
|
29
|
+
source = { registry = "https://pypi.org/simple" }
|
|
30
|
+
dependencies = [
|
|
31
|
+
{ name = "typing-extensions" },
|
|
32
|
+
]
|
|
33
|
+
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" }
|
|
34
|
+
wheels = [
|
|
35
|
+
{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" },
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[[package]]
|
|
39
|
+
name = "iniconfig"
|
|
40
|
+
version = "2.3.1"
|
|
41
|
+
source = { registry = "https://pypi.org/simple" }
|
|
42
|
+
sdist = { url = "https://files.pythonhosted.org/packages/01/e1/2069291243c926a2ff1cd706c7f3eeb9b62144bf60f77c9fb9ff2fb26bd3/iniconfig-2.3.1.tar.gz", hash = "sha256:67f4b9c50da0dedf52af349e7749a80a9057a5031199791b906c3bb3ae878960", size = 21209, upload-time = "2026-10-06T22:48:38.076Z" }
|
|
43
|
+
wheels = [
|
|
44
|
+
{ url = "https://files.pythonhosted.org/packages/56/43/4ca9e49d27a1fcf6bece6f6aec0ea46bb9112489b93d4b688fb415457bdb/iniconfig-2.3.1-py3-none-any.whl", hash = "sha256:9121e2c1fdb355232495be3194c8dfe87ccc2d5dee45947b78e68f499790d7a7", size = 7552, upload-time = "2026-10-06T22:48:36.959Z" },
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[[package]]
|
|
48
|
+
name = "nodejs-wheel-binaries"
|
|
49
|
+
version = "24.19.0"
|
|
50
|
+
source = { registry = "https://pypi.org/simple" }
|
|
51
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c0/76/7e97195e14346598565a0de4ca8bdbd5e634b3fb5b1ba590b7b1b89f8a63/nodejs_wheel_binaries-24.19.0.tar.gz", hash = "sha256:db217eef8cab8551667863379b08db4d9067403f6cbbe87481eb40edceb8aa9b", size = 8058, upload-time = "2026-08-19T21:47:19.671Z" }
|
|
52
|
+
wheels = [
|
|
53
|
+
{ url = "https://files.pythonhosted.org/packages/8c/52/0774b52c7be8151ad9d5aff44edc100c3f13d6d8eb3765f63ffa40e69fe8/nodejs_wheel_binaries-24.19.0-py2.py3-none-macosx_13_0_arm64.whl", hash = "sha256:e12cbfd69089504e42fb14194ce734a9dcf3eb38c820ca63dd511d36fb964e9c", size = 56047203, upload-time = "2026-08-19T21:46:43.448Z" },
|
|
54
|
+
{ url = "https://files.pythonhosted.org/packages/67/3a/4fdbbfecf2c23d52c0e3f68de7f7c1b3c97a26d328c69c5f6c49c48e340e/nodejs_wheel_binaries-24.19.0-py2.py3-none-macosx_13_0_x86_64.whl", hash = "sha256:1c890adf4b7e6556ccc1ca66c866bb81884b6c9a581dee4e530dc7f78fb9d514", size = 56219459, upload-time = "2026-08-19T21:46:48.45Z" },
|
|
55
|
+
{ url = "https://files.pythonhosted.org/packages/5f/a8/0147149415195c59b8a72a594916bfb80d6be4d586f9fbfda313889e0efc/nodejs_wheel_binaries-24.19.0-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:4e029dadfae1295876063c96b236f673487e8c27379fe146c1e2250283520227", size = 60588256, upload-time = "2026-08-19T21:46:53.298Z" },
|
|
56
|
+
{ url = "https://files.pythonhosted.org/packages/f4/89/6631d0982353da1bb7bc00bb1988f702822c62b42634f57999ee53b5c337/nodejs_wheel_binaries-24.19.0-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:4196a947bcc883f2003ab101762d729f3e99b5e86b75bd09151563403e2eceb8", size = 61123607, upload-time = "2026-08-19T21:46:58.117Z" },
|
|
57
|
+
{ url = "https://files.pythonhosted.org/packages/32/a2/fa30f0841e4602995782e124359f9b910c7b481d98decf61ef0b2fc3ebfb/nodejs_wheel_binaries-24.19.0-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:352e048ab4dd35e7de5f338d1cc4fcbf77a0e93da30bf7336a8217ee246b31d7", size = 62632842, upload-time = "2026-08-19T21:47:03.42Z" },
|
|
58
|
+
{ url = "https://files.pythonhosted.org/packages/18/01/22d97ca72213f66cc386ee638db30c2e62757fdf761c6029074bced83d1c/nodejs_wheel_binaries-24.19.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:28d078b2ced9e2069516e652dc4b1380e7a1a7f2d3934eccd1611586d283ba4c", size = 63250653, upload-time = "2026-08-19T21:47:07.938Z" },
|
|
59
|
+
{ url = "https://files.pythonhosted.org/packages/88/d1/e3be8fa327a795bcaf7a19cd84299e338a7bce32ff0665fdce9cfa22573c/nodejs_wheel_binaries-24.19.0-py2.py3-none-win_amd64.whl", hash = "sha256:67e3abeb9c3830cae8c8487ae8a2af7cc27dfa75af06145cee5ca7d1857c81bd", size = 42448503, upload-time = "2026-08-19T21:47:12.093Z" },
|
|
60
|
+
{ url = "https://files.pythonhosted.org/packages/1d/37/34cf28ba1691a060174948a9927fe61091982d6048b2e403071a9acce443/nodejs_wheel_binaries-24.19.0-py2.py3-none-win_arm64.whl", hash = "sha256:d9074c665ea68b04e183d82482c86dc907d3a9bd15eb6cf85542cb785266bb36", size = 40090155, upload-time = "2026-08-19T21:47:16.032Z" },
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
[[package]]
|
|
64
|
+
name = "packaging"
|
|
65
|
+
version = "26.3"
|
|
66
|
+
source = { registry = "https://pypi.org/simple" }
|
|
67
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" }
|
|
68
|
+
wheels = [
|
|
69
|
+
{ url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" },
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[[package]]
|
|
73
|
+
name = "pluggy"
|
|
74
|
+
version = "1.7.0"
|
|
75
|
+
source = { registry = "https://pypi.org/simple" }
|
|
76
|
+
sdist = { url = "https://files.pythonhosted.org/packages/bf/db/7fc19e6f2dc92a966727031389fc2e08b558f0f25eb7403c1119ad4713cd/pluggy-1.7.0.tar.gz", hash = "sha256:d1eaa46ebb595891b860ab086b4d09c8588af65ebd4361b8e8f4bb8920b90ba8", size = 123304, upload-time = "2026-10-15T09:50:58.343Z" }
|
|
77
|
+
wheels = [
|
|
78
|
+
{ url = "https://files.pythonhosted.org/packages/40/9e/2b38731e0fc536806f16490e1a12d7f0dc2a1235aa8cc07bcc75416a7daa/pluggy-1.7.0-py3-none-any.whl", hash = "sha256:7dd7b0d8832ba3cb632c306926ded123429211b83641b35dc5c41ad2d34f9bec", size = 27082, upload-time = "2026-10-15T09:50:56.808Z" },
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
[[package]]
|
|
82
|
+
name = "pygments"
|
|
83
|
+
version = "2.21.0"
|
|
84
|
+
source = { registry = "https://pypi.org/simple" }
|
|
85
|
+
sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" }
|
|
86
|
+
wheels = [
|
|
87
|
+
{ url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" },
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
[[package]]
|
|
91
|
+
name = "pyside6-essentials"
|
|
92
|
+
version = "6.12.0"
|
|
93
|
+
source = { registry = "https://pypi.org/simple" }
|
|
94
|
+
dependencies = [
|
|
95
|
+
{ name = "shiboken6" },
|
|
96
|
+
]
|
|
97
|
+
wheels = [
|
|
98
|
+
{ url = "https://files.pythonhosted.org/packages/e1/90/d528f8dd3f9f20712bc719e10c698d27c998e1dd76ed3f33b6fb606d0972/pyside6_essentials-6.12.0-cp310-abi3-macosx_14_0_universal2.whl", hash = "sha256:0867b709a724db28b161227c7d6ecb5ed10cc09226a53542417ac6dee1308239", size = 116002775, upload-time = "2026-10-08T09:09:54.453Z" },
|
|
99
|
+
{ url = "https://files.pythonhosted.org/packages/7b/3c/7597d8dcb36aa8315427635ec6ec9d850ffbad4ce78b9118ac854889f2d3/pyside6_essentials-6.12.0-cp310-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:16f4b5e41daf49235ae048458243da9efe5f3d8040f9cc5aa454ce69893d3bd9", size = 84346433, upload-time = "2026-10-08T09:10:02.825Z" },
|
|
100
|
+
{ url = "https://files.pythonhosted.org/packages/5e/4e/f4fd4c016719be832ec49d3c87940459e87fd666179a0a199a3998d07916/pyside6_essentials-6.12.0-cp310-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:08c5841063fc1df69b7fa1ee405f539e66576a83fc48004be3e2c5e35ccbfa69", size = 83810102, upload-time = "2026-10-08T09:10:09.13Z" },
|
|
101
|
+
{ url = "https://files.pythonhosted.org/packages/03/61/9a7e32a37b224f68506785bfb0f288d516098ec71681782d72b695a6c95d/pyside6_essentials-6.12.0-cp310-abi3-win_amd64.whl", hash = "sha256:c9a95102aa23c1f86516a30d5a9be37552d324eee7e567eb7508973f1218cb42", size = 82153795, upload-time = "2026-10-08T09:10:15.104Z" },
|
|
102
|
+
{ url = "https://files.pythonhosted.org/packages/92/11/43afb3d0e7c25dd09f0eb7e44f1283dadb5fa8d8b517249fe3fde02e6702/pyside6_essentials-6.12.0-cp310-abi3-win_arm64.whl", hash = "sha256:c76aa689989bf9bb9b45535e0a81c6733294df720b0eed1308fa30d2606b98cc", size = 62073456, upload-time = "2026-10-08T09:10:20.202Z" },
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
[[package]]
|
|
106
|
+
name = "pytest"
|
|
107
|
+
version = "9.1.1"
|
|
108
|
+
source = { registry = "https://pypi.org/simple" }
|
|
109
|
+
dependencies = [
|
|
110
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
111
|
+
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
|
|
112
|
+
{ name = "iniconfig" },
|
|
113
|
+
{ name = "packaging" },
|
|
114
|
+
{ name = "pluggy" },
|
|
115
|
+
{ name = "pygments" },
|
|
116
|
+
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
|
117
|
+
]
|
|
118
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
|
|
119
|
+
wheels = [
|
|
120
|
+
{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
[[package]]
|
|
124
|
+
name = "ruff"
|
|
125
|
+
version = "0.17.2"
|
|
126
|
+
source = { registry = "https://pypi.org/simple" }
|
|
127
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ae/58/690cf56da80c8f2c8bf12042b6017beac2c34fe961f65420bcb3fb7fac38/ruff-0.17.2.tar.gz", hash = "sha256:84d632402d14c23b488f941db23712d6736a013225162062d34558c3f3c780eb", size = 5333400, upload-time = "2026-10-22T18:38:00.181Z" }
|
|
128
|
+
wheels = [
|
|
129
|
+
{ url = "https://files.pythonhosted.org/packages/98/b8/8b6d69c57e8fe1cc6af1aa7493b72a1a5b5a8afe34694e302025441729d4/ruff-0.17.2-py3-none-linux_armv6l.whl", hash = "sha256:96a65e755d8dba094707fb23ab602111d9a31ec2835b3a6992a1914a8fcb211e", size = 10183857, upload-time = "2026-10-22T18:37:14.956Z" },
|
|
130
|
+
{ url = "https://files.pythonhosted.org/packages/e8/61/12cc2ff7b2fa90a268ce1e2162c23aaf76e601d22623f6a31b0eeaa764b0/ruff-0.17.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:39c5b55c960515cdb32be16e69efb5734c589c06a0eb38a22694524a336b889d", size = 10210904, upload-time = "2026-10-22T18:37:17.985Z" },
|
|
131
|
+
{ url = "https://files.pythonhosted.org/packages/e8/7c/b8850a8e4ad29f64a827dd6c6902db4a9aa538fb2b9eef4e26084001a3bb/ruff-0.17.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:92a80d2f44584dabb0189b3a6c393e37e525e04942838482010575cb81945be7", size = 9408439, upload-time = "2026-10-22T18:37:20.964Z" },
|
|
132
|
+
{ url = "https://files.pythonhosted.org/packages/b7/b6/6a64fae86ca5e5e29d5adc311e5481de726cedf9aee607435a16c31c442a/ruff-0.17.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7d0906677d89bbf3cf73cde64b5bbe2ab35df3ae43e49ee2627301e91265bac", size = 10047078, upload-time = "2026-10-22T18:37:23.717Z" },
|
|
133
|
+
{ url = "https://files.pythonhosted.org/packages/10/19/23d376547715175aa1bd46df48df6aacc7c6439d9daf19cac15975180aa5/ruff-0.17.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7cfd783590edf2b77317882631900f6a13ea2e8eacefe6ebf2370d2715299160", size = 9990478, upload-time = "2026-10-22T18:37:26.584Z" },
|
|
134
|
+
{ url = "https://files.pythonhosted.org/packages/93/6c/34cda32cbe13adac5c6b291a307a5570d8ebd37c0c86339f0fe628e55632/ruff-0.17.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122258f6ecde0e0dd1bb60b24263c3edde4338caf723fca711cc729f9bfd414a", size = 10673624, upload-time = "2026-10-22T18:37:29.767Z" },
|
|
135
|
+
{ url = "https://files.pythonhosted.org/packages/bf/10/5d762a4dbc851d8bb47863cf3a28a61bf31c804d393b70d891fac899f5d1/ruff-0.17.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f8fba429d6ac4128ab29cfb8fa6240d2fa671d04adf7f84d3b22fc7b6b6bea4", size = 11351797, upload-time = "2026-10-22T18:37:32.535Z" },
|
|
136
|
+
{ url = "https://files.pythonhosted.org/packages/3f/04/a0e92a81faf5c81c1c98d4374c8401734ccf2b8cca7d0170cb0fec08c6e2/ruff-0.17.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:583bd67bb9e7061dd09bc46a0a884bae2bbd214dbcd48e509813612619683869", size = 10949414, upload-time = "2026-10-22T18:37:35.501Z" },
|
|
137
|
+
{ url = "https://files.pythonhosted.org/packages/c3/d8/59894cf630d2d86882457a2a6a0a1533410c5c805bfbac6f6eb4b5aef69d/ruff-0.17.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c60f93fec7142dba5b8f487f94bf2f6231dae24dc11e4c48648347c8b0720004", size = 10528000, upload-time = "2026-10-22T18:37:37.88Z" },
|
|
138
|
+
{ url = "https://files.pythonhosted.org/packages/ab/95/d6e30c51e851d37e10762ad91fa1e76ddaad998589b5667962a3cfbc9edd/ruff-0.17.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c555a877f8f41447e318101cfefea9bf12dfa9f82eedf90c376e57e069f917d0", size = 10571779, upload-time = "2026-10-22T18:37:40.444Z" },
|
|
139
|
+
{ url = "https://files.pythonhosted.org/packages/f4/5a/a7e1d74fb464250137d3d4eca645d323536533b672004d04ee0e46e0caf3/ruff-0.17.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ba405cbd5ec7bda1f555d5e52be1fd68d02608d4d95d24591bdac92cfacb579f", size = 10051707, upload-time = "2026-10-22T18:37:42.812Z" },
|
|
140
|
+
{ url = "https://files.pythonhosted.org/packages/6e/f2/02fca29ca7999380f0350a7212fe755c11ab9c22d61327356cce8decdbc6/ruff-0.17.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8c21b4ab24485358f17291a4f8dc5399b834e963b8efedd920fe4fdb02081bb4", size = 9998227, upload-time = "2026-10-22T18:37:45.224Z" },
|
|
141
|
+
{ url = "https://files.pythonhosted.org/packages/d1/00/55aa604a093dfdc1526e570fae0bb7d37a2221c7b4728d5f080b2add16ba/ruff-0.17.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5875a16b0de70b43cb81eabea5ae5e8f5d1b2fd1b5e6ed07f80cfe5019d0bd5a", size = 10377692, upload-time = "2026-10-22T18:37:47.704Z" },
|
|
142
|
+
{ url = "https://files.pythonhosted.org/packages/e4/5a/a7a640f47bb906ec8fa233ea84319d503e6dee02b59e3901bd312ebd1f9b/ruff-0.17.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:2d086be452eed686aa51271ecf2cbe5037956517cc6ee39a17b4489ac12f8bbe", size = 10790587, upload-time = "2026-10-22T18:37:50.191Z" },
|
|
143
|
+
{ url = "https://files.pythonhosted.org/packages/2c/d4/c3b74e1b4808438ea7f14bb914478025e2d51261f60774a54a0fa222ec46/ruff-0.17.2-py3-none-win32.whl", hash = "sha256:6bce7d1f5165701ae18f5df85c65afe78cddfa6c5fb4b9bdb0014d60388f3edd", size = 9870537, upload-time = "2026-10-22T18:37:52.486Z" },
|
|
144
|
+
{ url = "https://files.pythonhosted.org/packages/1c/9a/c7da96c2c96d20704cf9027f7a5121da272a8c05f1d1531ba949e3b3df04/ruff-0.17.2-py3-none-win_amd64.whl", hash = "sha256:1b59d447f197bef9ef48a22ba1a6016137753c6099e9bac9c36eb566e422424c", size = 10282826, upload-time = "2026-10-22T18:37:55.2Z" },
|
|
145
|
+
{ url = "https://files.pythonhosted.org/packages/81/60/a3604c79cb02777b6cb84da894104021986f06c4bc41375102cc95049a32/ruff-0.17.2-py3-none-win_arm64.whl", hash = "sha256:195ad918027f817c119310ca89a42d347887dfc28934aaa869325e9c5dc9d962", size = 9827036, upload-time = "2026-10-22T18:37:58.031Z" },
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
[[package]]
|
|
149
|
+
name = "shiboken6"
|
|
150
|
+
version = "6.12.0"
|
|
151
|
+
source = { registry = "https://pypi.org/simple" }
|
|
152
|
+
wheels = [
|
|
153
|
+
{ url = "https://files.pythonhosted.org/packages/b5/45/11536fba5f50a57671eb14441c6098096f3e57074e54c9d7d66039a5831e/shiboken6-6.12.0-cp310-abi3-macosx_14_0_universal2.whl", hash = "sha256:47105e05baf57d35453e07d240bbe59cb4b8d9565377ea5134ff9fb37d4f5c02", size = 479653, upload-time = "2026-10-08T09:10:41.506Z" },
|
|
154
|
+
{ url = "https://files.pythonhosted.org/packages/49/c2/a04fa003b4360e99d8e3fc2829abacf37396ace63ea1cd616402209ec7c6/shiboken6-6.12.0-cp310-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:3bde565bb0890044b5c7f63808adddede5abc241e9395a2bfed61919884d6240", size = 279268, upload-time = "2026-10-08T09:10:42.982Z" },
|
|
155
|
+
{ url = "https://files.pythonhosted.org/packages/97/ca/a4415e6218e0dff764fe2b2d30db2fc8f499a08ace07634232ade3f73adc/shiboken6-6.12.0-cp310-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:ff72a72b3277b418902d562b987b33a6f6818bed9fe40a49d634d09bc67f620e", size = 276562, upload-time = "2026-10-08T09:10:44.25Z" },
|
|
156
|
+
{ url = "https://files.pythonhosted.org/packages/2a/b6/bee97e7a2edeab72aafabb46ee5adc939790a638d107860b4cad7a20e407/shiboken6-6.12.0-cp310-abi3-win_amd64.whl", hash = "sha256:a1906cb8116869178c64b6bab52623bbc8b4ceed7b30bfc3c9aa0f6e67f6438e", size = 1265476, upload-time = "2026-10-08T09:10:45.627Z" },
|
|
157
|
+
{ url = "https://files.pythonhosted.org/packages/8c/d5/5894d35f8a470ca8acff0d1cd8f15b1c94cbfdfe0ce4a6ec0fcf10b95bd1/shiboken6-6.12.0-cp310-abi3-win_arm64.whl", hash = "sha256:da382e68f0815b31b6dc2bce11a465b148c4f42c37b91546a361de1576567d10", size = 1838851, upload-time = "2026-10-08T09:10:47.123Z" },
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
[[package]]
|
|
161
|
+
name = "talos-bar"
|
|
162
|
+
version = "0.0.1"
|
|
163
|
+
source = { editable = "." }
|
|
164
|
+
dependencies = [
|
|
165
|
+
{ name = "pyside6-essentials" },
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
[package.dev-dependencies]
|
|
169
|
+
dev = [
|
|
170
|
+
{ name = "basedpyright" },
|
|
171
|
+
{ name = "pytest" },
|
|
172
|
+
{ name = "ruff" },
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
[package.metadata]
|
|
176
|
+
requires-dist = [{ name = "pyside6-essentials", specifier = ">=6.7" }]
|
|
177
|
+
|
|
178
|
+
[package.metadata.requires-dev]
|
|
179
|
+
dev = [
|
|
180
|
+
{ name = "basedpyright", specifier = ">=1.20" },
|
|
181
|
+
{ name = "pytest", specifier = ">=8" },
|
|
182
|
+
{ name = "ruff", specifier = ">=0.6" },
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
[[package]]
|
|
186
|
+
name = "tomli"
|
|
187
|
+
version = "2.5.0"
|
|
188
|
+
source = { registry = "https://pypi.org/simple" }
|
|
189
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b0/78/9ad63712633ed3ab5cc1a648d863d7e7da371e9425e209555a0fe711b695/tomli-2.5.0.tar.gz", hash = "sha256:264507556cd8b8c8e7c6ee037cdf443a463f03f4c958e57195e3d369711b8ff6", size = 17662, upload-time = "2026-10-07T12:23:37.892Z" }
|
|
190
|
+
wheels = [
|
|
191
|
+
{ url = "https://files.pythonhosted.org/packages/22/a6/ab99b60ee52acd949684febabc3005d0045d0f66bebd9cdebd67372d26dd/tomli-2.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c4dc1c1781f2f716de763d1e9a7b34c6a894e167e291c7c5d16c72f7a9538545", size = 163901, upload-time = "2026-10-07T12:22:15.601Z" },
|
|
192
|
+
{ url = "https://files.pythonhosted.org/packages/bc/00/ee01b7ed4579180fff07142d290257f25ba786f23f3ec6005f620933c2f5/tomli-2.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eff8babca5a7999bc137acbc7482a8b7e17ffca5075ab41f5d770ab408c7bfef", size = 163756, upload-time = "2026-10-07T12:22:16.957Z" },
|
|
193
|
+
{ url = "https://files.pythonhosted.org/packages/72/c2/4efebf65372f6583185f79799312109dddb61102d47e5c33dcfd1a297aca/tomli-2.5.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:86665cee9c4835b7a7f1e8ec2c719b5258d4dc782887aded5a8ae7352a96843b", size = 268038, upload-time = "2026-10-07T12:22:18.135Z" },
|
|
194
|
+
{ url = "https://files.pythonhosted.org/packages/53/07/5850468e925d898abb36038666f9c333a94d2a223e802a8ba5b6d319d23f/tomli-2.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e369fd63331746182360977b1892bfc215476a30d61612d732425311639f56", size = 276422, upload-time = "2026-10-07T12:22:19.567Z" },
|
|
195
|
+
{ url = "https://files.pythonhosted.org/packages/b4/87/f293984cdcf83c054196d4fd3dad44fc68ae55b4b8c44bc76cef360c3150/tomli-2.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ad1ea345759240d6463efa0ed1c704402752e49aa21476620738d74d72d8aa1", size = 272616, upload-time = "2026-10-07T12:22:20.794Z" },
|
|
196
|
+
{ url = "https://files.pythonhosted.org/packages/ce/ce/db582886b3c1219d3fec93ebd669332482e5aee7a91e0f7838d84f2d1759/tomli-2.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:96243987194634bd411066ce40c952e108f86af04db533ecd8ac3ff2a85b1885", size = 276593, upload-time = "2026-10-07T12:22:22.12Z" },
|
|
197
|
+
{ url = "https://files.pythonhosted.org/packages/bf/72/7619b87dea4261fc27dd7b54c4461c129c1f7d9bb7ba3aec89c797a431b8/tomli-2.5.0-cp311-cp311-win32.whl", hash = "sha256:610b27d99f28ec5f191c7064a48f3ddb179a1fe6ca73d571483ae859f57b605e", size = 101830, upload-time = "2026-10-07T12:22:23.651Z" },
|
|
198
|
+
{ url = "https://files.pythonhosted.org/packages/1e/74/220106da34502304b6751a2a9b8a9fbca6c3fd47e737a2e2e3da7c61c9db/tomli-2.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:c804ae44fe7b4bab5da295e4f980a1ff04670bca9d23fe0a4e887e08ebd741a8", size = 112742, upload-time = "2026-10-07T12:22:24.972Z" },
|
|
199
|
+
{ url = "https://files.pythonhosted.org/packages/27/99/7d9c8b41837a7773613e169504147375c157a290167aa59ad74a085f521f/tomli-2.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:cfac177ebd6236003846ea339981f71457cb6eb748f23381eb257e45092e3980", size = 109332, upload-time = "2026-10-07T12:22:26.117Z" },
|
|
200
|
+
{ url = "https://files.pythonhosted.org/packages/52/ed/7baa86f87493646a594de388c7c1c40a39dd0461f7e9c0359cbeefc91fe8/tomli-2.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f4a40d03fb9f63424f0979855bdeaf44dd7696b8d59501822c10ed30ba532df", size = 164854, upload-time = "2026-10-07T12:22:27.444Z" },
|
|
201
|
+
{ url = "https://files.pythonhosted.org/packages/a5/b1/44c0341f2224397855723c7a8a39f718ea6fcbcc3dacc66e5aeca0f334e3/tomli-2.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9ebf8d19b17bd0daeb7b7dec81a946a439b753942fd0210d6e96c532249eea6b", size = 164074, upload-time = "2026-10-07T12:22:28.679Z" },
|
|
202
|
+
{ url = "https://files.pythonhosted.org/packages/23/04/e2d5b7d3fba47adedb23de616c16d428ea076c79a3d8e1d95d649ffe197e/tomli-2.5.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf0b5e8e0f68ebb494356e577c06c139161efd8d3b9050f93b39b7c26cc54ff0", size = 274274, upload-time = "2026-10-07T12:22:29.804Z" },
|
|
203
|
+
{ url = "https://files.pythonhosted.org/packages/43/90/6090e706ff27a6f89f4a40578e3324b95c3cd8c4150868aabf33a8f414c3/tomli-2.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cf74416bdc94ae458b14e37286c1073081850ac8459a00d0c5efef5d44294c6", size = 286435, upload-time = "2026-10-07T12:22:31.297Z" },
|
|
204
|
+
{ url = "https://files.pythonhosted.org/packages/0a/9e/a2c40768df16c408f22430afb0a73e9d7e5f79c950884954649d1146b74d/tomli-2.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:61ea1ebe1e55a34ea8199cc8dbff398d35027b82271c8ac4802fd3a1fd5b1bcc", size = 278119, upload-time = "2026-10-07T12:22:32.601Z" },
|
|
205
|
+
{ url = "https://files.pythonhosted.org/packages/12/25/3c0cb485b98e9cfac495629b1c93c87ccf0b72fbe9d2689fd8fe62c6d5a3/tomli-2.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed53f7e89bb04f6d9e8e7799112360b0c4d5cbff067de0814c98c37c39b920f7", size = 286177, upload-time = "2026-10-07T12:22:33.745Z" },
|
|
206
|
+
{ url = "https://files.pythonhosted.org/packages/77/8b/0144c65f0e37e51c18d04ae15c21b19431c165002d0131fe9aa8b0b8b1e8/tomli-2.5.0-cp312-cp312-win32.whl", hash = "sha256:e7ad033e27a516a233bea839cdb77b80146facb3b4f40bf02cd0cac165cdd5c2", size = 102760, upload-time = "2026-10-07T12:22:34.887Z" },
|
|
207
|
+
{ url = "https://files.pythonhosted.org/packages/de/32/5d6d8f42fc9a05fce69354e00ff256484192f5f2fc9a2165718fa0de61ec/tomli-2.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:bd05de8c1698f8413dd7d869492693a0bf2211543b787ac78cd5e7536af1a6d7", size = 112722, upload-time = "2026-10-07T12:22:36.162Z" },
|
|
208
|
+
{ url = "https://files.pythonhosted.org/packages/30/65/df18032218db0fb9b769fb23c8039a051f15c811993995ea04c350273a32/tomli-2.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:069435bd5480429b98c5e5afb02ab21c219b6f0064680671c6dc0d46817346ea", size = 109534, upload-time = "2026-10-07T12:22:37.296Z" },
|
|
209
|
+
{ url = "https://files.pythonhosted.org/packages/42/e5/51736d70da209350969e15aca5c5ab6e2ce1ea87a0a892a6c13aec172a86/tomli-2.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:943276cf269e0071948d9ff697159c1735e623c1151d88abb09b74659ef0cbea", size = 163328, upload-time = "2026-10-07T12:22:38.373Z" },
|
|
210
|
+
{ url = "https://files.pythonhosted.org/packages/ec/55/086f80dab4ab497602644274e6dea7ec5dd0b4e262e443a8ad3bb7edee2d/tomli-2.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:463b16086865b97facd8d0b3fb4cb7c544e3f58d2a69dc3113d6db9653fdb043", size = 162246, upload-time = "2026-10-07T12:22:39.673Z" },
|
|
211
|
+
{ url = "https://files.pythonhosted.org/packages/aa/eb/3ecc94459f3635c92321f4e7bde571323fdb2267c50e19e3188a281eae3b/tomli-2.5.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1245a6638fc4bb0a60af38a7d45413db34a13842027c77597c712c998c62fdf0", size = 272655, upload-time = "2026-10-07T12:22:41.08Z" },
|
|
212
|
+
{ url = "https://files.pythonhosted.org/packages/c0/d7/494fd1f0c37a621f1ad9975c2efadb523e8101f144ed6edb2e7fe64738f2/tomli-2.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5d8bac3d603c97e6854424e5b2b5b741bdbde387e09f162fb0446812b4a8362b", size = 283595, upload-time = "2026-10-07T12:22:42.222Z" },
|
|
213
|
+
{ url = "https://files.pythonhosted.org/packages/70/51/bb8d62b1317e6640866f6949b2d5855e5300f2c99d46de1cd245570bba65/tomli-2.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:21e4cae4114aba25aa0d4f85cdf486d290fb35c0954d7bba536248da64d43066", size = 276253, upload-time = "2026-10-07T12:22:43.625Z" },
|
|
214
|
+
{ url = "https://files.pythonhosted.org/packages/66/f4/f46bd7f0763cd47de2db697dca9257c6a4adfd1a93b018cc75c8190ed5a8/tomli-2.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bbaefc84548d754be821bba7c4141c4787dda182f9e77f2f87b71213529efa7b", size = 283582, upload-time = "2026-10-07T12:22:44.983Z" },
|
|
215
|
+
{ url = "https://files.pythonhosted.org/packages/ac/03/70f2bcb2923a6db37818d917e124270a7f4cfd38ea576f5aa753a91c0ef5/tomli-2.5.0-cp313-cp313-win32.whl", hash = "sha256:abdbf6313b8d9efe157edeb7ab6eae4de064b1300ad31abf73755154b30abe68", size = 102628, upload-time = "2026-10-07T12:22:46.508Z" },
|
|
216
|
+
{ url = "https://files.pythonhosted.org/packages/dc/98/d52024bb5b0ff68b4f0d276d867f634c84a67319a7e9f6b7708a37742333/tomli-2.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd4dc129784e0c5335bd4e61dfcc4487499a013419e655cf2da1d091b7e0efdc", size = 113301, upload-time = "2026-10-07T12:22:47.647Z" },
|
|
217
|
+
{ url = "https://files.pythonhosted.org/packages/6f/f2/540db3a70572a8c23a28aba3e9c358ce0ffffbafc990905c1343aa265b31/tomli-2.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:69491c143d2fe063046e0301e62a810bed338fa4d1ce0fd870c27dc1e09b0d84", size = 109744, upload-time = "2026-10-07T12:22:48.925Z" },
|
|
218
|
+
{ url = "https://files.pythonhosted.org/packages/e4/49/caf6b307766eb9567664a8707e9d6be5fcc0e8903f18781c6677a60d80c7/tomli-2.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d3182ee2d887e507bd67319a0a61105d1dd33facc111329559a233b772c1a105", size = 162899, upload-time = "2026-10-07T12:22:50.088Z" },
|
|
219
|
+
{ url = "https://files.pythonhosted.org/packages/d3/c8/68cfce773a2733a49c74f99d627fb461bd990756860099eac25617889585/tomli-2.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:521345fd1f19d45b8df87657aaa38b6f2ca3800059fadf428e7ebf479a383646", size = 162080, upload-time = "2026-10-07T12:22:51.558Z" },
|
|
220
|
+
{ url = "https://files.pythonhosted.org/packages/7e/b2/e5bb8651fdad593f670501a7d718b1a7f73f064d44dea15e04c04dfef45d/tomli-2.5.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e95c7614e705bfe2b04b27aa124adec59752d15813df37e2156747cab3a006b", size = 273380, upload-time = "2026-10-07T12:22:52.918Z" },
|
|
221
|
+
{ url = "https://files.pythonhosted.org/packages/8d/d2/9e2d7f8b1dfe0e2b34c245986ebd55c4c553ea4ce6c47c443b332673253f/tomli-2.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ac2027d37c3afbdf4bdd377f2676f6f1d2122a5be1f1137b49dced590b37e75", size = 283228, upload-time = "2026-10-07T12:22:54.173Z" },
|
|
222
|
+
{ url = "https://files.pythonhosted.org/packages/ba/df/ec7b876b7b1a2718bd74a3743c076fff565b04029ba33e8f61fac262739f/tomli-2.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c414be4ed9d3cac80c42e348fa5a956117d1a48227f48026e31f59cb4a7671eb", size = 277189, upload-time = "2026-10-07T12:22:55.342Z" },
|
|
223
|
+
{ url = "https://files.pythonhosted.org/packages/7d/7b/e192d9eed0b9cb80da799f4d77052297fb9a2c3cc9b19f571f56ea88add6/tomli-2.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9b03d7dc168353b4132965bde20feceabaa470e570c6f59660dfae59b1f9eeb3", size = 283632, upload-time = "2026-10-07T12:22:56.735Z" },
|
|
224
|
+
{ url = "https://files.pythonhosted.org/packages/84/50/ff94454e75461d75623e47401ed323d65c10aab8fe9033242c20cd2fdf32/tomli-2.5.0-cp314-cp314-win32.whl", hash = "sha256:6f041843c4d3a37245c0c056fd955b186bf8b1fb85690cbe40b81230891dc34b", size = 103535, upload-time = "2026-10-07T12:22:58.084Z" },
|
|
225
|
+
{ url = "https://files.pythonhosted.org/packages/54/0b/bdacf05f963bd6026ebf6eeb0beda847d1d60e03e440725c64a4e08a0afd/tomli-2.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:f4b653094e18f9031102d3a1da5c729c8f222d85225b18037dac621695e46e1a", size = 114621, upload-time = "2026-10-07T12:22:59.2Z" },
|
|
226
|
+
{ url = "https://files.pythonhosted.org/packages/61/99/53f438fa6ae4f9d4ed0ddde3e7242b3bdc34b48c8f9948b72b9e9b127676/tomli-2.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:3f89d10c1ff6a38d992c27fc8a4816af71a909e08a40ec66934240b1e74347c3", size = 111572, upload-time = "2026-10-07T12:23:00.479Z" },
|
|
227
|
+
{ url = "https://files.pythonhosted.org/packages/b9/20/1f88f19427d380a40e90a770e087489eaafe4aeee070ae88ed2bbec00acd/tomli-2.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:e9e15b4a6c7dd6b85b5fbab29488a73f1f70de516942308daa266bf0e0aeb0d4", size = 171814, upload-time = "2026-10-07T12:23:01.914Z" },
|
|
228
|
+
{ url = "https://files.pythonhosted.org/packages/d0/56/cbe5079c9f9a54b9b3e27fc82f08f3cb36edee75561679f53d2380c801d6/tomli-2.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e12bbcd32897272fb05929110362ae9ff4c1b9bb26bd9e971e71dcd3275b4c3d", size = 171324, upload-time = "2026-10-07T12:23:03.18Z" },
|
|
229
|
+
{ url = "https://files.pythonhosted.org/packages/2b/30/1d53fd3b0f1cb3ba542e345ec32c26aefdddc4e829e4f3429af8a4f27782/tomli-2.5.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20aa36de8f2cf87237143bc1fa1aae8d6612c09118f4da21c6a684db5dd1f6f9", size = 297441, upload-time = "2026-10-07T12:23:04.345Z" },
|
|
230
|
+
{ url = "https://files.pythonhosted.org/packages/66/d9/0800acb6a111686f764c1b91ef15cc42a20a66a46013bb42220f1d2c61c1/tomli-2.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22185fad8a1e622f064e78008018a0dd3323550dcb479cb7a1d296888d74024f", size = 307476, upload-time = "2026-10-07T12:23:05.671Z" },
|
|
231
|
+
{ url = "https://files.pythonhosted.org/packages/e8/63/30a8f3cd51b5bec37f04744bad0b0dc6160df84aad4f27b0e9283d66f221/tomli-2.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:984012f71908165449a951de2050d52f276bfe3aa5d5f570f63ddad814370374", size = 296113, upload-time = "2026-10-07T12:23:07.202Z" },
|
|
232
|
+
{ url = "https://files.pythonhosted.org/packages/ab/18/0b9ffc597e69c5a1e20a7823cb60d54b39a9f54e91edcb8574f022186758/tomli-2.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f79203b3965b4000e91808aaa7c040206093f2b8bf86f455982f2274c9ccf442", size = 307725, upload-time = "2026-10-07T12:23:08.508Z" },
|
|
233
|
+
{ url = "https://files.pythonhosted.org/packages/ab/c7/18f8baae0b5607a60e8e19b4a7fedee43a8ff6458e3896dcbbadeeac9c22/tomli-2.5.0-cp314-cp314t-win32.whl", hash = "sha256:91294a9fb94a75542f6e46e4a2ae709bd8d9b51134098cae5cf3bea5478b6d03", size = 108546, upload-time = "2026-10-07T12:23:09.956Z" },
|
|
234
|
+
{ url = "https://files.pythonhosted.org/packages/72/34/4cca9739254130627bde87500b3f2b512154fe2f278efa7e2a5e10ad4bcb/tomli-2.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f15e3e0b835a6d68b10c86bf80a3149780498d6911c93c3ffd1861d19f9200f1", size = 117814, upload-time = "2026-10-07T12:23:11.486Z" },
|
|
235
|
+
{ url = "https://files.pythonhosted.org/packages/7d/fb/afa530d47dd80a78fce43beac6bc6e00f84558eafcffbc6f37b21e80d056/tomli-2.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:6664b7ae7af7294256c53960a6103077f4914cec8ff98479c352f622c6f6b2f0", size = 115188, upload-time = "2026-10-07T12:23:12.728Z" },
|
|
236
|
+
{ url = "https://files.pythonhosted.org/packages/66/98/316fdc00f8c0939e6fe50461dd343c162d3ad51d1286eb25b7db54361d50/tomli-2.5.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:a525685c2f97da40762b8695eb7aa0af4c8344ca1905c73e4e29cb04d34607dc", size = 162775, upload-time = "2026-10-07T12:23:13.941Z" },
|
|
237
|
+
{ url = "https://files.pythonhosted.org/packages/c5/22/7b10fa5bb01c9539f53f69b619361b19350acc73657772ea7ac70ba309a8/tomli-2.5.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:9dbb18c1cfb2f6517942fc9314437f66aa06d94436ffb1f06102ef3572f35276", size = 161406, upload-time = "2026-10-07T12:23:15.215Z" },
|
|
238
|
+
{ url = "https://files.pythonhosted.org/packages/9c/e7/1a069d86dfd20f1f84f71c63faed9f83c1d890bc06c27d82dc7d888fb573/tomli-2.5.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:752e8b1aa6a4367ef8bf6a1a1e005540f7ed055ba36d7193796812ca5404eb52", size = 273855, upload-time = "2026-10-07T12:23:16.471Z" },
|
|
239
|
+
{ url = "https://files.pythonhosted.org/packages/ae/83/d1ef43d1687d092ab9c235455c76e6e709483b346b056f086095c7c263a5/tomli-2.5.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c47300f9bf791808f77d82747691c4bb09cb14bdf3060cca99b42cdc4361d5a7", size = 284910, upload-time = "2026-10-07T12:23:18.166Z" },
|
|
240
|
+
{ url = "https://files.pythonhosted.org/packages/cc/05/f4d9cf7de61822ece0c3873f30d291e324911c71a378b8bfe5ced13fd9f5/tomli-2.5.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:19b0dd8749f4ea2f112c5fcfb3c5248390c899d7e2e173f1d91abee1fa0ff391", size = 277723, upload-time = "2026-10-07T12:23:19.355Z" },
|
|
241
|
+
{ url = "https://files.pythonhosted.org/packages/42/28/78262493141fa543151cf005760c3cb01d09fc28a11f993c05109902cb8c/tomli-2.5.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:57b1c3b01fab802e2899bc3d168dca320e14165e2fd9fd584760fb4ca5826859", size = 285115, upload-time = "2026-10-07T12:23:20.698Z" },
|
|
242
|
+
{ url = "https://files.pythonhosted.org/packages/1a/b9/e1dab9a30bcb677b5cc5cee810609cfd64f24306a3055767dd3fda00b1e0/tomli-2.5.0-cp315-cp315-win32.whl", hash = "sha256:667e521b37a6c5ccaa044202c235b530f90177ffe2cd4a64ecc213c7dd535feb", size = 103475, upload-time = "2026-10-07T12:23:21.941Z" },
|
|
243
|
+
{ url = "https://files.pythonhosted.org/packages/4c/bd/31a3790c11d6ea95fcf5e6022ac0f8d0543c9b61120b730fc481bd43d3b4/tomli-2.5.0-cp315-cp315-win_amd64.whl", hash = "sha256:d747252933c8a65ef6bd8da0fbb7ce28a90eb6119d8cd00772cd528aa07b68d5", size = 114589, upload-time = "2026-10-07T12:23:23.098Z" },
|
|
244
|
+
{ url = "https://files.pythonhosted.org/packages/47/a2/4f6310fa699364f0e3af7ee3af88dddd9af066d33e716a0265bbe2b3ea84/tomli-2.5.0-cp315-cp315-win_arm64.whl", hash = "sha256:75dbcde8751b0a960aa3de173aa5e894d590755c6d7758b7e774c06f1dc3cbdd", size = 111493, upload-time = "2026-10-07T12:23:24.233Z" },
|
|
245
|
+
{ url = "https://files.pythonhosted.org/packages/68/14/00853f0b396d8971107ae1921bb5b322fdee1650d2f16bf06c20adb532e5/tomli-2.5.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:2419c2a189551987b59d80e63ec355671283336f41c6b9b89462df679c7d0c57", size = 171380, upload-time = "2026-10-07T12:23:25.512Z" },
|
|
246
|
+
{ url = "https://files.pythonhosted.org/packages/89/ad/fa6949321dadee46b27363974fb197b94c911c3b0f7a5fd26d7dc18fc2a0/tomli-2.5.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:0dc598040da8d42cf20f0be588ed7004f46db12a0ac6c32e03a59dccedaaadcd", size = 170553, upload-time = "2026-10-07T12:23:26.855Z" },
|
|
247
|
+
{ url = "https://files.pythonhosted.org/packages/53/aa/3056c919eb3e084df3752b2cf5f865dcc04af0b27dba2f66d7b28af4633a/tomli-2.5.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49096930c8d886c9bbdab62d2d0d17ce823ddeea522309a190b36245d5b49e01", size = 294428, upload-time = "2026-10-07T12:23:28.132Z" },
|
|
248
|
+
{ url = "https://files.pythonhosted.org/packages/96/b2/faeeb5d8769ea3832021d73e892c8391eae7b4b4f8b55a789127bd8b18a9/tomli-2.5.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8ade5023067f99fe72b88accd30d0ea05a158e9e32a11f124e731ea9695313f", size = 304909, upload-time = "2026-10-07T12:23:29.381Z" },
|
|
249
|
+
{ url = "https://files.pythonhosted.org/packages/f6/52/f094c09e73fb654b621716d019acb5d29bdfd1be01df80c281d552bda48d/tomli-2.5.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b69564772b5c8f22ea5f498dff08cfa825045b4d4c4400529000bdf818aa3b2a", size = 293220, upload-time = "2026-10-07T12:23:30.608Z" },
|
|
250
|
+
{ url = "https://files.pythonhosted.org/packages/86/f5/0c30541078ca4b505ce3bd76ed931facbfec524dd018535d691d1af0a6d2/tomli-2.5.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:8ff3a2ca028c7eee0c777f9a092038d0a594a9fa04e215f929a22c329e2cb142", size = 305705, upload-time = "2026-10-07T12:23:32.181Z" },
|
|
251
|
+
{ url = "https://files.pythonhosted.org/packages/05/74/590e7d19d6a118fc5cc5704ff358e21d95b8573f6b9443b1519f29ca8825/tomli-2.5.0-cp315-cp315t-win32.whl", hash = "sha256:62fc1bc8eb03e3a9cadfca713d65614ed8e09d974a283295ffe3a831976b4dc5", size = 108432, upload-time = "2026-10-07T12:23:33.496Z" },
|
|
252
|
+
{ url = "https://files.pythonhosted.org/packages/1c/b8/63a75cfb27a17c38550e44025d3a6e7be64516fd8608a3b75703bf37d81b/tomli-2.5.0-cp315-cp315t-win_amd64.whl", hash = "sha256:f3fcbc57b1791fa6cbe5d8434179d51de12be1a4811469529f47f6e7487a2571", size = 117281, upload-time = "2026-10-07T12:23:34.648Z" },
|
|
253
|
+
{ url = "https://files.pythonhosted.org/packages/72/01/e8c1debb2173973372934c68fc8e46170ab60ef23ed4592dff4dec6e8993/tomli-2.5.0-cp315-cp315t-win_arm64.whl", hash = "sha256:d2ba24db8a9376921b5e87b4762b9adb0f3f1deaea68f2b8b0bb2c11efb9c3e7", size = 115069, upload-time = "2026-10-07T12:23:35.77Z" },
|
|
254
|
+
{ url = "https://files.pythonhosted.org/packages/60/3f/3e3f8fd0919249b0200c80fbc4f9a1e70be19f9883da71dfb7f8b9ab8aca/tomli-2.5.0-py3-none-any.whl", hash = "sha256:32a7b79ac57a2e83670ce329ccf675798bc5a2094783a63676866b70503f2e2b", size = 14765, upload-time = "2026-10-07T12:23:36.875Z" },
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
[[package]]
|
|
258
|
+
name = "typing-extensions"
|
|
259
|
+
version = "4.16.0"
|
|
260
|
+
source = { registry = "https://pypi.org/simple" }
|
|
261
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
|
|
262
|
+
wheels = [
|
|
263
|
+
{ url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
|
|
264
|
+
]
|