70 Commits
main ... main

Author SHA1 Message Date
593db00166 fix(themes): typo in GAME_CARD_ANIMATION
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-17 14:39:21 +05:00
79a78c785b chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-17 14:26:19 +05:00
0b92d058a9 feat: move GameCard animation properties to styles
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-17 14:24:06 +05:00
9df22edfc9 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-16 22:36:56 +05:00
4559231712 fix: prevent multiple GameCard highlight animations on rapid mouse movement
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-16 22:34:06 +05:00
18dbd42369 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-16 17:14:22 +05:00
76c0e607c5 fedora 40 is EOL
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-16 17:11:52 +05:00
a91c9dacd8 fix(build): fedora dependency
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-16 17:10:18 +05:00
62b8da2dc4 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 22:53:23 +05:00
b77609cb5f fix: resolve Pyright type errors
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 22:51:50 +05:00
56b105d7b4 fix: completly exit on app close
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 22:33:33 +05:00
14687d12ca feat(ci): extract downloaded artifacts
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 22:14:01 +05:00
6a648a2a8d fix(ci): install original-awk
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 18:33:41 +05:00
c0b2006338 fix(ci): release body generate
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 18:13:39 +05:00
2c2fc082a7 fix(ci): use download-artifact@v3
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 17:51:44 +05:00
66e1871304 chore: bump ver
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 17:17:50 +05:00
6daa28b393 chore(readme): update todo
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 16:54:36 +05:00
a3445898e5 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 16:49:59 +05:00
076d06a9c0 fix(input-manager): remap add_game to X for avoid conflicts with PS
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 16:44:26 +05:00
d85e7f058f fix(input-manager): restore gamepad rumble on game launch by delaying disable_gamepad_handling
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 16:39:32 +05:00
dd05ef8a1f feat: close QMessageBox using confirm key on gamepad
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 16:35:48 +05:00
326b2d7411 chore: update steam apps list 2025-06-15T10:52:34Z 2025-06-15 10:52:34 +00:00
d280cf2531 feat(dev-scripts): parse all ppdb topics from our forum
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 15:48:16 +05:00
3cc40154b0 fix: disable gamepad handling on game start thanks to @Vector_null
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 14:00:06 +05:00
f765b5e840 fix: restore else block in ClickableLabel paintEvent to render text without icon
Restore the `else` block in `paintEvent` of `ClickableLabel` to set `text_rect` when no icon is present. This fixes a regression where `favoriteLabel` in `GameCard` was invisible but clickable, as text (`★` or `☆`) was not rendered without a pixmap.

Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-15 00:52:18 +05:00
c54c3273a0 chore(readme): update todo
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 14:18:14 +05:00
502b5b5256 feat: change badge position and size on slider change
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 14:17:11 +05:00
0b45ba963a chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 11:51:04 +05:00
7becbf5de2 feat(input_manager): added change slider size to RT and LT
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 11:49:28 +05:00
66b4b82d49 feat: change game card size only on slider released
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 11:14:22 +05:00
dbf3a30119 chore(localization): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 10:38:31 +05:00
4c2e2a9c8d feat: drop title translate from FramelessWindow
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 10:35:46 +05:00
802d5a2ba1 chore(metainfo): sync screenshots with standart theme
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 00:07:42 +05:00
1d47caf4aa chore(readme): update todo
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 00:01:21 +05:00
502664438c chore: update screenshots in standart theme
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-14 00:00:02 +05:00
f4e155dade chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-13 23:49:25 +05:00
74400d1389 feat: align keyboard arrow key navigation with D-pad logic
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-13 23:34:11 +05:00
2a46cf7a2f feat: no longer lock the full screen button when automatic full screen mode is enabled
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-13 19:31:35 +05:00
f105af01ef fix: resolve Pyright type errors in SystemOverlay class
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-13 17:43:49 +05:00
e9ecb466b2 combobox styles for hover & focus 2025-06-13 18:09:06 +07:00
2ce41697ef changed context_menu_style 2025-06-13 17:50:36 +07:00
997e66afa6 system_overlay now borderless thanks to @Vector_null 2025-06-13 17:36:27 +07:00
bad91fed4e dialogs.py add input styles 2025-06-13 11:44:20 +07:00
a1bdff73fe getAntiCheatIconFilename expand the list of status 2025-06-13 11:21:57 +07:00
0c7cb0092b change getAntiCheatIconFilename 2025-06-13 11:11:32 +07:00
120f2a5590 change color of icons for areweanticheat 2025-06-13 11:04:17 +07:00
fbe8d87b3d system_overlay change from QPushButton to AutoSizeButton 2025-06-13 10:56:39 +07:00
568120fb0e add icons for system_overlay 2025-06-13 10:55:01 +07:00
bff5e456cf change ACTION_BUTTON_STYLE style 2025-06-13 09:30:43 +07:00
de3b95d06c merge upstream 2025-06-12 09:52:06 +00:00
db95120b87 change addgame, play, find_games hover color 2025-06-12 16:50:45 +07:00
337db17467 add areweanticheat status icons 2025-06-12 16:41:43 +07:00
dbf1340f88 feat: added colors to AreWeAntiCheatYet badges
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-12 14:37:03 +05:00
09066521e8 add epic games & gog icons 2025-06-12 16:25:39 +07:00
186ee048f7 add background color to NAV_WIDGET_STYLE 2025-06-12 15:58:03 +07:00
79e2ad1997 change nav buttons focus color 2025-06-12 15:50:24 +07:00
a4a3271df9 fix hardlink to checkbox icon 2025-06-12 15:44:56 +07:00
213709e88b add login icon 2025-06-12 15:37:45 +07:00
9f86eae5ef fix focus styles for buttons, text fields & checkbox 2025-06-12 15:13:46 +07:00
748f9c886b add checkboxes styles 2025-06-12 14:33:37 +07:00
84708ed260 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 23:19:31 +05:00
9fe5a8315a chore(localization): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 23:17:35 +05:00
c1b8eac127 feat: add gamepad haptic feedback setting
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 23:11:38 +05:00
953e4fa715 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 19:11:56 +05:00
24ca66a1af chore(readme): update todo
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 19:09:56 +05:00
30a4fc6ed7 feat(input-manager): add haptic feedback for game launch with gamepad
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 19:08:58 +05:00
2d7369d46c chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 18:28:27 +05:00
0587cf58ed feat(input_manager): open system overlay by Insert button
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 18:20:48 +05:00
58c7541fa3 feat(input_manager): rework gamepad buttons maping
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 18:16:08 +05:00
b9d7fc2326 feat(input_manager): add dualshock 4 and dualsence mapping
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-06-11 17:53:08 +05:00
60 changed files with 8893 additions and 1401 deletions

View File

@ -40,7 +40,7 @@ jobs:
strategy: strategy:
matrix: matrix:
fedora_version: [40, 41, 42, rawhide] fedora_version: [41, 42, rawhide]
container: container:
image: fedora:${{ matrix.fedora_version }} image: fedora:${{ matrix.fedora_version }}

View File

@ -8,7 +8,7 @@ on:
env: env:
# Common version, will be used for tagging the release # Common version, will be used for tagging the release
VERSION: v0.1.1 VERSION: 0.1.2
PKGDEST: "/tmp/portprotonqt" PKGDEST: "/tmp/portprotonqt"
PACKAGE: "portprotonqt" PACKAGE: "portprotonqt"
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
@ -97,7 +97,7 @@ jobs:
strategy: strategy:
matrix: matrix:
fedora_version: [40, 41, 42, rawhide] fedora_version: [41, 42, rawhide]
container: container:
image: fedora:${{ matrix.fedora_version }} image: fedora:${{ matrix.fedora_version }}
@ -140,16 +140,29 @@ jobs:
needs: [build-appimage, build-arch, build-fedora] needs: [build-appimage, build-arch, build-fedora]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: https://gitea.com/actions/checkout@v4
- name: Install required dependencies
run: |
sudo apt update
sudo apt install -y original-awk unzip
- name: Download all artifacts - name: Download all artifacts
uses: https://gitea.com/actions/download-artifact@v4 uses: https://gitea.com/actions/download-artifact@v3
with: with:
path: release/ path: release/
- name: Extract downloaded artifacts
run: |
mkdir -p extracted
find release/ -name '*.zip' -exec unzip -o {} -d extracted/ \;
find extracted/ -type f -exec mv {} release/ \;
rm -rf extracted/
- name: Extract changelog for version - name: Extract changelog for version
id: changelog id: changelog
run: | run: |
VERSION="${{ env.VERSION }}" VERSION="${{ env.VERSION }}"
VERSION=${VERSION#v} # Remove 'v' prefix if present
awk "/^## \\[$VERSION\\]/ {flag=1; next} /^## \\[/ || /^---/ {flag=0} flag" CHANGELOG.md > changelog.txt awk "/^## \\[$VERSION\\]/ {flag=1; next} /^## \\[/ || /^---/ {flag=0} flag" CHANGELOG.md > changelog.txt
- name: Release - name: Release
@ -157,7 +170,7 @@ jobs:
with: with:
body_path: changelog.txt body_path: changelog.txt
token: ${{ env.GITEA_TOKEN }} token: ${{ env.GITEA_TOKEN }}
tag_name: ${{ env.VERSION }} tag_name: v${{ env.VERSION }}
prerelease: true prerelease: true
files: release/**/* files: release/**/*
sha256sum: true sha256sum: true

View File

@ -30,6 +30,8 @@ jobs:
run: python dev-scripts/get_id.py run: python dev-scripts/get_id.py
env: env:
STEAM_KEY: ${{ secrets.STEAM_KEY }} STEAM_KEY: ${{ secrets.STEAM_KEY }}
LINUX_GAMING_API_KEY: ${{ secrets.LINUX_GAMING_API_KEY }}
LINUX_GAMING_API_USERNAME: ${{ secrets.LINUX_GAMING_API_USERNAME }}
- name: Commit and push changes - name: Commit and push changes
env: env:

View File

@ -5,27 +5,42 @@
## [Unreleased] ## [Unreleased]
### Added
### Changed
- Удалены сборки для Fedora 40
- Перенесены параметры анимации GameCard в `styles.py` с подробной документацией для поддержки кастомизации тем.
### Fixed
- Дублирование обводки выделения карточек при быстром перемешении мыши
---
## [0.1.2] - 2025-06-15
### Added ### Added
- Кнопки сброса настроек и очистки кэша - Кнопки сброса настроек и очистки кэша
- Бейдж PortProton - Бейдж PortProton
- Зависимость от `xdg-utils` - Зависимость от `xdg-utils`
- Интеграция статуса WeAntiCheatYet в карточку - Интеграция статуса WeAntiCheatYet в карточку
- Стили в AddGameDialog
- Переключение полноэкранного режима через F11 или кнопку Select на геймпаде - Переключение полноэкранного режима через F11 или кнопку Select на геймпаде
- Выбор QCheckBox через Enter или кнопку A на геймпаде - Выбор состояния `QCheckBox` через Enter или кнопку A на геймпаде
- Закрытие диалога добавления игры через ESC или кнопку B на геймпаде - Закрытие диалога добавления игры через ESC или кнопку B на геймпаде
- Закрытие окна приложения по комбинации клавиш Ctrl+Q - Закрытие окна приложения по комбинации клавиш Ctrl+Q
- Сохранение и восстановление размера окна при перезапуске - Сохранение и восстановление размера окна при перезапуске
- Переключатель полноэкранного режима приложения - Переключатель полноэкранного режима приложения
- Пункт в контекстном меню «Открыть папку игры» - Пункт в контекстном меню «Открыть папку игры»
- Пункты в контекстном меню «Добавить в Steam» и «Удалить из Steam» - Пункты в контекстном меню «Добавить в Steam» и «Удалить из Steam»
- Пункты в контекстном меню «Добавить в Избранное» и «Удалить из Избранного» для переключения статуса избранного через геймпад - Пункты в контекстном меню «Добавить в Избранное» и «Удалить из Избранного»
- Метод сортировки «Сначала избранное» - Метод сортировки «Сначала избранное»
- Настройка автоматического перехода в полноэкранный режим при подключении геймпада (по умолчанию отключена) - Настройка автоматического перехода в полноэкранный режим при подключении геймпада (по умолчанию отключена)
- Обработчики для QMenu и QComboBox при управлении геймпадом - Поддержка управления геймпадом в `QMenu` и `QComboBox`
- Аргумент `--fullscreen` для запуска приложения в полноэкранном режиме - Аргумент `--fullscreen` для запуска приложения в полноэкранном режиме
- Оверлей на кнопку Xbox/PS для закрытия приложения, выключения, перезагрузки и перехода в спящий режим - Оверлей на кнопку Insert или кнопку Xbox/PS на геймпаде для закрытия приложения, выключения, перезагрузки и перехода в спящий режим или переключения между сессиями
- [Gamescope сессия](https://git.linux-gaming.ru/Boria138/gamescope-session-portprotonqt) - [Gamescope сессия](https://git.linux-gaming.ru/Boria138/gamescope-session-portprotonqt)
- Пресеты управления для DualShock 4 и DualSense
- Настройка тактильной отдачи на геймпаде при запуске игры (по умолчанию выключена)
- Переводы пунктов настроек
### Changed ### Changed
- Обновлены все иконки - Обновлены все иконки
@ -34,29 +49,33 @@
- Логика контекстного меню вынесена в `ContextMenuManager` - Логика контекстного меню вынесена в `ContextMenuManager`
- Бейдж Steam теперь открывает Steam Community - Бейдж Steam теперь открывает Steam Community
- Изменена лицензия с MIT на GPL-3.0 для совместимости с кодом от legendary - Изменена лицензия с MIT на GPL-3.0 для совместимости с кодом от legendary
- Оптимизирована генерация карточек для предотвращения задержек при поиске и изменении размера окна - Оптимизирована генерация карточек для плавной работы при поиске и изменении размера окна
- Бейджи с карточек теперь отображаются также на странице с деталями, а не только в библиотеке - Бейджи с карточек теперь отображаются также на странице с деталями, а не только в библиотеке
- Установлена ширина бейджа в две трети ширины карточки - Установлена ширина бейджа в две трети ширины карточки
- Бейджи источников (`Steam`, `EGS`, `PortProton`) теперь отображаются только при активном фильтре `all` или `favorites` - Бейджи источников (`Steam`, `EGS`, `PortProton`) теперь отображаются только при активном фильтре `all` или `favorites`
- Карточки теперь фокусируются в направлении движения стрелок или D-pad: например, при нажатии D-pad вниз фокус переходит на карточку в следующей колонке, а не по порядку - Карточки теперь фокусируются в направлении движения стрелок или D-pad:
- Теперь D-pad можно зажимать для переключения карточек - Поддерживается удержание D-pad для непрерывного переключения карточек
- D-pad больше не переключает вкладки, только RB и LB - Объединён обработчик управления стрелками клавиатуры и D-pad для консистентности
- D-pad больше не переключает вкладки (только кнопки RB/LB)
- Кнопка добавления игры больше не фокусируется - Кнопка добавления игры больше не фокусируется
- Диалог добавления игры теперь открывается только в библиотеке - Диалог добавления игры теперь открывается только в библиотеке
- Удалены все упоминания PortProtonQT из кода и заменены на PortProtonQt - Удалены все упоминания PortProtonQT из кода и заменены на PortProtonQt
- Размер карточек теперь меняется только при отпускании слайдера
- Слайдер теперь управляется через тригеры на геймпаде
- Диалог добавления игры теперь открывается на X, а не на Y
### Fixed ### Fixed
- Обработка несуществующей темы с возвратом к «standard» - Возврат к теме «standard» при выборе несуществующей темы
- Открытие контекстного меню - Корректное открытие контекстного меню
- Запуск при отсутствии exiftool - Запуск приложения при отсутствии `exiftool`
- Переводы пунктов настроек - Предотвращено бесконечное обращение к `get_portproton_location`
- Бесконечное обращение к `get_portproton_location` - Обновлены ссылки на документацию в README
- Ссылки на документацию в README - Устранён traceback при отсутствии обложек (placeholder)
- Traceback при загрузке placeholder при отсутствии обложек - Устранены утечки памяти при загрузке обложек
- Утечки памяти при загрузке обложек - Исправлены ошибки при подключении геймпада
- Ошибки при подключении геймпада из-за работы в разных потоках - Предотвращено многократное открытие диалога добавления игры через геймпад
- Многократное открытие диалога добавления игры при использовании геймпада - Корректная обработка событий геймпада во время игры
- Перехват событий геймпада во время работы игры - Убийсво всех процессов "зомби" при закрытии программы
--- ---

View File

@ -62,10 +62,12 @@
- [ ] Добавить поддержку GOG (?) - [ ] Добавить поддержку GOG (?)
- [X] Определиться с названием (PortProtonQt или PortProtonQT или вообще третий вариант) - [X] Определиться с названием (PortProtonQt или PortProtonQT или вообще третий вариант)
- [ ] Добавить данные с HowLongToBeat на страницу с деталями игры (?) - [ ] Добавить данные с HowLongToBeat на страницу с деталями игры (?)
- [ ] Добавить виброотдачу на геймпаде при запуске игры (?) - [X] Добавить виброотдачу на геймпаде при запуске игры
- [ ] Исправить некорректную работу слайдера увеличения размера карточек([Последствия регрессии после этого коммита](https://github.com/Boria138/PortProtonQt/commit/aebdd60b5537280f06a922ff80469cd4ab27bc63) - [X] Исправить некорректную работу слайдера увеличения размера карточек([Последствия регрессии после этого коммита](https://github.com/Boria138/PortProtonQt/commit/aebdd60b5537280f06a922ff80469cd4ab27bc63)
- [X] Исправить баг с наложением карточек друг на друга при изменении фильтра отображения ([Последствия регрессии после этого коммита](https://github.com/Boria138/PortProtonQt/commit/aebdd60b5537280f06a922ff80469cd4ab27bc63)) - [X] Исправить баг с наложением карточек друг на друга при изменении фильтра отображения ([Последствия регрессии после этого коммита](https://github.com/Boria138/PortProtonQt/commit/aebdd60b5537280f06a922ff80469cd4ab27bc63))
- [ ] Скопировать логику управления с D-pad на стрелки с клавиатуры - [X] Скопировать логику управления с D-pad на стрелки с клавиатуры
- [ ] Доделать светлую тему
- [ ] Добавить подсказки к управлению с геймпада
### Установка (devel) ### Установка (devel)
@ -109,6 +111,5 @@ pre-commit run --all-files
> [!WARNING] > [!WARNING]
> Проект находится на стадии WIP (work in progress) корректная работоспособность не гарантирована > Проект находится на стадии WIP (work in progress) корректная работоспособность не гарантирована
> [!WARNING] > [!WARNING]
> **Будьте осторожны!** Если вы берёте тему не из официального репозитория или надёжного источника, убедитесь, что в её файле `styles.py` нет вредоносного или нежелательного кода. Поскольку `styles.py` — это обычный Python-файл, он может содержать любые инструкции. Всегда проверяйте содержимое чужих тем перед использованием. > **Будьте осторожны!** Если вы берёте тему не из официального репозитория или надёжного источника, убедитесь, что в её файле `styles.py` нет вредоносного или нежелательного кода. Поскольку `styles.py` — это обычный Python-файл, он может содержать любые инструкции. Всегда проверяйте содержимое чужих тем перед использованием.

View File

@ -25,7 +25,7 @@ AppDir:
id: ru.linux_gaming.PortProtonQt id: ru.linux_gaming.PortProtonQt
name: PortProtonQt name: PortProtonQt
icon: ru.linux_gaming.PortProtonQt icon: ru.linux_gaming.PortProtonQt
version: 0.1.1 version: 0.1.2
exec: usr/bin/python3 exec: usr/bin/python3
exec_args: "-m portprotonqt.app $@" exec_args: "-m portprotonqt.app $@"

View File

@ -1,5 +1,5 @@
pkgname=portprotonqt pkgname=portprotonqt
pkgver=0.1.1 pkgver=0.1.2
pkgrel=1 pkgrel=1
pkgdesc="Modern GUI for managing and launching games from PortProton, Steam, and Epic Games Store" pkgdesc="Modern GUI for managing and launching games from PortProton, Steam, and Epic Games Store"
arch=('any') arch=('any')

View File

@ -28,19 +28,19 @@ BuildRequires: git
%package -n python3-%{pypi_name}-git %package -n python3-%{pypi_name}-git
Summary: %{summary} Summary: %{summary}
%{?python_provide:%python_provide python3-%{pypi_name}} %{?python_provide:%python_provide python3-%{pypi_name}}
Requires: python3dist(babel) Requires: python3-babel
Requires: python3dist(evdev) Requires: python3-evdev
Requires: python3dist(icoextract) Requires: python3-icoextract
Requires: python3dist(numpy) Requires: python3-numpy
Requires: python3dist(orjson) Requires: python3-orjson
Requires: python3dist(psutil) Requires: python3-psutil
Requires: python3dist(pyside6) Requires: python3-pyside6
Requires: python3dist(pyudev) Requires: python3-pyudev
Requires: python3dist(requests) Requires: python3-requests
Requires: python3dist(tqdm) Requires: python3-tqdm
Requires: python3dist(vdf) Requires: python3-vdf
Requires: python3dist(pefile) Requires: python3-pefile
Requires: python3dist(pillow) Requires: python3-pillow
Requires: perl-Image-ExifTool Requires: perl-Image-ExifTool
Requires: xdg-utils Requires: xdg-utils

View File

@ -1,5 +1,5 @@
%global pypi_name portprotonqt %global pypi_name portprotonqt
%global pypi_version 0.1.1 %global pypi_version 0.1.2
%global oname PortProtonQt %global oname PortProtonQt
Name: python-%{pypi_name} Name: python-%{pypi_name}
@ -25,19 +25,19 @@ BuildRequires: git
%package -n python3-%{pypi_name} %package -n python3-%{pypi_name}
Summary: %{summary} Summary: %{summary}
%{?python_provide:%python_provide python3-%{pypi_name}} %{?python_provide:%python_provide python3-%{pypi_name}}
Requires: python3dist(babel) Requires: python3-babel
Requires: python3dist(evdev) Requires: python3-evdev
Requires: python3dist(icoextract) Requires: python3-icoextract
Requires: python3dist(numpy) Requires: python3-numpy
Requires: python3dist(orjson) Requires: python3-orjson
Requires: python3dist(psutil) Requires: python3-psutil
Requires: python3dist(pyside6) Requires: python3-pyside6
Requires: python3dist(pyudev) Requires: python3-pyudev
Requires: python3dist(requests) Requires: python3-requests
Requires: python3dist(tqdm) Requires: python3-tqdm
Requires: python3dist(vdf) Requires: python3-vdf
Requires: python3dist(pefile) Requires: python3-pefile
Requires: python3dist(pillow) Requires: python3-pillow
Requires: perl-Image-ExifTool Requires: perl-Image-ExifTool
Requires: xdg-utils Requires: xdg-utils

View File

@ -49,6 +49,16 @@
<caption>Settings</caption> <caption>Settings</caption>
<caption xml:lang="ru">Настройки</caption> <caption xml:lang="ru">Настройки</caption>
</screenshot> </screenshot>
<screenshot>
<image>https://git.linux-gaming.ru/Boria138/PortProtonQt/raw/branch/main/portprotonqt/themes/standart/images/screenshots/%D0%9A%D0%BE%D0%BD%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BD%D0%BE%D0%B5%20%D0%BC%D0%B5%D0%BD%D1%8E.png</image>
<caption>Context Menu</caption>
<caption xml:lang="ru">Контекстное меню</caption>
</screenshot>
<screenshot>
<image>https://git.linux-gaming.ru/Boria138/PortProtonQt/src/branch/main/portprotonqt/themes/standart/images/screenshots/%D0%9E%D0%B2%D0%B5%D1%80%D0%BB%D0%B5%D0%B9.png</image>
<caption>Overlay</caption>
<caption xml:lang="ru">Оверлей</caption>
</screenshot>
</screenshots> </screenshots>
<keywords> <keywords>
<keyword translate="no">wine</keyword> <keyword translate="no">wine</keyword>

View File

@ -1573,7 +1573,7 @@
}, },
{ {
"normalized_name": "dune awakening", "normalized_name": "dune awakening",
"status": "Broken" "status": "Running"
}, },
{ {
"normalized_name": "warcraft iii reforged", "normalized_name": "warcraft iii reforged",
@ -2337,7 +2337,7 @@
}, },
{ {
"normalized_name": "punishing gray raven", "normalized_name": "punishing gray raven",
"status": "Broken" "status": "Running"
}, },
{ {
"normalized_name": "brainbread 2", "normalized_name": "brainbread 2",
@ -3951,10 +3951,6 @@
"normalized_name": "outpost infinity siege", "normalized_name": "outpost infinity siege",
"status": "Running" "status": "Running"
}, },
{
"normalized_name": "avatar frontiers of pandora",
"status": "Broken"
},
{ {
"normalized_name": "v rising", "normalized_name": "v rising",
"status": "Running" "status": "Running"
@ -4406,5 +4402,17 @@
{ {
"normalized_name": "elden ring nightreign", "normalized_name": "elden ring nightreign",
"status": "Running" "status": "Running"
},
{
"normalized_name": "steel hunters",
"status": "Running"
},
{
"normalized_name": "reverse 1999",
"status": "Running"
},
{
"normalized_name": "ragnarok origin roo",
"status": "Running"
} }
] ]

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -6,11 +6,20 @@ import asyncio
import aiohttp import aiohttp
import tarfile import tarfile
# Получаем ключи и данные из переменных окружения
STEAM_KEY = os.environ.get('STEAM_KEY')
LINUX_GAMING_API_KEY = os.environ.get('LINUX_GAMING_API_KEY')
LINUX_GAMING_API_USERNAME = os.environ.get('LINUX_GAMING_API_USERNAME')
# Получаем ключ Steam из переменной окружения. # Конфигурация API
key = os.environ.get('STEAM_KEY') STEAM_BASE_URL = "https://api.steampowered.com/IStoreService/GetAppList/v1/?"
base_url = "https://api.steampowered.com/IStoreService/GetAppList/v1/?" LINUX_GAMING_BASE_URL = "https://linux-gaming.ru"
category = "games" CATEGORY_STEAM = "games"
CATEGORY_LINUX_GAMING = "ppdb"
LINUX_GAMING_HEADERS = {
"Api-Key": LINUX_GAMING_API_KEY,
"Api-Username": LINUX_GAMING_API_USERNAME
}
def normalize_name(s): def normalize_name(s):
""" """
@ -32,13 +41,11 @@ def normalize_name(s):
if s.endswith(suffix): if s.endswith(suffix):
s = s[:-len(suffix)].strip() s = s[:-len(suffix)].strip()
# Удаляем служебные слова, которые не должны влиять на сопоставление
keywords_to_remove = {"ultimate", "edition", "definitive", "complete", "remastered"} keywords_to_remove = {"ultimate", "edition", "definitive", "complete", "remastered"}
words = s.split() words = s.split()
filtered_words = [word for word in words if word not in keywords_to_remove] filtered_words = [word for word in words if word not in keywords_to_remove]
return " ".join(filtered_words) return " ".join(filtered_words)
def process_steam_apps(steam_apps): def process_steam_apps(steam_apps):
""" """
Для каждого приложения из Steam добавляет ключ "normalized_name", Для каждого приложения из Steam добавляет ключ "normalized_name",
@ -49,16 +56,14 @@ def process_steam_apps(steam_apps):
original = app.get("name", "") original = app.get("name", "")
if not app.get("normalized_name"): if not app.get("normalized_name"):
app["normalized_name"] = normalize_name(original) app["normalized_name"] = normalize_name(original)
# Удаляем ненужные поля
app.pop("name", None) app.pop("name", None)
app.pop("last_modified", None) app.pop("last_modified", None)
app.pop("price_change_number", None) app.pop("price_change_number", None)
return steam_apps return steam_apps
async def get_app_list(session, last_appid, endpoint): async def get_app_list(session, last_appid, endpoint):
""" """
Получает часть списка приложений из API. Получает часть списка приложений из API Steam.
Если last_appid передан, добавляет его к URL для постраничной загрузки. Если last_appid передан, добавляет его к URL для постраничной загрузки.
""" """
url = endpoint url = endpoint
@ -68,7 +73,6 @@ async def get_app_list(session, last_appid, endpoint):
response.raise_for_status() response.raise_for_status()
return await response.json() return await response.json()
async def fetch_games_json(session): async def fetch_games_json(session):
""" """
Загружает JSON с данными из AreWeAntiCheatYet и извлекает поля normalized_name и status. Загружает JSON с данными из AreWeAntiCheatYet и извлекает поля normalized_name и status.
@ -79,21 +83,46 @@ async def fetch_games_json(session):
response.raise_for_status() response.raise_for_status()
text = await response.text() text = await response.text()
data = json.loads(text) data = json.loads(text)
# Извлекаем только поля normalized_name и status
return [{"normalized_name": normalize_name(game["name"]), "status": game["status"]} for game in data] return [{"normalized_name": normalize_name(game["name"]), "status": game["status"]} for game in data]
except Exception as error: except Exception as error:
print(f"Ошибка загрузки games.json: {error}") print(f"Ошибка загрузки games.json: {error}")
return [] return []
async def get_linux_gaming_topics(session, category_slug):
"""
Получает все темы из указанной категории linux-gaming.ru.
Сохраняет только нормализованное название (normalized_title) и slug.
"""
page = 0
all_topics = []
while True:
page += 1
url = f"{LINUX_GAMING_BASE_URL}/c/{category_slug}/l/latest.json?page={page}"
try:
async with session.get(url, headers=LINUX_GAMING_HEADERS) as response:
response.raise_for_status()
data = await response.json()
topics = data.get("topic_list", {}).get("topics", [])
if not topics:
break
for topic in topics:
all_topics.append({
"normalized_title": normalize_name(topic["title"]),
"slug": topic["slug"]
})
print(f"Обработано {len(topics)} тем на странице {page}, всего: {len(all_topics)}.")
except Exception as error:
print(f"Ошибка получения тем для страницы {page}: {error}")
break
return all_topics
async def request_data(): async def request_data():
""" """
Получает данные списка приложений для категории "games" до тех пор, Получает данные из Steam, AreWeAntiCheatYet и linux-gaming.ru,
пока не закончатся результаты, обрабатывает данные для добавления обрабатывает их и сохраняет в JSON-файлы и tar.xz архивы.
нормализованных имён и записывает итоговый результат в JSON-файл.
Отдельно загружает games.json и сохраняет его в отдельный JSON-файл.
""" """
# Параметры запроса для игр. # Параметры запроса для Steam
game_param = "&include_games=true" game_param = "&include_games=true"
dlc_param = "&include_dlc=false" dlc_param = "&include_dlc=false"
software_param = "&include_software=false" software_param = "&include_software=false"
@ -101,13 +130,15 @@ async def request_data():
hardware_param = "&include_hardware=false" hardware_param = "&include_hardware=false"
endpoint = ( endpoint = (
f"{base_url}key={key}" f"{STEAM_BASE_URL}key={STEAM_KEY}"
f"{game_param}{dlc_param}{software_param}{videos_param}{hardware_param}" f"{game_param}{dlc_param}{software_param}{videos_param}{hardware_param}"
f"&max_results=50000" f"&max_results=50000"
) )
output_json = [] output_json = []
total_parsed = 0 total_parsed = 0
linux_gaming_topics = []
anticheat_games = []
try: try:
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
@ -117,58 +148,62 @@ async def request_data():
while have_more_results: while have_more_results:
app_list = await get_app_list(session, last_appid_val, endpoint) app_list = await get_app_list(session, last_appid_val, endpoint)
apps = app_list['response']['apps'] apps = app_list['response']['apps']
# Обрабатываем приложения для добавления нормализованных имён
apps = process_steam_apps(apps) apps = process_steam_apps(apps)
output_json.extend(apps) output_json.extend(apps)
total_parsed += len(apps) total_parsed += len(apps)
have_more_results = app_list['response'].get('have_more_results', False) have_more_results = app_list['response'].get('have_more_results', False)
last_appid_val = app_list['response'].get('last_appid') last_appid_val = app_list['response'].get('last_appid')
print(f"Обработано {len(apps)} игр Steam, всего: {total_parsed}.")
print(f"Обработано {len(apps)} игр, всего: {total_parsed}.") # Загружаем данные AreWeAntiCheatYet
# Загружаем и сохраняем games.json отдельно
anticheat_games = await fetch_games_json(session) anticheat_games = await fetch_games_json(session)
# Загружаем данные linux-gaming.ru
if LINUX_GAMING_API_KEY and LINUX_GAMING_API_USERNAME:
linux_gaming_topics = await get_linux_gaming_topics(session, CATEGORY_LINUX_GAMING)
else:
print("Предупреждение: LINUX_GAMING_API_KEY или LINUX_GAMING_API_USERNAME не установлены.")
except Exception as error: except Exception as error:
print(f"Ошибка получения данных для {category}: {error}") print(f"Ошибка получения данных: {error}")
return False return False
repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
data_dir = os.path.join(repo_root, "data") data_dir = os.path.join(repo_root, "data")
os.makedirs(data_dir, exist_ok=True) os.makedirs(data_dir, exist_ok=True)
# Путь к JSON-файлам для Steam # Сохранение данных Steam
output_json_full = os.path.join(data_dir, f"{category}_appid.json") output_json_full = os.path.join(data_dir, f"{CATEGORY_STEAM}_appid.json")
output_json_min = os.path.join(data_dir, f"{category}_appid_min.json") output_json_min = os.path.join(data_dir, f"{CATEGORY_STEAM}_appid_min.json")
# Записываем полные данные Steam с отступами
with open(output_json_full, "w", encoding="utf-8") as f: with open(output_json_full, "w", encoding="utf-8") as f:
json.dump(output_json, f, ensure_ascii=False, indent=2) json.dump(output_json, f, ensure_ascii=False, indent=2)
# Записываем минимизированные данные Steam
with open(output_json_min, "w", encoding="utf-8") as f: with open(output_json_min, "w", encoding="utf-8") as f:
json.dump(output_json, f, ensure_ascii=False, separators=(',',':')) json.dump(output_json, f, ensure_ascii=False, separators=(',',':'))
# Путь к JSON-файлам для AreWeAntiCheatYet # Сохранение данных AreWeAntiCheatYet
anticheat_json_full = os.path.join(data_dir, "anticheat_games.json") anticheat_json_full = os.path.join(data_dir, "anticheat_games.json")
anticheat_json_min = os.path.join(data_dir, "anticheat_games_min.json") anticheat_json_min = os.path.join(data_dir, "anticheat_games_min.json")
# Записываем полные данные AreWeAntiCheatYet с отступами
with open(anticheat_json_full, "w", encoding="utf-8") as f: with open(anticheat_json_full, "w", encoding="utf-8") as f:
json.dump(anticheat_games, f, ensure_ascii=False, indent=2) json.dump(anticheat_games, f, ensure_ascii=False, indent=2)
# Записываем минимизированные данные AreWeAntiCheatYet
with open(anticheat_json_min, "w", encoding="utf-8") as f: with open(anticheat_json_min, "w", encoding="utf-8") as f:
json.dump(anticheat_games, f, ensure_ascii=False, separators=(',',':')) json.dump(anticheat_games, f, ensure_ascii=False, separators=(',',':'))
# Упаковка только минифицированных JSON в tar.xz архивы с максимальным сжатием # Сохранение данных linux-gaming.ru
linux_gaming_json_full = os.path.join(data_dir, "linux_gaming_topics.json")
linux_gaming_json_min = os.path.join(data_dir, "linux_gaming_topics_min.json")
if linux_gaming_topics:
with open(linux_gaming_json_full, "w", encoding="utf-8") as f:
json.dump(linux_gaming_topics, f, ensure_ascii=False, indent=2)
with open(linux_gaming_json_min, "w", encoding="utf-8") as f:
json.dump(linux_gaming_topics, f, ensure_ascii=False, separators=(',',':'))
# Упаковка минифицированных JSON в tar.xz архивы
# Архив для Steam # Архив для Steam
steam_archive_path = os.path.join(data_dir, f"{category}_appid.tar.xz") steam_archive_path = os.path.join(data_dir, f"{CATEGORY_STEAM}_appid.tar.xz")
try: try:
with tarfile.open(steam_archive_path, "w:xz", preset=9) as tar: with tarfile.open(steam_archive_path, "w:xz", preset=9) as tar:
tar.add(output_json_min, arcname=os.path.basename(output_json_min)) tar.add(output_json_min, arcname=os.path.basename(output_json_min))
print(f"Упаковано минифицированное JSON Steam в архив: {steam_archive_path}") print(f"Упаковано минифицированное JSON Steam в архив: {steam_archive_path}")
# Удаляем исходный минифицированный файл после упаковки
os.remove(output_json_min) os.remove(output_json_min)
except Exception as e: except Exception as e:
print(f"Ошибка при упаковке архива Steam: {e}") print(f"Ошибка при упаковке архива Steam: {e}")
@ -180,20 +215,29 @@ async def request_data():
with tarfile.open(anticheat_archive_path, "w:xz", preset=9) as tar: with tarfile.open(anticheat_archive_path, "w:xz", preset=9) as tar:
tar.add(anticheat_json_min, arcname=os.path.basename(anticheat_json_min)) tar.add(anticheat_json_min, arcname=os.path.basename(anticheat_json_min))
print(f"Упаковано минифицированное JSON AreWeAntiCheatYet в архив: {anticheat_archive_path}") print(f"Упаковано минифицированное JSON AreWeAntiCheatYet в архив: {anticheat_archive_path}")
# Удаляем исходный минифицированный файл после упаковки
os.remove(anticheat_json_min) os.remove(anticheat_json_min)
except Exception as e: except Exception as e:
print(f"Ошибка при упаковке архива AreWeAntiCheatYet: {e}") print(f"Ошибка при упаковке архива AreWeAntiCheatYet: {e}")
return False return False
return True # Архив для linux-gaming.ru
if linux_gaming_topics:
linux_gaming_archive_path = os.path.join(data_dir, "linux_gaming_topics.tar.xz")
try:
with tarfile.open(linux_gaming_archive_path, "w:xz", preset=9) as tar:
tar.add(linux_gaming_json_min, arcname=os.path.basename(linux_gaming_json_min))
print(f"Упаковано минифицированное JSON linux-gaming.ru в архив: {linux_gaming_archive_path}")
os.remove(linux_gaming_json_min)
except Exception as e:
print(f"Ошибка при упаковке архива linux-gaming.ru: {e}")
return False
return True
async def run(): async def run():
success = await request_data() success = await request_data()
if not success: if not success:
exit(1) exit(1)
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(run()) asyncio.run(run())

View File

@ -20,9 +20,9 @@ Current translation status:
| Locale | Progress | Translated | | Locale | Progress | Translated |
| :----- | -------: | ---------: | | :----- | -------: | ---------: |
| [de_DE](./de_DE/LC_MESSAGES/messages.po) | 0% | 0 of 160 | | [de_DE](./de_DE/LC_MESSAGES/messages.po) | 0% | 0 of 161 |
| [es_ES](./es_ES/LC_MESSAGES/messages.po) | 0% | 0 of 160 | | [es_ES](./es_ES/LC_MESSAGES/messages.po) | 0% | 0 of 161 |
| [ru_RU](./ru_RU/LC_MESSAGES/messages.po) | 100% | 160 of 160 | | [ru_RU](./ru_RU/LC_MESSAGES/messages.po) | 100% | 161 of 161 |
--- ---

View File

@ -20,9 +20,9 @@
| Локаль | Прогресс | Переведено | | Локаль | Прогресс | Переведено |
| :----- | -------: | ---------: | | :----- | -------: | ---------: |
| [de_DE](./de_DE/LC_MESSAGES/messages.po) | 0% | 0 из 160 | | [de_DE](./de_DE/LC_MESSAGES/messages.po) | 0% | 0 из 161 |
| [es_ES](./es_ES/LC_MESSAGES/messages.po) | 0% | 0 из 160 | | [es_ES](./es_ES/LC_MESSAGES/messages.po) | 0% | 0 из 161 |
| [ru_RU](./ru_RU/LC_MESSAGES/messages.po) | 100% | 160 из 160 | | [ru_RU](./ru_RU/LC_MESSAGES/messages.po) | 100% | 161 из 161 |
--- ---

View File

@ -12,7 +12,7 @@ logger = get_logger(__name__)
__app_id__ = "ru.linux_gaming.PortProtonQt" __app_id__ = "ru.linux_gaming.PortProtonQt"
__app_name__ = "PortProtonQt" __app_name__ = "PortProtonQt"
__app_version__ = "0.1.1" __app_version__ = "0.1.2"
def main(): def main():
app = QApplication(sys.argv) app = QApplication(sys.argv)
@ -29,14 +29,12 @@ def main():
else: else:
logger.error(f"Qt translations for {system_locale.name()} not found in {translations_path}") logger.error(f"Qt translations for {system_locale.name()} not found in {translations_path}")
# Парсинг аргументов командной строки
args = parse_args() args = parse_args()
window = MainWindow() window = MainWindow()
# Обработка флага --fullscreen
if args.fullscreen: if args.fullscreen:
logger.info("Запуск в полноэкранном режиме по флагу --fullscreen") logger.info("Launching in fullscreen mode due to --fullscreen flag")
save_fullscreen_config(True) save_fullscreen_config(True)
window.showFullScreen() window.showFullScreen()
@ -47,13 +45,29 @@ def main():
def recreate_tray(): def recreate_tray():
nonlocal tray nonlocal tray
tray.hide_tray() if tray:
logger.debug("Recreating system tray")
tray.cleanup()
tray = None
current_theme = read_theme_from_config() current_theme = read_theme_from_config()
tray = SystemTray(app, current_theme) tray = SystemTray(app, current_theme)
tray.show_action.triggered.connect(window.show) # Ensure window is not None before connecting signals
tray.hide_action.triggered.connect(window.hide) if window:
tray.show_action.triggered.connect(window.show)
tray.hide_action.triggered.connect(window.hide)
def cleanup_on_exit():
nonlocal tray, window
app.aboutToQuit.disconnect()
if tray:
tray.cleanup()
tray = None
if window:
window.close()
app.quit()
window.settings_saved.connect(recreate_tray) window.settings_saved.connect(recreate_tray)
app.aboutToQuit.connect(cleanup_on_exit)
window.show() window.show()

View File

@ -322,6 +322,41 @@ def save_favorites(favorites):
with open(CONFIG_FILE, "w", encoding="utf-8") as configfile: with open(CONFIG_FILE, "w", encoding="utf-8") as configfile:
cp.write(configfile) cp.write(configfile)
def read_rumble_config():
"""
Читает настройку виброотдачи геймпада из секции [Gamepad].
Если параметр отсутствует, сохраняет и возвращает False по умолчанию.
"""
cp = configparser.ConfigParser()
if os.path.exists(CONFIG_FILE):
try:
cp.read(CONFIG_FILE, encoding="utf-8")
except Exception as e:
logger.error("Ошибка чтения конфигурационного файла: %s", e)
save_rumble_config(False)
return False
if not cp.has_section("Gamepad") or not cp.has_option("Gamepad", "rumble_enabled"):
save_rumble_config(False)
return False
return cp.getboolean("Gamepad", "rumble_enabled", fallback=False)
return False
def save_rumble_config(rumble_enabled):
"""
Сохраняет настройку виброотдачи геймпада в секцию [Gamepad].
"""
cp = configparser.ConfigParser()
if os.path.exists(CONFIG_FILE):
try:
cp.read(CONFIG_FILE, encoding="utf-8")
except (configparser.DuplicateSectionError, configparser.DuplicateOptionError) as e:
logger.error("Ошибка чтения конфигурационного файла: %s", e)
if "Gamepad" not in cp:
cp["Gamepad"] = {}
cp["Gamepad"]["rumble_enabled"] = str(rumble_enabled)
with open(CONFIG_FILE, "w", encoding="utf-8") as configfile:
cp.write(configfile)
def ensure_default_proxy_config(): def ensure_default_proxy_config():
""" """
Проверяет наличие секции [Proxy] в конфигурационном файле. Проверяет наличие секции [Proxy] в конфигурационном файле.
@ -342,7 +377,6 @@ def ensure_default_proxy_config():
with open(CONFIG_FILE, "w", encoding="utf-8") as configfile: with open(CONFIG_FILE, "w", encoding="utf-8") as configfile:
cp.write(configfile) cp.write(configfile)
def read_proxy_config(): def read_proxy_config():
""" """
Читает настройки прокси из секции [Proxy] конфигурационного файла. Читает настройки прокси из секции [Proxy] конфигурационного файла.
@ -421,8 +455,6 @@ def save_fullscreen_config(fullscreen):
with open(CONFIG_FILE, "w", encoding="utf-8") as configfile: with open(CONFIG_FILE, "w", encoding="utf-8") as configfile:
cp.write(configfile) cp.write(configfile)
def read_window_geometry() -> tuple[int, int]: def read_window_geometry() -> tuple[int, int]:
""" """
Читает ширину и высоту окна из секции [MainWindow] конфигурационного файла. Читает ширину и высоту окна из секции [MainWindow] конфигурационного файла.

View File

@ -1,5 +1,5 @@
import numpy as np import numpy as np
from PySide6.QtWidgets import QLabel, QPushButton, QWidget, QLayout, QStyleOption, QLayoutItem from PySide6.QtWidgets import QLabel, QPushButton, QWidget, QLayout, QLayoutItem
from PySide6.QtCore import Qt, Signal, QRect, QPoint, QSize from PySide6.QtCore import Qt, Signal, QRect, QPoint, QSize
from PySide6.QtGui import QFont, QFontMetrics, QPainter from PySide6.QtGui import QFont, QFontMetrics, QPainter
@ -133,18 +133,7 @@ class FlowLayout(QLayout):
class ClickableLabel(QLabel): class ClickableLabel(QLabel):
clicked = Signal() clicked = Signal()
def __init__(self, *args, icon=None, icon_size=16, icon_space=5, change_cursor=True, **kwargs): def __init__(self, *args, icon=None, icon_size=16, icon_space=5, change_cursor=True, font_scale_factor=0.06, **kwargs):
"""
Поддерживаются вызовы:
- ClickableLabel("текст", parent=...) первый аргумент строка,
- ClickableLabel(parent, text="...") если первым аргументом передается родитель.
Аргументы:
icon: QIcon или None иконка, которая будет отрисована вместе с текстом.
icon_size: int размер иконки (ширина и высота).
icon_space: int отступ между иконкой и текстом.
change_cursor: bool изменять ли курсор на PointingHandCursor при наведении (по умолчанию True).
"""
if args and isinstance(args[0], str): if args and isinstance(args[0], str):
text = args[0] text = args[0]
parent = kwargs.get("parent", None) parent = kwargs.get("parent", None)
@ -162,20 +151,38 @@ class ClickableLabel(QLabel):
self._icon = icon self._icon = icon
self._icon_size = icon_size self._icon_size = icon_size
self._icon_space = icon_space self._icon_space = icon_space
self._font_scale_factor = font_scale_factor
self._card_width = 250 # Значение по умолчанию
if change_cursor: if change_cursor:
self.setCursor(Qt.CursorShape.PointingHandCursor) self.setCursor(Qt.CursorShape.PointingHandCursor)
self.updateFontSize()
def setIcon(self, icon): def setIcon(self, icon):
"""Устанавливает иконку и перерисовывает виджет."""
self._icon = icon self._icon = icon
self.update() self.update()
def icon(self): def icon(self):
"""Возвращает текущую иконку."""
return self._icon return self._icon
def setIconSize(self, icon_size: int, icon_space: int):
self._icon_size = icon_size
self._icon_space = icon_space
self.update()
def setCardWidth(self, card_width: int):
"""Обновляет ширину карточки и пересчитывает размер шрифта."""
self._card_width = card_width
self.updateFontSize()
def updateFontSize(self):
"""Обновляет размер шрифта на основе card_width и font_scale_factor."""
font = self.font()
font_size = int(self._card_width * self._font_scale_factor)
font.setPointSize(max(8, font_size)) # Минимальный размер шрифта 8
self.setFont(font)
self.update()
def paintEvent(self, event): def paintEvent(self, event):
"""Переопределяем отрисовку: рисуем иконку и текст в одном лейбле."""
painter = QPainter(self) painter = QPainter(self)
painter.setRenderHint(QPainter.RenderHint.Antialiasing) painter.setRenderHint(QPainter.RenderHint.Antialiasing)
@ -190,7 +197,6 @@ class ClickableLabel(QLabel):
text = self.text() text = self.text()
if self._icon: if self._icon:
# Получаем QPixmap нужного размера
pixmap = self._icon.pixmap(icon_size, icon_size) pixmap = self._icon.pixmap(icon_size, icon_size)
icon_rect = QRect(0, 0, icon_size, icon_size) icon_rect = QRect(0, 0, icon_size, icon_size)
icon_rect.moveTop(rect.top() + (rect.height() - icon_size) // 2) icon_rect.moveTop(rect.top() + (rect.height() - icon_size) // 2)
@ -214,13 +220,11 @@ class ClickableLabel(QLabel):
if pixmap: if pixmap:
icon_rect.moveLeft(x) icon_rect.moveLeft(x)
text_rect = QRect(x + icon_size + spacing, y, text_width, text_height) text_rect = QRect(x + icon_size + spacing, y, text_width, text_height)
painter.drawPixmap(icon_rect, pixmap)
else: else:
# Устанавливаем text_rect для меток без иконки (например, favoriteLabel)
text_rect = QRect(x, y, text_width, text_height) text_rect = QRect(x, y, text_width, text_height)
option = QStyleOption()
option.initFrom(self)
if pixmap:
painter.drawPixmap(icon_rect, pixmap)
self.style().drawItemText( self.style().drawItemText(
painter, painter,
text_rect, text_rect,

View File

@ -98,7 +98,7 @@ class AddGameDialog(QDialog):
# Game name # Game name
self.nameEdit = QLineEdit(self) self.nameEdit = QLineEdit(self)
self.nameEdit.setStyleSheet(self.theme.SEARCH_EDIT_STYLE + " QLineEdit { color: #ffffff; font-size: 14px; }") self.nameEdit.setStyleSheet(self.theme.ADDGAME_INPUT_STYLE)
if game_name: if game_name:
self.nameEdit.setText(game_name) self.nameEdit.setText(game_name)
name_label = QLabel(_("Game Name:")) name_label = QLabel(_("Game Name:"))
@ -107,7 +107,7 @@ class AddGameDialog(QDialog):
# Exe path # Exe path
self.exeEdit = QLineEdit(self) self.exeEdit = QLineEdit(self)
self.exeEdit.setStyleSheet(self.theme.SEARCH_EDIT_STYLE + " QLineEdit { color: #ffffff; font-size: 14px; }") self.exeEdit.setStyleSheet(self.theme.ADDGAME_INPUT_STYLE)
if exe_path: if exe_path:
self.exeEdit.setText(exe_path) self.exeEdit.setText(exe_path)
exeBrowseButton = QPushButton(_("Browse..."), self) exeBrowseButton = QPushButton(_("Browse..."), self)
@ -123,7 +123,7 @@ class AddGameDialog(QDialog):
# Cover path # Cover path
self.coverEdit = QLineEdit(self) self.coverEdit = QLineEdit(self)
self.coverEdit.setStyleSheet(self.theme.SEARCH_EDIT_STYLE + " QLineEdit { color: #ffffff; font-size: 14px; }") self.coverEdit.setStyleSheet(self.theme.ADDGAME_INPUT_STYLE)
if cover_path: if cover_path:
self.coverEdit.setText(cover_path) self.coverEdit.setText(cover_path)
coverBrowseButton = QPushButton(_("Browse..."), self) coverBrowseButton = QPushButton(_("Browse..."), self)

View File

@ -25,6 +25,7 @@ class GameCard(QFrame):
addToSteamRequested = Signal(str, str, str) # name, exec_line, cover_path addToSteamRequested = Signal(str, str, str) # name, exec_line, cover_path
removeFromSteamRequested = Signal(str, str) # name, exec_line removeFromSteamRequested = Signal(str, str) # name, exec_line
openGameFolderRequested = Signal(str, str) # name, exec_line openGameFolderRequested = Signal(str, str) # name, exec_line
hoverChanged = Signal(str, bool)
def __init__(self, name, description, cover_path, appid, controller_support, exec_line, def __init__(self, name, description, cover_path, appid, controller_support, exec_line,
last_launch, formatted_playtime, protondb_tier, anticheat_status, last_launch_ts, playtime_seconds, game_source, last_launch, formatted_playtime, protondb_tier, anticheat_status, last_launch_ts, playtime_seconds, game_source,
@ -43,6 +44,7 @@ class GameCard(QFrame):
self.game_source = game_source self.game_source = game_source
self.last_launch_ts = last_launch_ts self.last_launch_ts = last_launch_ts
self.playtime_seconds = playtime_seconds self.playtime_seconds = playtime_seconds
self.card_width = card_width
self.select_callback = select_callback self.select_callback = select_callback
self.context_menu_manager = context_menu_manager self.context_menu_manager = context_menu_manager
@ -54,6 +56,10 @@ class GameCard(QFrame):
self.display_filter = read_display_filter() self.display_filter = read_display_filter()
self.current_theme_name = read_theme_from_config() self.current_theme_name = read_theme_from_config()
self.steam_visible = (str(game_source).lower() == "steam" and self.display_filter in ("all", "favorites"))
self.egs_visible = (str(game_source).lower() == "epic" and self.display_filter in ("all", "favorites"))
self.portproton_visible = (str(game_source).lower() == "portproton" and self.display_filter in ("all", "favorites"))
# Дополнительное пространство для анимации # Дополнительное пространство для анимации
extra_margin = 20 extra_margin = 20
self.setFixedSize(card_width + extra_margin, int(card_width * 1.6) + extra_margin) self.setFixedSize(card_width + extra_margin, int(card_width * 1.6) + extra_margin)
@ -61,14 +67,14 @@ class GameCard(QFrame):
self.setStyleSheet(self.theme.GAME_CARD_WINDOW_STYLE) self.setStyleSheet(self.theme.GAME_CARD_WINDOW_STYLE)
# Параметры анимации обводки # Параметры анимации обводки
self._borderWidth = 2 self._borderWidth = self.theme.GAME_CARD_ANIMATION["default_border_width"]
self._gradientAngle = 0.0 self._gradientAngle = self.theme.GAME_CARD_ANIMATION["gradient_start_angle"]
self._hovered = False self._hovered = False
self._focused = False self._focused = False
# Анимации # Анимации
self.thickness_anim = QPropertyAnimation(self, QByteArray(b"borderWidth")) self.thickness_anim = QPropertyAnimation(self, QByteArray(b"borderWidth"))
self.thickness_anim.setDuration(300) self.thickness_anim.setDuration(self.theme.GAME_CARD_ANIMATION["thickness_anim_duration"])
self.gradient_anim = None self.gradient_anim = None
self.pulse_anim = None self.pulse_anim = None
@ -121,9 +127,11 @@ class GameCard(QFrame):
self.update_favorite_icon() self.update_favorite_icon()
self.favoriteLabel.raise_() self.favoriteLabel.raise_()
steam_visible = (str(game_source).lower() == "steam" and self.display_filter in ("all", "favorites")) # Определяем общие параметры для бейджей
egs_visible = (str(game_source).lower() == "epic" and self.display_filter in ("all", "favorites")) badge_width = int(card_width * 2/3)
portproton_visible = (str(game_source).lower() == "portproton" and self.display_filter in ("all", "favorites")) icon_size = int(card_width * 0.06) # 6% от ширины карточки
icon_space = int(card_width * 0.012) # 1.2% от ширины карточки
font_scale_factor = 0.06 # Шрифт будет 6% от card_width
# ProtonDB бейдж # ProtonDB бейдж
tier_text = self.getProtonDBText(protondb_tier) tier_text = self.getProtonDBText(protondb_tier)
@ -134,17 +142,17 @@ class GameCard(QFrame):
tier_text, tier_text,
icon=icon, icon=icon,
parent=coverWidget, parent=coverWidget,
icon_size=16, icon_size=icon_size,
icon_space=3, icon_space=icon_space,
font_scale_factor=font_scale_factor
) )
self.protondbLabel.setStyleSheet(self.theme.get_protondb_badge_style(protondb_tier)) self.protondbLabel.setStyleSheet(self.theme.get_protondb_badge_style(protondb_tier))
self.protondbLabel.setFixedWidth(int(card_width * 2/3)) self.protondbLabel.setFixedWidth(badge_width)
protondb_visible = True self.protondbLabel.setCardWidth(card_width)
else: else:
self.protondbLabel = ClickableLabel("", parent=coverWidget, icon_size=16, icon_space=3) self.protondbLabel = ClickableLabel("", parent=coverWidget, icon_size=icon_size, icon_space=icon_space)
self.protondbLabel.setFixedWidth(int(card_width * 2/3)) self.protondbLabel.setFixedWidth(badge_width)
self.protondbLabel.setVisible(False) self.protondbLabel.setVisible(False)
protondb_visible = False
# Steam бейдж # Steam бейдж
steam_icon = self.theme_manager.get_icon("steam") steam_icon = self.theme_manager.get_icon("steam")
@ -152,12 +160,14 @@ class GameCard(QFrame):
"Steam", "Steam",
icon=steam_icon, icon=steam_icon,
parent=coverWidget, parent=coverWidget,
icon_size=16, icon_size=icon_size,
icon_space=5, icon_space=icon_space,
font_scale_factor=font_scale_factor
) )
self.steamLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE) self.steamLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE)
self.steamLabel.setFixedWidth(int(card_width * 2/3)) self.steamLabel.setFixedWidth(badge_width)
self.steamLabel.setVisible(steam_visible) self.steamLabel.setCardWidth(card_width)
self.steamLabel.setVisible(self.steam_visible)
# Epic Games Store бейдж # Epic Games Store бейдж
egs_icon = self.theme_manager.get_icon("steam") egs_icon = self.theme_manager.get_icon("steam")
@ -165,27 +175,31 @@ class GameCard(QFrame):
"Epic Games", "Epic Games",
icon=egs_icon, icon=egs_icon,
parent=coverWidget, parent=coverWidget,
icon_size=16, icon_size=icon_size,
icon_space=5, icon_space=icon_space,
font_scale_factor=font_scale_factor,
change_cursor=False change_cursor=False
) )
self.egsLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE) self.egsLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE)
self.egsLabel.setFixedWidth(int(card_width * 2/3)) self.egsLabel.setFixedWidth(badge_width)
self.egsLabel.setVisible(egs_visible) self.egsLabel.setCardWidth(card_width)
self.egsLabel.setVisible(self.egs_visible)
# PortProton badge # PortProton бейдж
portproton_icon = self.theme_manager.get_icon("ppqt-tray") portproton_icon = self.theme_manager.get_icon("ppqt-tray")
self.portprotonLabel = ClickableLabel( self.portprotonLabel = ClickableLabel(
"PortProton", "PortProton",
icon=portproton_icon, icon=portproton_icon,
parent=coverWidget, parent=coverWidget,
icon_size=16, icon_size=icon_size,
icon_space=5, icon_space=icon_space,
font_scale_factor=font_scale_factor,
change_cursor=False change_cursor=False
) )
self.portprotonLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE) self.portprotonLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE)
self.portprotonLabel.setFixedWidth(int(card_width * 2/3)) self.portprotonLabel.setFixedWidth(badge_width)
self.portprotonLabel.setVisible(portproton_visible) self.portprotonLabel.setCardWidth(card_width)
self.portprotonLabel.setVisible(self.portproton_visible)
# WeAntiCheatYet бейдж # WeAntiCheatYet бейдж
anticheat_text = self.getAntiCheatText(anticheat_status) anticheat_text = self.getAntiCheatText(anticheat_status)
@ -196,53 +210,20 @@ class GameCard(QFrame):
anticheat_text, anticheat_text,
icon=icon, icon=icon,
parent=coverWidget, parent=coverWidget,
icon_size=16, icon_size=icon_size,
icon_space=3, icon_space=icon_space,
font_scale_factor=font_scale_factor
) )
self.anticheatLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE) self.anticheatLabel.setStyleSheet(self.theme.get_anticheat_badge_style(anticheat_status))
self.anticheatLabel.setFixedWidth(int(card_width * 2/3)) self.anticheatLabel.setFixedWidth(badge_width)
anticheat_visible = True self.anticheatLabel.setCardWidth(card_width)
else: else:
self.anticheatLabel = ClickableLabel("", parent=coverWidget, icon_size=16, icon_space=3) self.anticheatLabel = ClickableLabel("", parent=coverWidget, icon_size=icon_size, icon_space=icon_space)
self.anticheatLabel.setFixedWidth(int(card_width * 2/3)) self.anticheatLabel.setFixedWidth(badge_width)
self.anticheatLabel.setVisible(False) self.anticheatLabel.setVisible(False)
anticheat_visible = False
# Расположение бейджей # Расположение бейджей
right_margin = 8 self._position_badges(card_width)
badge_spacing = 5
top_y = 10
badge_y_positions = []
badge_width = int(card_width * 2/3)
if steam_visible:
steam_x = card_width - badge_width - right_margin
self.steamLabel.move(steam_x, top_y)
badge_y_positions.append(top_y + self.steamLabel.height())
if egs_visible:
egs_x = card_width - badge_width - right_margin
egs_y = badge_y_positions[-1] + badge_spacing if badge_y_positions else top_y
self.egsLabel.move(egs_x, egs_y)
badge_y_positions.append(egs_y + self.egsLabel.height())
if portproton_visible:
portproton_x = card_width - badge_width - right_margin
portproton_y = badge_y_positions[-1] + badge_spacing if badge_y_positions else top_y
self.portprotonLabel.move(portproton_x, portproton_y)
badge_y_positions.append(portproton_y + self.portprotonLabel.height())
if protondb_visible:
protondb_x = card_width - badge_width - right_margin
protondb_y = badge_y_positions[-1] + badge_spacing if badge_y_positions else top_y
self.protondbLabel.move(protondb_x, protondb_y)
badge_y_positions.append(protondb_y + self.protondbLabel.height())
if anticheat_visible:
anticheat_x = card_width - badge_width - right_margin
anticheat_y = badge_y_positions[-1] + badge_spacing if badge_y_positions else top_y
self.anticheatLabel.move(anticheat_x, anticheat_y)
self.anticheatLabel.raise_()
self.protondbLabel.raise_()
self.portprotonLabel.raise_()
self.egsLabel.raise_()
self.steamLabel.raise_()
self.protondbLabel.clicked.connect(self.open_protondb_report) self.protondbLabel.clicked.connect(self.open_protondb_report)
self.steamLabel.clicked.connect(self.open_steam_page) self.steamLabel.clicked.connect(self.open_steam_page)
self.anticheatLabel.clicked.connect(self.open_weanticheatyet_page) self.anticheatLabel.clicked.connect(self.open_weanticheatyet_page)
@ -255,8 +236,79 @@ class GameCard(QFrame):
nameLabel.setStyleSheet(self.theme.GAME_CARD_NAME_LABEL_STYLE) nameLabel.setStyleSheet(self.theme.GAME_CARD_NAME_LABEL_STYLE)
layout.addWidget(nameLabel) layout.addWidget(nameLabel)
def _position_badges(self, card_width):
"""Позиционирует бейджи на основе ширины карточки."""
right_margin = 8
badge_spacing = int(card_width * 0.02) # 2% от ширины карточки
top_y = 10
badge_y_positions = []
badge_width = int(card_width * 2/3)
badges = [
(self.steam_visible, self.steamLabel),
(self.egs_visible, self.egsLabel),
(self.portproton_visible, self.portprotonLabel),
(bool(self.getProtonDBText(self.protondb_tier)), self.protondbLabel),
(bool(self.getAntiCheatText(self.anticheat_status)), self.anticheatLabel),
]
for is_visible, badge in badges:
if is_visible:
badge_x = card_width - badge_width - right_margin
badge_y = badge_y_positions[-1] + badge_spacing if badge_y_positions else top_y
badge.move(badge_x, badge_y)
badge_y_positions.append(badge_y + badge.height())
# Поднимаем бейджи в правильном порядке (от нижнего к верхнему)
self.anticheatLabel.raise_()
self.protondbLabel.raise_()
self.portprotonLabel.raise_()
self.egsLabel.raise_()
self.steamLabel.raise_()
def update_card_size(self, new_width: int):
"""Обновляет размер карточки, обложки и бейджей."""
self.card_width = new_width
extra_margin = 20
self.setFixedSize(new_width + extra_margin, int(new_width * 1.6) + extra_margin)
if self.coverLabel is None:
return
coverWidget = self.coverLabel.parentWidget()
if coverWidget is None:
return
coverWidget.setFixedSize(new_width, int(new_width * 1.2))
self.coverLabel.setFixedSize(new_width, int(new_width * 1.2))
label_ref = weakref.ref(self.coverLabel)
def on_cover_loaded(pixmap):
label = label_ref()
if label:
scaled_pixmap = pixmap.scaled(new_width, int(new_width * 1.2), Qt.AspectRatioMode.KeepAspectRatioByExpanding, Qt.TransformationMode.SmoothTransformation)
rounded_pixmap = round_corners(scaled_pixmap, 15)
label.setPixmap(rounded_pixmap)
load_pixmap_async(self.cover_path or "", new_width, int(new_width * 1.2), on_cover_loaded)
# Обновляем размеры и шрифты бейджей
badge_width = int(new_width * 2/3)
icon_size = int(new_width * 0.06)
icon_space = int(new_width * 0.012)
for label in [self.steamLabel, self.egsLabel, self.portprotonLabel, self.protondbLabel, self.anticheatLabel]:
if label is not None:
label.setFixedWidth(badge_width)
label.setIconSize(icon_size, icon_space)
label.setCardWidth(new_width) # Пересчитываем размер шрифта
# Перепозиционируем бейджи
self._position_badges(new_width)
self.update()
def update_badge_visibility(self, display_filter: str): def update_badge_visibility(self, display_filter: str):
"""Update badge visibility based on the provided display_filter.""" """Обновляет видимость бейджей на основе display_filter."""
self.display_filter = display_filter self.display_filter = display_filter
self.steam_visible = (str(self.game_source).lower() == "steam" and display_filter in ("all", "favorites")) self.steam_visible = (str(self.game_source).lower() == "steam" and display_filter in ("all", "favorites"))
self.egs_visible = (str(self.game_source).lower() == "epic" and display_filter in ("all", "favorites")) self.egs_visible = (str(self.game_source).lower() == "epic" and display_filter in ("all", "favorites"))
@ -271,35 +323,8 @@ class GameCard(QFrame):
self.protondbLabel.setVisible(protondb_visible) self.protondbLabel.setVisible(protondb_visible)
self.anticheatLabel.setVisible(anticheat_visible) self.anticheatLabel.setVisible(anticheat_visible)
# Подготавливаем список всех бейджей с их текущей видимостью # Перепозиционируем бейджи
badges = [ self._position_badges(self.card_width)
(self.steam_visible, self.steamLabel),
(self.egs_visible, self.egsLabel),
(self.portproton_visible, self.portprotonLabel),
(protondb_visible, self.protondbLabel),
(anticheat_visible, self.anticheatLabel),
]
# Пересчитываем позиции бейджей
right_margin = 8
badge_spacing = 5
top_y = 10
badge_y_positions = []
badge_width = int(self.coverLabel.width() * 2/3)
for is_visible, badge in badges:
if is_visible:
badge_x = self.coverLabel.width() - badge_width - right_margin
badge_y = badge_y_positions[-1] + badge_spacing if badge_y_positions else top_y
badge.move(badge_x, badge_y)
badge_y_positions.append(badge_y + badge.height())
# Поднимаем бейджи в правильном порядке (от нижнего к верхнему)
self.anticheatLabel.raise_()
self.protondbLabel.raise_()
self.portprotonLabel.raise_()
self.egsLabel.raise_()
self.steamLabel.raise_()
def _show_context_menu(self, pos): def _show_context_menu(self, pos):
"""Delegate context menu display to ContextMenuManager.""" """Delegate context menu display to ContextMenuManager."""
@ -322,10 +347,16 @@ class GameCard(QFrame):
@staticmethod @staticmethod
def getAntiCheatIconFilename(status: str) -> str: def getAntiCheatIconFilename(status: str) -> str:
status = status.lower() status = status.lower()
if status in ("supported", "running"): if status in ("supported"):
return "platinum-gold" return "ac_supported"
elif status in ("denied", "planned", "broken"): elif status in ("running"):
return "broken" return "ac_running"
elif status in ("planned"):
return "ac_planned"
elif status in ("denied"):
return "ac_denied"
elif status in ("broken"):
return "ac_broken"
return "" return ""
@staticmethod @staticmethod
@ -417,10 +448,8 @@ class GameCard(QFrame):
if self._hovered or self._focused: if self._hovered or self._focused:
center = self.rect().center() center = self.rect().center()
gradient = QConicalGradient(center, self._gradientAngle) gradient = QConicalGradient(center, self._gradientAngle)
gradient.setColorAt(0, QColor("#00fff5")) for stop in self.theme.GAME_CARD_ANIMATION["gradient_colors"]:
gradient.setColorAt(0.33, QColor("#FF5733")) gradient.setColorAt(stop["position"], QColor(stop["color"]))
gradient.setColorAt(0.66, QColor("#9B59B6"))
gradient.setColorAt(1, QColor("#00fff5"))
pen.setBrush(QBrush(gradient)) pen.setBrush(QBrush(gradient))
else: else:
pen.setColor(QColor(0, 0, 0, 0)) pen.setColor(QColor(0, 0, 0, 0))
@ -437,22 +466,23 @@ class GameCard(QFrame):
if self.pulse_anim: if self.pulse_anim:
self.pulse_anim.stop() self.pulse_anim.stop()
self.pulse_anim = QPropertyAnimation(self, QByteArray(b"borderWidth")) self.pulse_anim = QPropertyAnimation(self, QByteArray(b"borderWidth"))
self.pulse_anim.setDuration(800) self.pulse_anim.setDuration(self.theme.GAME_CARD_ANIMATION["pulse_anim_duration"])
self.pulse_anim.setLoopCount(0) self.pulse_anim.setLoopCount(0)
self.pulse_anim.setKeyValueAt(0, 8) self.pulse_anim.setKeyValueAt(0, self.theme.GAME_CARD_ANIMATION["pulse_min_border_width"])
self.pulse_anim.setKeyValueAt(0.5, 10) self.pulse_anim.setKeyValueAt(0.5, self.theme.GAME_CARD_ANIMATION["pulse_max_border_width"])
self.pulse_anim.setKeyValueAt(1, 8) self.pulse_anim.setKeyValueAt(1, self.theme.GAME_CARD_ANIMATION["pulse_min_border_width"])
self.pulse_anim.start() self.pulse_anim.start()
def enterEvent(self, event): def enterEvent(self, event):
self._hovered = True self._hovered = True
self.hoverChanged.emit(self.name, True)
self.thickness_anim.stop() self.thickness_anim.stop()
if self._isPulseAnimationConnected: if self._isPulseAnimationConnected:
self.thickness_anim.finished.disconnect(self.startPulseAnimation) self.thickness_anim.finished.disconnect(self.startPulseAnimation)
self._isPulseAnimationConnected = False self._isPulseAnimationConnected = False
self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type.OutBack)) self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type[self.theme.GAME_CARD_ANIMATION["thickness_easing_curve"]]))
self.thickness_anim.setStartValue(self._borderWidth) self.thickness_anim.setStartValue(self._borderWidth)
self.thickness_anim.setEndValue(8) self.thickness_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["hover_border_width"])
self.thickness_anim.finished.connect(self.startPulseAnimation) self.thickness_anim.finished.connect(self.startPulseAnimation)
self._isPulseAnimationConnected = True self._isPulseAnimationConnected = True
self.thickness_anim.start() self.thickness_anim.start()
@ -460,9 +490,9 @@ class GameCard(QFrame):
if self.gradient_anim: if self.gradient_anim:
self.gradient_anim.stop() self.gradient_anim.stop()
self.gradient_anim = QPropertyAnimation(self, QByteArray(b"gradientAngle")) self.gradient_anim = QPropertyAnimation(self, QByteArray(b"gradientAngle"))
self.gradient_anim.setDuration(3000) self.gradient_anim.setDuration(self.theme.GAME_CARD_ANIMATION["gradient_anim_duration"])
self.gradient_anim.setStartValue(360) self.gradient_anim.setStartValue(self.theme.GAME_CARD_ANIMATION["gradient_start_angle"])
self.gradient_anim.setEndValue(0) self.gradient_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["gradient_end_angle"])
self.gradient_anim.setLoopCount(-1) self.gradient_anim.setLoopCount(-1)
self.gradient_anim.start() self.gradient_anim.start()
@ -470,22 +500,23 @@ class GameCard(QFrame):
def leaveEvent(self, event): def leaveEvent(self, event):
self._hovered = False self._hovered = False
if not self._focused: # Сохраняем анимацию, если есть фокус self.hoverChanged.emit(self.name, False)
if not self._focused:
if self.gradient_anim: if self.gradient_anim:
self.gradient_anim.stop() self.gradient_anim.stop()
self.gradient_anim = None self.gradient_anim = None
self.thickness_anim.stop()
if self._isPulseAnimationConnected:
self.thickness_anim.finished.disconnect(self.startPulseAnimation)
self._isPulseAnimationConnected = False
if self.pulse_anim: if self.pulse_anim:
self.pulse_anim.stop() self.pulse_anim.stop()
self.pulse_anim = None self.pulse_anim = None
self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type.InBack)) if self.thickness_anim:
self.thickness_anim.stop()
if self._isPulseAnimationConnected:
self.thickness_anim.finished.disconnect(self.startPulseAnimation)
self._isPulseAnimationConnected = False
self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type[self.theme.GAME_CARD_ANIMATION["thickness_easing_curve_out"]]))
self.thickness_anim.setStartValue(self._borderWidth) self.thickness_anim.setStartValue(self._borderWidth)
self.thickness_anim.setEndValue(2) self.thickness_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["default_border_width"])
self.thickness_anim.start() self.thickness_anim.start()
super().leaveEvent(event) super().leaveEvent(event)
def focusInEvent(self, event): def focusInEvent(self, event):
@ -494,9 +525,9 @@ class GameCard(QFrame):
if self._isPulseAnimationConnected: if self._isPulseAnimationConnected:
self.thickness_anim.finished.disconnect(self.startPulseAnimation) self.thickness_anim.finished.disconnect(self.startPulseAnimation)
self._isPulseAnimationConnected = False self._isPulseAnimationConnected = False
self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type.OutBack)) self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type[self.theme.GAME_CARD_ANIMATION["thickness_easing_curve"]]))
self.thickness_anim.setStartValue(self._borderWidth) self.thickness_anim.setStartValue(self._borderWidth)
self.thickness_anim.setEndValue(12) self.thickness_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["focus_border_width"])
self.thickness_anim.finished.connect(self.startPulseAnimation) self.thickness_anim.finished.connect(self.startPulseAnimation)
self._isPulseAnimationConnected = True self._isPulseAnimationConnected = True
self.thickness_anim.start() self.thickness_anim.start()
@ -504,9 +535,9 @@ class GameCard(QFrame):
if self.gradient_anim: if self.gradient_anim:
self.gradient_anim.stop() self.gradient_anim.stop()
self.gradient_anim = QPropertyAnimation(self, QByteArray(b"gradientAngle")) self.gradient_anim = QPropertyAnimation(self, QByteArray(b"gradientAngle"))
self.gradient_anim.setDuration(3000) self.gradient_anim.setDuration(self.theme.GAME_CARD_ANIMATION["gradient_anim_duration"])
self.gradient_anim.setStartValue(360) self.gradient_anim.setStartValue(self.theme.GAME_CARD_ANIMATION["gradient_start_angle"])
self.gradient_anim.setEndValue(0) self.gradient_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["gradient_end_angle"])
self.gradient_anim.setLoopCount(-1) self.gradient_anim.setLoopCount(-1)
self.gradient_anim.start() self.gradient_anim.start()
@ -525,11 +556,10 @@ class GameCard(QFrame):
if self.pulse_anim: if self.pulse_anim:
self.pulse_anim.stop() self.pulse_anim.stop()
self.pulse_anim = None self.pulse_anim = None
self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type.InBack)) self.thickness_anim.setEasingCurve(QEasingCurve(QEasingCurve.Type[self.theme.GAME_CARD_ANIMATION["thickness_easing_curve_out"]]))
self.thickness_anim.setStartValue(self._borderWidth) self.thickness_anim.setStartValue(self._borderWidth)
self.thickness_anim.setEndValue(2) self.thickness_anim.setEndValue(self.theme.GAME_CARD_ANIMATION["default_border_width"])
self.thickness_anim.start() self.thickness_anim.start()
super().focusOutEvent(event) super().focusOutEvent(event)
def mousePressEvent(self, event): def mousePressEvent(self, event):

View File

@ -1,8 +1,8 @@
import time import time
import threading import threading
from typing import Protocol, cast from typing import Protocol, cast
from evdev import InputDevice, ecodes, list_devices from evdev import InputDevice, InputEvent, ecodes, list_devices, ff
import pyudev from pyudev import Context, Monitor, MonitorObserver, Device
from PySide6.QtWidgets import QWidget, QStackedWidget, QApplication, QScrollArea, QLineEdit, QDialog, QMenu, QComboBox, QListView, QMessageBox from PySide6.QtWidgets import QWidget, QStackedWidget, QApplication, QScrollArea, QLineEdit, QDialog, QMenu, QComboBox, QListView, QMessageBox
from PySide6.QtCore import Qt, QObject, QEvent, QPoint, Signal, Slot, QTimer from PySide6.QtCore import Qt, QObject, QEvent, QPoint, Signal, Slot, QTimer
from PySide6.QtGui import QKeyEvent from PySide6.QtGui import QKeyEvent
@ -10,7 +10,7 @@ from portprotonqt.logger import get_logger
from portprotonqt.image_utils import FullscreenDialog from portprotonqt.image_utils import FullscreenDialog
from portprotonqt.custom_widgets import NavLabel from portprotonqt.custom_widgets import NavLabel
from portprotonqt.game_card import GameCard from portprotonqt.game_card import GameCard
from portprotonqt.config_utils import read_fullscreen_config, read_window_geometry, save_window_geometry, read_auto_fullscreen_gamepad from portprotonqt.config_utils import read_fullscreen_config, read_window_geometry, save_window_geometry, read_auto_fullscreen_gamepad, read_rumble_config
logger = get_logger(__name__) logger = get_logger(__name__)
@ -26,7 +26,9 @@ class MainWindowProtocol(Protocol):
def toggleGame(self, exec_line: str | None, button: QWidget | None = None) -> None: def toggleGame(self, exec_line: str | None, button: QWidget | None = None) -> None:
... ...
def openSystemOverlay(self) -> None: def openSystemOverlay(self) -> None:
... ...
def on_slider_released(self) -> None:
...
stackedWidget: QStackedWidget stackedWidget: QStackedWidget
tabButtons: dict[int, QWidget] tabButtons: dict[int, QWidget]
gamesListWidget: QWidget gamesListWidget: QWidget
@ -34,25 +36,27 @@ class MainWindowProtocol(Protocol):
current_exec_line: str | None current_exec_line: str | None
current_add_game_dialog: QDialog | None current_add_game_dialog: QDialog | None
# Mapping of actions to evdev button codes, includes PlayStation, Xbox, and Switch controllers # Mapping of actions to evdev button codes, includes Xbox and PlayStation controllers
# https://github.com/torvalds/linux/blob/master/drivers/hid/hid-playstation.c
# https://github.com/torvalds/linux/blob/master/drivers/input/joystick/xpad.c
BUTTONS = { BUTTONS = {
'confirm': {ecodes.BTN_A}, 'confirm': {ecodes.BTN_SOUTH}, # A (Xbox) / Cross (PS)
'back': {ecodes.BTN_B}, 'back': {ecodes.BTN_EAST}, # B (Xbox) / Circle (PS)
'add_game': {ecodes.BTN_Y}, 'add_game': {ecodes.BTN_NORTH}, # X (Xbox) / Triangle (PS)
'prev_tab': {ecodes.BTN_TL}, 'prev_tab': {ecodes.BTN_TL}, # LB (Xbox) / L1 (PS)
'next_tab': {ecodes.BTN_TR}, 'next_tab': {ecodes.BTN_TR}, # RB (Xbox) / R1 (PS)
'confirm_stick': {ecodes.BTN_THUMBL, ecodes.BTN_THUMBR}, 'context_menu': {ecodes.BTN_START}, # Start (Xbox) / Options (PS)
'context_menu': {ecodes.BTN_START}, 'menu': {ecodes.BTN_SELECT}, # Select (Xbox) / Share (PS)
'menu': {ecodes.BTN_SELECT}, 'guide': {ecodes.BTN_MODE}, # Xbox Button / PS Button
'guide': {ecodes.BTN_MODE, ecodes.KEY_HOMEPAGE}, 'increase_size': {ecodes.ABS_RZ}, # RT (Xbox) / R2 (PS)
'decrease_size': {ecodes.ABS_Z}, # LT (Xbox) / L2 (PS)
} }
class InputManager(QObject): class InputManager(QObject):
""" """
Manages input from gamepads and keyboards for navigating the application interface. Manages input from gamepads and keyboards for navigating the application interface.
Supports gamepad hotplugging, button and axis events, and keyboard event filtering Supports gamepad hotplugging, button and axis events, and keyboard event filtering
for seamless UI interaction. Enables fullscreen mode when a gamepad is connected for seamless UI interaction.
and restores normal mode when disconnected.
""" """
# Signals for gamepad events # Signals for gamepad events
button_pressed = Signal(int) # Signal for button presses button_pressed = Signal(int) # Signal for button presses
@ -68,6 +72,7 @@ class InputManager(QObject):
): ):
super().__init__(cast(QObject, main_window)) super().__init__(cast(QObject, main_window))
self._parent = main_window self._parent = main_window
self._gamepad_handling_enabled = True
# Ensure attributes exist on main_window # Ensure attributes exist on main_window
self._parent.currentDetailPage = getattr(self._parent, 'currentDetailPage', None) self._parent.currentDetailPage = getattr(self._parent, 'currentDetailPage', None)
self._parent.current_exec_line = getattr(self._parent, 'current_exec_line', None) self._parent.current_exec_line = getattr(self._parent, 'current_exec_line', None)
@ -82,6 +87,11 @@ class InputManager(QObject):
self.gamepad_thread: threading.Thread | None = None self.gamepad_thread: threading.Thread | None = None
self.running = True self.running = True
self._is_fullscreen = read_fullscreen_config() self._is_fullscreen = read_fullscreen_config()
self.rumble_effect_id: int | None = None # Store the rumble effect ID
self.lt_pressed = False
self.rt_pressed = False
self.last_trigger_time = 0.0
self.trigger_cooldown = 0.2
# Add variables for continuous D-pad movement # Add variables for continuous D-pad movement
self.dpad_timer = QTimer(self) self.dpad_timer = QTimer(self)
@ -105,8 +115,6 @@ class InputManager(QObject):
@Slot(bool) @Slot(bool)
def handle_fullscreen_slot(self, enable: bool) -> None: def handle_fullscreen_slot(self, enable: bool) -> None:
try: try:
if read_fullscreen_config():
return
window = self._parent window = self._parent
if not isinstance(window, QWidget): if not isinstance(window, QWidget):
return return
@ -125,10 +133,64 @@ class InputManager(QObject):
except Exception as e: except Exception as e:
logger.error(f"Error in handle_fullscreen_slot: {e}", exc_info=True) logger.error(f"Error in handle_fullscreen_slot: {e}", exc_info=True)
def disable_gamepad_handling(self) -> None:
"""Отключает обработку событий геймпада."""
self._gamepad_handling_enabled = False
self.stop_rumble()
self.dpad_timer.stop()
def enable_gamepad_handling(self) -> None:
"""Включает обработку событий геймпада."""
self._gamepad_handling_enabled = True
def trigger_rumble(self, duration_ms: int = 200, strong_magnitude: int = 0x8000, weak_magnitude: int = 0x8000) -> None:
"""Trigger a rumble effect on the gamepad if supported."""
if not read_rumble_config():
return
if not self.gamepad:
return
try:
# Check if the gamepad supports force feedback
caps = self.gamepad.capabilities()
if ecodes.EV_FF not in caps or ecodes.FF_RUMBLE not in caps.get(ecodes.EV_FF, []):
logger.debug("Gamepad does not support force feedback or rumble")
return
# Create a rumble effect
rumble = ff.Rumble(strong_magnitude=strong_magnitude, weak_magnitude=weak_magnitude)
effect = ff.Effect(
id=-1, # Let evdev assign an ID
type=ecodes.FF_RUMBLE,
direction=0, # Direction (not used for rumble)
replay=ff.Replay(length=duration_ms, delay=0),
u=ff.EffectType(ff_rumble_effect=rumble)
)
# Upload the effect
self.rumble_effect_id = self.gamepad.upload_effect(effect)
# Play the effect
event = InputEvent(0, 0, ecodes.EV_FF, self.rumble_effect_id, 1)
self.gamepad.write_event(event)
# Schedule effect erasure after duration
QTimer.singleShot(duration_ms, self.stop_rumble)
except Exception as e:
logger.error(f"Error triggering rumble: {e}", exc_info=True)
def stop_rumble(self) -> None:
"""Stop the rumble effect and clean up."""
if self.gamepad and self.rumble_effect_id is not None:
try:
self.gamepad.erase_effect(self.rumble_effect_id)
self.rumble_effect_id = None
except Exception as e:
logger.error(f"Error stopping rumble: {e}", exc_info=True)
@Slot(int) @Slot(int)
def handle_button_slot(self, button_code: int) -> None: def handle_button_slot(self, button_code: int) -> None:
if not self._gamepad_handling_enabled:
return
try: try:
# Игнорировать события геймпада, если игра запущена # Ignore gamepad events if a game is launched
if getattr(self._parent, '_gameLaunched', False): if getattr(self._parent, '_gameLaunched', False):
return return
@ -147,19 +209,29 @@ class InputManager(QObject):
# Handle QMenu (context menu) # Handle QMenu (context menu)
if isinstance(popup, QMenu): if isinstance(popup, QMenu):
if button_code in BUTTONS['confirm'] or button_code in BUTTONS['confirm_stick']: if button_code in BUTTONS['confirm']:
if popup.activeAction(): if popup.activeAction():
popup.activeAction().trigger() popup.activeAction().trigger()
popup.close() popup.close()
return return
elif button_code in BUTTONS['back'] or button_code in BUTTONS['menu']: elif button_code in BUTTONS['back']:
popup.close() popup.close()
return return
return return
# Handle QMessageBox
if isinstance(active, QMessageBox):
if button_code in BUTTONS['confirm']:
active.accept() # Close QMessageBox with the default button
return
elif button_code in BUTTONS['back']:
active.reject() # Close QMessageBox on back button
return
return
# Handle QComboBox # Handle QComboBox
if isinstance(focused, QComboBox): if isinstance(focused, QComboBox):
if button_code in BUTTONS['confirm'] or button_code in BUTTONS['confirm_stick']: if button_code in BUTTONS['confirm']:
focused.showPopup() focused.showPopup()
return return
@ -173,7 +245,7 @@ class InputManager(QObject):
break break
parent = parent.parentWidget() parent = parent.parentWidget()
if button_code in BUTTONS['confirm'] or button_code in BUTTONS['confirm_stick']: if button_code in BUTTONS['confirm']:
idx = focused.currentIndex() idx = focused.currentIndex()
if idx.isValid(): if idx.isValid():
if combo: if combo:
@ -194,7 +266,7 @@ class InputManager(QObject):
focused.clearSelection() focused.clearSelection()
focused.hide() focused.hide()
# Закрытие AddGameDialog на кнопку B # Close AddGameDialog on B button
if button_code in BUTTONS['back'] and isinstance(active, QDialog): if button_code in BUTTONS['back'] and isinstance(active, QDialog):
active.reject() active.reject()
return return
@ -219,18 +291,18 @@ class InputManager(QObject):
return return
# Game launch on detail page # Game launch on detail page
if (button_code in BUTTONS['confirm'] or button_code in BUTTONS['confirm_stick']) and self._parent.currentDetailPage is not None and self._parent.current_add_game_dialog is None: if (button_code in BUTTONS['confirm']) and self._parent.currentDetailPage is not None and self._parent.current_add_game_dialog is None:
if self._parent.current_exec_line: if self._parent.current_exec_line:
self.trigger_rumble()
self._parent.toggleGame(self._parent.current_exec_line, None) self._parent.toggleGame(self._parent.current_exec_line, None)
return return
# Standard navigation # Standard navigation
if button_code in BUTTONS['confirm'] or button_code in BUTTONS['confirm_stick']: if button_code in BUTTONS['confirm']:
self._parent.activateFocusedWidget() self._parent.activateFocusedWidget()
elif button_code in BUTTONS['back'] or button_code in BUTTONS['menu']: elif button_code in BUTTONS['back']:
self._parent.goBackDetailPage(getattr(self._parent, 'currentDetailPage', None)) self._parent.goBackDetailPage(getattr(self._parent, 'currentDetailPage', None))
elif button_code in BUTTONS['add_game']: elif button_code in BUTTONS['add_game']:
# Only open AddGameDialog if in library tab (index 0)
if self._parent.stackedWidget.currentIndex() == 0: if self._parent.stackedWidget.currentIndex() == 0:
self._parent.openAddGameDialog() self._parent.openAddGameDialog()
elif button_code in BUTTONS['prev_tab']: elif button_code in BUTTONS['prev_tab']:
@ -241,6 +313,20 @@ class InputManager(QObject):
idx = (self._parent.stackedWidget.currentIndex() + 1) % len(self._parent.tabButtons) idx = (self._parent.stackedWidget.currentIndex() + 1) % len(self._parent.tabButtons)
self._parent.switchTab(idx) self._parent.switchTab(idx)
self._parent.tabButtons[idx].setFocus(Qt.FocusReason.OtherFocusReason) self._parent.tabButtons[idx].setFocus(Qt.FocusReason.OtherFocusReason)
elif button_code in BUTTONS['increase_size'] and self._parent.stackedWidget.currentIndex() == 0:
# Increase card size with RT (Xbox) / R2 (PS)
size_slider = getattr(self._parent, 'sizeSlider', None)
if size_slider:
new_value = min(size_slider.value() + 10, size_slider.maximum())
size_slider.setValue(new_value)
self._parent.on_slider_released()
elif button_code in BUTTONS['decrease_size'] and self._parent.stackedWidget.currentIndex() == 0:
# Decrease card size with LT (Xbox) / L2 (PS)
size_slider = getattr(self._parent, 'sizeSlider', None)
if size_slider:
new_value = max(size_slider.value() - 10, size_slider.minimum())
size_slider.setValue(new_value)
self._parent.on_slider_released()
except Exception as e: except Exception as e:
logger.error(f"Error in handle_button_slot: {e}", exc_info=True) logger.error(f"Error in handle_button_slot: {e}", exc_info=True)
@ -255,8 +341,10 @@ class InputManager(QObject):
@Slot(int, int, float) @Slot(int, int, float)
def handle_dpad_slot(self, code: int, value: int, current_time: float) -> None: def handle_dpad_slot(self, code: int, value: int, current_time: float) -> None:
if not self._gamepad_handling_enabled:
return
try: try:
# Игнорировать события геймпада, если игра запущена # Ignore gamepad events if a game is launched
if getattr(self._parent, '_gameLaunched', False): if getattr(self._parent, '_gameLaunched', False):
return return
@ -482,236 +570,133 @@ class InputManager(QObject):
if not app: if not app:
return super().eventFilter(obj, event) return super().eventFilter(obj, event)
# Handle only key press events # Handle key press and release events
if not (isinstance(event, QKeyEvent) and event.type() == QEvent.Type.KeyPress): if not isinstance(event, QKeyEvent):
return super().eventFilter(obj, event) return super().eventFilter(obj, event)
key = event.key() key = event.key()
modifiers = event.modifiers() modifiers = event.modifiers()
focused = QApplication.focusWidget() focused = QApplication.focusWidget()
popup = QApplication.activePopupWidget() popup = QApplication.activePopupWidget()
# Close application with Ctrl+Q
if key == Qt.Key.Key_Q and modifiers & Qt.KeyboardModifier.ControlModifier:
app.quit()
return True
# Закрытие AddGameDialog на Esc
if key == Qt.Key.Key_Escape and isinstance(popup, QDialog):
popup.reject() # Закрываем диалог
return True
# Skip navigation keys if a popup is open
if popup:
return False
# FullscreenDialog navigation
active_win = QApplication.activeWindow() active_win = QApplication.activeWindow()
if isinstance(active_win, FullscreenDialog):
if key == Qt.Key.Key_Right:
active_win.show_next()
return True
if key == Qt.Key.Key_Left:
active_win.show_prev()
return True
if key in (Qt.Key.Key_Escape, Qt.Key.Key_Return, Qt.Key.Key_Enter, Qt.Key.Key_Backspace):
active_win.close()
return True
# Launch/stop game on detail page # Handle key press events
if self._parent.currentDetailPage and key in (Qt.Key.Key_Return, Qt.Key.Key_Enter): if event.type() == QEvent.Type.KeyPress:
if self._parent.current_exec_line: # Open system overlay with Insert
self._parent.toggleGame(self._parent.current_exec_line, None) if key == Qt.Key.Key_Insert:
return True if not popup and not isinstance(active_win, QDialog):
self._parent.openSystemOverlay()
# Context menu for GameCard
if isinstance(focused, GameCard):
if key == Qt.Key.Key_F10 and Qt.KeyboardModifier.ShiftModifier:
pos = QPoint(focused.width() // 2, focused.height() // 2)
focused._show_context_menu(pos)
return True
# Handle Up/Down keys for non-GameCard tabs
if key in (Qt.Key.Key_Up, Qt.Key.Key_Down) and not isinstance(focused, GameCard):
page = self._parent.stackedWidget.currentWidget()
if key == Qt.Key.Key_Down:
if isinstance(focused, NavLabel):
focusables = page.findChildren(QWidget, options=Qt.FindChildOption.FindChildrenRecursively)
focusables = [w for w in focusables if w.focusPolicy() & Qt.FocusPolicy.StrongFocus]
if focusables:
focusables[0].setFocus()
return True
elif focused:
focused.focusNextChild()
return True
elif key == Qt.Key.Key_Up and focused:
focused.focusPreviousChild()
return True
# Tab switching with Left/Right keys (non-GameCard focus or no focus)
idx = self._parent.stackedWidget.currentIndex()
total = len(self._parent.tabButtons)
if key == Qt.Key.Key_Left and (not isinstance(focused, GameCard) or focused is None):
new = (idx - 1) % total
self._parent.switchTab(new)
self._parent.tabButtons[new].setFocus()
return True
if key == Qt.Key.Key_Right and (not isinstance(focused, GameCard) or focused is None):
new = (idx + 1) % total
self._parent.switchTab(new)
self._parent.tabButtons[new].setFocus()
return True
# Library tab navigation
if self._parent.stackedWidget.currentIndex() == 0:
game_cards = self._parent.gamesListWidget.findChildren(GameCard)
scroll_area = self._parent.gamesListWidget.parentWidget()
while scroll_area and not isinstance(scroll_area, QScrollArea):
scroll_area = scroll_area.parentWidget()
if key in (Qt.Key.Key_Left, Qt.Key.Key_Right, Qt.Key.Key_Up, Qt.Key.Key_Down):
if not game_cards:
return True return True
# If no focused widget or not a GameCard, focus the first card # Close application with Ctrl+Q
if not isinstance(focused, GameCard) or focused not in game_cards: if key == Qt.Key.Key_Q and modifiers & Qt.KeyboardModifier.ControlModifier:
game_cards[0].setFocus() app.quit()
if scroll_area: return True
scroll_area.ensureWidgetVisible(game_cards[0], 50, 50)
# Close AddGameDialog with Escape
if key == Qt.Key.Key_Escape and isinstance(popup, QDialog):
popup.reject()
return True
# FullscreenDialog navigation
if isinstance(active_win, FullscreenDialog):
if key in (Qt.Key.Key_Escape, Qt.Key.Key_Return, Qt.Key.Key_Enter, Qt.Key.Key_Backspace):
active_win.close()
return True
elif key in (Qt.Key.Key_Left, Qt.Key.Key_Right):
# Navigate screenshots in FullscreenDialog
if key == Qt.Key.Key_Left:
active_win.show_prev()
elif key == Qt.Key.Key_Right:
active_win.show_next()
return True # Consume event to prevent tab switching
# Handle tab switching with Left/Right arrow keys when not in GameCard focus
if key in (Qt.Key.Key_Left, Qt.Key.Key_Right) and (not isinstance(focused, GameCard) or focused is None):
idx = self._parent.stackedWidget.currentIndex()
total = len(self._parent.tabButtons)
if key == Qt.Key.Key_Left:
new_idx = (idx - 1) % total
self._parent.switchTab(new_idx)
self._parent.tabButtons[new_idx].setFocus(Qt.FocusReason.OtherFocusReason)
return True
elif key == Qt.Key.Key_Right:
new_idx = (idx + 1) % total
self._parent.switchTab(new_idx)
self._parent.tabButtons[new_idx].setFocus(Qt.FocusReason.OtherFocusReason)
return True return True
# Group cards by rows based on y-coordinate # Map arrow keys to D-pad press events for other contexts
rows = {} if key in (Qt.Key.Key_Up, Qt.Key.Key_Down, Qt.Key.Key_Left, Qt.Key.Key_Right):
for card in game_cards: now = time.time()
y = card.pos().y() dpad_code = None
if y not in rows: dpad_value = 0
rows[y] = [] if key == Qt.Key.Key_Up:
rows[y].append(card) dpad_code = ecodes.ABS_HAT0Y
# Sort cards in each row by x-coordinate dpad_value = -1
for y in rows:
rows[y].sort(key=lambda c: c.pos().x())
# Sort rows by y-coordinate
sorted_rows = sorted(rows.items(), key=lambda x: x[0])
# Find current row and column
current_y = focused.pos().y()
current_row_idx = next(i for i, (y, _) in enumerate(sorted_rows) if y == current_y)
current_row = sorted_rows[current_row_idx][1]
current_col_idx = current_row.index(focused)
if key == Qt.Key.Key_Right:
next_col_idx = current_col_idx + 1
if next_col_idx < len(current_row):
next_card = current_row[next_col_idx]
next_card.setFocus()
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
return True
else:
# Move to the first card of the next row if available
if current_row_idx < len(sorted_rows) - 1:
next_row = sorted_rows[current_row_idx + 1][1]
next_card = next_row[0] if next_row else None
if next_card:
next_card.setFocus()
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
return True
elif key == Qt.Key.Key_Left:
next_col_idx = current_col_idx - 1
if next_col_idx >= 0:
next_card = current_row[next_col_idx]
next_card.setFocus()
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
return True
else:
# Move to the last card of the previous row if available
if current_row_idx > 0:
prev_row = sorted_rows[current_row_idx - 1][1]
next_card = prev_row[-1] if prev_row else None
if next_card:
next_card.setFocus()
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
return True
elif key == Qt.Key.Key_Down: elif key == Qt.Key.Key_Down:
next_row_idx = current_row_idx + 1 dpad_code = ecodes.ABS_HAT0Y
if next_row_idx < len(sorted_rows): dpad_value = 1
next_row = sorted_rows[next_row_idx][1] elif key == Qt.Key.Key_Left:
target_x = focused.pos().x() dpad_code = ecodes.ABS_HAT0X
next_card = min( dpad_value = -1
next_row, elif key == Qt.Key.Key_Right:
key=lambda c: abs(c.pos().x() - target_x), dpad_code = ecodes.ABS_HAT0X
default=None dpad_value = 1
)
if next_card:
next_card.setFocus()
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
return True
elif key == Qt.Key.Key_Up:
next_row_idx = current_row_idx - 1
if next_row_idx >= 0:
next_row = sorted_rows[next_row_idx][1]
target_x = focused.pos().x()
next_card = min(
next_row,
key=lambda c: abs(c.pos().x() - target_x),
default=None
)
if next_card:
next_card.setFocus()
if scroll_area:
scroll_area.ensureWidgetVisible(next_card, 50, 50)
return True
elif current_row_idx == 0:
self._parent.tabButtons[0].setFocus()
return True
# Navigate down into tab content if dpad_code is not None:
if key == Qt.Key.Key_Down: self.dpad_moved.emit(dpad_code, dpad_value, now)
if isinstance(focused, NavLabel):
page = self._parent.stackedWidget.currentWidget()
focusables = page.findChildren(QWidget, options=Qt.FindChildOption.FindChildrenRecursively)
focusables = [w for w in focusables if w.focusPolicy() & Qt.FocusPolicy.StrongFocus]
if focusables:
focusables[0].setFocus()
return True return True
elif focused:
focused.focusNextChild() # Launch/stop game on detail page
if self._parent.currentDetailPage and key in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
if self._parent.current_exec_line:
self._parent.toggleGame(self._parent.current_exec_line, None)
return True
# Context menu for GameCard
if isinstance(focused, GameCard):
if key == Qt.Key.Key_F10 and modifiers & Qt.KeyboardModifier.ShiftModifier:
pos = QPoint(focused.width() // 2, focused.height() // 2)
focused._show_context_menu(pos)
return True
# General actions: Activate, Back, Add
if key in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
self._parent.activateFocusedWidget()
return True return True
# Navigate up through tab content elif key in (Qt.Key.Key_Escape, Qt.Key.Key_Backspace):
if key == Qt.Key.Key_Up: if isinstance(focused, QLineEdit):
if isinstance(focused, NavLabel): return False
self._parent.goBackDetailPage(self._parent.currentDetailPage)
return True return True
if focused is not None: elif key == Qt.Key.Key_E:
focused.focusPreviousChild() if isinstance(focused, QLineEdit):
return False
# Only open AddGameDialog if in library tab (index 0)
if self._parent.stackedWidget.currentIndex() == 0:
self._parent.openAddGameDialog()
return True
# Toggle fullscreen with F11
if key == Qt.Key.Key_F11:
self.toggle_fullscreen.emit(not self._is_fullscreen)
return True return True
# General actions: Activate, Back, Add # Handle key release events for arrow keys
if key in (Qt.Key.Key_Return, Qt.Key.Key_Enter): elif event.type() == QEvent.Type.KeyRelease:
self._parent.activateFocusedWidget() if key in (Qt.Key.Key_Up, Qt.Key.Key_Down, Qt.Key.Key_Left, Qt.Key.Key_Right):
return True now = time.time()
elif key in (Qt.Key.Key_Escape, Qt.Key.Key_Backspace): dpad_code = None
if isinstance(focused, QLineEdit): if key in (Qt.Key.Key_Up, Qt.Key.Key_Down):
return False dpad_code = ecodes.ABS_HAT0Y
self._parent.goBackDetailPage(self._parent.currentDetailPage) elif key in (Qt.Key.Key_Left, Qt.Key.Key_Right):
return True dpad_code = ecodes.ABS_HAT0X
elif key == Qt.Key.Key_E:
if isinstance(focused, QLineEdit):
return False
# Only open AddGameDialog if in library tab (index 0)
if self._parent.stackedWidget.currentIndex() == 0:
self._parent.openAddGameDialog()
return True
# Toggle fullscreen with F11 if dpad_code is not None:
if key == Qt.Key.Key_F11: # Emit release event with value 0 to stop continuous movement
if read_fullscreen_config(): self.dpad_moved.emit(dpad_code, 0, now)
return True return True
self.toggle_fullscreen.emit(not self._is_fullscreen)
return True
return super().eventFilter(obj, event) return super().eventFilter(obj, event)
@ -722,17 +707,17 @@ class InputManager(QObject):
def run_udev_monitor(self) -> None: def run_udev_monitor(self) -> None:
try: try:
context = pyudev.Context() context = Context()
monitor = pyudev.Monitor.from_netlink(context) monitor = Monitor.from_netlink(context)
monitor.filter_by(subsystem='input') monitor.filter_by(subsystem='input')
observer = pyudev.MonitorObserver(monitor, self.handle_udev_event) observer = MonitorObserver(monitor, self.handle_udev_event)
observer.start() observer.start()
while self.running: while self.running:
time.sleep(1) time.sleep(1)
except Exception as e: except Exception as e:
logger.error(f"Error in udev monitor: {e}", exc_info=True) logger.error(f"Error in udev monitor: {e}", exc_info=True)
def handle_udev_event(self, action: str, device: pyudev.Device) -> None: def handle_udev_event(self, action: str, device: Device) -> None:
try: try:
if action == 'add': if action == 'add':
time.sleep(0.1) time.sleep(0.1)
@ -740,6 +725,7 @@ class InputManager(QObject):
elif action == 'remove' and self.gamepad: elif action == 'remove' and self.gamepad:
if not any(self.gamepad.path == path for path in list_devices()): if not any(self.gamepad.path == path for path in list_devices()):
logger.info("Gamepad disconnected") logger.info("Gamepad disconnected")
self.stop_rumble()
self.gamepad = None self.gamepad = None
if self.gamepad_thread: if self.gamepad_thread:
self.gamepad_thread.join() self.gamepad_thread.join()
@ -753,14 +739,15 @@ class InputManager(QObject):
new_gamepad = self.find_gamepad() new_gamepad = self.find_gamepad()
if new_gamepad and new_gamepad != self.gamepad: if new_gamepad and new_gamepad != self.gamepad:
logger.info(f"Gamepad connected: {new_gamepad.name}") logger.info(f"Gamepad connected: {new_gamepad.name}")
self.stop_rumble()
self.gamepad = new_gamepad self.gamepad = new_gamepad
if self.gamepad_thread: if self.gamepad_thread:
self.gamepad_thread.join() self.gamepad_thread.join()
self.gamepad_thread = threading.Thread(target=self.monitor_gamepad, daemon=True) self.gamepad_thread = threading.Thread(target=self.monitor_gamepad, daemon=True)
self.gamepad_thread.start() self.gamepad_thread.start()
# Отправляем сигнал для полноэкранного режима только если: # Send signal for fullscreen mode only if:
# 1. auto_fullscreen_gamepad включено # 1. auto_fullscreen_gamepad is enabled
# 2. fullscreen выключено (чтобы не конфликтовать с основной настройкой) # 2. fullscreen is not already enabled (to avoid conflict)
if read_auto_fullscreen_gamepad() and not read_fullscreen_config(): if read_auto_fullscreen_gamepad() and not read_fullscreen_config():
self.toggle_fullscreen.emit(True) self.toggle_fullscreen.emit(True)
except Exception as e: except Exception as e:
@ -789,14 +776,31 @@ class InputManager(QObject):
continue continue
now = time.time() now = time.time()
if event.type == ecodes.EV_KEY and event.value == 1: if event.type == ecodes.EV_KEY and event.value == 1:
# Обработка кнопки Select для переключения полноэкранного режима
if event.code in BUTTONS['menu']: if event.code in BUTTONS['menu']:
# Переключаем полноэкранный режим
self.toggle_fullscreen.emit(not self._is_fullscreen) self.toggle_fullscreen.emit(not self._is_fullscreen)
else: else:
self.button_pressed.emit(event.code) self.button_pressed.emit(event.code)
elif event.type == ecodes.EV_ABS: elif event.type == ecodes.EV_ABS:
self.dpad_moved.emit(event.code, event.value, now) if event.code in {ecodes.ABS_Z, ecodes.ABS_RZ}:
# Проверяем, достаточно ли времени прошло с последнего срабатывания
if now - self.last_trigger_time < self.trigger_cooldown:
continue
if event.code == ecodes.ABS_Z: # LT/L2
if event.value > 128 and not self.lt_pressed:
self.lt_pressed = True
self.button_pressed.emit(event.code)
self.last_trigger_time = now
elif event.value <= 128 and self.lt_pressed:
self.lt_pressed = False
elif event.code == ecodes.ABS_RZ: # RT/R2
if event.value > 128 and not self.rt_pressed:
self.rt_pressed = True
self.button_pressed.emit(event.code)
self.last_trigger_time = now
elif event.value <= 128 and self.rt_pressed:
self.rt_pressed = False
else:
self.dpad_moved.emit(event.code, event.value, now)
except OSError as e: except OSError as e:
if e.errno == 19: # ENODEV: No such device if e.errno == 19: # ENODEV: No such device
logger.info("Gamepad disconnected during event loop") logger.info("Gamepad disconnected during event loop")
@ -807,6 +811,7 @@ class InputManager(QObject):
finally: finally:
if self.gamepad: if self.gamepad:
try: try:
self.stop_rumble()
self.gamepad.close() self.gamepad.close()
except Exception: except Exception:
pass pass
@ -816,6 +821,7 @@ class InputManager(QObject):
try: try:
self.running = False self.running = False
self.dpad_timer.stop() self.dpad_timer.stop()
self.stop_rumble()
if self.gamepad_thread: if self.gamepad_thread:
self.gamepad_thread.join() self.gamepad_thread.join()
if self.gamepad: if self.gamepad:

View File

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-10 10:25+0500\n" "POT-Creation-Date: 2025-06-14 10:37+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de_DE\n" "Language: de_DE\n"
@ -376,6 +376,12 @@ msgstr ""
msgid "Auto Fullscreen on Gamepad connected:" msgid "Auto Fullscreen on Gamepad connected:"
msgstr "" msgstr ""
msgid "Gamepad haptic feedback"
msgstr ""
msgid "Gamepad haptic feedback:"
msgstr ""
msgid "Save Settings" msgid "Save Settings"
msgstr "" msgstr ""
@ -488,9 +494,6 @@ msgstr ""
msgid "Launching" msgid "Launching"
msgstr "" msgstr ""
msgid "System Overlay"
msgstr ""
msgid "Reboot" msgid "Reboot"
msgstr "" msgstr ""

View File

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-10 10:25+0500\n" "POT-Creation-Date: 2025-06-14 10:37+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: es_ES\n" "Language: es_ES\n"
@ -376,6 +376,12 @@ msgstr ""
msgid "Auto Fullscreen on Gamepad connected:" msgid "Auto Fullscreen on Gamepad connected:"
msgstr "" msgstr ""
msgid "Gamepad haptic feedback"
msgstr ""
msgid "Gamepad haptic feedback:"
msgstr ""
msgid "Save Settings" msgid "Save Settings"
msgstr "" msgstr ""
@ -488,9 +494,6 @@ msgstr ""
msgid "Launching" msgid "Launching"
msgstr "" msgstr ""
msgid "System Overlay"
msgstr ""
msgid "Reboot" msgid "Reboot"
msgstr "" msgstr ""

View File

@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PortProtonQt 0.1.1\n" "Project-Id-Version: PortProtonQt 0.1.1\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-10 10:25+0500\n" "POT-Creation-Date: 2025-06-14 10:37+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -374,6 +374,12 @@ msgstr ""
msgid "Auto Fullscreen on Gamepad connected:" msgid "Auto Fullscreen on Gamepad connected:"
msgstr "" msgstr ""
msgid "Gamepad haptic feedback"
msgstr ""
msgid "Gamepad haptic feedback:"
msgstr ""
msgid "Save Settings" msgid "Save Settings"
msgstr "" msgstr ""
@ -486,9 +492,6 @@ msgstr ""
msgid "Launching" msgid "Launching"
msgstr "" msgstr ""
msgid "System Overlay"
msgstr ""
msgid "Reboot" msgid "Reboot"
msgstr "" msgstr ""

View File

@ -9,8 +9,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-06-10 10:25+0500\n" "POT-Creation-Date: 2025-06-14 10:37+0500\n"
"PO-Revision-Date: 2025-06-10 10:24+0500\n" "PO-Revision-Date: 2025-06-14 10:37+0500\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language: ru_RU\n" "Language: ru_RU\n"
"Language-Team: ru_RU <LL@li.org>\n" "Language-Team: ru_RU <LL@li.org>\n"
@ -383,6 +383,12 @@ msgstr "Режим полноэкранного отображения прил
msgid "Auto Fullscreen on Gamepad connected:" msgid "Auto Fullscreen on Gamepad connected:"
msgstr "Режим полноэкранного отображения приложения при подключении геймпада:" msgstr "Режим полноэкранного отображения приложения при подключении геймпада:"
msgid "Gamepad haptic feedback"
msgstr "Тактильная отдача на геймпаде"
msgid "Gamepad haptic feedback:"
msgstr "Тактильная отдача на геймпаде:"
msgid "Save Settings" msgid "Save Settings"
msgstr "Сохранить настройки" msgstr "Сохранить настройки"
@ -497,9 +503,6 @@ msgstr "Невозможно запустить игру пока запущен
msgid "Launching" msgid "Launching"
msgstr "Идёт запуск" msgstr "Идёт запуск"
msgid "System Overlay"
msgstr "Системный оверлей"
msgid "Reboot" msgid "Reboot"
msgstr "Перезагрузить" msgstr "Перезагрузить"

View File

@ -26,7 +26,7 @@ from portprotonqt.config_utils import (
read_display_filter, read_favorites, save_favorites, save_time_config, save_sort_method, read_display_filter, read_favorites, save_favorites, save_time_config, save_sort_method,
save_display_filter, save_proxy_config, read_proxy_config, read_fullscreen_config, save_display_filter, save_proxy_config, read_proxy_config, read_fullscreen_config,
save_fullscreen_config, read_window_geometry, save_window_geometry, reset_config, save_fullscreen_config, read_window_geometry, save_window_geometry, reset_config,
clear_cache, read_auto_fullscreen_gamepad, save_auto_fullscreen_gamepad clear_cache, read_auto_fullscreen_gamepad, save_auto_fullscreen_gamepad, read_rumble_config, save_rumble_config
) )
from portprotonqt.localization import _ from portprotonqt.localization import _
from portprotonqt.logger import get_logger from portprotonqt.logger import get_logger
@ -65,6 +65,7 @@ class MainWindow(QMainWindow):
self.games_load_timer.timeout.connect(self.finalize_game_loading) self.games_load_timer.timeout.connect(self.finalize_game_loading)
self.games_loaded.connect(self.on_games_loaded) self.games_loaded.connect(self.on_games_loaded)
self.current_add_game_dialog = None self.current_add_game_dialog = None
self.current_hovered_card = None
# Добавляем таймер для дебаунсинга сохранения настроек # Добавляем таймер для дебаунсинга сохранения настроек
self.settingsDebounceTimer = QTimer(self) self.settingsDebounceTimer = QTimer(self)
@ -241,6 +242,32 @@ class MainWindow(QMainWindow):
self.updateGameGrid() self.updateGameGrid()
self.progress_bar.setVisible(False) self.progress_bar.setVisible(False)
def _on_card_hovered(self, game_name: str, is_hovered: bool):
"""Обработчик сигнала hoverChanged от GameCard."""
card_key = None
# Находим ключ карточки по имени игры
for key, card in self.game_card_cache.items():
if card.name == game_name:
card_key = key
break
if not card_key:
return
card = self.game_card_cache[card_key]
if is_hovered:
# Если мышь наведена на карточку
if self.current_hovered_card and self.current_hovered_card != card:
# Сбрасываем предыдущую выделенную карточку
self.current_hovered_card._hovered = False
self.current_hovered_card.leaveEvent(None) # Принудительно вызываем leaveEvent
self.current_hovered_card = card
else:
# Если мышь покинула карточку
if self.current_hovered_card == card:
self.current_hovered_card = None
def loadGames(self): def loadGames(self):
display_filter = read_display_filter() display_filter = read_display_filter()
favorites = read_favorites() favorites = read_favorites()
@ -535,11 +562,13 @@ class MainWindow(QMainWindow):
def startSearchDebounce(self, text): def startSearchDebounce(self, text):
self.searchDebounceTimer.start() self.searchDebounceTimer.start()
def on_slider_value_changed(self, value: int): def on_slider_released(self):
self.card_width = value self.card_width = self.sizeSlider.value()
self.sizeSlider.setToolTip(f"{value} px") self.sizeSlider.setToolTip(f"{self.card_width} px")
save_card_size(value) save_card_size(self.card_width)
self.updateGameGrid() for card in self.game_card_cache.values():
card.update_card_size(self.card_width)
self.updateGameGrid()
def filterGamesDelayed(self): def filterGamesDelayed(self):
"""Filters games based on search text and updates the grid.""" """Filters games based on search text and updates the grid."""
@ -581,7 +610,7 @@ class MainWindow(QMainWindow):
self.sizeSlider.setFixedWidth(150) self.sizeSlider.setFixedWidth(150)
self.sizeSlider.setToolTip(f"{self.card_width} px") self.sizeSlider.setToolTip(f"{self.card_width} px")
self.sizeSlider.setStyleSheet(self.theme.SLIDER_SIZE_STYLE) self.sizeSlider.setStyleSheet(self.theme.SLIDER_SIZE_STYLE)
self.sizeSlider.valueChanged.connect(self.on_slider_value_changed) self.sizeSlider.sliderReleased.connect(self.on_slider_released)
sliderLayout.addWidget(self.sizeSlider) sliderLayout.addWidget(self.sizeSlider)
layout.addLayout(sliderLayout) layout.addLayout(sliderLayout)
@ -679,6 +708,7 @@ class MainWindow(QMainWindow):
card_width=self.card_width, card_width=self.card_width,
context_menu_manager=self.context_menu_manager context_menu_manager=self.context_menu_manager
) )
card.hoverChanged.connect(self._on_card_hovered)
# Подключаем сигналы контекстного меню # Подключаем сигналы контекстного меню
card.editShortcutRequested.connect(self.context_menu_manager.edit_game_shortcut) card.editShortcutRequested.connect(self.context_menu_manager.edit_game_shortcut)
card.deleteGameRequested.connect(self.context_menu_manager.delete_game) card.deleteGameRequested.connect(self.context_menu_manager.delete_game)
@ -988,6 +1018,7 @@ class MainWindow(QMainWindow):
# 6. Automatic fullscreen on gamepad connection # 6. Automatic fullscreen on gamepad connection
self.autoFullscreenGamepadCheckBox = QCheckBox(_("Auto Fullscreen on Gamepad connected")) self.autoFullscreenGamepadCheckBox = QCheckBox(_("Auto Fullscreen on Gamepad connected"))
self.autoFullscreenGamepadCheckBox.setStyleSheet(self.theme.SETTINGS_CHECKBOX_STYLE)
self.autoFullscreenGamepadCheckBox.setFocusPolicy(Qt.FocusPolicy.StrongFocus) self.autoFullscreenGamepadCheckBox.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
self.autoFullscreenGamepadCheckBox.setStyleSheet(self.theme.SETTINGS_CHECKBOX_STYLE) self.autoFullscreenGamepadCheckBox.setStyleSheet(self.theme.SETTINGS_CHECKBOX_STYLE)
self.autoFullscreenGamepadTitle = QLabel(_("Auto Fullscreen on Gamepad connected:")) self.autoFullscreenGamepadTitle = QLabel(_("Auto Fullscreen on Gamepad connected:"))
@ -997,6 +1028,17 @@ class MainWindow(QMainWindow):
self.autoFullscreenGamepadCheckBox.setChecked(current_auto_fullscreen) self.autoFullscreenGamepadCheckBox.setChecked(current_auto_fullscreen)
formLayout.addRow(self.autoFullscreenGamepadTitle, self.autoFullscreenGamepadCheckBox) formLayout.addRow(self.autoFullscreenGamepadTitle, self.autoFullscreenGamepadCheckBox)
# 7. Gamepad haptic feedback config
self.gamepadRumbleCheckBox = QCheckBox(_("Gamepad haptic feedback"))
self.gamepadRumbleCheckBox.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
self.gamepadRumbleCheckBox.setStyleSheet(self.theme.SETTINGS_CHECKBOX_STYLE)
self.gamepadRumbleTitle = QLabel(_("Gamepad haptic feedback:"))
self.gamepadRumbleTitle.setStyleSheet(self.theme.PARAMS_TITLE_STYLE)
self.gamepadRumbleTitle.setFocusPolicy(Qt.FocusPolicy.NoFocus)
current_rumble_state = read_rumble_config()
self.gamepadRumbleCheckBox.setChecked(current_rumble_state)
formLayout.addRow(self.gamepadRumbleTitle, self.gamepadRumbleCheckBox)
layout.addLayout(formLayout) layout.addLayout(formLayout)
# Кнопки # Кнопки
@ -1117,6 +1159,10 @@ class MainWindow(QMainWindow):
auto_fullscreen_gamepad = self.autoFullscreenGamepadCheckBox.isChecked() auto_fullscreen_gamepad = self.autoFullscreenGamepadCheckBox.isChecked()
save_auto_fullscreen_gamepad(auto_fullscreen_gamepad) save_auto_fullscreen_gamepad(auto_fullscreen_gamepad)
# Сохранение настройки виброотдачи геймпада
rumble_enabled = self.gamepadRumbleCheckBox.isChecked()
save_rumble_config(rumble_enabled)
for card in self.game_card_cache.values(): for card in self.game_card_cache.values():
card.update_badge_visibility(filter_key) card.update_badge_visibility(filter_key)
@ -1477,7 +1523,7 @@ class MainWindow(QMainWindow):
icon_size=16, icon_size=16,
icon_space=3, icon_space=3,
) )
anticheatLabel.setStyleSheet(self.theme.STEAM_BADGE_STYLE) anticheatLabel.setStyleSheet(self.theme.get_anticheat_badge_style(anticheat_status))
anticheatLabel.setFixedWidth(badge_width) anticheatLabel.setFixedWidth(badge_width)
anticheatLabel.clicked.connect(lambda: QDesktopServices.openUrl(QUrl(f"https://areweanticheatyet.com/game/{name.lower().replace(' ', '-')}"))) anticheatLabel.clicked.connect(lambda: QDesktopServices.openUrl(QUrl(f"https://areweanticheatyet.com/game/{name.lower().replace(' ', '-')}")))
anticheat_visible = True anticheat_visible = True
@ -1708,6 +1754,8 @@ class MainWindow(QMainWindow):
elif not child_running: elif not child_running:
# Игра завершилась сбрасываем флаг, сбрасываем кнопку и останавливаем таймер # Игра завершилась сбрасываем флаг, сбрасываем кнопку и останавливаем таймер
self._gameLaunched = False self._gameLaunched = False
if hasattr(self, 'input_manager'):
self.input_manager.enable_gamepad_handling()
self.resetPlayButton() self.resetPlayButton()
#self._uninhibit_screensaver() #self._uninhibit_screensaver()
if hasattr(self, 'checkProcessTimer') and self.checkProcessTimer is not None: if hasattr(self, 'checkProcessTimer') and self.checkProcessTimer is not None:
@ -1764,6 +1812,9 @@ class MainWindow(QMainWindow):
# Если игра уже запущена для этого exe останавливаем её по нажатию кнопки # Если игра уже запущена для этого exe останавливаем её по нажатию кнопки
if self.game_processes and self.target_exe == current_exe: if self.game_processes and self.target_exe == current_exe:
if hasattr(self, 'input_manager'):
self.input_manager.enable_gamepad_handling()
for proc in self.game_processes: for proc in self.game_processes:
try: try:
parent = psutil.Process(proc.pid) parent = psutil.Process(proc.pid)
@ -1803,6 +1854,11 @@ class MainWindow(QMainWindow):
self.target_exe = current_exe self.target_exe = current_exe
exe_name = os.path.splitext(current_exe)[0] exe_name = os.path.splitext(current_exe)[0]
env_vars = os.environ.copy() env_vars = os.environ.copy()
# Delay disabling gamepad handling to allow rumble to complete
if hasattr(self, 'input_manager'):
QTimer.singleShot(200, self.input_manager.disable_gamepad_handling)
if entry_exec_split[0] == "env" and len(entry_exec_split) > 1 and 'data/scripts/start.sh' in entry_exec_split[1]: if entry_exec_split[0] == "env" and len(entry_exec_split) > 1 and 'data/scripts/start.sh' in entry_exec_split[1]:
env_vars['START_FROM_STEAM'] = '1' env_vars['START_FROM_STEAM'] = '1'
elif entry_exec_split[0] == "flatpak": elif entry_exec_split[0] == "flatpak":
@ -1824,14 +1880,46 @@ class MainWindow(QMainWindow):
self.checkProcessTimer.start(500) self.checkProcessTimer.start(500)
def closeEvent(self, event): def closeEvent(self, event):
"""Завершает все дочерние процессы и сохраняет настройки при закрытии окна."""
# Завершаем все игровые процессы
for proc in self.game_processes: for proc in self.game_processes:
try: try:
parent = psutil.Process(proc.pid)
children = parent.children(recursive=True)
for child in children:
try:
logger.debug(f"Terminating child process {child.pid}")
child.terminate()
except psutil.NoSuchProcess:
logger.debug(f"Child process {child.pid} already terminated")
psutil.wait_procs(children, timeout=5)
for child in children:
if child.is_running():
logger.debug(f"Killing child process {child.pid}")
child.kill()
logger.debug(f"Terminating process group {proc.pid}")
os.killpg(os.getpgid(proc.pid), signal.SIGTERM) os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
except ProcessLookupError: except (psutil.NoSuchProcess, ProcessLookupError) as e:
pass # процесс уже завершился logger.debug(f"Process {proc.pid} already terminated: {e}")
self.game_processes = [] # Очищаем список процессов
# Сохраняем настройки окна
if not read_fullscreen_config(): if not read_fullscreen_config():
logger.debug(f"Saving window geometry: {self.width()}x{self.height()}")
save_window_geometry(self.width(), self.height()) save_window_geometry(self.width(), self.height())
save_card_size(self.card_width) save_card_size(self.card_width)
# Очищаем таймеры и другие ресурсы
if hasattr(self, 'games_load_timer') and self.games_load_timer.isActive():
self.games_load_timer.stop()
if hasattr(self, 'settingsDebounceTimer') and self.settingsDebounceTimer.isActive():
self.settingsDebounceTimer.stop()
if hasattr(self, 'searchDebounceTimer') and self.searchDebounceTimer.isActive():
self.searchDebounceTimer.stop()
if hasattr(self, 'checkProcessTimer') and self.checkProcessTimer and self.checkProcessTimer.isActive():
self.checkProcessTimer.stop()
self.checkProcessTimer.deleteLater()
self.checkProcessTimer = None
event.accept() event.accept()

View File

@ -1,10 +1,11 @@
import subprocess import subprocess
from PySide6.QtWidgets import QDialog, QVBoxLayout, QPushButton, QMessageBox from PySide6.QtWidgets import QDialog, QVBoxLayout, QPushButton, QMessageBox, QApplication, QWidget
from PySide6.QtWidgets import QApplication
from PySide6.QtCore import Qt from PySide6.QtCore import Qt
from portprotonqt.logger import get_logger from portprotonqt.logger import get_logger
import os import os
from portprotonqt.localization import _ from portprotonqt.localization import _
from portprotonqt.custom_widgets import AutoSizeButton
from portprotonqt.theme_manager import ThemeManager
logger = get_logger(__name__) logger = get_logger(__name__)
@ -13,44 +14,64 @@ class SystemOverlay(QDialog):
def __init__(self, parent, theme): def __init__(self, parent, theme):
super().__init__(parent) super().__init__(parent)
self.theme = theme self.theme = theme
self.setWindowTitle(_("System Overlay")) self.setWindowTitle("System Overlay")
self.setModal(True) self.setModal(True)
self.setFixedSize(400, 300) self.setFixedSize(400, 300)
self.theme_manager = ThemeManager()
self.setStyleSheet(self.theme.OVERLAY_WINDOW_STYLE)
# Убираем рамку окна
self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.Dialog)
layout = QVBoxLayout(self) layout = QVBoxLayout(self)
layout.setContentsMargins(20, 20, 20, 20) layout.setContentsMargins(20, 20, 20, 20)
layout.setSpacing(10) layout.setSpacing(10)
# Reboot button # Reboot button
reboot_button = QPushButton(_("Reboot")) reboot_button = AutoSizeButton(
_("Reboot"),
icon=self.theme_manager.get_icon("reboot")
)
reboot_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE) reboot_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE)
reboot_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus) reboot_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
reboot_button.clicked.connect(self.reboot) reboot_button.clicked.connect(self.reboot)
layout.addWidget(reboot_button) layout.addWidget(reboot_button)
# Shutdown button # Shutdown button
shutdown_button = QPushButton(_("Shutdown")) shutdown_button = AutoSizeButton(
_("Shutdown"),
icon=self.theme_manager.get_icon("shutdown")
)
shutdown_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE) shutdown_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE)
shutdown_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus) shutdown_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
shutdown_button.clicked.connect(self.shutdown) shutdown_button.clicked.connect(self.shutdown)
layout.addWidget(shutdown_button) layout.addWidget(shutdown_button)
# Suspend button # Suspend button
suspend_button = QPushButton(_("Suspend")) suspend_button = AutoSizeButton(
_("Suspend"),
icon=self.theme_manager.get_icon("suspend")
)
suspend_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE) suspend_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE)
suspend_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus) suspend_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
suspend_button.clicked.connect(self.suspend) suspend_button.clicked.connect(self.suspend)
layout.addWidget(suspend_button) layout.addWidget(suspend_button)
# Exit application button # Exit application button
exit_button = QPushButton(_("Exit Application")) exit_button = AutoSizeButton(
_("Exit Application"),
icon=self.theme_manager.get_icon("exit")
)
exit_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE) exit_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE)
exit_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus) exit_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
exit_button.clicked.connect(self.exit_application) exit_button.clicked.connect(self.exit_application)
layout.addWidget(exit_button) layout.addWidget(exit_button)
# Return to Desktop button # Return to Desktop button
desktop_button = QPushButton(_("Return to Desktop")) desktop_button = AutoSizeButton(
_("Return to Desktop"),
icon=self.theme_manager.get_icon("desktop")
)
desktop_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE) desktop_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE)
desktop_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus) desktop_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
desktop_button.clicked.connect(self.return_to_desktop) desktop_button.clicked.connect(self.return_to_desktop)
@ -62,14 +83,31 @@ class SystemOverlay(QDialog):
layout.addWidget(desktop_button) layout.addWidget(desktop_button)
# Cancel button # Cancel button
cancel_button = QPushButton(_("Cancel")) cancel_button = AutoSizeButton(
_("Cancel"),
icon=self.theme_manager.get_icon("cancel")
)
cancel_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE) cancel_button.setStyleSheet(self.theme.OVERLAY_BUTTON_STYLE)
cancel_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus) cancel_button.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
cancel_button.clicked.connect(self.reject) cancel_button.clicked.connect(self.reject)
layout.addWidget(cancel_button) layout.addWidget(cancel_button)
# Set focus to the first button def showEvent(self, event):
reboot_button.setFocus() """Override showEvent to center window and set focus."""
super().showEvent(event)
# Center window relative to parent or screen
parent = self.parent()
if isinstance(parent, QWidget) and parent.isVisible():
self.move(parent.geometry().center() - self.rect().center())
else:
screen_geometry = QApplication.primaryScreen().availableGeometry()
self.move(screen_geometry.center() - self.rect().center())
# Set focus on first button
button = self.findChild(QPushButton)
if button is not None:
button.setFocus()
def reboot(self): def reboot(self):
try: try:

View File

@ -8,6 +8,76 @@ current_theme_name = read_theme_from_config()
favoriteLabelSize = 48, 48 favoriteLabelSize = 48, 48
pixmapsScaledSize = 60, 60 pixmapsScaledSize = 60, 60
GAME_CARD_ANIMATION = {
# Ширина обводки карточки в состоянии покоя (без наведения или фокуса).
# Влияет на толщину рамки вокруг карточки, когда она не выделена.
# Значение в пикселях.
"default_border_width": 2,
# Ширина обводки при наведении курсора.
# Увеличивает толщину рамки, когда курсор находится над карточкой.
# Значение в пикселях.
"hover_border_width": 8,
# Ширина обводки при фокусе (например, при выборе с клавиатуры).
# Увеличивает толщину рамки, когда карточка в фокусе.
# Значение в пикселях.
"focus_border_width": 12,
# Минимальная ширина обводки во время пульсирующей анимации.
# Определяет минимальную толщину рамки при пульсации (анимация "дыхания").
# Значение в пикселях.
"pulse_min_border_width": 8,
# Максимальная ширина обводки во время пульсирующей анимации.
# Определяет максимальную толщину рамки при пульсации.
# Значение в пикселях.
"pulse_max_border_width": 10,
# Длительность анимации изменения толщины обводки (например, при наведении или фокусе).
# Влияет на скорость перехода от одной ширины обводки к другой.
# Значение в миллисекундах.
"thickness_anim_duration": 300,
# Длительность одного цикла пульсирующей анимации.
# Определяет, как быстро рамка "пульсирует" между min и max значениями.
# Значение в миллисекундах.
"pulse_anim_duration": 800,
# Длительность анимации вращения градиента.
# Влияет на скорость, с которой градиентная обводка вращается вокруг карточки.
# Значение в миллисекундах.
"gradient_anim_duration": 3000,
# Начальный угол градиента (в градусах).
# Определяет начальную точку вращения градиента при старте анимации.
"gradient_start_angle": 360,
# Конечный угол градиента (в градусах).
# Определяет конечную точку вращения градиента.
# Значение 0 означает полный поворот на 360 градусов.
"gradient_end_angle": 0,
# Тип кривой сглаживания для анимации увеличения обводки (при наведении/фокусе).
# Влияет на "чувство" анимации (например, плавное ускорение или замедление).
# Возможные значения: строки, соответствующие QEasingCurve.Type (например, "OutBack", "InOutQuad").
"thickness_easing_curve": "OutBack",
# Тип кривой сглаживания для анимации уменьшения обводки (при уходе курсора/потере фокуса).
# Влияет на "чувство" возврата к исходной ширине обводки.
"thickness_easing_curve_out": "InBack",
# Цвета градиента для анимированной обводки.
# Список словарей, где каждый словарь задает позицию (0.01.0) и цвет в формате hex.
# Влияет на внешний вид обводки при наведении или фокусе.
"gradient_colors": [
{"position": 0, "color": "#00fff5"}, # Начальный цвет (циан)
{"position": 0.33, "color": "#FF5733"}, # Цвет на 33% (оранжевый)
{"position": 0.66, "color": "#9B59B6"}, # Цвет на 66% (пурпурный)
{"position": 1, "color": "#00fff5"} # Конечный цвет (возвращение к циану)
]
}
# СТИЛЬ ШАПКИ ГЛАВНОГО ОКНА # СТИЛЬ ШАПКИ ГЛАВНОГО ОКНА
MAIN_WINDOW_HEADER_STYLE = """ MAIN_WINDOW_HEADER_STYLE = """
QFrame { QFrame {
@ -416,6 +486,26 @@ def get_protondb_badge_style(tier):
font-weight: bold; font-weight: bold;
""" """
def get_anticheat_badge_style(status):
status = status.lower()
status_colors = {
"supported": {"background": "rgba(102, 168, 15, 0.7)", "color": "black"},
"running": {"background": "rgba(25, 113, 194, 0.7)", "color": "black"},
"planned": {"background": "rgba(156, 54, 181, 0.7)", "color": "black"},
"broken": {"background": "rgba(232, 89, 12, 0.7)", "color": "black"},
"denied": {"background": "rgba(224, 49, 49, 0.7)", "color": "black"}
}
colors = status_colors.get(status, {"background": "rgba(0, 0, 0, 0.5)", "color": "white"})
return f"""
qproperty-alignment: AlignCenter;
background-color: {colors["background"]};
color: {colors["color"]};
font-size: 14px;
border-radius: 5px;
font-family: 'Poppins';
font-weight: bold;
"""
# СТИЛИ БЕЙДЖА STEAM # СТИЛИ БЕЙДЖА STEAM
STEAM_BADGE_STYLE= """ STEAM_BADGE_STYLE= """
qproperty-alignment: AlignCenter; qproperty-alignment: AlignCenter;

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.8581 0-7 3.1419-7 7s3.1419 7 7 7 7-3.1419 7-7-3.1419-7-7-7zm0 1.3988c3.1014 0 5.6012 2.4998 5.6012 5.6012s-2.4998 5.6012-5.6012 5.6012-5.6012-2.4998-5.6012-5.6012 2.4998-5.6012 5.6012-5.6012zm-2.1002 3.501a0.70007 0.70007 0 0 0-0.69938 0.69938 0.70007 0.70007 0 0 0 0.69938 0.70144h0.0062a0.70007 0.70007 0 0 0 0.70144-0.70144 0.70007 0.70007 0 0 0-0.70144-0.69938zm4.2004 0a0.70007 0.70007 0 0 0-0.69938 0.69938 0.70007 0.70007 0 0 0 0.69938 0.70144h0.0062a0.70007 0.70007 0 0 0 0.70144-0.70144 0.70007 0.70007 0 0 0-0.70144-0.69938zm-2.1002 2.9452c-0.81784 0-1.6354 0.31214-2.2499 0.93935a0.70007 0.70007 0 0 0 0.01026 0.99062 0.70007 0.70007 0 0 0 0.98857-0.01026c0.69244-0.70672 1.8098-0.70672 2.5022 0a0.70007 0.70007 0 0 0 0.98857 0.01026 0.70007 0.70007 0 0 0 0.01026-0.99062c-0.61461-0.62721-1.4321-0.93935-2.2499-0.93935z" stop-color="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.0501"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m8.4694 1c-0.38007 0-0.76931 0.12326-1.0795 0.39899-0.24769 0.22016-0.42499 0.54342-0.48662 0.90798-0.11341-0.02303-0.22892-0.03356-0.34306-0.03356-0.38003 0-0.76934 0.12329-1.0795 0.39899s-0.51086 0.71412-0.51086 1.1914v3.2534c-0.58842-0.47053-1.4218-0.53407-2.0788-0.13983-0.73301 0.43947-0.98585 1.3992-0.56679 2.1441 1.1968 2.1273 1.8635 3.2982 2.1124 3.6804h-0.0019c0.04201 0.06466 0.08444 0.12946 0.12678 0.1939 0.78928 1.1985 2.1179 1.8996 3.5443 1.9595a0.63645 0.63645 0 0 0 0.04475 0.044746h1.2734c2.4527 0 4.4541-2.0014 4.4541-4.4541v-5.4087c0-0.47729-0.20066-0.9175-0.51085-1.1932-0.31015-0.27573-0.69944-0.39899-1.0795-0.39899-0.11425 0-0.22955 0.010492-0.34306 0.03356-0.0619-0.36382-0.23934-0.68631-0.48662-0.90611-0.3102-0.27573-0.69944-0.39899-1.0795-0.39899-0.11414 0-0.22964 0.010534-0.34306 0.03356-0.06162-0.36456-0.23893-0.68781-0.48662-0.90798-0.3102-0.27573-0.69944-0.39899-1.0795-0.39899zm0 1.2734c0.09723 0 0.18528 0.033977 0.23305 0.076442 0.04778 0.042465 0.08576 0.081413 0.08576 0.24051v5.4106a0.63639 0.63639 0 0 0 0.63577 0.63577 0.63639 0.63639 0 0 0 0.63577-0.63577v-4.1353a0.63639 0.63639 0 0 0 0-0.00186c0-0.1591 0.038-0.19805 0.08576-0.24051 0.04778-0.042465 0.13583-0.078306 0.23305-0.078306 0.09723 0 0.18528 0.035841 0.23305 0.078306 0.04778 0.042465 0.08576 0.081413 0.08576 0.24051v4.1372a0.63639 0.63639 0 0 0 0.63577 0.63577 0.63639 0.63639 0 0 0 0.63577-0.63577v-2.8619a0.63639 0.63639 0 0 0 0-0.00186c0-0.1591 0.03799-0.19805 0.08576-0.24051 0.04777-0.042465 0.13583-0.078306 0.23305-0.078306 0.09723 0 0.18528 0.035841 0.23305 0.078306s0.08576 0.081413 0.08576 0.24051v5.4087c0 1.7649-1.4177 3.1826-3.1826 3.1826h-1.141c-1.0712 1.81e-4 -2.0676-0.53724-2.6568-1.4319-0.04114-0.06262-0.08223-0.12548-0.12305-0.18831-0.14817-0.22748-0.8766-1.4876-2.0714-3.6114-0.08788-0.1562-0.03999-0.33666 0.11373-0.42882a0.63645 0.63645 0 0 0 0.0019 0c0.2198-0.13189 0.4917-0.097253 0.67306 0.083899l0.92662 0.92476 0.0093 0.00932a0.63639 0.63639 0 0 0 0.01492 0.011187 0.63623 0.63623 0 0 0 0.04847 0.042882 0.63623 0.63623 0 0 0 0.06898 0.046611 0.63623 0.63623 0 0 0 0.07458 0.037289 0.63623 0.63623 0 0 0 0.07831 0.026102 0.63623 0.63623 0 0 0 0.07831 0.01678 0.63639 0.63639 0 0 0 0.0037 0 0.63623 0.63623 0 0 0 0.08203 0.00559 0.63623 0.63623 0 0 0 0.08203-0.00559 0.63639 0.63639 0 0 0 0.36729-0.18085 0.63623 0.63623 0 0 0 0.05407-0.063391 0.63639 0.63639 0 0 0 0.04661-0.068984 0.63623 0.63623 0 0 0 0.08576-0.31695v-4.7729c0-0.15914 0.03796-0.19802 0.08576-0.24051 0.04781-0.042493 0.13579-0.078306 0.23305-0.078306s0.18525 0.035813 0.23305 0.078306c0.04781 0.042493 0.08576 0.081374 0.08576 0.24051v4.1372a0.63623 0.63623 0 0 0 0.63577 0.63577 0.63623 0.63623 0 0 0 0.63577-0.63577v-4.1353a0.63639 0.63639 0 0 0 0-0.00186v-1.2734c0-0.1591 0.038-0.19805 0.08576-0.24051 0.04778-0.042465 0.13583-0.076442 0.23305-0.076442z" stop-color="#000000" stroke-width="0"/></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m4.499 1c-0.76498 0-1.3988 0.63379-1.3988 1.3988v1.4008c0 1.5752 0.61452 2.8449 1.5464 3.6733 0.22594 0.20084 0.46887 0.37639 0.724 0.5271-0.25512 0.15071-0.49805 0.32626-0.724 0.5271-0.93192 0.82837-1.5464 2.0982-1.5464 3.6733v1.4008c0 0.76498 0.63379 1.3988 1.3988 1.3988h7.002c0.76498 0 1.3988-0.63379 1.3988-1.3988v-1.4008c0-1.5752-0.61452-2.8449-1.5464-3.6733-0.22594-0.20084-0.46887-0.37639-0.724-0.5271 0.25513-0.15071 0.49805-0.32626 0.724-0.5271 0.93192-0.82837 1.5464-2.0982 1.5464-3.6733v-1.4008c0-0.76498-0.63379-1.3988-1.3988-1.3988zm0 1.3988h7.002v1.4008h-7.002zm0.23381 2.8016h6.5344c-0.18996 0.50569-0.4851 0.90658-0.845 1.2265-0.64324 0.57176-1.5277 0.87372-2.4222 0.87372s-1.779-0.30195-2.4222-0.87372c-0.3599-0.31991-0.65504-0.7208-0.845-1.2265zm3.2672 3.499c0.89453 0 1.779 0.30195 2.4222 0.87372 0.3599 0.31991 0.65504 0.7208 0.845 1.2265h-6.5344c0.18996-0.50569 0.4851-0.90658 0.845-1.2265 0.64324-0.57176 1.5277-0.87372 2.4222-0.87372zm-3.501 3.501h7.002v1.4008h-7.002z" stop-color="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.0501"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m9.3899 1a1.4351 1.4351 0 0 0-1.4349 1.4349 1.4351 1.4351 0 0 0 1.4349 1.4349 1.4351 1.4351 0 0 0 1.4349-1.4349 1.4351 1.4351 0 0 0-1.4349-1.4349zm-0.73373 3.5667a0.69575 0.69575 0 0 0-0.01427 0.00204 0.69568 0.69568 0 0 0-0.0591 0.00611 0.69575 0.69575 0 0 0-0.02446 0.00408 0.69568 0.69568 0 0 0-0.02038 0.00408l-3.4567 0.69093a0.69575 0.69575 0 0 0-0.56049 0.68278v2.0871a0.69568 0.69568 0 0 0 0.69704 0.69501 0.69568 0.69568 0 0 0 0.69501-0.69501v-1.5164l1.9322-0.38725-0.53196 3.1815a0.69575 0.69575 0 0 0 0.26904 0.67055l2.5049 1.8771v2.4356a0.69568 0.69568 0 0 0 0.69501 0.69501 0.69568 0.69568 0 0 0 0.69704-0.69501v-2.7821a0.69575 0.69575 0 0 0-0.27922-0.55641l-2.4437-1.8343 0.40355-2.4234 1.1312 1.1312a0.69575 0.69575 0 0 0 0.27107 0.16713l2.0871 0.69704a0.69568 0.69568 0 0 0 0.88048-0.44024 0.69568 0.69568 0 0 0-0.44024-0.88048l-1.9301-0.64405-1.9709-1.9709a0.69575 0.69575 0 0 0-0.05095-0.044839 0.69568 0.69568 0 0 0-0.0061-0.00408 0.69575 0.69575 0 0 0-0.04076-0.030572 0.69568 0.69568 0 0 0-0.05911-0.036687 0.69575 0.69575 0 0 0-0.04892-0.024458 0.69568 0.69568 0 0 0-0.0061-0.00204 0.69575 0.69575 0 0 0-0.06318-0.024458 0.69568 0.69568 0 0 0-0.10394-0.026496 0.69568 0.69568 0 0 0-0.0163-0.00204 0.69575 0.69575 0 0 0-0.13656-0.00611zm-1.5673 5.9127a0.69568 0.69568 0 0 0-0.58087 0.38317l-0.2833 0.56864-2.9573-0.59106a0.69568 0.69568 0 0 0-0.81933 0.54622 0.69568 0.69568 0 0 0 0.54622 0.8173l3.4771 0.69704a0.69575 0.69575 0 0 0 0.76023-0.37094l0.52176-1.0435a0.69568 0.69568 0 0 0-0.31184-0.93347 0.69568 0.69568 0 0 0-0.3526-0.07337z" stop-color="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.0435"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m11.896 0.99999a0.77558 0.77558 0 0 0-0.04089 0.0023c-2.9888 0.16296-5.5645 2.0598-6.7001 4.803-1.6574 0.22304-3.1671 1.0967-4.0123 2.5628a0.7755 0.7755 0 0 0-0.03181 0.2431 0.7755 0.7755 0 0 0-0.06589 0.052255 0.7755 0.7755 0 0 0 0.04998 0.063615 0.7755 0.7755 0 0 0 0.33171 0.69977 0.7755 0.7755 0 0 0 0.18176-0.047712 0.7755 0.7755 0 0 0 0.11587 0.14768c0.30901 0.036723 0.60932 0.09847 0.8997 0.18403-1.1944 1.1741-1.8021 2.8615-1.579 4.5735a0.77558 0.77558 0 0 0 0.67023 0.67023c1.712 0.22304 3.3994-0.38463 4.5735-1.579 0.08557 0.29041 0.1473 0.59066 0.18403 0.8997a0.77558 0.77558 0 0 0 1.1587 0.58163c1.4661-0.84521 2.3398-2.3549 2.5628-4.0123 2.7432-1.1355 4.64-3.7113 4.803-6.7001a0.77558 0.77558 0 0 0 0.0023-0.0409c0-1.704-1.3995-3.1035-3.1035-3.1035zm0.02045 1.5608c0.84612 0.01261 1.5096 0.67611 1.5222 1.5222-0.14636 2.4969-1.7648 4.6608-4.1259 5.4914a0.77558 0.77558 0 0 0-0.51801 0.70658c-0.03211 0.97216-0.51756 1.7993-1.1746 2.481-0.10516-0.31723-0.23158-0.62236-0.37715-0.91561a0.7755 0.7755 0 0 0-0.36352-0.64751c-0.53452-0.83732-1.2415-1.5443-2.0789-2.0789a0.7755 0.7755 0 0 0-0.64751-0.36352c-0.29324-0.14557-0.59838-0.27199-0.91561-0.37715 0.68166-0.65705 1.5088-1.1425 2.481-1.1746a0.77558 0.77558 0 0 0 0.70658-0.51801c0.83059-2.3611 2.9944-3.9795 5.4914-4.1259zm-1.5699 1.5427c-0.36621 0-0.74435 0.11713-1.0497 0.38851-0.3053 0.27138-0.50211 0.7086-0.50211 1.161s0.19681 0.89187 0.50211 1.1633c0.3053 0.27138 0.68345 0.38851 1.0497 0.38851 0.36621 0 0.74208-0.11713 1.0474-0.38851 0.3053-0.27138 0.50211-0.71088 0.50211-1.1633s-0.19681-0.8896-0.50211-1.161c-0.3053-0.27138-0.68117-0.38851-1.0474-0.38851zm-6.1843 6.3388c0.54645 0.37575 1.0192 0.84854 1.395 1.395-0.66921 0.88979-1.7235 1.346-2.8377 1.4427 0.09666-1.1142 0.55292-2.1685 1.4427-2.8377z" stop-color="#000000" stroke-width="0"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m8 15q-1.4525 0-2.73-0.55125t-2.2225-1.4962-1.4962-2.2225-0.55125-2.73 0.55125-2.73 1.4962-2.2225 2.2225-1.4962 2.73-0.55125 2.73 0.55125 2.2225 1.4962 1.4962 2.2225 0.55125 2.73-0.55125 2.73-1.4962 2.2225-2.2225 1.4962-2.73 0.55125zm0-1.4q0.945 0 1.82-0.30625t1.61-0.88375l-7.84-7.84q-0.5775 0.735-0.88375 1.61t-0.30625 1.82q0 2.345 1.6275 3.9725t3.9725 1.6275zm4.41-2.17q0.5775-0.735 0.88375-1.61t0.30625-1.82q0-2.345-1.6275-3.9725t-3.9725-1.6275q-0.945 0-1.82 0.30625t-1.61 0.88375z" fill="#fff" stroke-width=".0175"/></svg>

After

Width:  |  Height:  |  Size: 655 B

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m6.5845 11.474-3.2932-3.2932 0.82331-0.82331 2.4699 2.4699 5.3009-5.3009 0.8233 0.82331z" fill="#fff" stroke-width=".014444"/></svg>

After

Width:  |  Height:  |  Size: 260 B

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m1 15v-1.5556h14v1.5556zm1.9091-2.3333q-0.525 0-0.89886-0.45694-0.37386-0.45694-0.37386-1.0986v-8.5556q0-0.64167 0.37386-1.0986 0.37386-0.45694 0.89886-0.45694h10.182q0.525 0 0.89886 0.45694 0.37386 0.45694 0.37386 1.0986v8.5556q0 0.64167-0.37386 1.0986-0.37386 0.45694-0.89886 0.45694zm0-1.5556h10.182v-8.5556h-10.182zm0 0v-8.5556z" fill="#fff" stroke-width=".017588"/></svg>

After

Width:  |  Height:  |  Size: 504 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m8 1v1.5547h5.4453v10.891h-5.4453v1.5547h5.4453c0.42777-7e-6 0.79303-0.15241 1.0977-0.45703 0.30463-0.30462 0.45703-0.66988 0.45703-1.0977v-10.891c0-0.42777-0.1524-0.79303-0.45703-1.0977-0.30462-0.30463-0.66988-0.45703-1.0977-0.45703h-5.4453zm-3.1113 3.1113-3.8887 3.8887 3.8887 3.8887 1.0703-1.127-1.9844-1.9844h6.3594v-1.5547h-6.3594l1.9844-1.9844-1.0703-1.127z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 512 B

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.86 0-7 3.1403-7 7s3.14 7 7 7 7-3.1403 7-7-3.14-7-7-7zm-4.0784 3.3478h1.7655c0.26874 0 0.48684 0.21779 0.48684 0.48684v2.9828c0 0.26904-0.21779 0.48684-0.48684 0.48684h-2.2523v-0.6087h1.9479c0.10074 0 0.18249-0.08175 0.18249-0.18249v-2.3742c0-0.10074-0.08175-0.18249-0.18249-0.18249h-1.1568c-0.10074 0-0.18249 0.08175-0.18249 0.18249v1.1568c0 0.10074 0.08175 0.18249 0.18249 0.18249h0.88273v0.6087h-1.1871c-0.26874 0-0.48684-0.2178-0.48684-0.48684v-1.7655c0-0.26904 0.21779-0.48684 0.48684-0.48684zm3.1957 0h1.7655c0.26843 0 0.48684 0.2184 0.48684 0.48684v1.7655c0 0.26844-0.2184 0.48684-0.48684 0.48684h-1.7655c-0.26843 0-0.48684-0.2184-0.48684-0.48684v-1.7655c0-0.26844 0.2184-0.48684 0.48684-0.48684zm3.1957 0h1.7655c0.26874 0 0.48684 0.21779 0.48684 0.48684v2.9828c0 0.26904-0.21779 0.48684-0.48684 0.48684h-2.2523v-0.6087h1.9479c0.10074 0 0.18249-0.08175 0.18249-0.18249v-2.3742c0-0.10074-0.08175-0.18249-0.18249-0.18249h-1.1568c-0.10074 0-0.18249 0.08175-0.18249 0.18249v1.1568c0 0.10074 0.08175 0.18249 0.18249 0.18249h0.88273v0.6087h-1.1871c-0.26874 0-0.48684-0.2178-0.48684-0.48684v-1.7655c0-0.26904 0.21779-0.48684 0.48684-0.48684zm-2.8913 0.6087c-0.10074 0-0.18249 0.08175-0.18249 0.18249v1.1568c0 0.10074 0.08175 0.18249 0.18249 0.18249h1.1568c0.10074 0 0.18249-0.08175 0.18249-0.18249v-1.1568c0-0.10074-0.08175-0.18249-0.18249-0.18249zm-3.5 3.9565h1.7958v0.6087h-1.4914c-0.10074 0-0.18249 0.08175-0.18249 0.18249v1.1568c0 0.10074 0.08175 0.18249 0.18249 0.18249h1.4914v0.6087h-1.7958c-0.26874 0-0.48684-0.21779-0.48684-0.48684v-1.7655c0-0.26874 0.21779-0.48684 0.48684-0.48684zm2.7391 0h1.7655c0.26844 0 0.48684 0.2184 0.48684 0.48684v1.7655c0 0.26844-0.2184 0.48684-0.48684 0.48684h-1.7655c-0.26844 0-0.48684-0.2184-0.48684-0.48684v-1.7655c0-0.26844 0.2184-0.48684 0.48684-0.48684zm3.1957 0h2.7088v2.7391h-0.6087v-2.1304h-0.50229c-0.10074 0-0.18249 0.08175-0.18249 0.18249v1.9479h-0.6087v-2.1304h-0.50229c-0.10074 0-0.18249 0.08175-0.18249 0.18249v1.9479h-0.6087v-2.2523c0-0.26874 0.21779-0.48684 0.48684-0.48684zm-2.8913 0.6087c-0.10074 0-0.18249 0.08175-0.18249 0.18249v1.1568c0 0.10074 0.08175 0.18249 0.18249 0.18249h1.1568c0.10074 0 0.18249-0.08175 0.18249-0.18249v-1.1568c0-0.10074-0.08175-0.18249-0.18249-0.18249z" fill="#fff" stroke-width=".30435"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m8 15v-1.5556h5.4444v-10.889h-5.4444v-1.5556h5.4444q0.64167 0 1.0986 0.45694 0.45694 0.45694 0.45694 1.0986v10.889q0 0.64167-0.45694 1.0986t-1.0986 0.45694zm-1.5556-3.1111-1.0694-1.1278 1.9833-1.9833h-6.3583v-1.5556h6.3583l-1.9833-1.9833 1.0694-1.1278 3.8889 3.8889z" fill="#fff" stroke-width=".019444"/></svg>

After

Width:  |  Height:  |  Size: 438 B

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m8 15q-1.4583 0-2.7319-0.55417-1.2735-0.55417-2.2167-1.4972-0.94313-0.94306-1.4972-2.2167t-0.55417-2.7319q-7.699e-5 -1.4583 0.55417-2.7319 0.55424-1.2736 1.4972-2.2167 0.94298-0.94306 2.2167-1.4972 1.2737-0.55417 2.7319-0.55417 1.5944 0 3.0237 0.68056 1.4292 0.68056 2.4208 1.925v-1.8278h1.5556v4.6667h-4.6667v-1.5556h2.1389q-0.79722-1.0889-1.9639-1.7111-1.1667-0.62222-2.5083-0.62222-2.275 0-3.8596 1.5848-1.5846 1.5848-1.5848 3.8596-1.55e-4 2.2748 1.5848 3.8596 1.585 1.5848 3.8596 1.5848 2.0417 0 3.5681-1.3222t1.7985-3.3444h1.5944q-0.29167 2.6639-2.2848 4.443-1.9931 1.7791-4.6763 1.7792z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 741 B

View File

@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m8 15q-1.4525 0-2.73-0.55125t-2.2225-1.4962-1.4962-2.2225-0.55125-2.73q0-1.47 0.55125-2.7388t1.4962-2.2138l0.98 0.98q-0.77 0.77-1.1988 1.785t-0.42875 2.1875q0 2.345 1.6275 3.9725t3.9725 1.6275 3.9725-1.6275 1.6275-3.9725q0-1.1725-0.42875-2.1875t-1.1988-1.785l0.98-0.98q0.945 0.945 1.4962 2.2138t0.55125 2.7388q0 1.4525-0.55125 2.73t-1.4962 2.2225-2.2225 1.4962-2.73 0.55125zm-0.7-6.3v-7.7h1.4v7.7z" fill="#fff" stroke-width=".0175"/></svg>

After

Width:  |  Height:  |  Size: 567 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 621 KiB

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -8,13 +8,79 @@ current_theme_name = read_theme_from_config()
favoriteLabelSize = 48, 48 favoriteLabelSize = 48, 48
pixmapsScaledSize = 60, 60 pixmapsScaledSize = 60, 60
GAME_CARD_ANIMATION = {
# Ширина обводки карточки в состоянии покоя (без наведения или фокуса).
# Влияет на толщину рамки вокруг карточки, когда она не выделена.
# Значение в пикселях.
"default_border_width": 2,
# Ширина обводки при наведении курсора.
# Увеличивает толщину рамки, когда курсор находится над карточкой.
# Значение в пикселях.
"hover_border_width": 8,
# Ширина обводки при фокусе (например, при выборе с клавиатуры).
# Увеличивает толщину рамки, когда карточка в фокусе.
# Значение в пикселях.
"focus_border_width": 12,
# Минимальная ширина обводки во время пульсирующей анимации.
# Определяет минимальную толщину рамки при пульсации (анимация "дыхания").
# Значение в пикселях.
"pulse_min_border_width": 8,
# Максимальная ширина обводки во время пульсирующей анимации.
# Определяет максимальную толщину рамки при пульсации.
# Значение в пикселях.
"pulse_max_border_width": 10,
# Длительность анимации изменения толщины обводки (например, при наведении или фокусе).
# Влияет на скорость перехода от одной ширины обводки к другой.
# Значение в миллисекундах.
"thickness_anim_duration": 300,
# Длительность одного цикла пульсирующей анимации.
# Определяет, как быстро рамка "пульсирует" между min и max значениями.
# Значение в миллисекундах.
"pulse_anim_duration": 800,
# Длительность анимации вращения градиента.
# Влияет на скорость, с которой градиентная обводка вращается вокруг карточки.
# Значение в миллисекундах.
"gradient_anim_duration": 3000,
# Начальный угол градиента (в градусах).
# Определяет начальную точку вращения градиента при старте анимации.
"gradient_start_angle": 360,
# Конечный угол градиента (в градусах).
# Определяет конечную точку вращения градиента.
# Значение 0 означает полный поворот на 360 градусов.
"gradient_end_angle": 0,
# Тип кривой сглаживания для анимации увеличения обводки (при наведении/фокусе).
# Влияет на "чувство" анимации (например, плавное ускорение или замедление).
# Возможные значения: строки, соответствующие QEasingCurve.Type (например, "OutBack", "InOutQuad").
"thickness_easing_curve": "OutBack",
# Тип кривой сглаживания для анимации уменьшения обводки (при уходе курсора/потере фокуса).
# Влияет на "чувство" возврата к исходной ширине обводки.
"thickness_easing_curve_out": "InBack",
# Цвета градиента для анимированной обводки.
# Список словарей, где каждый словарь задает позицию (0.01.0) и цвет в формате hex.
# Влияет на внешний вид обводки при наведении или фокусе.
"gradient_colors": [
{"position": 0, "color": "#00fff5"}, # Начальный цвет (циан)
{"position": 0.33, "color": "#FF5733"}, # Цвет на 33% (оранжевый)
{"position": 0.66, "color": "#9B59B6"}, # Цвет на 66% (пурпурный)
{"position": 1, "color": "#00fff5"} # Конечный цвет (возвращение к циану)
]
}
CONTEXT_MENU_STYLE = """ CONTEXT_MENU_STYLE = """
QMenu { QMenu {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0, background: #282a33;;
stop:0 rgba(40, 40, 40, 0.95),
stop:1 rgba(25, 25, 25, 0.95));
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 12px;
color: #ffffff; color: #ffffff;
font-family: 'Play'; font-family: 'Play';
font-size: 16px; font-size: 16px;
@ -27,12 +93,12 @@ CONTEXT_MENU_STYLE = """
color: #ffffff; color: #ffffff;
} }
QMenu::item:selected { QMenu::item:selected {
background: #282a33; background: #409EFF;
color: #09bec8; color: #ffffff;
} }
QMenu::item:hover { QMenu::item:hover {
background: #282a33; background: #409EFF;
color: #09bec8; color: #ffffff;
} }
QMenu::item:focus { QMenu::item:focus {
background: #409EFF; background: #409EFF;
@ -67,7 +133,7 @@ TITLE_LABEL_STYLE = """
# СТИЛЬ ОБЛАСТИ НАВИГАЦИИ (КНОПКИ ВКЛАДОК) # СТИЛЬ ОБЛАСТИ НАВИГАЦИИ (КНОПКИ ВКЛАДОК)
NAV_WIDGET_STYLE = """ NAV_WIDGET_STYLE = """
QWidget { QWidget {
background: none; background: #282a33;
border: 0px solid; border: 0px solid;
} }
""" """
@ -82,19 +148,19 @@ NAV_BUTTON_STYLE = """
font-family: 'Play'; font-family: 'Play';
font-size: 16px; font-size: 16px;
text-transform: uppercase; text-transform: uppercase;
border: none; border: #409EFF;
border-radius: 15px; border-radius: 15px;
} }
NavLabel[checked = true] { NavLabel[checked = true] {
background: rgba(0,122,255,0); background: rgba(0,122,255,0);
color: #09bec8; color: #409EFF;
font-weight: normal; font-weight: normal;
text-decoration: underline; text-decoration: underline;
border-radius: 15px; border-radius: 15px;
} }
NavLabel:hover { NavLabel:hover {
background: none; background: none;
color: #09bec8; color: #409EFF;
} }
""" """
@ -120,7 +186,7 @@ SEARCH_EDIT_STYLE = """
color: #ffffff; color: #ffffff;
} }
QLineEdit:focus { QLineEdit:focus {
border: 1px solid #09bec8; border: 1px solid #409EFF;
} }
""" """
@ -228,7 +294,7 @@ INSTALLED_TAB_TITLE_STYLE = "font-family: 'Play'; font-size: 24px; color: #fffff
ACTION_BUTTON_STYLE = """ ACTION_BUTTON_STYLE = """
QPushButton { QPushButton {
background: #3f424d; background: #3f424d;
border: 1px solid rgba(255, 255, 255, 0.20); border: 2px solid rgba(255, 255, 255, 0.01);
border-radius: 10px; border-radius: 10px;
color: #ffffff; color: #ffffff;
font-size: 16px; font-size: 16px;
@ -236,36 +302,40 @@ ACTION_BUTTON_STYLE = """
padding: 8px 16px; padding: 8px 16px;
} }
QPushButton:hover { QPushButton:hover {
background: #282a33; background: #409EFF;
border: 2px solid #409EFF;
} }
QPushButton:pressed { QPushButton:pressed {
background: #282a33; background: #282a33;
} }
QPushButton:focus { QPushButton:focus {
border: 2px solid #409EFF; border: 2px solid #409EFF;
background-color: #404554; background-color: #409EFF;
} }
""" """
# СТИЛЬ КНОПОК ОВЕРЛЕЯ # СТИЛЬ ОВЕРЛЕЯ
OVERLAY_WINDOW_STYLE = "background: #282a33;"
OVERLAY_BUTTON_STYLE = """ OVERLAY_BUTTON_STYLE = """
QPushButton { QPushButton {
background: #3f424d; background: #3f424d;
border: 1px solid rgba(255, 255, 255, 0.20); border: 2px solid rgba(255, 255, 255, 0.01);
border-radius: 10px; border-radius: 10px;
color: #ffffff; color: #ffffff;
font-size: 16px; font-size: 16px;
font-family: 'Play'; font-family: 'Play';
padding: 8px 16px;
} }
QPushButton:hover { QPushButton:hover {
background: #282a33; background: #409EFF;
border: 2px solid #409EFF;
} }
QPushButton:pressed { QPushButton:pressed {
background: #282a33; background: #282a33;
} }
QPushButton:focus { QPushButton:focus {
border: 2px solid #409EFF; border: 2px solid #409EFF;
background-color: #404554; background-color: #409EFF;
} }
""" """
@ -331,10 +401,10 @@ ADDGAME_BACK_BUTTON_STYLE = """
padding: 8px 16px; padding: 8px 16px;
} }
QPushButton:hover { QPushButton:hover {
background: #09bec8; background: #409EFF;
} }
QPushButton:pressed { QPushButton:pressed {
background: #09bec8; background: #409EFF;
} }
""" """
@ -388,10 +458,10 @@ PLAY_BUTTON_STYLE = """
min-height: 40px; min-height: 40px;
} }
QPushButton:hover { QPushButton:hover {
background: #09bec8; background: #409EFF;
} }
QPushButton:pressed { QPushButton:pressed {
background: #09bec8; background: #409EFF;
} }
""" """
@ -416,6 +486,40 @@ DIALOG_BROWSE_BUTTON_STYLE = """
} }
""" """
ADDGAME_INPUT_STYLE = """
QLineEdit {
background: #3f424d;
border: 2px solid rgba(255, 255, 255, 0.01);
border-radius: 10px;
height: 34px;
padding-left: 12px;
color: #ffffff;
font-family: 'Play';
font-size: 16px;
}
QLineEdit:hover {
background: #3f424d;
border: 2px solid #409EFF;
}
QLineEdit:focus {
border: 2px solid #409EFF;
background-color: #404554;
}
QMenu {
border: 1px solid rgba(255, 255, 255, 0.2);
padding: 5px 10px;
background: #32343d;
}
QMenu::item {
padding: 0px 10px;
border: 10px solid transparent; /* reserve space for selection border */
}
QMenu::item:selected {
background: #3f424d;
border-radius: 10px;
}
"""
# СТИЛЬ КАРТОЧКИ ИГРЫ (GAMECARD) # СТИЛЬ КАРТОЧКИ ИГРЫ (GAMECARD)
GAME_CARD_WINDOW_STYLE = """ GAME_CARD_WINDOW_STYLE = """
QFrame { QFrame {
@ -478,6 +582,27 @@ def get_protondb_badge_style(tier):
font-weight: bold; font-weight: bold;
""" """
# СТИЛИ БЕЙДЖА WEANTICHEATYET
def get_anticheat_badge_style(status):
status = status.lower()
status_colors = {
"supported": {"background": "rgba(102, 168, 15, 0.7)", "color": "black"},
"running": {"background": "rgba(25, 113, 194, 0.7)", "color": "black"},
"planned": {"background": "rgba(156, 54, 181, 0.7)", "color": "black"},
"broken": {"background": "rgba(232, 89, 12, 0.7)", "color": "black"},
"denied": {"background": "rgba(224, 49, 49, 0.7)", "color": "black"}
}
colors = status_colors.get(status, {"background": "rgba(0, 0, 0, 0.5)", "color": "white"})
return f"""
qproperty-alignment: AlignCenter;
background-color: {colors["background"]};
color: {colors["color"]};
font-size: 16px;
border-radius: 5px;
font-family: 'Play';
font-weight: bold;
"""
# СТИЛИ БЕЙДЖА STEAM # СТИЛИ БЕЙДЖА STEAM
STEAM_BADGE_STYLE= """ STEAM_BADGE_STYLE= """
qproperty-alignment: AlignCenter; qproperty-alignment: AlignCenter;
@ -532,7 +657,7 @@ PARAMS_TITLE_STYLE = "color: #ffffff; font-family: 'Play'; font-size: 16px; padd
PROXY_INPUT_STYLE = """ PROXY_INPUT_STYLE = """
QLineEdit { QLineEdit {
background: #282a33; background: #282a33;
border: 0px solid rgba(255, 255, 255, 0.2); border: 2px solid rgba(255, 255, 255, 0.01);
border-radius: 10px; border-radius: 10px;
height: 34px; height: 34px;
padding-left: 12px; padding-left: 12px;
@ -540,8 +665,13 @@ PROXY_INPUT_STYLE = """
font-family: 'Play'; font-family: 'Play';
font-size: 16px; font-size: 16px;
} }
QLineEdit:hover {
background: #3f424d;
border: 2px solid #409EFF;
}
QLineEdit:focus { QLineEdit:focus {
border: 1px solid rgba(255, 255, 255, 0.2); border: 2px solid #409EFF;
background-color: #404554;
} }
QMenu { QMenu {
border: 1px solid rgba(255, 255, 255, 0.2); border: 1px solid rgba(255, 255, 255, 0.2);
@ -561,7 +691,7 @@ PROXY_INPUT_STYLE = """
SETTINGS_COMBO_STYLE = f""" SETTINGS_COMBO_STYLE = f"""
QComboBox {{ QComboBox {{
background: #3f424d; background: #3f424d;
border: 0px solid rgba(255, 255, 255, 0.2); border: 2px solid rgba(255, 255, 255, 0.01);
border-radius: 10px; border-radius: 10px;
height: 34px; height: 34px;
padding-left: 12px; padding-left: 12px;
@ -573,19 +703,20 @@ SETTINGS_COMBO_STYLE = f"""
}} }}
QComboBox:on {{ QComboBox:on {{
background: #373a43; background: #373a43;
border: 1px solid rgba(255, 255, 255, 0.2); border: 1px solid #409EFF;
border-top-left-radius: 10px; border-top-left-radius: 10px;
border-top-right-radius: 10px; border-top-right-radius: 10px;
border-bottom-left-radius: 0px; border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px; border-bottom-right-radius: 0px;
}} }}
QComboBox:hover {{ QComboBox:hover {{
border: 1px solid rgba(255, 255, 255, 0.2); border: 2px solid #409EFF;
background: #409EFF;
}} }}
/* Состояние фокуса */ /* Состояние фокуса */
QComboBox:focus {{ QComboBox:focus {{
border: 2px solid #409EFF; border: 2px solid #409EFF;
background-color: #404554; background-color: #409EFF;
}} }}
QComboBox::drop-down {{ QComboBox::drop-down {{
subcontrol-origin: padding; subcontrol-origin: padding;
@ -610,7 +741,7 @@ SETTINGS_COMBO_STYLE = f"""
/* Список при открытом комбобоксе */ /* Список при открытом комбобоксе */
QComboBox QAbstractItemView {{ QComboBox QAbstractItemView {{
outline: none; outline: none;
border: 1px solid rgba(255, 255, 255, 0.2); border: 1px solid #409EFF;
border-top-style: none; border-top-style: none;
}} }}
QListView {{ QListView {{
@ -634,6 +765,30 @@ SETTINGS_COMBO_STYLE = f"""
}} }}
""" """
SETTINGS_CHECKBOX_STYLE = f"""
QCheckBox {{
height: 34px;
}}
QCheckBox::indicator {{
width: 24px;
height: 24px;
border: 2px solid rgba(255, 255, 255, 0.01);
border-radius: 10px;
background: #282a33;
}}
QCheckBox::indicator:hover {{
background: #3f424d;
border: 2px solid #409EFF;
}}
QCheckBox::indicator:focus {{
border: 2px solid #409EFF;
}}
QCheckBox::indicator:checked {{
image: url({theme_manager.get_icon("check", current_theme_name, as_path=True)});
border: 2px solid #409EFF;
}}
"""
# ФУНКЦИЯ ДЛЯ ДИНАМИЧЕСКОГО ГРАДИЕНТА (ДЕТАЛИ ИГР) # ФУНКЦИЯ ДЛЯ ДИНАМИЧЕСКОГО ГРАДИЕНТА (ДЕТАЛИ ИГР)
# Функции из этой темы срабатывает всегда вне зависимости от выбранной темы, функции из других тем работают только в этих темах # Функции из этой темы срабатывает всегда вне зависимости от выбранной темы, функции из других тем работают только в этих темах

View File

@ -7,12 +7,13 @@ from portprotonqt.config_utils import read_theme_from_config
class SystemTray: class SystemTray:
def __init__(self, app, theme=None): def __init__(self, app, theme=None):
self.app = app
self.theme_manager = ThemeManager() self.theme_manager = ThemeManager()
self.theme = theme if theme is not None else default_styles self.theme = theme if theme is not None else default_styles
self.current_theme_name = read_theme_from_config() self.current_theme_name = read_theme_from_config()
self.tray = QSystemTrayIcon() self.tray = QSystemTrayIcon()
self.tray.setIcon(cast(QIcon, self.theme_manager.get_icon("ppqt-tray", self.current_theme_name))) self.tray.setIcon(cast(QIcon, self.theme_manager.get_icon("ppqt-tray", self.current_theme_name)))
self.tray.setToolTip("PortProton QT") self.tray.setToolTip("PortProtonQt")
self.tray.setVisible(True) self.tray.setVisible(True)
# Создаём меню # Создаём меню
@ -32,4 +33,17 @@ class SystemTray:
def hide_tray(self): def hide_tray(self):
"""Скрыть иконку трея""" """Скрыть иконку трея"""
self.tray.hide() if self.tray:
self.tray.setVisible(False)
if self.menu:
self.menu.deleteLater()
self.menu = None
def cleanup(self):
"""Очистка ресурсов трея"""
if self.tray:
self.tray.setVisible(False)
self.tray = None
if self.menu:
self.menu.deleteLater()
self.menu = None

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "portprotonqt" name = "portprotonqt"
version = "0.1.1" version = "0.1.2"
description = "A project to rewrite PortProton (PortWINE) using PySide" description = "A project to rewrite PortProton (PortWINE) using PySide"
readme = "README.md" readme = "README.md"
license = { text = "GPL-3.0" } license = { text = "GPL-3.0" }

698
uv.lock generated
View File

@ -1,126 +1,126 @@
version = 1 version = 1
revision = 2 revision = 1
requires-python = ">=3.10" requires-python = ">=3.10"
[[package]] [[package]]
name = "babel" name = "babel"
version = "2.17.0" version = "2.17.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537 },
] ]
[[package]] [[package]]
name = "certifi" name = "certifi"
version = "2025.4.26" version = "2025.4.26"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618 },
] ]
[[package]] [[package]]
name = "cfgv" name = "cfgv"
version = "3.4.0" version = "3.4.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 },
] ]
[[package]] [[package]]
name = "charset-normalizer" name = "charset-normalizer"
version = "3.4.1" version = "3.4.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188, upload-time = "2024-12-24T18:12:35.43Z" } sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013, upload-time = "2024-12-24T18:09:43.671Z" }, { url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013 },
{ url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285, upload-time = "2024-12-24T18:09:48.113Z" }, { url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285 },
{ url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449, upload-time = "2024-12-24T18:09:50.845Z" }, { url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449 },
{ url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892, upload-time = "2024-12-24T18:09:52.078Z" }, { url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892 },
{ url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123, upload-time = "2024-12-24T18:09:54.575Z" }, { url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123 },
{ url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943, upload-time = "2024-12-24T18:09:57.324Z" }, { url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943 },
{ url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063, upload-time = "2024-12-24T18:09:59.794Z" }, { url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063 },
{ url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578, upload-time = "2024-12-24T18:10:02.357Z" }, { url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578 },
{ url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629, upload-time = "2024-12-24T18:10:03.678Z" }, { url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629 },
{ url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778, upload-time = "2024-12-24T18:10:06.197Z" }, { url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778 },
{ url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453, upload-time = "2024-12-24T18:10:08.848Z" }, { url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453 },
{ url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479, upload-time = "2024-12-24T18:10:10.044Z" }, { url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479 },
{ url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790, upload-time = "2024-12-24T18:10:11.323Z" }, { url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790 },
{ url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995, upload-time = "2024-12-24T18:10:12.838Z" }, { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995 },
{ url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471, upload-time = "2024-12-24T18:10:14.101Z" }, { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471 },
{ url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831, upload-time = "2024-12-24T18:10:15.512Z" }, { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831 },
{ url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335, upload-time = "2024-12-24T18:10:18.369Z" }, { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335 },
{ url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862, upload-time = "2024-12-24T18:10:19.743Z" }, { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862 },
{ url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673, upload-time = "2024-12-24T18:10:21.139Z" }, { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673 },
{ url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211, upload-time = "2024-12-24T18:10:22.382Z" }, { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211 },
{ url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039, upload-time = "2024-12-24T18:10:24.802Z" }, { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039 },
{ url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939, upload-time = "2024-12-24T18:10:26.124Z" }, { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939 },
{ url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075, upload-time = "2024-12-24T18:10:30.027Z" }, { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075 },
{ url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340, upload-time = "2024-12-24T18:10:32.679Z" }, { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340 },
{ url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205, upload-time = "2024-12-24T18:10:34.724Z" }, { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205 },
{ url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441, upload-time = "2024-12-24T18:10:37.574Z" }, { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441 },
{ url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105, upload-time = "2024-12-24T18:10:38.83Z" }, { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 },
{ url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404, upload-time = "2024-12-24T18:10:44.272Z" }, { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 },
{ url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423, upload-time = "2024-12-24T18:10:45.492Z" }, { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 },
{ url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184, upload-time = "2024-12-24T18:10:47.898Z" }, { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 },
{ url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268, upload-time = "2024-12-24T18:10:50.589Z" }, { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 },
{ url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601, upload-time = "2024-12-24T18:10:52.541Z" }, { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 },
{ url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098, upload-time = "2024-12-24T18:10:53.789Z" }, { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 },
{ url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520, upload-time = "2024-12-24T18:10:55.048Z" }, { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 },
{ url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852, upload-time = "2024-12-24T18:10:57.647Z" }, { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 },
{ url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488, upload-time = "2024-12-24T18:10:59.43Z" }, { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 },
{ url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192, upload-time = "2024-12-24T18:11:00.676Z" }, { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 },
{ url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550, upload-time = "2024-12-24T18:11:01.952Z" }, { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 },
{ url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785, upload-time = "2024-12-24T18:11:03.142Z" }, { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 },
{ url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698, upload-time = "2024-12-24T18:11:05.834Z" }, { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 },
{ url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162, upload-time = "2024-12-24T18:11:07.064Z" }, { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 },
{ url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263, upload-time = "2024-12-24T18:11:08.374Z" }, { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 },
{ url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966, upload-time = "2024-12-24T18:11:09.831Z" }, { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 },
{ url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992, upload-time = "2024-12-24T18:11:12.03Z" }, { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 },
{ url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162, upload-time = "2024-12-24T18:11:13.372Z" }, { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 },
{ url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972, upload-time = "2024-12-24T18:11:14.628Z" }, { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 },
{ url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095, upload-time = "2024-12-24T18:11:17.672Z" }, { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 },
{ url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668, upload-time = "2024-12-24T18:11:18.989Z" }, { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 },
{ url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073, upload-time = "2024-12-24T18:11:21.507Z" }, { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 },
{ url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732, upload-time = "2024-12-24T18:11:22.774Z" }, { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 },
{ url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391, upload-time = "2024-12-24T18:11:24.139Z" }, { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 },
{ url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702, upload-time = "2024-12-24T18:11:26.535Z" }, { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 },
{ url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload-time = "2024-12-24T18:12:32.852Z" }, { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 },
] ]
[[package]] [[package]]
name = "colorama" name = "colorama"
version = "0.4.6" version = "0.4.6"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
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" } sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
wheels = [ wheels = [
{ 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" }, { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
] ]
[[package]] [[package]]
name = "distlib" name = "distlib"
version = "0.3.9" version = "0.3.9"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923, upload-time = "2024-10-09T18:35:47.551Z" } sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973, upload-time = "2024-10-09T18:35:44.272Z" }, { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 },
] ]
[[package]] [[package]]
name = "evdev" name = "evdev"
version = "1.9.2" version = "1.9.2"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/63/fe/a17c106a1f4061ce83f04d14bcedcfb2c38c7793ea56bfb906a6fadae8cb/evdev-1.9.2.tar.gz", hash = "sha256:5d3278892ce1f92a74d6bf888cc8525d9f68af85dbe336c95d1c87fb8f423069", size = 33301, upload-time = "2025-05-01T19:53:47.69Z" } sdist = { url = "https://files.pythonhosted.org/packages/63/fe/a17c106a1f4061ce83f04d14bcedcfb2c38c7793ea56bfb906a6fadae8cb/evdev-1.9.2.tar.gz", hash = "sha256:5d3278892ce1f92a74d6bf888cc8525d9f68af85dbe336c95d1c87fb8f423069", size = 33301 }
[[package]] [[package]]
name = "filelock" name = "filelock"
version = "3.18.0" version = "3.18.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075, upload-time = "2025-03-14T07:11:40.47Z" } sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215, upload-time = "2025-03-14T07:11:39.145Z" }, { url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215 },
] ]
[[package]] [[package]]
@ -130,261 +130,261 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "pefile" }, { name = "pefile" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/a9/57/9e9295209f39dac4712df622b1677d5ea97a5ea987f2033c489b4ad2b0d4/icoextract-0.1.6.tar.gz", hash = "sha256:492f27ea5a3a22e56ca40a2e2dec8a7c35c1042e8b257ca0745367c56b1f56fa", size = 10051, upload-time = "2025-03-02T23:34:46.087Z" } sdist = { url = "https://files.pythonhosted.org/packages/a9/57/9e9295209f39dac4712df622b1677d5ea97a5ea987f2033c489b4ad2b0d4/icoextract-0.1.6.tar.gz", hash = "sha256:492f27ea5a3a22e56ca40a2e2dec8a7c35c1042e8b257ca0745367c56b1f56fa", size = 10051 }
[[package]] [[package]]
name = "identify" name = "identify"
version = "2.6.9" version = "2.6.9"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/9b/98/a71ab060daec766acc30fb47dfca219d03de34a70d616a79a38c6066c5bf/identify-2.6.9.tar.gz", hash = "sha256:d40dfe3142a1421d8518e3d3985ef5ac42890683e32306ad614a29490abeb6bf", size = 99249, upload-time = "2025-03-08T15:54:13.632Z" } sdist = { url = "https://files.pythonhosted.org/packages/9b/98/a71ab060daec766acc30fb47dfca219d03de34a70d616a79a38c6066c5bf/identify-2.6.9.tar.gz", hash = "sha256:d40dfe3142a1421d8518e3d3985ef5ac42890683e32306ad614a29490abeb6bf", size = 99249 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/07/ce/0845144ed1f0e25db5e7a79c2354c1da4b5ce392b8966449d5db8dca18f1/identify-2.6.9-py2.py3-none-any.whl", hash = "sha256:c98b4322da415a8e5a70ff6e51fbc2d2932c015532d77e9f8537b4ba7813b150", size = 99101, upload-time = "2025-03-08T15:54:12.026Z" }, { url = "https://files.pythonhosted.org/packages/07/ce/0845144ed1f0e25db5e7a79c2354c1da4b5ce392b8966449d5db8dca18f1/identify-2.6.9-py2.py3-none-any.whl", hash = "sha256:c98b4322da415a8e5a70ff6e51fbc2d2932c015532d77e9f8537b4ba7813b150", size = 99101 },
] ]
[[package]] [[package]]
name = "idna" name = "idna"
version = "3.10" version = "3.10"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
] ]
[[package]] [[package]]
name = "nodeenv" name = "nodeenv"
version = "1.9.1" version = "1.9.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 },
] ]
[[package]] [[package]]
name = "numpy" name = "numpy"
version = "2.2.6" version = "2.2.6"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245 },
{ url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048 },
{ url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542 },
{ url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301 },
{ url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320 },
{ url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050 },
{ url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034 },
{ url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185 },
{ url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149 },
{ url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620 },
{ url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963 },
{ url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743 },
{ url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616 },
{ url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579 },
{ url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005 },
{ url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570 },
{ url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548 },
{ url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521 },
{ url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866 },
{ url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455 },
{ url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348 },
{ url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362 },
{ url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103 },
{ url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382 },
{ url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462 },
{ url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618 },
{ url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511 },
{ url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783 },
{ url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506 },
{ url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190 },
{ url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828 },
{ url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006 },
{ url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765 },
{ url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736 },
{ url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719 },
{ url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072 },
{ url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213 },
{ url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632 },
{ url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532 },
{ url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885 },
{ url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467 },
{ url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144 },
{ url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217 },
{ url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014 },
{ url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935 },
{ url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122 },
{ url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143 },
{ url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260 },
{ url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225 },
{ url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374 },
{ url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391 },
{ url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754 },
{ url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476 },
{ url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666 },
] ]
[[package]] [[package]]
name = "orjson" name = "orjson"
version = "3.10.18" version = "3.10.18"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/81/0b/fea456a3ffe74e70ba30e01ec183a9b26bec4d497f61dcfce1b601059c60/orjson-3.10.18.tar.gz", hash = "sha256:e8da3947d92123eda795b68228cafe2724815621fe35e8e320a9e9593a4bcd53", size = 5422810, upload-time = "2025-04-29T23:30:08.423Z" } sdist = { url = "https://files.pythonhosted.org/packages/81/0b/fea456a3ffe74e70ba30e01ec183a9b26bec4d497f61dcfce1b601059c60/orjson-3.10.18.tar.gz", hash = "sha256:e8da3947d92123eda795b68228cafe2724815621fe35e8e320a9e9593a4bcd53", size = 5422810 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/27/16/2ceb9fb7bc2b11b1e4a3ea27794256e93dee2309ebe297fd131a778cd150/orjson-3.10.18-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a45e5d68066b408e4bc383b6e4ef05e717c65219a9e1390abc6155a520cac402", size = 248927, upload-time = "2025-04-29T23:28:08.643Z" }, { url = "https://files.pythonhosted.org/packages/27/16/2ceb9fb7bc2b11b1e4a3ea27794256e93dee2309ebe297fd131a778cd150/orjson-3.10.18-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a45e5d68066b408e4bc383b6e4ef05e717c65219a9e1390abc6155a520cac402", size = 248927 },
{ url = "https://files.pythonhosted.org/packages/3d/e1/d3c0a2bba5b9906badd121da449295062b289236c39c3a7801f92c4682b0/orjson-3.10.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be3b9b143e8b9db05368b13b04c84d37544ec85bb97237b3a923f076265ec89c", size = 136995, upload-time = "2025-04-29T23:28:11.503Z" }, { url = "https://files.pythonhosted.org/packages/3d/e1/d3c0a2bba5b9906badd121da449295062b289236c39c3a7801f92c4682b0/orjson-3.10.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be3b9b143e8b9db05368b13b04c84d37544ec85bb97237b3a923f076265ec89c", size = 136995 },
{ url = "https://files.pythonhosted.org/packages/d7/51/698dd65e94f153ee5ecb2586c89702c9e9d12f165a63e74eb9ea1299f4e1/orjson-3.10.18-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9b0aa09745e2c9b3bf779b096fa71d1cc2d801a604ef6dd79c8b1bfef52b2f92", size = 132893, upload-time = "2025-04-29T23:28:12.751Z" }, { url = "https://files.pythonhosted.org/packages/d7/51/698dd65e94f153ee5ecb2586c89702c9e9d12f165a63e74eb9ea1299f4e1/orjson-3.10.18-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9b0aa09745e2c9b3bf779b096fa71d1cc2d801a604ef6dd79c8b1bfef52b2f92", size = 132893 },
{ url = "https://files.pythonhosted.org/packages/b3/e5/155ce5a2c43a85e790fcf8b985400138ce5369f24ee6770378ee6b691036/orjson-3.10.18-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53a245c104d2792e65c8d225158f2b8262749ffe64bc7755b00024757d957a13", size = 137017, upload-time = "2025-04-29T23:28:14.498Z" }, { url = "https://files.pythonhosted.org/packages/b3/e5/155ce5a2c43a85e790fcf8b985400138ce5369f24ee6770378ee6b691036/orjson-3.10.18-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53a245c104d2792e65c8d225158f2b8262749ffe64bc7755b00024757d957a13", size = 137017 },
{ url = "https://files.pythonhosted.org/packages/46/bb/6141ec3beac3125c0b07375aee01b5124989907d61c72c7636136e4bd03e/orjson-3.10.18-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9495ab2611b7f8a0a8a505bcb0f0cbdb5469caafe17b0e404c3c746f9900469", size = 138290, upload-time = "2025-04-29T23:28:16.211Z" }, { url = "https://files.pythonhosted.org/packages/46/bb/6141ec3beac3125c0b07375aee01b5124989907d61c72c7636136e4bd03e/orjson-3.10.18-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9495ab2611b7f8a0a8a505bcb0f0cbdb5469caafe17b0e404c3c746f9900469", size = 138290 },
{ url = "https://files.pythonhosted.org/packages/77/36/6961eca0b66b7809d33c4ca58c6bd4c23a1b914fb23aba2fa2883f791434/orjson-3.10.18-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73be1cbcebadeabdbc468f82b087df435843c809cd079a565fb16f0f3b23238f", size = 142828, upload-time = "2025-04-29T23:28:18.065Z" }, { url = "https://files.pythonhosted.org/packages/77/36/6961eca0b66b7809d33c4ca58c6bd4c23a1b914fb23aba2fa2883f791434/orjson-3.10.18-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73be1cbcebadeabdbc468f82b087df435843c809cd079a565fb16f0f3b23238f", size = 142828 },
{ url = "https://files.pythonhosted.org/packages/8b/2f/0c646d5fd689d3be94f4d83fa9435a6c4322c9b8533edbb3cd4bc8c5f69a/orjson-3.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8936ee2679e38903df158037a2f1c108129dee218975122e37847fb1d4ac68", size = 132806, upload-time = "2025-04-29T23:28:19.782Z" }, { url = "https://files.pythonhosted.org/packages/8b/2f/0c646d5fd689d3be94f4d83fa9435a6c4322c9b8533edbb3cd4bc8c5f69a/orjson-3.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8936ee2679e38903df158037a2f1c108129dee218975122e37847fb1d4ac68", size = 132806 },
{ url = "https://files.pythonhosted.org/packages/ea/af/65907b40c74ef4c3674ef2bcfa311c695eb934710459841b3c2da212215c/orjson-3.10.18-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7115fcbc8525c74e4c2b608129bef740198e9a120ae46184dac7683191042056", size = 135005, upload-time = "2025-04-29T23:28:21.367Z" }, { url = "https://files.pythonhosted.org/packages/ea/af/65907b40c74ef4c3674ef2bcfa311c695eb934710459841b3c2da212215c/orjson-3.10.18-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7115fcbc8525c74e4c2b608129bef740198e9a120ae46184dac7683191042056", size = 135005 },
{ url = "https://files.pythonhosted.org/packages/c7/d1/68bd20ac6a32cd1f1b10d23e7cc58ee1e730e80624e3031d77067d7150fc/orjson-3.10.18-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:771474ad34c66bc4d1c01f645f150048030694ea5b2709b87d3bda273ffe505d", size = 413418, upload-time = "2025-04-29T23:28:23.097Z" }, { url = "https://files.pythonhosted.org/packages/c7/d1/68bd20ac6a32cd1f1b10d23e7cc58ee1e730e80624e3031d77067d7150fc/orjson-3.10.18-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:771474ad34c66bc4d1c01f645f150048030694ea5b2709b87d3bda273ffe505d", size = 413418 },
{ url = "https://files.pythonhosted.org/packages/31/31/c701ec0bcc3e80e5cb6e319c628ef7b768aaa24b0f3b4c599df2eaacfa24/orjson-3.10.18-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7c14047dbbea52886dd87169f21939af5d55143dad22d10db6a7514f058156a8", size = 153288, upload-time = "2025-04-29T23:28:25.02Z" }, { url = "https://files.pythonhosted.org/packages/31/31/c701ec0bcc3e80e5cb6e319c628ef7b768aaa24b0f3b4c599df2eaacfa24/orjson-3.10.18-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7c14047dbbea52886dd87169f21939af5d55143dad22d10db6a7514f058156a8", size = 153288 },
{ url = "https://files.pythonhosted.org/packages/d9/31/5e1aa99a10893a43cfc58009f9da840990cc8a9ebb75aa452210ba18587e/orjson-3.10.18-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:641481b73baec8db14fdf58f8967e52dc8bda1f2aba3aa5f5c1b07ed6df50b7f", size = 137181, upload-time = "2025-04-29T23:28:26.318Z" }, { url = "https://files.pythonhosted.org/packages/d9/31/5e1aa99a10893a43cfc58009f9da840990cc8a9ebb75aa452210ba18587e/orjson-3.10.18-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:641481b73baec8db14fdf58f8967e52dc8bda1f2aba3aa5f5c1b07ed6df50b7f", size = 137181 },
{ url = "https://files.pythonhosted.org/packages/bf/8c/daba0ac1b8690011d9242a0f37235f7d17df6d0ad941021048523b76674e/orjson-3.10.18-cp310-cp310-win32.whl", hash = "sha256:607eb3ae0909d47280c1fc657c4284c34b785bae371d007595633f4b1a2bbe06", size = 142694, upload-time = "2025-04-29T23:28:28.092Z" }, { url = "https://files.pythonhosted.org/packages/bf/8c/daba0ac1b8690011d9242a0f37235f7d17df6d0ad941021048523b76674e/orjson-3.10.18-cp310-cp310-win32.whl", hash = "sha256:607eb3ae0909d47280c1fc657c4284c34b785bae371d007595633f4b1a2bbe06", size = 142694 },
{ url = "https://files.pythonhosted.org/packages/16/62/8b687724143286b63e1d0fab3ad4214d54566d80b0ba9d67c26aaf28a2f8/orjson-3.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:8770432524ce0eca50b7efc2a9a5f486ee0113a5fbb4231526d414e6254eba92", size = 134600, upload-time = "2025-04-29T23:28:29.422Z" }, { url = "https://files.pythonhosted.org/packages/16/62/8b687724143286b63e1d0fab3ad4214d54566d80b0ba9d67c26aaf28a2f8/orjson-3.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:8770432524ce0eca50b7efc2a9a5f486ee0113a5fbb4231526d414e6254eba92", size = 134600 },
{ url = "https://files.pythonhosted.org/packages/97/c7/c54a948ce9a4278794f669a353551ce7db4ffb656c69a6e1f2264d563e50/orjson-3.10.18-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e0a183ac3b8e40471e8d843105da6fbe7c070faab023be3b08188ee3f85719b8", size = 248929, upload-time = "2025-04-29T23:28:30.716Z" }, { url = "https://files.pythonhosted.org/packages/97/c7/c54a948ce9a4278794f669a353551ce7db4ffb656c69a6e1f2264d563e50/orjson-3.10.18-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e0a183ac3b8e40471e8d843105da6fbe7c070faab023be3b08188ee3f85719b8", size = 248929 },
{ url = "https://files.pythonhosted.org/packages/9e/60/a9c674ef1dd8ab22b5b10f9300e7e70444d4e3cda4b8258d6c2488c32143/orjson-3.10.18-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:5ef7c164d9174362f85238d0cd4afdeeb89d9e523e4651add6a5d458d6f7d42d", size = 133364, upload-time = "2025-04-29T23:28:32.392Z" }, { url = "https://files.pythonhosted.org/packages/9e/60/a9c674ef1dd8ab22b5b10f9300e7e70444d4e3cda4b8258d6c2488c32143/orjson-3.10.18-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:5ef7c164d9174362f85238d0cd4afdeeb89d9e523e4651add6a5d458d6f7d42d", size = 133364 },
{ url = "https://files.pythonhosted.org/packages/c1/4e/f7d1bdd983082216e414e6d7ef897b0c2957f99c545826c06f371d52337e/orjson-3.10.18-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd14c5d99cdc7bf93f22b12ec3b294931518aa019e2a147e8aa2f31fd3240f7", size = 136995, upload-time = "2025-04-29T23:28:34.024Z" }, { url = "https://files.pythonhosted.org/packages/c1/4e/f7d1bdd983082216e414e6d7ef897b0c2957f99c545826c06f371d52337e/orjson-3.10.18-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd14c5d99cdc7bf93f22b12ec3b294931518aa019e2a147e8aa2f31fd3240f7", size = 136995 },
{ url = "https://files.pythonhosted.org/packages/17/89/46b9181ba0ea251c9243b0c8ce29ff7c9796fa943806a9c8b02592fce8ea/orjson-3.10.18-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b672502323b6cd133c4af6b79e3bea36bad2d16bca6c1f645903fce83909a7a", size = 132894, upload-time = "2025-04-29T23:28:35.318Z" }, { url = "https://files.pythonhosted.org/packages/17/89/46b9181ba0ea251c9243b0c8ce29ff7c9796fa943806a9c8b02592fce8ea/orjson-3.10.18-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b672502323b6cd133c4af6b79e3bea36bad2d16bca6c1f645903fce83909a7a", size = 132894 },
{ url = "https://files.pythonhosted.org/packages/ca/dd/7bce6fcc5b8c21aef59ba3c67f2166f0a1a9b0317dcca4a9d5bd7934ecfd/orjson-3.10.18-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51f8c63be6e070ec894c629186b1c0fe798662b8687f3d9fdfa5e401c6bd7679", size = 137016, upload-time = "2025-04-29T23:28:36.674Z" }, { url = "https://files.pythonhosted.org/packages/ca/dd/7bce6fcc5b8c21aef59ba3c67f2166f0a1a9b0317dcca4a9d5bd7934ecfd/orjson-3.10.18-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51f8c63be6e070ec894c629186b1c0fe798662b8687f3d9fdfa5e401c6bd7679", size = 137016 },
{ url = "https://files.pythonhosted.org/packages/1c/4a/b8aea1c83af805dcd31c1f03c95aabb3e19a016b2a4645dd822c5686e94d/orjson-3.10.18-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9478ade5313d724e0495d167083c6f3be0dd2f1c9c8a38db9a9e912cdaf947", size = 138290, upload-time = "2025-04-29T23:28:38.3Z" }, { url = "https://files.pythonhosted.org/packages/1c/4a/b8aea1c83af805dcd31c1f03c95aabb3e19a016b2a4645dd822c5686e94d/orjson-3.10.18-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9478ade5313d724e0495d167083c6f3be0dd2f1c9c8a38db9a9e912cdaf947", size = 138290 },
{ url = "https://files.pythonhosted.org/packages/36/d6/7eb05c85d987b688707f45dcf83c91abc2251e0dd9fb4f7be96514f838b1/orjson-3.10.18-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:187aefa562300a9d382b4b4eb9694806e5848b0cedf52037bb5c228c61bb66d4", size = 142829, upload-time = "2025-04-29T23:28:39.657Z" }, { url = "https://files.pythonhosted.org/packages/36/d6/7eb05c85d987b688707f45dcf83c91abc2251e0dd9fb4f7be96514f838b1/orjson-3.10.18-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:187aefa562300a9d382b4b4eb9694806e5848b0cedf52037bb5c228c61bb66d4", size = 142829 },
{ url = "https://files.pythonhosted.org/packages/d2/78/ddd3ee7873f2b5f90f016bc04062713d567435c53ecc8783aab3a4d34915/orjson-3.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da552683bc9da222379c7a01779bddd0ad39dd699dd6300abaf43eadee38334", size = 132805, upload-time = "2025-04-29T23:28:40.969Z" }, { url = "https://files.pythonhosted.org/packages/d2/78/ddd3ee7873f2b5f90f016bc04062713d567435c53ecc8783aab3a4d34915/orjson-3.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da552683bc9da222379c7a01779bddd0ad39dd699dd6300abaf43eadee38334", size = 132805 },
{ url = "https://files.pythonhosted.org/packages/8c/09/c8e047f73d2c5d21ead9c180203e111cddeffc0848d5f0f974e346e21c8e/orjson-3.10.18-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e450885f7b47a0231979d9c49b567ed1c4e9f69240804621be87c40bc9d3cf17", size = 135008, upload-time = "2025-04-29T23:28:42.284Z" }, { url = "https://files.pythonhosted.org/packages/8c/09/c8e047f73d2c5d21ead9c180203e111cddeffc0848d5f0f974e346e21c8e/orjson-3.10.18-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e450885f7b47a0231979d9c49b567ed1c4e9f69240804621be87c40bc9d3cf17", size = 135008 },
{ url = "https://files.pythonhosted.org/packages/0c/4b/dccbf5055ef8fb6eda542ab271955fc1f9bf0b941a058490293f8811122b/orjson-3.10.18-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5e3c9cc2ba324187cd06287ca24f65528f16dfc80add48dc99fa6c836bb3137e", size = 413419, upload-time = "2025-04-29T23:28:43.673Z" }, { url = "https://files.pythonhosted.org/packages/0c/4b/dccbf5055ef8fb6eda542ab271955fc1f9bf0b941a058490293f8811122b/orjson-3.10.18-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5e3c9cc2ba324187cd06287ca24f65528f16dfc80add48dc99fa6c836bb3137e", size = 413419 },
{ url = "https://files.pythonhosted.org/packages/8a/f3/1eac0c5e2d6d6790bd2025ebfbefcbd37f0d097103d76f9b3f9302af5a17/orjson-3.10.18-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:50ce016233ac4bfd843ac5471e232b865271d7d9d44cf9d33773bcd883ce442b", size = 153292, upload-time = "2025-04-29T23:28:45.573Z" }, { url = "https://files.pythonhosted.org/packages/8a/f3/1eac0c5e2d6d6790bd2025ebfbefcbd37f0d097103d76f9b3f9302af5a17/orjson-3.10.18-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:50ce016233ac4bfd843ac5471e232b865271d7d9d44cf9d33773bcd883ce442b", size = 153292 },
{ url = "https://files.pythonhosted.org/packages/1f/b4/ef0abf64c8f1fabf98791819ab502c2c8c1dc48b786646533a93637d8999/orjson-3.10.18-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b3ceff74a8f7ffde0b2785ca749fc4e80e4315c0fd887561144059fb1c138aa7", size = 137182, upload-time = "2025-04-29T23:28:47.229Z" }, { url = "https://files.pythonhosted.org/packages/1f/b4/ef0abf64c8f1fabf98791819ab502c2c8c1dc48b786646533a93637d8999/orjson-3.10.18-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b3ceff74a8f7ffde0b2785ca749fc4e80e4315c0fd887561144059fb1c138aa7", size = 137182 },
{ url = "https://files.pythonhosted.org/packages/a9/a3/6ea878e7b4a0dc5c888d0370d7752dcb23f402747d10e2257478d69b5e63/orjson-3.10.18-cp311-cp311-win32.whl", hash = "sha256:fdba703c722bd868c04702cac4cb8c6b8ff137af2623bc0ddb3b3e6a2c8996c1", size = 142695, upload-time = "2025-04-29T23:28:48.564Z" }, { url = "https://files.pythonhosted.org/packages/a9/a3/6ea878e7b4a0dc5c888d0370d7752dcb23f402747d10e2257478d69b5e63/orjson-3.10.18-cp311-cp311-win32.whl", hash = "sha256:fdba703c722bd868c04702cac4cb8c6b8ff137af2623bc0ddb3b3e6a2c8996c1", size = 142695 },
{ url = "https://files.pythonhosted.org/packages/79/2a/4048700a3233d562f0e90d5572a849baa18ae4e5ce4c3ba6247e4ece57b0/orjson-3.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:c28082933c71ff4bc6ccc82a454a2bffcef6e1d7379756ca567c772e4fb3278a", size = 134603, upload-time = "2025-04-29T23:28:50.442Z" }, { url = "https://files.pythonhosted.org/packages/79/2a/4048700a3233d562f0e90d5572a849baa18ae4e5ce4c3ba6247e4ece57b0/orjson-3.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:c28082933c71ff4bc6ccc82a454a2bffcef6e1d7379756ca567c772e4fb3278a", size = 134603 },
{ url = "https://files.pythonhosted.org/packages/03/45/10d934535a4993d27e1c84f1810e79ccf8b1b7418cef12151a22fe9bb1e1/orjson-3.10.18-cp311-cp311-win_arm64.whl", hash = "sha256:a6c7c391beaedd3fa63206e5c2b7b554196f14debf1ec9deb54b5d279b1b46f5", size = 131400, upload-time = "2025-04-29T23:28:51.838Z" }, { url = "https://files.pythonhosted.org/packages/03/45/10d934535a4993d27e1c84f1810e79ccf8b1b7418cef12151a22fe9bb1e1/orjson-3.10.18-cp311-cp311-win_arm64.whl", hash = "sha256:a6c7c391beaedd3fa63206e5c2b7b554196f14debf1ec9deb54b5d279b1b46f5", size = 131400 },
{ url = "https://files.pythonhosted.org/packages/21/1a/67236da0916c1a192d5f4ccbe10ec495367a726996ceb7614eaa687112f2/orjson-3.10.18-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:50c15557afb7f6d63bc6d6348e0337a880a04eaa9cd7c9d569bcb4e760a24753", size = 249184, upload-time = "2025-04-29T23:28:53.612Z" }, { url = "https://files.pythonhosted.org/packages/21/1a/67236da0916c1a192d5f4ccbe10ec495367a726996ceb7614eaa687112f2/orjson-3.10.18-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:50c15557afb7f6d63bc6d6348e0337a880a04eaa9cd7c9d569bcb4e760a24753", size = 249184 },
{ url = "https://files.pythonhosted.org/packages/b3/bc/c7f1db3b1d094dc0c6c83ed16b161a16c214aaa77f311118a93f647b32dc/orjson-3.10.18-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:356b076f1662c9813d5fa56db7d63ccceef4c271b1fb3dd522aca291375fcf17", size = 133279, upload-time = "2025-04-29T23:28:55.055Z" }, { url = "https://files.pythonhosted.org/packages/b3/bc/c7f1db3b1d094dc0c6c83ed16b161a16c214aaa77f311118a93f647b32dc/orjson-3.10.18-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:356b076f1662c9813d5fa56db7d63ccceef4c271b1fb3dd522aca291375fcf17", size = 133279 },
{ url = "https://files.pythonhosted.org/packages/af/84/664657cd14cc11f0d81e80e64766c7ba5c9b7fc1ec304117878cc1b4659c/orjson-3.10.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:559eb40a70a7494cd5beab2d73657262a74a2c59aff2068fdba8f0424ec5b39d", size = 136799, upload-time = "2025-04-29T23:28:56.828Z" }, { url = "https://files.pythonhosted.org/packages/af/84/664657cd14cc11f0d81e80e64766c7ba5c9b7fc1ec304117878cc1b4659c/orjson-3.10.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:559eb40a70a7494cd5beab2d73657262a74a2c59aff2068fdba8f0424ec5b39d", size = 136799 },
{ url = "https://files.pythonhosted.org/packages/9a/bb/f50039c5bb05a7ab024ed43ba25d0319e8722a0ac3babb0807e543349978/orjson-3.10.18-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f3c29eb9a81e2fbc6fd7ddcfba3e101ba92eaff455b8d602bf7511088bbc0eae", size = 132791, upload-time = "2025-04-29T23:28:58.751Z" }, { url = "https://files.pythonhosted.org/packages/9a/bb/f50039c5bb05a7ab024ed43ba25d0319e8722a0ac3babb0807e543349978/orjson-3.10.18-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f3c29eb9a81e2fbc6fd7ddcfba3e101ba92eaff455b8d602bf7511088bbc0eae", size = 132791 },
{ url = "https://files.pythonhosted.org/packages/93/8c/ee74709fc072c3ee219784173ddfe46f699598a1723d9d49cbc78d66df65/orjson-3.10.18-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6612787e5b0756a171c7d81ba245ef63a3533a637c335aa7fcb8e665f4a0966f", size = 137059, upload-time = "2025-04-29T23:29:00.129Z" }, { url = "https://files.pythonhosted.org/packages/93/8c/ee74709fc072c3ee219784173ddfe46f699598a1723d9d49cbc78d66df65/orjson-3.10.18-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6612787e5b0756a171c7d81ba245ef63a3533a637c335aa7fcb8e665f4a0966f", size = 137059 },
{ url = "https://files.pythonhosted.org/packages/6a/37/e6d3109ee004296c80426b5a62b47bcadd96a3deab7443e56507823588c5/orjson-3.10.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ac6bd7be0dcab5b702c9d43d25e70eb456dfd2e119d512447468f6405b4a69c", size = 138359, upload-time = "2025-04-29T23:29:01.704Z" }, { url = "https://files.pythonhosted.org/packages/6a/37/e6d3109ee004296c80426b5a62b47bcadd96a3deab7443e56507823588c5/orjson-3.10.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ac6bd7be0dcab5b702c9d43d25e70eb456dfd2e119d512447468f6405b4a69c", size = 138359 },
{ url = "https://files.pythonhosted.org/packages/4f/5d/387dafae0e4691857c62bd02839a3bf3fa648eebd26185adfac58d09f207/orjson-3.10.18-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f72f100cee8dde70100406d5c1abba515a7df926d4ed81e20a9730c062fe9ad", size = 142853, upload-time = "2025-04-29T23:29:03.576Z" }, { url = "https://files.pythonhosted.org/packages/4f/5d/387dafae0e4691857c62bd02839a3bf3fa648eebd26185adfac58d09f207/orjson-3.10.18-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f72f100cee8dde70100406d5c1abba515a7df926d4ed81e20a9730c062fe9ad", size = 142853 },
{ url = "https://files.pythonhosted.org/packages/27/6f/875e8e282105350b9a5341c0222a13419758545ae32ad6e0fcf5f64d76aa/orjson-3.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dca85398d6d093dd41dc0983cbf54ab8e6afd1c547b6b8a311643917fbf4e0c", size = 133131, upload-time = "2025-04-29T23:29:05.753Z" }, { url = "https://files.pythonhosted.org/packages/27/6f/875e8e282105350b9a5341c0222a13419758545ae32ad6e0fcf5f64d76aa/orjson-3.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dca85398d6d093dd41dc0983cbf54ab8e6afd1c547b6b8a311643917fbf4e0c", size = 133131 },
{ url = "https://files.pythonhosted.org/packages/48/b2/73a1f0b4790dcb1e5a45f058f4f5dcadc8a85d90137b50d6bbc6afd0ae50/orjson-3.10.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22748de2a07fcc8781a70edb887abf801bb6142e6236123ff93d12d92db3d406", size = 134834, upload-time = "2025-04-29T23:29:07.35Z" }, { url = "https://files.pythonhosted.org/packages/48/b2/73a1f0b4790dcb1e5a45f058f4f5dcadc8a85d90137b50d6bbc6afd0ae50/orjson-3.10.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22748de2a07fcc8781a70edb887abf801bb6142e6236123ff93d12d92db3d406", size = 134834 },
{ url = "https://files.pythonhosted.org/packages/56/f5/7ed133a5525add9c14dbdf17d011dd82206ca6840811d32ac52a35935d19/orjson-3.10.18-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3a83c9954a4107b9acd10291b7f12a6b29e35e8d43a414799906ea10e75438e6", size = 413368, upload-time = "2025-04-29T23:29:09.301Z" }, { url = "https://files.pythonhosted.org/packages/56/f5/7ed133a5525add9c14dbdf17d011dd82206ca6840811d32ac52a35935d19/orjson-3.10.18-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3a83c9954a4107b9acd10291b7f12a6b29e35e8d43a414799906ea10e75438e6", size = 413368 },
{ url = "https://files.pythonhosted.org/packages/11/7c/439654221ed9c3324bbac7bdf94cf06a971206b7b62327f11a52544e4982/orjson-3.10.18-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:303565c67a6c7b1f194c94632a4a39918e067bd6176a48bec697393865ce4f06", size = 153359, upload-time = "2025-04-29T23:29:10.813Z" }, { url = "https://files.pythonhosted.org/packages/11/7c/439654221ed9c3324bbac7bdf94cf06a971206b7b62327f11a52544e4982/orjson-3.10.18-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:303565c67a6c7b1f194c94632a4a39918e067bd6176a48bec697393865ce4f06", size = 153359 },
{ url = "https://files.pythonhosted.org/packages/48/e7/d58074fa0cc9dd29a8fa2a6c8d5deebdfd82c6cfef72b0e4277c4017563a/orjson-3.10.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:86314fdb5053a2f5a5d881f03fca0219bfdf832912aa88d18676a5175c6916b5", size = 137466, upload-time = "2025-04-29T23:29:12.26Z" }, { url = "https://files.pythonhosted.org/packages/48/e7/d58074fa0cc9dd29a8fa2a6c8d5deebdfd82c6cfef72b0e4277c4017563a/orjson-3.10.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:86314fdb5053a2f5a5d881f03fca0219bfdf832912aa88d18676a5175c6916b5", size = 137466 },
{ url = "https://files.pythonhosted.org/packages/57/4d/fe17581cf81fb70dfcef44e966aa4003360e4194d15a3f38cbffe873333a/orjson-3.10.18-cp312-cp312-win32.whl", hash = "sha256:187ec33bbec58c76dbd4066340067d9ece6e10067bb0cc074a21ae3300caa84e", size = 142683, upload-time = "2025-04-29T23:29:13.865Z" }, { url = "https://files.pythonhosted.org/packages/57/4d/fe17581cf81fb70dfcef44e966aa4003360e4194d15a3f38cbffe873333a/orjson-3.10.18-cp312-cp312-win32.whl", hash = "sha256:187ec33bbec58c76dbd4066340067d9ece6e10067bb0cc074a21ae3300caa84e", size = 142683 },
{ url = "https://files.pythonhosted.org/packages/e6/22/469f62d25ab5f0f3aee256ea732e72dc3aab6d73bac777bd6277955bceef/orjson-3.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:f9f94cf6d3f9cd720d641f8399e390e7411487e493962213390d1ae45c7814fc", size = 134754, upload-time = "2025-04-29T23:29:15.338Z" }, { url = "https://files.pythonhosted.org/packages/e6/22/469f62d25ab5f0f3aee256ea732e72dc3aab6d73bac777bd6277955bceef/orjson-3.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:f9f94cf6d3f9cd720d641f8399e390e7411487e493962213390d1ae45c7814fc", size = 134754 },
{ url = "https://files.pythonhosted.org/packages/10/b0/1040c447fac5b91bc1e9c004b69ee50abb0c1ffd0d24406e1350c58a7fcb/orjson-3.10.18-cp312-cp312-win_arm64.whl", hash = "sha256:3d600be83fe4514944500fa8c2a0a77099025ec6482e8087d7659e891f23058a", size = 131218, upload-time = "2025-04-29T23:29:17.324Z" }, { url = "https://files.pythonhosted.org/packages/10/b0/1040c447fac5b91bc1e9c004b69ee50abb0c1ffd0d24406e1350c58a7fcb/orjson-3.10.18-cp312-cp312-win_arm64.whl", hash = "sha256:3d600be83fe4514944500fa8c2a0a77099025ec6482e8087d7659e891f23058a", size = 131218 },
{ url = "https://files.pythonhosted.org/packages/04/f0/8aedb6574b68096f3be8f74c0b56d36fd94bcf47e6c7ed47a7bd1474aaa8/orjson-3.10.18-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:69c34b9441b863175cc6a01f2935de994025e773f814412030f269da4f7be147", size = 249087, upload-time = "2025-04-29T23:29:19.083Z" }, { url = "https://files.pythonhosted.org/packages/04/f0/8aedb6574b68096f3be8f74c0b56d36fd94bcf47e6c7ed47a7bd1474aaa8/orjson-3.10.18-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:69c34b9441b863175cc6a01f2935de994025e773f814412030f269da4f7be147", size = 249087 },
{ url = "https://files.pythonhosted.org/packages/bc/f7/7118f965541aeac6844fcb18d6988e111ac0d349c9b80cda53583e758908/orjson-3.10.18-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:1ebeda919725f9dbdb269f59bc94f861afbe2a27dce5608cdba2d92772364d1c", size = 133273, upload-time = "2025-04-29T23:29:20.602Z" }, { url = "https://files.pythonhosted.org/packages/bc/f7/7118f965541aeac6844fcb18d6988e111ac0d349c9b80cda53583e758908/orjson-3.10.18-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:1ebeda919725f9dbdb269f59bc94f861afbe2a27dce5608cdba2d92772364d1c", size = 133273 },
{ url = "https://files.pythonhosted.org/packages/fb/d9/839637cc06eaf528dd8127b36004247bf56e064501f68df9ee6fd56a88ee/orjson-3.10.18-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5adf5f4eed520a4959d29ea80192fa626ab9a20b2ea13f8f6dc58644f6927103", size = 136779, upload-time = "2025-04-29T23:29:22.062Z" }, { url = "https://files.pythonhosted.org/packages/fb/d9/839637cc06eaf528dd8127b36004247bf56e064501f68df9ee6fd56a88ee/orjson-3.10.18-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5adf5f4eed520a4959d29ea80192fa626ab9a20b2ea13f8f6dc58644f6927103", size = 136779 },
{ url = "https://files.pythonhosted.org/packages/2b/6d/f226ecfef31a1f0e7d6bf9a31a0bbaf384c7cbe3fce49cc9c2acc51f902a/orjson-3.10.18-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7592bb48a214e18cd670974f289520f12b7aed1fa0b2e2616b8ed9e069e08595", size = 132811, upload-time = "2025-04-29T23:29:23.602Z" }, { url = "https://files.pythonhosted.org/packages/2b/6d/f226ecfef31a1f0e7d6bf9a31a0bbaf384c7cbe3fce49cc9c2acc51f902a/orjson-3.10.18-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7592bb48a214e18cd670974f289520f12b7aed1fa0b2e2616b8ed9e069e08595", size = 132811 },
{ url = "https://files.pythonhosted.org/packages/73/2d/371513d04143c85b681cf8f3bce743656eb5b640cb1f461dad750ac4b4d4/orjson-3.10.18-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f872bef9f042734110642b7a11937440797ace8c87527de25e0c53558b579ccc", size = 137018, upload-time = "2025-04-29T23:29:25.094Z" }, { url = "https://files.pythonhosted.org/packages/73/2d/371513d04143c85b681cf8f3bce743656eb5b640cb1f461dad750ac4b4d4/orjson-3.10.18-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f872bef9f042734110642b7a11937440797ace8c87527de25e0c53558b579ccc", size = 137018 },
{ url = "https://files.pythonhosted.org/packages/69/cb/a4d37a30507b7a59bdc484e4a3253c8141bf756d4e13fcc1da760a0b00cb/orjson-3.10.18-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0315317601149c244cb3ecef246ef5861a64824ccbcb8018d32c66a60a84ffbc", size = 138368, upload-time = "2025-04-29T23:29:26.609Z" }, { url = "https://files.pythonhosted.org/packages/69/cb/a4d37a30507b7a59bdc484e4a3253c8141bf756d4e13fcc1da760a0b00cb/orjson-3.10.18-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0315317601149c244cb3ecef246ef5861a64824ccbcb8018d32c66a60a84ffbc", size = 138368 },
{ url = "https://files.pythonhosted.org/packages/1e/ae/cd10883c48d912d216d541eb3db8b2433415fde67f620afe6f311f5cd2ca/orjson-3.10.18-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0da26957e77e9e55a6c2ce2e7182a36a6f6b180ab7189315cb0995ec362e049", size = 142840, upload-time = "2025-04-29T23:29:28.153Z" }, { url = "https://files.pythonhosted.org/packages/1e/ae/cd10883c48d912d216d541eb3db8b2433415fde67f620afe6f311f5cd2ca/orjson-3.10.18-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0da26957e77e9e55a6c2ce2e7182a36a6f6b180ab7189315cb0995ec362e049", size = 142840 },
{ url = "https://files.pythonhosted.org/packages/6d/4c/2bda09855c6b5f2c055034c9eda1529967b042ff8d81a05005115c4e6772/orjson-3.10.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb70d489bc79b7519e5803e2cc4c72343c9dc1154258adf2f8925d0b60da7c58", size = 133135, upload-time = "2025-04-29T23:29:29.726Z" }, { url = "https://files.pythonhosted.org/packages/6d/4c/2bda09855c6b5f2c055034c9eda1529967b042ff8d81a05005115c4e6772/orjson-3.10.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb70d489bc79b7519e5803e2cc4c72343c9dc1154258adf2f8925d0b60da7c58", size = 133135 },
{ url = "https://files.pythonhosted.org/packages/13/4a/35971fd809a8896731930a80dfff0b8ff48eeb5d8b57bb4d0d525160017f/orjson-3.10.18-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e9e86a6af31b92299b00736c89caf63816f70a4001e750bda179e15564d7a034", size = 134810, upload-time = "2025-04-29T23:29:31.269Z" }, { url = "https://files.pythonhosted.org/packages/13/4a/35971fd809a8896731930a80dfff0b8ff48eeb5d8b57bb4d0d525160017f/orjson-3.10.18-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e9e86a6af31b92299b00736c89caf63816f70a4001e750bda179e15564d7a034", size = 134810 },
{ url = "https://files.pythonhosted.org/packages/99/70/0fa9e6310cda98365629182486ff37a1c6578e34c33992df271a476ea1cd/orjson-3.10.18-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c382a5c0b5931a5fc5405053d36c1ce3fd561694738626c77ae0b1dfc0242ca1", size = 413491, upload-time = "2025-04-29T23:29:33.315Z" }, { url = "https://files.pythonhosted.org/packages/99/70/0fa9e6310cda98365629182486ff37a1c6578e34c33992df271a476ea1cd/orjson-3.10.18-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c382a5c0b5931a5fc5405053d36c1ce3fd561694738626c77ae0b1dfc0242ca1", size = 413491 },
{ url = "https://files.pythonhosted.org/packages/32/cb/990a0e88498babddb74fb97855ae4fbd22a82960e9b06eab5775cac435da/orjson-3.10.18-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8e4b2ae732431127171b875cb2668f883e1234711d3c147ffd69fe5be51a8012", size = 153277, upload-time = "2025-04-29T23:29:34.946Z" }, { url = "https://files.pythonhosted.org/packages/32/cb/990a0e88498babddb74fb97855ae4fbd22a82960e9b06eab5775cac435da/orjson-3.10.18-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8e4b2ae732431127171b875cb2668f883e1234711d3c147ffd69fe5be51a8012", size = 153277 },
{ url = "https://files.pythonhosted.org/packages/92/44/473248c3305bf782a384ed50dd8bc2d3cde1543d107138fd99b707480ca1/orjson-3.10.18-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d808e34ddb24fc29a4d4041dcfafbae13e129c93509b847b14432717d94b44f", size = 137367, upload-time = "2025-04-29T23:29:36.52Z" }, { url = "https://files.pythonhosted.org/packages/92/44/473248c3305bf782a384ed50dd8bc2d3cde1543d107138fd99b707480ca1/orjson-3.10.18-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d808e34ddb24fc29a4d4041dcfafbae13e129c93509b847b14432717d94b44f", size = 137367 },
{ url = "https://files.pythonhosted.org/packages/ad/fd/7f1d3edd4ffcd944a6a40e9f88af2197b619c931ac4d3cfba4798d4d3815/orjson-3.10.18-cp313-cp313-win32.whl", hash = "sha256:ad8eacbb5d904d5591f27dee4031e2c1db43d559edb8f91778efd642d70e6bea", size = 142687, upload-time = "2025-04-29T23:29:38.292Z" }, { url = "https://files.pythonhosted.org/packages/ad/fd/7f1d3edd4ffcd944a6a40e9f88af2197b619c931ac4d3cfba4798d4d3815/orjson-3.10.18-cp313-cp313-win32.whl", hash = "sha256:ad8eacbb5d904d5591f27dee4031e2c1db43d559edb8f91778efd642d70e6bea", size = 142687 },
{ url = "https://files.pythonhosted.org/packages/4b/03/c75c6ad46be41c16f4cfe0352a2d1450546f3c09ad2c9d341110cd87b025/orjson-3.10.18-cp313-cp313-win_amd64.whl", hash = "sha256:aed411bcb68bf62e85588f2a7e03a6082cc42e5a2796e06e72a962d7c6310b52", size = 134794, upload-time = "2025-04-29T23:29:40.349Z" }, { url = "https://files.pythonhosted.org/packages/4b/03/c75c6ad46be41c16f4cfe0352a2d1450546f3c09ad2c9d341110cd87b025/orjson-3.10.18-cp313-cp313-win_amd64.whl", hash = "sha256:aed411bcb68bf62e85588f2a7e03a6082cc42e5a2796e06e72a962d7c6310b52", size = 134794 },
{ url = "https://files.pythonhosted.org/packages/c2/28/f53038a5a72cc4fd0b56c1eafb4ef64aec9685460d5ac34de98ca78b6e29/orjson-3.10.18-cp313-cp313-win_arm64.whl", hash = "sha256:f54c1385a0e6aba2f15a40d703b858bedad36ded0491e55d35d905b2c34a4cc3", size = 131186, upload-time = "2025-04-29T23:29:41.922Z" }, { url = "https://files.pythonhosted.org/packages/c2/28/f53038a5a72cc4fd0b56c1eafb4ef64aec9685460d5ac34de98ca78b6e29/orjson-3.10.18-cp313-cp313-win_arm64.whl", hash = "sha256:f54c1385a0e6aba2f15a40d703b858bedad36ded0491e55d35d905b2c34a4cc3", size = 131186 },
] ]
[[package]] [[package]]
name = "pefile" name = "pefile"
version = "2024.8.26" version = "2024.8.26"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/03/4f/2750f7f6f025a1507cd3b7218691671eecfd0bbebebe8b39aa0fe1d360b8/pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632", size = 76008, upload-time = "2024-08-26T20:58:38.155Z" } sdist = { url = "https://files.pythonhosted.org/packages/03/4f/2750f7f6f025a1507cd3b7218691671eecfd0bbebebe8b39aa0fe1d360b8/pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632", size = 76008 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/54/16/12b82f791c7f50ddec566873d5bdd245baa1491bac11d15ffb98aecc8f8b/pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f", size = 74766, upload-time = "2024-08-26T21:01:02.632Z" }, { url = "https://files.pythonhosted.org/packages/54/16/12b82f791c7f50ddec566873d5bdd245baa1491bac11d15ffb98aecc8f8b/pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f", size = 74766 },
] ]
[[package]] [[package]]
name = "pillow" name = "pillow"
version = "11.2.1" version = "11.2.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/af/cb/bb5c01fcd2a69335b86c22142b2bccfc3464087efb7fd382eee5ffc7fdf7/pillow-11.2.1.tar.gz", hash = "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6", size = 47026707, upload-time = "2025-04-12T17:50:03.289Z" } sdist = { url = "https://files.pythonhosted.org/packages/af/cb/bb5c01fcd2a69335b86c22142b2bccfc3464087efb7fd382eee5ffc7fdf7/pillow-11.2.1.tar.gz", hash = "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6", size = 47026707 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/0d/8b/b158ad57ed44d3cc54db8d68ad7c0a58b8fc0e4c7a3f995f9d62d5b464a1/pillow-11.2.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:d57a75d53922fc20c165016a20d9c44f73305e67c351bbc60d1adaf662e74047", size = 3198442, upload-time = "2025-04-12T17:47:10.666Z" }, { url = "https://files.pythonhosted.org/packages/0d/8b/b158ad57ed44d3cc54db8d68ad7c0a58b8fc0e4c7a3f995f9d62d5b464a1/pillow-11.2.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:d57a75d53922fc20c165016a20d9c44f73305e67c351bbc60d1adaf662e74047", size = 3198442 },
{ url = "https://files.pythonhosted.org/packages/b1/f8/bb5d956142f86c2d6cc36704943fa761f2d2e4c48b7436fd0a85c20f1713/pillow-11.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:127bf6ac4a5b58b3d32fc8289656f77f80567d65660bc46f72c0d77e6600cc95", size = 3030553, upload-time = "2025-04-12T17:47:13.153Z" }, { url = "https://files.pythonhosted.org/packages/b1/f8/bb5d956142f86c2d6cc36704943fa761f2d2e4c48b7436fd0a85c20f1713/pillow-11.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:127bf6ac4a5b58b3d32fc8289656f77f80567d65660bc46f72c0d77e6600cc95", size = 3030553 },
{ url = "https://files.pythonhosted.org/packages/22/7f/0e413bb3e2aa797b9ca2c5c38cb2e2e45d88654e5b12da91ad446964cfae/pillow-11.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ba4be812c7a40280629e55ae0b14a0aafa150dd6451297562e1764808bbe61", size = 4405503, upload-time = "2025-04-12T17:47:15.36Z" }, { url = "https://files.pythonhosted.org/packages/22/7f/0e413bb3e2aa797b9ca2c5c38cb2e2e45d88654e5b12da91ad446964cfae/pillow-11.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ba4be812c7a40280629e55ae0b14a0aafa150dd6451297562e1764808bbe61", size = 4405503 },
{ url = "https://files.pythonhosted.org/packages/f3/b4/cc647f4d13f3eb837d3065824aa58b9bcf10821f029dc79955ee43f793bd/pillow-11.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8bd62331e5032bc396a93609982a9ab6b411c05078a52f5fe3cc59234a3abd1", size = 4490648, upload-time = "2025-04-12T17:47:17.37Z" }, { url = "https://files.pythonhosted.org/packages/f3/b4/cc647f4d13f3eb837d3065824aa58b9bcf10821f029dc79955ee43f793bd/pillow-11.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8bd62331e5032bc396a93609982a9ab6b411c05078a52f5fe3cc59234a3abd1", size = 4490648 },
{ url = "https://files.pythonhosted.org/packages/c2/6f/240b772a3b35cdd7384166461567aa6713799b4e78d180c555bd284844ea/pillow-11.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:562d11134c97a62fe3af29581f083033179f7ff435f78392565a1ad2d1c2c45c", size = 4508937, upload-time = "2025-04-12T17:47:19.066Z" }, { url = "https://files.pythonhosted.org/packages/c2/6f/240b772a3b35cdd7384166461567aa6713799b4e78d180c555bd284844ea/pillow-11.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:562d11134c97a62fe3af29581f083033179f7ff435f78392565a1ad2d1c2c45c", size = 4508937 },
{ url = "https://files.pythonhosted.org/packages/f3/5e/7ca9c815ade5fdca18853db86d812f2f188212792780208bdb37a0a6aef4/pillow-11.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:c97209e85b5be259994eb5b69ff50c5d20cca0f458ef9abd835e262d9d88b39d", size = 4599802, upload-time = "2025-04-12T17:47:21.404Z" }, { url = "https://files.pythonhosted.org/packages/f3/5e/7ca9c815ade5fdca18853db86d812f2f188212792780208bdb37a0a6aef4/pillow-11.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:c97209e85b5be259994eb5b69ff50c5d20cca0f458ef9abd835e262d9d88b39d", size = 4599802 },
{ url = "https://files.pythonhosted.org/packages/02/81/c3d9d38ce0c4878a77245d4cf2c46d45a4ad0f93000227910a46caff52f3/pillow-11.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0c3e6d0f59171dfa2e25d7116217543310908dfa2770aa64b8f87605f8cacc97", size = 4576717, upload-time = "2025-04-12T17:47:23.571Z" }, { url = "https://files.pythonhosted.org/packages/02/81/c3d9d38ce0c4878a77245d4cf2c46d45a4ad0f93000227910a46caff52f3/pillow-11.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0c3e6d0f59171dfa2e25d7116217543310908dfa2770aa64b8f87605f8cacc97", size = 4576717 },
{ url = "https://files.pythonhosted.org/packages/42/49/52b719b89ac7da3185b8d29c94d0e6aec8140059e3d8adcaa46da3751180/pillow-11.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc1c3bc53befb6096b84165956e886b1729634a799e9d6329a0c512ab651e579", size = 4654874, upload-time = "2025-04-12T17:47:25.783Z" }, { url = "https://files.pythonhosted.org/packages/42/49/52b719b89ac7da3185b8d29c94d0e6aec8140059e3d8adcaa46da3751180/pillow-11.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc1c3bc53befb6096b84165956e886b1729634a799e9d6329a0c512ab651e579", size = 4654874 },
{ url = "https://files.pythonhosted.org/packages/5b/0b/ede75063ba6023798267023dc0d0401f13695d228194d2242d5a7ba2f964/pillow-11.2.1-cp310-cp310-win32.whl", hash = "sha256:312c77b7f07ab2139924d2639860e084ec2a13e72af54d4f08ac843a5fc9c79d", size = 2331717, upload-time = "2025-04-12T17:47:28.922Z" }, { url = "https://files.pythonhosted.org/packages/5b/0b/ede75063ba6023798267023dc0d0401f13695d228194d2242d5a7ba2f964/pillow-11.2.1-cp310-cp310-win32.whl", hash = "sha256:312c77b7f07ab2139924d2639860e084ec2a13e72af54d4f08ac843a5fc9c79d", size = 2331717 },
{ url = "https://files.pythonhosted.org/packages/ed/3c/9831da3edea527c2ed9a09f31a2c04e77cd705847f13b69ca60269eec370/pillow-11.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9bc7ae48b8057a611e5fe9f853baa88093b9a76303937449397899385da06fad", size = 2676204, upload-time = "2025-04-12T17:47:31.283Z" }, { url = "https://files.pythonhosted.org/packages/ed/3c/9831da3edea527c2ed9a09f31a2c04e77cd705847f13b69ca60269eec370/pillow-11.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9bc7ae48b8057a611e5fe9f853baa88093b9a76303937449397899385da06fad", size = 2676204 },
{ url = "https://files.pythonhosted.org/packages/01/97/1f66ff8a1503d8cbfc5bae4dc99d54c6ec1e22ad2b946241365320caabc2/pillow-11.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:2728567e249cdd939f6cc3d1f049595c66e4187f3c34078cbc0a7d21c47482d2", size = 2414767, upload-time = "2025-04-12T17:47:34.655Z" }, { url = "https://files.pythonhosted.org/packages/01/97/1f66ff8a1503d8cbfc5bae4dc99d54c6ec1e22ad2b946241365320caabc2/pillow-11.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:2728567e249cdd939f6cc3d1f049595c66e4187f3c34078cbc0a7d21c47482d2", size = 2414767 },
{ url = "https://files.pythonhosted.org/packages/68/08/3fbf4b98924c73037a8e8b4c2c774784805e0fb4ebca6c5bb60795c40125/pillow-11.2.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35ca289f712ccfc699508c4658a1d14652e8033e9b69839edf83cbdd0ba39e70", size = 3198450, upload-time = "2025-04-12T17:47:37.135Z" }, { url = "https://files.pythonhosted.org/packages/68/08/3fbf4b98924c73037a8e8b4c2c774784805e0fb4ebca6c5bb60795c40125/pillow-11.2.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35ca289f712ccfc699508c4658a1d14652e8033e9b69839edf83cbdd0ba39e70", size = 3198450 },
{ url = "https://files.pythonhosted.org/packages/84/92/6505b1af3d2849d5e714fc75ba9e69b7255c05ee42383a35a4d58f576b16/pillow-11.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0409af9f829f87a2dfb7e259f78f317a5351f2045158be321fd135973fff7bf", size = 3030550, upload-time = "2025-04-12T17:47:39.345Z" }, { url = "https://files.pythonhosted.org/packages/84/92/6505b1af3d2849d5e714fc75ba9e69b7255c05ee42383a35a4d58f576b16/pillow-11.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0409af9f829f87a2dfb7e259f78f317a5351f2045158be321fd135973fff7bf", size = 3030550 },
{ url = "https://files.pythonhosted.org/packages/3c/8c/ac2f99d2a70ff966bc7eb13dacacfaab57c0549b2ffb351b6537c7840b12/pillow-11.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4e5c5edee874dce4f653dbe59db7c73a600119fbea8d31f53423586ee2aafd7", size = 4415018, upload-time = "2025-04-12T17:47:41.128Z" }, { url = "https://files.pythonhosted.org/packages/3c/8c/ac2f99d2a70ff966bc7eb13dacacfaab57c0549b2ffb351b6537c7840b12/pillow-11.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4e5c5edee874dce4f653dbe59db7c73a600119fbea8d31f53423586ee2aafd7", size = 4415018 },
{ url = "https://files.pythonhosted.org/packages/1f/e3/0a58b5d838687f40891fff9cbaf8669f90c96b64dc8f91f87894413856c6/pillow-11.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b93a07e76d13bff9444f1a029e0af2964e654bfc2e2c2d46bfd080df5ad5f3d8", size = 4498006, upload-time = "2025-04-12T17:47:42.912Z" }, { url = "https://files.pythonhosted.org/packages/1f/e3/0a58b5d838687f40891fff9cbaf8669f90c96b64dc8f91f87894413856c6/pillow-11.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b93a07e76d13bff9444f1a029e0af2964e654bfc2e2c2d46bfd080df5ad5f3d8", size = 4498006 },
{ url = "https://files.pythonhosted.org/packages/21/f5/6ba14718135f08fbfa33308efe027dd02b781d3f1d5c471444a395933aac/pillow-11.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:e6def7eed9e7fa90fde255afaf08060dc4b343bbe524a8f69bdd2a2f0018f600", size = 4517773, upload-time = "2025-04-12T17:47:44.611Z" }, { url = "https://files.pythonhosted.org/packages/21/f5/6ba14718135f08fbfa33308efe027dd02b781d3f1d5c471444a395933aac/pillow-11.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:e6def7eed9e7fa90fde255afaf08060dc4b343bbe524a8f69bdd2a2f0018f600", size = 4517773 },
{ url = "https://files.pythonhosted.org/packages/20/f2/805ad600fc59ebe4f1ba6129cd3a75fb0da126975c8579b8f57abeb61e80/pillow-11.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8f4f3724c068be008c08257207210c138d5f3731af6c155a81c2b09a9eb3a788", size = 4607069, upload-time = "2025-04-12T17:47:46.46Z" }, { url = "https://files.pythonhosted.org/packages/20/f2/805ad600fc59ebe4f1ba6129cd3a75fb0da126975c8579b8f57abeb61e80/pillow-11.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8f4f3724c068be008c08257207210c138d5f3731af6c155a81c2b09a9eb3a788", size = 4607069 },
{ url = "https://files.pythonhosted.org/packages/71/6b/4ef8a288b4bb2e0180cba13ca0a519fa27aa982875882392b65131401099/pillow-11.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a0a6709b47019dff32e678bc12c63008311b82b9327613f534e496dacaefb71e", size = 4583460, upload-time = "2025-04-12T17:47:49.255Z" }, { url = "https://files.pythonhosted.org/packages/71/6b/4ef8a288b4bb2e0180cba13ca0a519fa27aa982875882392b65131401099/pillow-11.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a0a6709b47019dff32e678bc12c63008311b82b9327613f534e496dacaefb71e", size = 4583460 },
{ url = "https://files.pythonhosted.org/packages/62/ae/f29c705a09cbc9e2a456590816e5c234382ae5d32584f451c3eb41a62062/pillow-11.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f6b0c664ccb879109ee3ca702a9272d877f4fcd21e5eb63c26422fd6e415365e", size = 4661304, upload-time = "2025-04-12T17:47:51.067Z" }, { url = "https://files.pythonhosted.org/packages/62/ae/f29c705a09cbc9e2a456590816e5c234382ae5d32584f451c3eb41a62062/pillow-11.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f6b0c664ccb879109ee3ca702a9272d877f4fcd21e5eb63c26422fd6e415365e", size = 4661304 },
{ url = "https://files.pythonhosted.org/packages/6e/1a/c8217b6f2f73794a5e219fbad087701f412337ae6dbb956db37d69a9bc43/pillow-11.2.1-cp311-cp311-win32.whl", hash = "sha256:cc5d875d56e49f112b6def6813c4e3d3036d269c008bf8aef72cd08d20ca6df6", size = 2331809, upload-time = "2025-04-12T17:47:54.425Z" }, { url = "https://files.pythonhosted.org/packages/6e/1a/c8217b6f2f73794a5e219fbad087701f412337ae6dbb956db37d69a9bc43/pillow-11.2.1-cp311-cp311-win32.whl", hash = "sha256:cc5d875d56e49f112b6def6813c4e3d3036d269c008bf8aef72cd08d20ca6df6", size = 2331809 },
{ url = "https://files.pythonhosted.org/packages/e2/72/25a8f40170dc262e86e90f37cb72cb3de5e307f75bf4b02535a61afcd519/pillow-11.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:0f5c7eda47bf8e3c8a283762cab94e496ba977a420868cb819159980b6709193", size = 2676338, upload-time = "2025-04-12T17:47:56.535Z" }, { url = "https://files.pythonhosted.org/packages/e2/72/25a8f40170dc262e86e90f37cb72cb3de5e307f75bf4b02535a61afcd519/pillow-11.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:0f5c7eda47bf8e3c8a283762cab94e496ba977a420868cb819159980b6709193", size = 2676338 },
{ url = "https://files.pythonhosted.org/packages/06/9e/76825e39efee61efea258b479391ca77d64dbd9e5804e4ad0fa453b4ba55/pillow-11.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:4d375eb838755f2528ac8cbc926c3e31cc49ca4ad0cf79cff48b20e30634a4a7", size = 2414918, upload-time = "2025-04-12T17:47:58.217Z" }, { url = "https://files.pythonhosted.org/packages/06/9e/76825e39efee61efea258b479391ca77d64dbd9e5804e4ad0fa453b4ba55/pillow-11.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:4d375eb838755f2528ac8cbc926c3e31cc49ca4ad0cf79cff48b20e30634a4a7", size = 2414918 },
{ url = "https://files.pythonhosted.org/packages/c7/40/052610b15a1b8961f52537cc8326ca6a881408bc2bdad0d852edeb6ed33b/pillow-11.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:78afba22027b4accef10dbd5eed84425930ba41b3ea0a86fa8d20baaf19d807f", size = 3190185, upload-time = "2025-04-12T17:48:00.417Z" }, { url = "https://files.pythonhosted.org/packages/c7/40/052610b15a1b8961f52537cc8326ca6a881408bc2bdad0d852edeb6ed33b/pillow-11.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:78afba22027b4accef10dbd5eed84425930ba41b3ea0a86fa8d20baaf19d807f", size = 3190185 },
{ url = "https://files.pythonhosted.org/packages/e5/7e/b86dbd35a5f938632093dc40d1682874c33dcfe832558fc80ca56bfcb774/pillow-11.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78092232a4ab376a35d68c4e6d5e00dfd73454bd12b230420025fbe178ee3b0b", size = 3030306, upload-time = "2025-04-12T17:48:02.391Z" }, { url = "https://files.pythonhosted.org/packages/e5/7e/b86dbd35a5f938632093dc40d1682874c33dcfe832558fc80ca56bfcb774/pillow-11.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78092232a4ab376a35d68c4e6d5e00dfd73454bd12b230420025fbe178ee3b0b", size = 3030306 },
{ url = "https://files.pythonhosted.org/packages/a4/5c/467a161f9ed53e5eab51a42923c33051bf8d1a2af4626ac04f5166e58e0c/pillow-11.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a5f306095c6780c52e6bbb6109624b95c5b18e40aab1c3041da3e9e0cd3e2d", size = 4416121, upload-time = "2025-04-12T17:48:04.554Z" }, { url = "https://files.pythonhosted.org/packages/a4/5c/467a161f9ed53e5eab51a42923c33051bf8d1a2af4626ac04f5166e58e0c/pillow-11.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a5f306095c6780c52e6bbb6109624b95c5b18e40aab1c3041da3e9e0cd3e2d", size = 4416121 },
{ url = "https://files.pythonhosted.org/packages/62/73/972b7742e38ae0e2ac76ab137ca6005dcf877480da0d9d61d93b613065b4/pillow-11.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c7b29dbd4281923a2bfe562acb734cee96bbb129e96e6972d315ed9f232bef4", size = 4501707, upload-time = "2025-04-12T17:48:06.831Z" }, { url = "https://files.pythonhosted.org/packages/62/73/972b7742e38ae0e2ac76ab137ca6005dcf877480da0d9d61d93b613065b4/pillow-11.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c7b29dbd4281923a2bfe562acb734cee96bbb129e96e6972d315ed9f232bef4", size = 4501707 },
{ url = "https://files.pythonhosted.org/packages/e4/3a/427e4cb0b9e177efbc1a84798ed20498c4f233abde003c06d2650a6d60cb/pillow-11.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e645b020f3209a0181a418bffe7b4a93171eef6c4ef6cc20980b30bebf17b7d", size = 4522921, upload-time = "2025-04-12T17:48:09.229Z" }, { url = "https://files.pythonhosted.org/packages/e4/3a/427e4cb0b9e177efbc1a84798ed20498c4f233abde003c06d2650a6d60cb/pillow-11.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e645b020f3209a0181a418bffe7b4a93171eef6c4ef6cc20980b30bebf17b7d", size = 4522921 },
{ url = "https://files.pythonhosted.org/packages/fe/7c/d8b1330458e4d2f3f45d9508796d7caf0c0d3764c00c823d10f6f1a3b76d/pillow-11.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2dbea1012ccb784a65349f57bbc93730b96e85b42e9bf7b01ef40443db720b4", size = 4612523, upload-time = "2025-04-12T17:48:11.631Z" }, { url = "https://files.pythonhosted.org/packages/fe/7c/d8b1330458e4d2f3f45d9508796d7caf0c0d3764c00c823d10f6f1a3b76d/pillow-11.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2dbea1012ccb784a65349f57bbc93730b96e85b42e9bf7b01ef40443db720b4", size = 4612523 },
{ url = "https://files.pythonhosted.org/packages/b3/2f/65738384e0b1acf451de5a573d8153fe84103772d139e1e0bdf1596be2ea/pillow-11.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:da3104c57bbd72948d75f6a9389e6727d2ab6333c3617f0a89d72d4940aa0443", size = 4587836, upload-time = "2025-04-12T17:48:13.592Z" }, { url = "https://files.pythonhosted.org/packages/b3/2f/65738384e0b1acf451de5a573d8153fe84103772d139e1e0bdf1596be2ea/pillow-11.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:da3104c57bbd72948d75f6a9389e6727d2ab6333c3617f0a89d72d4940aa0443", size = 4587836 },
{ url = "https://files.pythonhosted.org/packages/6a/c5/e795c9f2ddf3debb2dedd0df889f2fe4b053308bb59a3cc02a0cd144d641/pillow-11.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:598174aef4589af795f66f9caab87ba4ff860ce08cd5bb447c6fc553ffee603c", size = 4669390, upload-time = "2025-04-12T17:48:15.938Z" }, { url = "https://files.pythonhosted.org/packages/6a/c5/e795c9f2ddf3debb2dedd0df889f2fe4b053308bb59a3cc02a0cd144d641/pillow-11.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:598174aef4589af795f66f9caab87ba4ff860ce08cd5bb447c6fc553ffee603c", size = 4669390 },
{ url = "https://files.pythonhosted.org/packages/96/ae/ca0099a3995976a9fce2f423166f7bff9b12244afdc7520f6ed38911539a/pillow-11.2.1-cp312-cp312-win32.whl", hash = "sha256:1d535df14716e7f8776b9e7fee118576d65572b4aad3ed639be9e4fa88a1cad3", size = 2332309, upload-time = "2025-04-12T17:48:17.885Z" }, { url = "https://files.pythonhosted.org/packages/96/ae/ca0099a3995976a9fce2f423166f7bff9b12244afdc7520f6ed38911539a/pillow-11.2.1-cp312-cp312-win32.whl", hash = "sha256:1d535df14716e7f8776b9e7fee118576d65572b4aad3ed639be9e4fa88a1cad3", size = 2332309 },
{ url = "https://files.pythonhosted.org/packages/7c/18/24bff2ad716257fc03da964c5e8f05d9790a779a8895d6566e493ccf0189/pillow-11.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:14e33b28bf17c7a38eede290f77db7c664e4eb01f7869e37fa98a5aa95978941", size = 2676768, upload-time = "2025-04-12T17:48:19.655Z" }, { url = "https://files.pythonhosted.org/packages/7c/18/24bff2ad716257fc03da964c5e8f05d9790a779a8895d6566e493ccf0189/pillow-11.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:14e33b28bf17c7a38eede290f77db7c664e4eb01f7869e37fa98a5aa95978941", size = 2676768 },
{ url = "https://files.pythonhosted.org/packages/da/bb/e8d656c9543276517ee40184aaa39dcb41e683bca121022f9323ae11b39d/pillow-11.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:21e1470ac9e5739ff880c211fc3af01e3ae505859392bf65458c224d0bf283eb", size = 2415087, upload-time = "2025-04-12T17:48:21.991Z" }, { url = "https://files.pythonhosted.org/packages/da/bb/e8d656c9543276517ee40184aaa39dcb41e683bca121022f9323ae11b39d/pillow-11.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:21e1470ac9e5739ff880c211fc3af01e3ae505859392bf65458c224d0bf283eb", size = 2415087 },
{ url = "https://files.pythonhosted.org/packages/36/9c/447528ee3776e7ab8897fe33697a7ff3f0475bb490c5ac1456a03dc57956/pillow-11.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fdec757fea0b793056419bca3e9932eb2b0ceec90ef4813ea4c1e072c389eb28", size = 3190098, upload-time = "2025-04-12T17:48:23.915Z" }, { url = "https://files.pythonhosted.org/packages/36/9c/447528ee3776e7ab8897fe33697a7ff3f0475bb490c5ac1456a03dc57956/pillow-11.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fdec757fea0b793056419bca3e9932eb2b0ceec90ef4813ea4c1e072c389eb28", size = 3190098 },
{ url = "https://files.pythonhosted.org/packages/b5/09/29d5cd052f7566a63e5b506fac9c60526e9ecc553825551333e1e18a4858/pillow-11.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0e130705d568e2f43a17bcbe74d90958e8a16263868a12c3e0d9c8162690830", size = 3030166, upload-time = "2025-04-12T17:48:25.738Z" }, { url = "https://files.pythonhosted.org/packages/b5/09/29d5cd052f7566a63e5b506fac9c60526e9ecc553825551333e1e18a4858/pillow-11.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0e130705d568e2f43a17bcbe74d90958e8a16263868a12c3e0d9c8162690830", size = 3030166 },
{ url = "https://files.pythonhosted.org/packages/71/5d/446ee132ad35e7600652133f9c2840b4799bbd8e4adba881284860da0a36/pillow-11.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdb5e09068332578214cadd9c05e3d64d99e0e87591be22a324bdbc18925be0", size = 4408674, upload-time = "2025-04-12T17:48:27.908Z" }, { url = "https://files.pythonhosted.org/packages/71/5d/446ee132ad35e7600652133f9c2840b4799bbd8e4adba881284860da0a36/pillow-11.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdb5e09068332578214cadd9c05e3d64d99e0e87591be22a324bdbc18925be0", size = 4408674 },
{ url = "https://files.pythonhosted.org/packages/69/5f/cbe509c0ddf91cc3a03bbacf40e5c2339c4912d16458fcb797bb47bcb269/pillow-11.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d189ba1bebfbc0c0e529159631ec72bb9e9bc041f01ec6d3233d6d82eb823bc1", size = 4496005, upload-time = "2025-04-12T17:48:29.888Z" }, { url = "https://files.pythonhosted.org/packages/69/5f/cbe509c0ddf91cc3a03bbacf40e5c2339c4912d16458fcb797bb47bcb269/pillow-11.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d189ba1bebfbc0c0e529159631ec72bb9e9bc041f01ec6d3233d6d82eb823bc1", size = 4496005 },
{ url = "https://files.pythonhosted.org/packages/f9/b3/dd4338d8fb8a5f312021f2977fb8198a1184893f9b00b02b75d565c33b51/pillow-11.2.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:191955c55d8a712fab8934a42bfefbf99dd0b5875078240943f913bb66d46d9f", size = 4518707, upload-time = "2025-04-12T17:48:31.874Z" }, { url = "https://files.pythonhosted.org/packages/f9/b3/dd4338d8fb8a5f312021f2977fb8198a1184893f9b00b02b75d565c33b51/pillow-11.2.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:191955c55d8a712fab8934a42bfefbf99dd0b5875078240943f913bb66d46d9f", size = 4518707 },
{ url = "https://files.pythonhosted.org/packages/13/eb/2552ecebc0b887f539111c2cd241f538b8ff5891b8903dfe672e997529be/pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155", size = 4610008, upload-time = "2025-04-12T17:48:34.422Z" }, { url = "https://files.pythonhosted.org/packages/13/eb/2552ecebc0b887f539111c2cd241f538b8ff5891b8903dfe672e997529be/pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155", size = 4610008 },
{ url = "https://files.pythonhosted.org/packages/72/d1/924ce51bea494cb6e7959522d69d7b1c7e74f6821d84c63c3dc430cbbf3b/pillow-11.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:750f96efe0597382660d8b53e90dd1dd44568a8edb51cb7f9d5d918b80d4de14", size = 4585420, upload-time = "2025-04-12T17:48:37.641Z" }, { url = "https://files.pythonhosted.org/packages/72/d1/924ce51bea494cb6e7959522d69d7b1c7e74f6821d84c63c3dc430cbbf3b/pillow-11.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:750f96efe0597382660d8b53e90dd1dd44568a8edb51cb7f9d5d918b80d4de14", size = 4585420 },
{ url = "https://files.pythonhosted.org/packages/43/ab/8f81312d255d713b99ca37479a4cb4b0f48195e530cdc1611990eb8fd04b/pillow-11.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fe15238d3798788d00716637b3d4e7bb6bde18b26e5d08335a96e88564a36b6b", size = 4667655, upload-time = "2025-04-12T17:48:39.652Z" }, { url = "https://files.pythonhosted.org/packages/43/ab/8f81312d255d713b99ca37479a4cb4b0f48195e530cdc1611990eb8fd04b/pillow-11.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fe15238d3798788d00716637b3d4e7bb6bde18b26e5d08335a96e88564a36b6b", size = 4667655 },
{ url = "https://files.pythonhosted.org/packages/94/86/8f2e9d2dc3d308dfd137a07fe1cc478df0a23d42a6c4093b087e738e4827/pillow-11.2.1-cp313-cp313-win32.whl", hash = "sha256:3fe735ced9a607fee4f481423a9c36701a39719252a9bb251679635f99d0f7d2", size = 2332329, upload-time = "2025-04-12T17:48:41.765Z" }, { url = "https://files.pythonhosted.org/packages/94/86/8f2e9d2dc3d308dfd137a07fe1cc478df0a23d42a6c4093b087e738e4827/pillow-11.2.1-cp313-cp313-win32.whl", hash = "sha256:3fe735ced9a607fee4f481423a9c36701a39719252a9bb251679635f99d0f7d2", size = 2332329 },
{ url = "https://files.pythonhosted.org/packages/6d/ec/1179083b8d6067a613e4d595359b5fdea65d0a3b7ad623fee906e1b3c4d2/pillow-11.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:74ee3d7ecb3f3c05459ba95eed5efa28d6092d751ce9bf20e3e253a4e497e691", size = 2676388, upload-time = "2025-04-12T17:48:43.625Z" }, { url = "https://files.pythonhosted.org/packages/6d/ec/1179083b8d6067a613e4d595359b5fdea65d0a3b7ad623fee906e1b3c4d2/pillow-11.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:74ee3d7ecb3f3c05459ba95eed5efa28d6092d751ce9bf20e3e253a4e497e691", size = 2676388 },
{ url = "https://files.pythonhosted.org/packages/23/f1/2fc1e1e294de897df39fa8622d829b8828ddad938b0eaea256d65b84dd72/pillow-11.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:5119225c622403afb4b44bad4c1ca6c1f98eed79db8d3bc6e4e160fc6339d66c", size = 2414950, upload-time = "2025-04-12T17:48:45.475Z" }, { url = "https://files.pythonhosted.org/packages/23/f1/2fc1e1e294de897df39fa8622d829b8828ddad938b0eaea256d65b84dd72/pillow-11.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:5119225c622403afb4b44bad4c1ca6c1f98eed79db8d3bc6e4e160fc6339d66c", size = 2414950 },
{ url = "https://files.pythonhosted.org/packages/c4/3e/c328c48b3f0ead7bab765a84b4977acb29f101d10e4ef57a5e3400447c03/pillow-11.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8ce2e8411c7aaef53e6bb29fe98f28cd4fbd9a1d9be2eeea434331aac0536b22", size = 3192759, upload-time = "2025-04-12T17:48:47.866Z" }, { url = "https://files.pythonhosted.org/packages/c4/3e/c328c48b3f0ead7bab765a84b4977acb29f101d10e4ef57a5e3400447c03/pillow-11.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8ce2e8411c7aaef53e6bb29fe98f28cd4fbd9a1d9be2eeea434331aac0536b22", size = 3192759 },
{ url = "https://files.pythonhosted.org/packages/18/0e/1c68532d833fc8b9f404d3a642991441d9058eccd5606eab31617f29b6d4/pillow-11.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9ee66787e095127116d91dea2143db65c7bb1e232f617aa5957c0d9d2a3f23a7", size = 3033284, upload-time = "2025-04-12T17:48:50.189Z" }, { url = "https://files.pythonhosted.org/packages/18/0e/1c68532d833fc8b9f404d3a642991441d9058eccd5606eab31617f29b6d4/pillow-11.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9ee66787e095127116d91dea2143db65c7bb1e232f617aa5957c0d9d2a3f23a7", size = 3033284 },
{ url = "https://files.pythonhosted.org/packages/b7/cb/6faf3fb1e7705fd2db74e070f3bf6f88693601b0ed8e81049a8266de4754/pillow-11.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9622e3b6c1d8b551b6e6f21873bdcc55762b4b2126633014cea1803368a9aa16", size = 4445826, upload-time = "2025-04-12T17:48:52.346Z" }, { url = "https://files.pythonhosted.org/packages/b7/cb/6faf3fb1e7705fd2db74e070f3bf6f88693601b0ed8e81049a8266de4754/pillow-11.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9622e3b6c1d8b551b6e6f21873bdcc55762b4b2126633014cea1803368a9aa16", size = 4445826 },
{ url = "https://files.pythonhosted.org/packages/07/94/8be03d50b70ca47fb434a358919d6a8d6580f282bbb7af7e4aa40103461d/pillow-11.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63b5dff3a68f371ea06025a1a6966c9a1e1ee452fc8020c2cd0ea41b83e9037b", size = 4527329, upload-time = "2025-04-12T17:48:54.403Z" }, { url = "https://files.pythonhosted.org/packages/07/94/8be03d50b70ca47fb434a358919d6a8d6580f282bbb7af7e4aa40103461d/pillow-11.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63b5dff3a68f371ea06025a1a6966c9a1e1ee452fc8020c2cd0ea41b83e9037b", size = 4527329 },
{ url = "https://files.pythonhosted.org/packages/fd/a4/bfe78777076dc405e3bd2080bc32da5ab3945b5a25dc5d8acaa9de64a162/pillow-11.2.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:31df6e2d3d8fc99f993fd253e97fae451a8db2e7207acf97859732273e108406", size = 4549049, upload-time = "2025-04-12T17:48:56.383Z" }, { url = "https://files.pythonhosted.org/packages/fd/a4/bfe78777076dc405e3bd2080bc32da5ab3945b5a25dc5d8acaa9de64a162/pillow-11.2.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:31df6e2d3d8fc99f993fd253e97fae451a8db2e7207acf97859732273e108406", size = 4549049 },
{ url = "https://files.pythonhosted.org/packages/65/4d/eaf9068dc687c24979e977ce5677e253624bd8b616b286f543f0c1b91662/pillow-11.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:062b7a42d672c45a70fa1f8b43d1d38ff76b63421cbbe7f88146b39e8a558d91", size = 4635408, upload-time = "2025-04-12T17:48:58.782Z" }, { url = "https://files.pythonhosted.org/packages/65/4d/eaf9068dc687c24979e977ce5677e253624bd8b616b286f543f0c1b91662/pillow-11.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:062b7a42d672c45a70fa1f8b43d1d38ff76b63421cbbe7f88146b39e8a558d91", size = 4635408 },
{ url = "https://files.pythonhosted.org/packages/1d/26/0fd443365d9c63bc79feb219f97d935cd4b93af28353cba78d8e77b61719/pillow-11.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4eb92eca2711ef8be42fd3f67533765d9fd043b8c80db204f16c8ea62ee1a751", size = 4614863, upload-time = "2025-04-12T17:49:00.709Z" }, { url = "https://files.pythonhosted.org/packages/1d/26/0fd443365d9c63bc79feb219f97d935cd4b93af28353cba78d8e77b61719/pillow-11.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4eb92eca2711ef8be42fd3f67533765d9fd043b8c80db204f16c8ea62ee1a751", size = 4614863 },
{ url = "https://files.pythonhosted.org/packages/49/65/dca4d2506be482c2c6641cacdba5c602bc76d8ceb618fd37de855653a419/pillow-11.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f91ebf30830a48c825590aede79376cb40f110b387c17ee9bd59932c961044f9", size = 4692938, upload-time = "2025-04-12T17:49:02.946Z" }, { url = "https://files.pythonhosted.org/packages/49/65/dca4d2506be482c2c6641cacdba5c602bc76d8ceb618fd37de855653a419/pillow-11.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f91ebf30830a48c825590aede79376cb40f110b387c17ee9bd59932c961044f9", size = 4692938 },
{ url = "https://files.pythonhosted.org/packages/b3/92/1ca0c3f09233bd7decf8f7105a1c4e3162fb9142128c74adad0fb361b7eb/pillow-11.2.1-cp313-cp313t-win32.whl", hash = "sha256:e0b55f27f584ed623221cfe995c912c61606be8513bfa0e07d2c674b4516d9dd", size = 2335774, upload-time = "2025-04-12T17:49:04.889Z" }, { url = "https://files.pythonhosted.org/packages/b3/92/1ca0c3f09233bd7decf8f7105a1c4e3162fb9142128c74adad0fb361b7eb/pillow-11.2.1-cp313-cp313t-win32.whl", hash = "sha256:e0b55f27f584ed623221cfe995c912c61606be8513bfa0e07d2c674b4516d9dd", size = 2335774 },
{ url = "https://files.pythonhosted.org/packages/a5/ac/77525347cb43b83ae905ffe257bbe2cc6fd23acb9796639a1f56aa59d191/pillow-11.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:36d6b82164c39ce5482f649b437382c0fb2395eabc1e2b1702a6deb8ad647d6e", size = 2681895, upload-time = "2025-04-12T17:49:06.635Z" }, { url = "https://files.pythonhosted.org/packages/a5/ac/77525347cb43b83ae905ffe257bbe2cc6fd23acb9796639a1f56aa59d191/pillow-11.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:36d6b82164c39ce5482f649b437382c0fb2395eabc1e2b1702a6deb8ad647d6e", size = 2681895 },
{ url = "https://files.pythonhosted.org/packages/67/32/32dc030cfa91ca0fc52baebbba2e009bb001122a1daa8b6a79ad830b38d3/pillow-11.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:225c832a13326e34f212d2072982bb1adb210e0cc0b153e688743018c94a2681", size = 2417234, upload-time = "2025-04-12T17:49:08.399Z" }, { url = "https://files.pythonhosted.org/packages/67/32/32dc030cfa91ca0fc52baebbba2e009bb001122a1daa8b6a79ad830b38d3/pillow-11.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:225c832a13326e34f212d2072982bb1adb210e0cc0b153e688743018c94a2681", size = 2417234 },
{ url = "https://files.pythonhosted.org/packages/33/49/c8c21e4255b4f4a2c0c68ac18125d7f5460b109acc6dfdef1a24f9b960ef/pillow-11.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9b7b0d4fd2635f54ad82785d56bc0d94f147096493a79985d0ab57aedd563156", size = 3181727, upload-time = "2025-04-12T17:49:31.898Z" }, { url = "https://files.pythonhosted.org/packages/33/49/c8c21e4255b4f4a2c0c68ac18125d7f5460b109acc6dfdef1a24f9b960ef/pillow-11.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9b7b0d4fd2635f54ad82785d56bc0d94f147096493a79985d0ab57aedd563156", size = 3181727 },
{ url = "https://files.pythonhosted.org/packages/6d/f1/f7255c0838f8c1ef6d55b625cfb286835c17e8136ce4351c5577d02c443b/pillow-11.2.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:aa442755e31c64037aa7c1cb186e0b369f8416c567381852c63444dd666fb772", size = 2999833, upload-time = "2025-04-12T17:49:34.2Z" }, { url = "https://files.pythonhosted.org/packages/6d/f1/f7255c0838f8c1ef6d55b625cfb286835c17e8136ce4351c5577d02c443b/pillow-11.2.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:aa442755e31c64037aa7c1cb186e0b369f8416c567381852c63444dd666fb772", size = 2999833 },
{ url = "https://files.pythonhosted.org/packages/e2/57/9968114457bd131063da98d87790d080366218f64fa2943b65ac6739abb3/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d3348c95b766f54b76116d53d4cb171b52992a1027e7ca50c81b43b9d9e363", size = 3437472, upload-time = "2025-04-12T17:49:36.294Z" }, { url = "https://files.pythonhosted.org/packages/e2/57/9968114457bd131063da98d87790d080366218f64fa2943b65ac6739abb3/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d3348c95b766f54b76116d53d4cb171b52992a1027e7ca50c81b43b9d9e363", size = 3437472 },
{ url = "https://files.pythonhosted.org/packages/b2/1b/e35d8a158e21372ecc48aac9c453518cfe23907bb82f950d6e1c72811eb0/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85d27ea4c889342f7e35f6d56e7e1cb345632ad592e8c51b693d7b7556043ce0", size = 3459976, upload-time = "2025-04-12T17:49:38.988Z" }, { url = "https://files.pythonhosted.org/packages/b2/1b/e35d8a158e21372ecc48aac9c453518cfe23907bb82f950d6e1c72811eb0/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85d27ea4c889342f7e35f6d56e7e1cb345632ad592e8c51b693d7b7556043ce0", size = 3459976 },
{ url = "https://files.pythonhosted.org/packages/26/da/2c11d03b765efff0ccc473f1c4186dc2770110464f2177efaed9cf6fae01/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bf2c33d6791c598142f00c9c4c7d47f6476731c31081331664eb26d6ab583e01", size = 3527133, upload-time = "2025-04-12T17:49:40.985Z" }, { url = "https://files.pythonhosted.org/packages/26/da/2c11d03b765efff0ccc473f1c4186dc2770110464f2177efaed9cf6fae01/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bf2c33d6791c598142f00c9c4c7d47f6476731c31081331664eb26d6ab583e01", size = 3527133 },
{ url = "https://files.pythonhosted.org/packages/79/1a/4e85bd7cadf78412c2a3069249a09c32ef3323650fd3005c97cca7aa21df/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e616e7154c37669fc1dfc14584f11e284e05d1c650e1c0f972f281c4ccc53193", size = 3571555, upload-time = "2025-04-12T17:49:42.964Z" }, { url = "https://files.pythonhosted.org/packages/79/1a/4e85bd7cadf78412c2a3069249a09c32ef3323650fd3005c97cca7aa21df/pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e616e7154c37669fc1dfc14584f11e284e05d1c650e1c0f972f281c4ccc53193", size = 3571555 },
{ url = "https://files.pythonhosted.org/packages/69/03/239939915216de1e95e0ce2334bf17a7870ae185eb390fab6d706aadbfc0/pillow-11.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39ad2e0f424394e3aebc40168845fee52df1394a4673a6ee512d840d14ab3013", size = 2674713, upload-time = "2025-04-12T17:49:44.944Z" }, { url = "https://files.pythonhosted.org/packages/69/03/239939915216de1e95e0ce2334bf17a7870ae185eb390fab6d706aadbfc0/pillow-11.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39ad2e0f424394e3aebc40168845fee52df1394a4673a6ee512d840d14ab3013", size = 2674713 },
{ url = "https://files.pythonhosted.org/packages/a4/ad/2613c04633c7257d9481ab21d6b5364b59fc5d75faafd7cb8693523945a3/pillow-11.2.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:80f1df8dbe9572b4b7abdfa17eb5d78dd620b1d55d9e25f834efdbee872d3aed", size = 3181734, upload-time = "2025-04-12T17:49:46.789Z" }, { url = "https://files.pythonhosted.org/packages/a4/ad/2613c04633c7257d9481ab21d6b5364b59fc5d75faafd7cb8693523945a3/pillow-11.2.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:80f1df8dbe9572b4b7abdfa17eb5d78dd620b1d55d9e25f834efdbee872d3aed", size = 3181734 },
{ url = "https://files.pythonhosted.org/packages/a4/fd/dcdda4471ed667de57bb5405bb42d751e6cfdd4011a12c248b455c778e03/pillow-11.2.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ea926cfbc3957090becbcbbb65ad177161a2ff2ad578b5a6ec9bb1e1cd78753c", size = 2999841, upload-time = "2025-04-12T17:49:48.812Z" }, { url = "https://files.pythonhosted.org/packages/a4/fd/dcdda4471ed667de57bb5405bb42d751e6cfdd4011a12c248b455c778e03/pillow-11.2.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ea926cfbc3957090becbcbbb65ad177161a2ff2ad578b5a6ec9bb1e1cd78753c", size = 2999841 },
{ url = "https://files.pythonhosted.org/packages/ac/89/8a2536e95e77432833f0db6fd72a8d310c8e4272a04461fb833eb021bf94/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:738db0e0941ca0376804d4de6a782c005245264edaa253ffce24e5a15cbdc7bd", size = 3437470, upload-time = "2025-04-12T17:49:50.831Z" }, { url = "https://files.pythonhosted.org/packages/ac/89/8a2536e95e77432833f0db6fd72a8d310c8e4272a04461fb833eb021bf94/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:738db0e0941ca0376804d4de6a782c005245264edaa253ffce24e5a15cbdc7bd", size = 3437470 },
{ url = "https://files.pythonhosted.org/packages/9d/8f/abd47b73c60712f88e9eda32baced7bfc3e9bd6a7619bb64b93acff28c3e/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db98ab6565c69082ec9b0d4e40dd9f6181dab0dd236d26f7a50b8b9bfbd5076", size = 3460013, upload-time = "2025-04-12T17:49:53.278Z" }, { url = "https://files.pythonhosted.org/packages/9d/8f/abd47b73c60712f88e9eda32baced7bfc3e9bd6a7619bb64b93acff28c3e/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db98ab6565c69082ec9b0d4e40dd9f6181dab0dd236d26f7a50b8b9bfbd5076", size = 3460013 },
{ url = "https://files.pythonhosted.org/packages/f6/20/5c0a0aa83b213b7a07ec01e71a3d6ea2cf4ad1d2c686cc0168173b6089e7/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:036e53f4170e270ddb8797d4c590e6dd14d28e15c7da375c18978045f7e6c37b", size = 3527165, upload-time = "2025-04-12T17:49:55.164Z" }, { url = "https://files.pythonhosted.org/packages/f6/20/5c0a0aa83b213b7a07ec01e71a3d6ea2cf4ad1d2c686cc0168173b6089e7/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:036e53f4170e270ddb8797d4c590e6dd14d28e15c7da375c18978045f7e6c37b", size = 3527165 },
{ url = "https://files.pythonhosted.org/packages/58/0e/2abab98a72202d91146abc839e10c14f7cf36166f12838ea0c4db3ca6ecb/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14f73f7c291279bd65fda51ee87affd7c1e097709f7fdd0188957a16c264601f", size = 3571586, upload-time = "2025-04-12T17:49:57.171Z" }, { url = "https://files.pythonhosted.org/packages/58/0e/2abab98a72202d91146abc839e10c14f7cf36166f12838ea0c4db3ca6ecb/pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14f73f7c291279bd65fda51ee87affd7c1e097709f7fdd0188957a16c264601f", size = 3571586 },
{ url = "https://files.pythonhosted.org/packages/21/2c/5e05f58658cf49b6667762cca03d6e7d85cededde2caf2ab37b81f80e574/pillow-11.2.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:208653868d5c9ecc2b327f9b9ef34e0e42a4cdd172c2988fd81d62d2bc9bc044", size = 2674751, upload-time = "2025-04-12T17:49:59.628Z" }, { url = "https://files.pythonhosted.org/packages/21/2c/5e05f58658cf49b6667762cca03d6e7d85cededde2caf2ab37b81f80e574/pillow-11.2.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:208653868d5c9ecc2b327f9b9ef34e0e42a4cdd172c2988fd81d62d2bc9bc044", size = 2674751 },
] ]
[[package]] [[package]]
name = "platformdirs" name = "platformdirs"
version = "4.3.7" version = "4.3.7"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351", size = 21291, upload-time = "2025-03-19T20:36:10.989Z" } sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351", size = 21291 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499, upload-time = "2025-03-19T20:36:09.038Z" }, { url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499 },
] ]
[[package]] [[package]]
name = "portprotonqt" name = "portprotonqt"
version = "0.1.1" version = "0.1.2"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "babel" }, { name = "babel" },
@ -442,24 +442,24 @@ dependencies = [
{ name = "pyyaml" }, { name = "pyyaml" },
{ name = "virtualenv" }, { name = "virtualenv" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/08/39/679ca9b26c7bb2999ff122d50faa301e49af82ca9c066ec061cfbc0c6784/pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146", size = 193424, upload-time = "2025-03-18T21:35:20.987Z" } sdist = { url = "https://files.pythonhosted.org/packages/08/39/679ca9b26c7bb2999ff122d50faa301e49af82ca9c066ec061cfbc0c6784/pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146", size = 193424 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707, upload-time = "2025-03-18T21:35:19.343Z" }, { url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707 },
] ]
[[package]] [[package]]
name = "psutil" name = "psutil"
version = "7.0.0" version = "7.0.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003, upload-time = "2025-02-13T21:54:07.946Z" } sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051, upload-time = "2025-02-13T21:54:12.36Z" }, { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051 },
{ url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535, upload-time = "2025-02-13T21:54:16.07Z" }, { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535 },
{ url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004, upload-time = "2025-02-13T21:54:18.662Z" }, { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004 },
{ url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986, upload-time = "2025-02-13T21:54:21.811Z" }, { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986 },
{ url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544, upload-time = "2025-02-13T21:54:24.68Z" }, { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544 },
{ url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053, upload-time = "2025-02-13T21:54:34.31Z" }, { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053 },
{ url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload-time = "2025-02-13T21:54:37.486Z" }, { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885 },
] ]
[[package]] [[package]]
@ -469,9 +469,9 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "requests" }, { name = "requests" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/6e/83/a4039c08cb9a57d8b7ad9e119fd87ab73ca6a8c4ea1421095afa70077979/pyaspeller-2.0.2.tar.gz", hash = "sha256:0aed696ab1ca11ca9d1a3874c7c2061fd567be9a2f1eff7b8e772031837701c0", size = 41039, upload-time = "2025-01-02T12:38:26.756Z" } sdist = { url = "https://files.pythonhosted.org/packages/6e/83/a4039c08cb9a57d8b7ad9e119fd87ab73ca6a8c4ea1421095afa70077979/pyaspeller-2.0.2.tar.gz", hash = "sha256:0aed696ab1ca11ca9d1a3874c7c2061fd567be9a2f1eff7b8e772031837701c0", size = 41039 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/73/ab/af7783445d4b564a8c4f6830f4126a219901c14f6b02c03c87a3853f0bb4/pyaspeller-2.0.2-py3-none-any.whl", hash = "sha256:1ae806e7054b0758521dfccadee1aa79747220cb88f21e06f211c59b27fd8e85", size = 16143, upload-time = "2025-01-02T12:38:25.265Z" }, { url = "https://files.pythonhosted.org/packages/73/ab/af7783445d4b564a8c4f6830f4126a219901c14f6b02c03c87a3853f0bb4/pyaspeller-2.0.2-py3-none-any.whl", hash = "sha256:1ae806e7054b0758521dfccadee1aa79747220cb88f21e06f211c59b27fd8e85", size = 16143 },
] ]
[[package]] [[package]]
@ -482,9 +482,9 @@ dependencies = [
{ name = "nodeenv" }, { name = "nodeenv" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/6c/cb/c306618a02d0ee8aed5fb8d0fe0ecfed0dbf075f71468f03a30b5f4e1fe0/pyright-1.1.400.tar.gz", hash = "sha256:b8a3ba40481aa47ba08ffb3228e821d22f7d391f83609211335858bf05686bdb", size = 3846546, upload-time = "2025-04-24T12:55:18.907Z" } sdist = { url = "https://files.pythonhosted.org/packages/6c/cb/c306618a02d0ee8aed5fb8d0fe0ecfed0dbf075f71468f03a30b5f4e1fe0/pyright-1.1.400.tar.gz", hash = "sha256:b8a3ba40481aa47ba08ffb3228e821d22f7d391f83609211335858bf05686bdb", size = 3846546 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/c8/a5/5d285e4932cf149c90e3c425610c5efaea005475d5f96f1bfdb452956c62/pyright-1.1.400-py3-none-any.whl", hash = "sha256:c80d04f98b5a4358ad3a35e241dbf2a408eee33a40779df365644f8054d2517e", size = 5563460, upload-time = "2025-04-24T12:55:17.002Z" }, { url = "https://files.pythonhosted.org/packages/c8/a5/5d285e4932cf149c90e3c425610c5efaea005475d5f96f1bfdb452956c62/pyright-1.1.400-py3-none-any.whl", hash = "sha256:c80d04f98b5a4358ad3a35e241dbf2a408eee33a40779df365644f8054d2517e", size = 5563460 },
] ]
[[package]] [[package]]
@ -497,11 +497,11 @@ dependencies = [
{ name = "shiboken6" }, { name = "shiboken6" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/46/74/0b465aa77644cfc3bfde912bb999b5a441d92c699272cab722335e92df3e/PySide6-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:b8f286a1bd143f3b2bdf08367b9362b13f469d26986c25700af9c4c68f79213e", size = 558001, upload-time = "2025-04-02T10:56:35.197Z" }, { url = "https://files.pythonhosted.org/packages/46/74/0b465aa77644cfc3bfde912bb999b5a441d92c699272cab722335e92df3e/PySide6-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:b8f286a1bd143f3b2bdf08367b9362b13f469d26986c25700af9c4c68f79213e", size = 558001 },
{ url = "https://files.pythonhosted.org/packages/91/53/ce78d2c279a4ed7d4baf5089a5ebff45d675670a42daa5e0f8dbb9ced6ed/PySide6-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:09239d1b808f18efccd3803db874d683917efcdebfdf0e8dec449cf50e74e7aa", size = 558139, upload-time = "2025-04-02T10:56:37.029Z" }, { url = "https://files.pythonhosted.org/packages/91/53/ce78d2c279a4ed7d4baf5089a5ebff45d675670a42daa5e0f8dbb9ced6ed/PySide6-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:09239d1b808f18efccd3803db874d683917efcdebfdf0e8dec449cf50e74e7aa", size = 558139 },
{ url = "https://files.pythonhosted.org/packages/4b/54/41d6ab0847c043f1fd96433a87ffd09a7cf17e11f5587e91e152777ec010/PySide6-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:1a176409dd0dd12b72d2c78b776e5051f569071ec52b7aaadd0a5b3333493c24", size = 558139, upload-time = "2025-04-02T10:56:38.519Z" }, { url = "https://files.pythonhosted.org/packages/4b/54/41d6ab0847c043f1fd96433a87ffd09a7cf17e11f5587e91e152777ec010/PySide6-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:1a176409dd0dd12b72d2c78b776e5051f569071ec52b7aaadd0a5b3333493c24", size = 558139 },
{ url = "https://files.pythonhosted.org/packages/63/03/55a632191beadd6bc59b04055961e2c3224a3475a906a63d1899a5ab493d/PySide6-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:0103e5d161696db40d75bfbf4e4b7d4f3372903c1b400c4e3379377b62c50290", size = 564479, upload-time = "2025-04-02T10:56:40.69Z" }, { url = "https://files.pythonhosted.org/packages/63/03/55a632191beadd6bc59b04055961e2c3224a3475a906a63d1899a5ab493d/PySide6-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:0103e5d161696db40d75bfbf4e4b7d4f3372903c1b400c4e3379377b62c50290", size = 564479 },
{ url = "https://files.pythonhosted.org/packages/e8/80/340523ecb17d2a168d7e37dfd8a7a0eebb81dcbec4870447f132f2a1a28e/PySide6-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:846fbccf0b3501eb31cf0791a46e137615efba6ce540da2b426d79fa3e7762c4", size = 401752, upload-time = "2025-04-02T10:56:42.175Z" }, { url = "https://files.pythonhosted.org/packages/e8/80/340523ecb17d2a168d7e37dfd8a7a0eebb81dcbec4870447f132f2a1a28e/PySide6-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:846fbccf0b3501eb31cf0791a46e137615efba6ce540da2b426d79fa3e7762c4", size = 401752 },
] ]
[[package]] [[package]]
@ -513,11 +513,11 @@ dependencies = [
{ name = "shiboken6" }, { name = "shiboken6" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/e8/a4/211077b3f30342827b2c543f80a5f6bc483ff3af6be99766984618e68fb6/PySide6_Addons-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:98f9ad4b65820736e12d49c18db2e570eac63727407fbb59a62ac753e89dc201", size = 315606763, upload-time = "2025-04-02T10:56:56.271Z" }, { url = "https://files.pythonhosted.org/packages/e8/a4/211077b3f30342827b2c543f80a5f6bc483ff3af6be99766984618e68fb6/PySide6_Addons-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:98f9ad4b65820736e12d49c18db2e570eac63727407fbb59a62ac753e89dc201", size = 315606763 },
{ url = "https://files.pythonhosted.org/packages/58/c1/21224090a7ee7e9ce5699e5bf16b84d576b7587f0712ccb6862a8b28476c/PySide6_Addons-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:fc9dcd63a0ce7565f238cb11c44494435a50eb6cb72b8dbce3b709618989c3dc", size = 166252767, upload-time = "2025-04-02T10:57:11.175Z" }, { url = "https://files.pythonhosted.org/packages/58/c1/21224090a7ee7e9ce5699e5bf16b84d576b7587f0712ccb6862a8b28476c/PySide6_Addons-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:fc9dcd63a0ce7565f238cb11c44494435a50eb6cb72b8dbce3b709618989c3dc", size = 166252767 },
{ url = "https://files.pythonhosted.org/packages/85/c3/add4948cf15648db542531a5c292f9de946ee288243730be7607499936ec/PySide6_Addons-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:d8a650644e0b9d1e7a092f6bcd11f25a63706d12f77d442b6ace75d346ab5d30", size = 161938789, upload-time = "2025-04-02T10:57:22.898Z" }, { url = "https://files.pythonhosted.org/packages/85/c3/add4948cf15648db542531a5c292f9de946ee288243730be7607499936ec/PySide6_Addons-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:d8a650644e0b9d1e7a092f6bcd11f25a63706d12f77d442b6ace75d346ab5d30", size = 161938789 },
{ url = "https://files.pythonhosted.org/packages/77/c0/b1718f62d1fcc9bac4c410d4150d7e1214235e73cc18f39dc36ad49f093f/PySide6_Addons-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:8cf54065b3d1b4698448fad825378a25c10ef52017d9dff48cead03200636d8d", size = 142994491, upload-time = "2025-04-02T10:57:34.865Z" }, { url = "https://files.pythonhosted.org/packages/77/c0/b1718f62d1fcc9bac4c410d4150d7e1214235e73cc18f39dc36ad49f093f/PySide6_Addons-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:8cf54065b3d1b4698448fad825378a25c10ef52017d9dff48cead03200636d8d", size = 142994491 },
{ url = "https://files.pythonhosted.org/packages/29/aa/810ceb3d111fa6a0cc865520e05198dd0cad4855558c8c8309d4d3852854/PySide6_Addons-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:260a56da59539f476c1635a3ff13591e10f1b04d92155c0617129bc53ca8b5f8", size = 26840861, upload-time = "2025-04-02T10:57:41.312Z" }, { url = "https://files.pythonhosted.org/packages/29/aa/810ceb3d111fa6a0cc865520e05198dd0cad4855558c8c8309d4d3852854/PySide6_Addons-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:260a56da59539f476c1635a3ff13591e10f1b04d92155c0617129bc53ca8b5f8", size = 26840861 },
] ]
[[package]] [[package]]
@ -528,64 +528,64 @@ dependencies = [
{ name = "shiboken6" }, { name = "shiboken6" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/98/ac/a3c8097d6fdcf414d961bdc0d532381d0ee141e4c699f5e2b881a7c3613f/PySide6_Essentials-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:b18e3e01b507e8a57481fe19792eb373d5f10a23a50702ce540da1435e722f39", size = 131981893, upload-time = "2025-04-02T10:57:49.618Z" }, { url = "https://files.pythonhosted.org/packages/98/ac/a3c8097d6fdcf414d961bdc0d532381d0ee141e4c699f5e2b881a7c3613f/PySide6_Essentials-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:b18e3e01b507e8a57481fe19792eb373d5f10a23a50702ce540da1435e722f39", size = 131981893 },
{ url = "https://files.pythonhosted.org/packages/9e/fd/46b713827007162de9108b22d01702868e75f31585da7eca5a79e3435590/PySide6_Essentials-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:45eaf7f17688d1991f39680dbfd3c41674f3cbb78f278aa10fe0b5f2f31c1989", size = 94232483, upload-time = "2025-04-02T10:57:58.879Z" }, { url = "https://files.pythonhosted.org/packages/9e/fd/46b713827007162de9108b22d01702868e75f31585da7eca5a79e3435590/PySide6_Essentials-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:45eaf7f17688d1991f39680dbfd3c41674f3cbb78f278aa10fe0b5f2f31c1989", size = 94232483 },
{ url = "https://files.pythonhosted.org/packages/ff/f1/72e1d400017a658e271594c8bd9c447c623dfd4fb936f4e043a4f9a8c93b/PySide6_Essentials-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:69aedfad77119c5bec0005ca31d5620e9bac8ba5ae66c7389160530cfd698ed8", size = 92102516, upload-time = "2025-04-02T10:58:06.598Z" }, { url = "https://files.pythonhosted.org/packages/ff/f1/72e1d400017a658e271594c8bd9c447c623dfd4fb936f4e043a4f9a8c93b/PySide6_Essentials-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:69aedfad77119c5bec0005ca31d5620e9bac8ba5ae66c7389160530cfd698ed8", size = 92102516 },
{ url = "https://files.pythonhosted.org/packages/96/8a/bc710350c4cf6894968e39970eaa613b85a82eb1f230052de597e44a00ac/PySide6_Essentials-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:94a0096d6bb1d3e5cef29ca4a5366d0f229d42480fbb17aa25ad85d72b1b7947", size = 72336994, upload-time = "2025-04-02T10:58:14.491Z" }, { url = "https://files.pythonhosted.org/packages/96/8a/bc710350c4cf6894968e39970eaa613b85a82eb1f230052de597e44a00ac/PySide6_Essentials-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:94a0096d6bb1d3e5cef29ca4a5366d0f229d42480fbb17aa25ad85d72b1b7947", size = 72336994 },
{ url = "https://files.pythonhosted.org/packages/49/a4/703e379a0979985f681cf04b9af4129f5dde20141b3cc64fc2a39d006614/PySide6_Essentials-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:d2dc45536f2269ad111991042e81257124f1cd1c9ed5ea778d7224fd65dc9e2b", size = 49449220, upload-time = "2025-04-02T10:58:21.192Z" }, { url = "https://files.pythonhosted.org/packages/49/a4/703e379a0979985f681cf04b9af4129f5dde20141b3cc64fc2a39d006614/PySide6_Essentials-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:d2dc45536f2269ad111991042e81257124f1cd1c9ed5ea778d7224fd65dc9e2b", size = 49449220 },
] ]
[[package]] [[package]]
name = "pyudev" name = "pyudev"
version = "0.24.3" version = "0.24.3"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c4/5c/6cc034da13830e3da123ccf9a30910bc868fa16670362f004e4b788d0df1/pyudev-0.24.3.tar.gz", hash = "sha256:2e945427a21674893bb97632401db62139d91cea1ee96137cc7b07ad22198fc7", size = 55970, upload-time = "2024-05-10T18:24:04.599Z" } sdist = { url = "https://files.pythonhosted.org/packages/c4/5c/6cc034da13830e3da123ccf9a30910bc868fa16670362f004e4b788d0df1/pyudev-0.24.3.tar.gz", hash = "sha256:2e945427a21674893bb97632401db62139d91cea1ee96137cc7b07ad22198fc7", size = 55970 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/9d/3b/c37870f68ceb067707ca7b04db364a1478fcd40c6194007fb6e492ff9a92/pyudev-0.24.3-py3-none-any.whl", hash = "sha256:e8246f0a014fe370119ba2bc781bfbe62c0298d0d6b39c94e83102a8a3f56960", size = 62677, upload-time = "2024-05-10T18:24:02.743Z" }, { url = "https://files.pythonhosted.org/packages/9d/3b/c37870f68ceb067707ca7b04db364a1478fcd40c6194007fb6e492ff9a92/pyudev-0.24.3-py3-none-any.whl", hash = "sha256:e8246f0a014fe370119ba2bc781bfbe62c0298d0d6b39c94e83102a8a3f56960", size = 62677 },
] ]
[[package]] [[package]]
name = "pyyaml" name = "pyyaml"
version = "6.0.2" version = "6.0.2"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload-time = "2024-08-06T20:31:40.178Z" }, { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 },
{ url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758, upload-time = "2024-08-06T20:31:42.173Z" }, { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 },
{ url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463, upload-time = "2024-08-06T20:31:44.263Z" }, { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 },
{ url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280, upload-time = "2024-08-06T20:31:50.199Z" }, { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 },
{ url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239, upload-time = "2024-08-06T20:31:52.292Z" }, { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 },
{ url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802, upload-time = "2024-08-06T20:31:53.836Z" }, { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 },
{ url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527, upload-time = "2024-08-06T20:31:55.565Z" }, { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 },
{ url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052, upload-time = "2024-08-06T20:31:56.914Z" }, { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 },
{ url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774, upload-time = "2024-08-06T20:31:58.304Z" }, { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 },
{ url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 },
{ url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 },
{ url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 },
{ url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 },
{ url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 },
{ url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 },
{ url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 },
{ url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 },
{ url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 },
{ url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 },
{ url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 },
{ url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 },
{ url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 },
{ url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 },
{ url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 },
{ url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 },
{ url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 },
{ url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 },
{ url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 },
{ url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 },
{ url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 },
{ url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 },
{ url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 },
{ url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 },
{ url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 },
{ url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 },
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 },
] ]
[[package]] [[package]]
@ -598,9 +598,9 @@ dependencies = [
{ name = "idna" }, { name = "idna" },
{ name = "urllib3" }, { name = "urllib3" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 },
] ]
[[package]] [[package]]
@ -608,11 +608,11 @@ name = "shiboken6"
version = "6.9.0" version = "6.9.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/be/85/97b36b045a233bcea9580e8c99d5c76d65cf9727dad8cb173527f6717471/shiboken6-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:c4d8e3a5907154ac4789e52c77957db95bcf584238c244d7743cb39e9b66dd26", size = 407067, upload-time = "2025-04-02T10:58:43.491Z" }, { url = "https://files.pythonhosted.org/packages/be/85/97b36b045a233bcea9580e8c99d5c76d65cf9727dad8cb173527f6717471/shiboken6-6.9.0-cp39-abi3-macosx_12_0_universal2.whl", hash = "sha256:c4d8e3a5907154ac4789e52c77957db95bcf584238c244d7743cb39e9b66dd26", size = 407067 },
{ url = "https://files.pythonhosted.org/packages/45/d3/f6ddef22d4f2ac11c079157ad3714d9b1fb9324d9cd3b200f824923fe2ba/shiboken6-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3f585caae5b814a7e23308db0a077355a7dc20c34d58ca4c339ff7625e9a1936", size = 206509, upload-time = "2025-04-02T10:58:44.905Z" }, { url = "https://files.pythonhosted.org/packages/45/d3/f6ddef22d4f2ac11c079157ad3714d9b1fb9324d9cd3b200f824923fe2ba/shiboken6-6.9.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3f585caae5b814a7e23308db0a077355a7dc20c34d58ca4c339ff7625e9a1936", size = 206509 },
{ url = "https://files.pythonhosted.org/packages/0d/59/6a91aad272fe89bf2293b7864fb6e926822c93a2f6192611528c6945196d/shiboken6-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:b61579b90bf9c53ecc174085a69429166dfe57a0b8b894f933d1281af9df6568", size = 202809, upload-time = "2025-04-02T10:58:46.667Z" }, { url = "https://files.pythonhosted.org/packages/0d/59/6a91aad272fe89bf2293b7864fb6e926822c93a2f6192611528c6945196d/shiboken6-6.9.0-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:b61579b90bf9c53ecc174085a69429166dfe57a0b8b894f933d1281af9df6568", size = 202809 },
{ url = "https://files.pythonhosted.org/packages/e2/6e/cf00d723ab141132fb6d35ba8faf109cbc0ee83412016343600abb423149/shiboken6-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:121ea290ed1afa5ad6abf690b377612693436292b69c61b0f8e10b1f0850f935", size = 1153132, upload-time = "2025-04-02T10:58:50.973Z" }, { url = "https://files.pythonhosted.org/packages/e2/6e/cf00d723ab141132fb6d35ba8faf109cbc0ee83412016343600abb423149/shiboken6-6.9.0-cp39-abi3-win_amd64.whl", hash = "sha256:121ea290ed1afa5ad6abf690b377612693436292b69c61b0f8e10b1f0850f935", size = 1153132 },
{ url = "https://files.pythonhosted.org/packages/b5/01/d59babab05786c99ebabdd152864ea3d4c500160979952c620eec68b1ff2/shiboken6-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:24f53857458881b54798d7e35704611d07f6b6885bcdf80f13a4c8bb485b8df2", size = 1831261, upload-time = "2025-04-02T10:58:52.789Z" }, { url = "https://files.pythonhosted.org/packages/b5/01/d59babab05786c99ebabdd152864ea3d4c500160979952c620eec68b1ff2/shiboken6-6.9.0-cp39-abi3-win_arm64.whl", hash = "sha256:24f53857458881b54798d7e35704611d07f6b6885bcdf80f13a4c8bb485b8df2", size = 1831261 },
] ]
[[package]] [[package]]
@ -622,36 +622,36 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" }, { name = "colorama", marker = "sys_platform == 'win32'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 },
] ]
[[package]] [[package]]
name = "typing-extensions" name = "typing-extensions"
version = "4.13.2" version = "4.13.2"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806 },
] ]
[[package]] [[package]]
name = "urllib3" name = "urllib3"
version = "2.4.0" version = "2.4.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 },
] ]
[[package]] [[package]]
name = "vdf" name = "vdf"
version = "3.4" version = "3.4"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/44/7f/74192f47d67c8bf3c47bf0d8487b3457614c2c98d58b6617721d217f3f79/vdf-3.4.tar.gz", hash = "sha256:fd5419f41e07a1009e5ffd027c7dcbe43d1f7e8ef453aeaa90d9d04b807de2af", size = 11132, upload-time = "2021-05-22T09:26:05.252Z" } sdist = { url = "https://files.pythonhosted.org/packages/44/7f/74192f47d67c8bf3c47bf0d8487b3457614c2c98d58b6617721d217f3f79/vdf-3.4.tar.gz", hash = "sha256:fd5419f41e07a1009e5ffd027c7dcbe43d1f7e8ef453aeaa90d9d04b807de2af", size = 11132 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/96/60/6456b687cf55cf60020dcd01f9bc51561c3cc84f05fd8e0feb71ce60f894/vdf-3.4-py2.py3-none-any.whl", hash = "sha256:68c1a125cc49e343d535af2dd25074e9cb0908c6607f073947c4a04bbe234534", size = 10357, upload-time = "2021-05-22T09:26:03.948Z" }, { url = "https://files.pythonhosted.org/packages/96/60/6456b687cf55cf60020dcd01f9bc51561c3cc84f05fd8e0feb71ce60f894/vdf-3.4-py2.py3-none-any.whl", hash = "sha256:68c1a125cc49e343d535af2dd25074e9cb0908c6607f073947c4a04bbe234534", size = 10357 },
] ]
[[package]] [[package]]
@ -663,7 +663,7 @@ dependencies = [
{ name = "filelock" }, { name = "filelock" },
{ name = "platformdirs" }, { name = "platformdirs" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/38/e0/633e369b91bbc664df47dcb5454b6c7cf441e8f5b9d0c250ce9f0546401e/virtualenv-20.30.0.tar.gz", hash = "sha256:800863162bcaa5450a6e4d721049730e7f2dae07720e0902b0e4040bd6f9ada8", size = 4346945, upload-time = "2025-03-31T16:33:29.185Z" } sdist = { url = "https://files.pythonhosted.org/packages/38/e0/633e369b91bbc664df47dcb5454b6c7cf441e8f5b9d0c250ce9f0546401e/virtualenv-20.30.0.tar.gz", hash = "sha256:800863162bcaa5450a6e4d721049730e7f2dae07720e0902b0e4040bd6f9ada8", size = 4346945 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/4c/ed/3cfeb48175f0671ec430ede81f628f9fb2b1084c9064ca67ebe8c0ed6a05/virtualenv-20.30.0-py3-none-any.whl", hash = "sha256:e34302959180fca3af42d1800df014b35019490b119eba981af27f2fa486e5d6", size = 4329461, upload-time = "2025-03-31T16:33:26.758Z" }, { url = "https://files.pythonhosted.org/packages/4c/ed/3cfeb48175f0671ec430ede81f628f9fb2b1084c9064ca67ebe8c0ed6a05/virtualenv-20.30.0-py3-none-any.whl", hash = "sha256:e34302959180fca3af42d1800df014b35019490b119eba981af27f2fa486e5d6", size = 4329461 },
] ]