diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..505a3b1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+# Python-generated files
+__pycache__/
+*.py[oc]
+build/
+dist/
+wheels/
+*.egg-info
+
+# Virtual environments
+.venv
diff --git a/.python-version b/.python-version
new file mode 100644
index 0000000..2c07333
--- /dev/null
+++ b/.python-version
@@ -0,0 +1 @@
+3.11
diff --git a/compile_ui.sh b/compile_ui.sh
new file mode 100644
index 0000000..608234e
--- /dev/null
+++ b/compile_ui.sh
@@ -0,0 +1,2 @@
+pyside6-uic ./src/ui/window.ui -o ./src/ui/window.py
+echo Done
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..48c6ce5
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,10 @@
+[project]
+name = "clipboard-link-cleaner"
+version = "0.1.0"
+description = "Add your description here"
+readme = "README.md"
+requires-python = ">=3.11"
+dependencies = [
+ "pyperclip>=1.11.0",
+ "pyside6>=6.10.0",
+]
diff --git a/src/main.py b/src/main.py
new file mode 100644
index 0000000..f97030c
--- /dev/null
+++ b/src/main.py
@@ -0,0 +1,140 @@
+import sys
+import html
+import signal
+from time import sleep
+from urllib.parse import unquote
+
+import pyperclip
+from PySide6.QtWidgets import QApplication
+from PySide6.QtWidgets import QMainWindow
+from PySide6.QtWidgets import QSystemTrayIcon
+from PySide6.QtWidgets import QTextBrowser
+from PySide6.QtCore import QThread
+from PySide6.QtCore import Signal
+from PySide6.QtGui import QIcon
+from PySide6.QtGui import QTextCharFormat, QColor
+
+from ui.window import Ui_MainWindow
+
+
+def highlight_special_chars(text):
+ text = html.escape(text)
+
+ text = text.replace(
+ "?", '?'
+ )
+ text = text.replace(
+ "&", '&'
+ )
+
+ return text
+
+def set_text_with_highlight(browser: QTextBrowser, text: str):
+ browser.clear()
+ text = unquote(text)
+ cursor = browser.textCursor()
+
+ highlight_fmt = QTextCharFormat()
+ highlight_fmt.setBackground(QColor("yellow"))
+ highlight_fmt.setForeground(QColor("black"))
+
+ normal_fmt = QTextCharFormat()
+
+ for ch in text:
+ if ch in ("?", "&"):
+ cursor.insertText(ch, highlight_fmt)
+ else:
+ cursor.insertText(ch, normal_fmt)
+
+class ClipboardWatcher(QThread):
+ clipboard_content = Signal(str)
+
+ def __init__(self):
+ super().__init__()
+ self.clipboard = ""
+
+ def run(self):
+ while True:
+ content = pyperclip.paste()
+ if content != self.clipboard:
+ self.clipboard = content
+ self.clipboard_content.emit(content)
+ sleep(.5)
+
+ def stop(self):
+ self.terminate()
+ self.wait()
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super(MainWindow, self).__init__()
+ self.ui = Ui_MainWindow()
+ self.ui.setupUi(self)
+ self.tray = QSystemTrayIcon()
+ self.tray.setIcon(QIcon.fromTheme("edit-copy"))
+ self.tray.setVisible(True)
+ self.clipboard_watcher = ClipboardWatcher()
+ self.clipboard_watcher.clipboard_content.connect(self.on_clipboard)
+ self.clipboard_watcher.start()
+
+ self.ui.button_cleanup.clicked.connect(self.on_cleanup)
+
+ self.notification_duration_seconds = 7
+ self.content = []
+ self.sanitized_link = False
+
+ def on_clipboard(self, content:str):
+ if not content.startswith("http"): return
+ self.cleanup(content)
+ self.ui.textbrowser_list.clear()
+ # self.ui.textbrowser_list.setHtml(highlight_special_chars(content))
+ set_text_with_highlight(browser=self.ui.textbrowser_list, text=self.content[0])
+
+ if len(self.content) == 2:
+ set_text_with_highlight(browser=self.ui.textbrowser_list_removed, text=self.content[1])
+ if self.ui.checkBox_auto_sanitize.isChecked():
+ self.overwrite_clipboard()
+ self.ui.listWidget_history.addItem(unquote(content))
+
+ def overwrite_clipboard(self):
+ pyperclip.copy(self.content[0])
+ self.sanitized_link = True
+ self.tray.showMessage(
+ "CliPy Utility",
+ "Sanitized link",
+ icon=QSystemTrayIcon.Information,
+ msecs=self.notification_duration_seconds * 1000
+ )
+
+ def on_cleanup(self):
+ self.overwrite_clipboard()
+
+ def cleanup(self, text):
+ self.content = text.split("?", 1)
+
+ def closeEvent(self, event) -> None:
+ """On close event take care to stop all QThreads
+
+ Args:
+ event (_type_): _description_
+ """
+ self.clipboard_watcher.stop()
+ super().closeEvent(event)
+
+ def handle_sigterm(self, *args) -> None:
+ """Handle SigInit and SigTerm
+ """
+ QApplication.quit()
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ window = MainWindow()
+ signal.signal(signal.SIGINT, window.handle_sigterm)
+ signal.signal(signal.SIGTERM, window.handle_sigterm)
+ window.setFixedSize(691,477)
+ window.setWindowIcon(QIcon.fromTheme("edit-copy"))
+ window.setWindowTitle("CliPy Utility")
+ window.show()
+ sys.exit(app.exec())
\ No newline at end of file
diff --git a/src/ui/window.py b/src/ui/window.py
new file mode 100644
index 0000000..ead73cf
--- /dev/null
+++ b/src/ui/window.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'window.ui'
+##
+## Created by: Qt User Interface Compiler version 6.9.0
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+ QMetaObject, QObject, QPoint, QRect,
+ QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+ QFont, QFontDatabase, QGradient, QIcon,
+ QImage, QKeySequence, QLinearGradient, QPainter,
+ QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QApplication, QCheckBox, QFrame, QLabel,
+ QListWidget, QListWidgetItem, QMainWindow, QMenuBar,
+ QPushButton, QSizePolicy, QSpinBox, QStatusBar,
+ QTabWidget, QTextBrowser, QWidget)
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
+ MainWindow.resize(691, 506)
+ MainWindow.setAnimated(True)
+ MainWindow.setDocumentMode(False)
+ MainWindow.setTabShape(QTabWidget.TabShape.Rounded)
+ self.centralwidget = QWidget(MainWindow)
+ self.centralwidget.setObjectName(u"centralwidget")
+ self.tabWidget = QTabWidget(self.centralwidget)
+ self.tabWidget.setObjectName(u"tabWidget")
+ self.tabWidget.setGeometry(QRect(0, 0, 691, 461))
+ self.tab_2 = QWidget()
+ self.tab_2.setObjectName(u"tab_2")
+ self.spinBox_max_history = QSpinBox(self.tab_2)
+ self.spinBox_max_history.setObjectName(u"spinBox_max_history")
+ self.spinBox_max_history.setGeometry(QRect(170, 10, 71, 21))
+ self.spinBox_max_history.setMaximum(10000)
+ self.label_max_history = QLabel(self.tab_2)
+ self.label_max_history.setObjectName(u"label_max_history")
+ self.label_max_history.setGeometry(QRect(10, 10, 81, 21))
+ self.checkBox_auto_sanitize = QCheckBox(self.tab_2)
+ self.checkBox_auto_sanitize.setObjectName(u"checkBox_auto_sanitize")
+ self.checkBox_auto_sanitize.setGeometry(QRect(170, 70, 71, 23))
+ self.checkBox_auto_sanitize.setChecked(True)
+ self.label = QLabel(self.tab_2)
+ self.label.setObjectName(u"label")
+ self.label.setGeometry(QRect(10, 40, 121, 18))
+ self.spinBox_notification_duration = QSpinBox(self.tab_2)
+ self.spinBox_notification_duration.setObjectName(u"spinBox_notification_duration")
+ self.spinBox_notification_duration.setGeometry(QRect(170, 40, 71, 21))
+ self.spinBox_notification_duration.setMaximum(10000)
+ self.spinBox_notification_duration.setValue(7)
+ self.label_2 = QLabel(self.tab_2)
+ self.label_2.setObjectName(u"label_2")
+ self.label_2.setGeometry(QRect(10, 70, 131, 18))
+ self.tabWidget.addTab(self.tab_2, "")
+ self.tab = QWidget()
+ self.tab.setObjectName(u"tab")
+ self.textbrowser_list = QTextBrowser(self.tab)
+ self.textbrowser_list.setObjectName(u"textbrowser_list")
+ self.textbrowser_list.setGeometry(QRect(0, 0, 681, 171))
+ self.textbrowser_list.setFrameShape(QFrame.Shape.Box)
+ self.button_cleanup = QPushButton(self.tab)
+ self.button_cleanup.setObjectName(u"button_cleanup")
+ self.button_cleanup.setGeometry(QRect(10, 390, 71, 26))
+ self.textbrowser_list_removed = QTextBrowser(self.tab)
+ self.textbrowser_list_removed.setObjectName(u"textbrowser_list_removed")
+ self.textbrowser_list_removed.setGeometry(QRect(0, 180, 681, 201))
+ self.textbrowser_list_removed.setFrameShape(QFrame.Shape.Box)
+ self.tabWidget.addTab(self.tab, "")
+ self.tab_3 = QWidget()
+ self.tab_3.setObjectName(u"tab_3")
+ self.listWidget_history = QListWidget(self.tab_3)
+ self.listWidget_history.setObjectName(u"listWidget_history")
+ self.listWidget_history.setGeometry(QRect(0, 0, 681, 381))
+ self.listWidget_history.setFrameShape(QFrame.Shape.Box)
+ self.pushButton_clear_history = QPushButton(self.tab_3)
+ self.pushButton_clear_history.setObjectName(u"pushButton_clear_history")
+ self.pushButton_clear_history.setGeometry(QRect(10, 390, 61, 26))
+ self.tabWidget.addTab(self.tab_3, "")
+ MainWindow.setCentralWidget(self.centralwidget)
+ self.menubar = QMenuBar(MainWindow)
+ self.menubar.setObjectName(u"menubar")
+ self.menubar.setGeometry(QRect(0, 0, 691, 23))
+ MainWindow.setMenuBar(self.menubar)
+ self.statusbar = QStatusBar(MainWindow)
+ self.statusbar.setObjectName(u"statusbar")
+ MainWindow.setStatusBar(self.statusbar)
+
+ self.retranslateUi(MainWindow)
+
+ self.tabWidget.setCurrentIndex(0)
+
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
+
+ def retranslateUi(self, MainWindow):
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Py Clipy Utility", None))
+ self.label_max_history.setText(QCoreApplication.translate("MainWindow", u"Max history", None))
+ self.checkBox_auto_sanitize.setText("")
+ self.label.setText(QCoreApplication.translate("MainWindow", u"Notify timeout (s)", None))
+ self.label_2.setText(QCoreApplication.translate("MainWindow", u"Auto-Sanitize links", None))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("MainWindow", u"General", None))
+ self.textbrowser_list.setHtml(QCoreApplication.translate("MainWindow", u"\n"
+"
\n"
+"
", None))
+ self.button_cleanup.setText(QCoreApplication.translate("MainWindow", u"Sanitize", None))
+ self.textbrowser_list_removed.setHtml(QCoreApplication.translate("MainWindow", u"\n"
+"\n"
+"
", None))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate("MainWindow", u"URLs", None))
+ self.pushButton_clear_history.setText(QCoreApplication.translate("MainWindow", u"Clear", None))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QCoreApplication.translate("MainWindow", u"History", None))
+ # retranslateUi
+
diff --git a/src/ui/window.ui b/src/ui/window.ui
new file mode 100644
index 0000000..d318130
--- /dev/null
+++ b/src/ui/window.ui
@@ -0,0 +1,238 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 691
+ 506
+
+
+
+ Py Clipy Utility
+
+
+ true
+
+
+ false
+
+
+ QTabWidget::TabShape::Rounded
+
+
+
+
+
+ 0
+ 0
+ 691
+ 461
+
+
+
+ 0
+
+
+
+ General
+
+
+
+
+ 170
+ 10
+ 71
+ 21
+
+
+
+ 10000
+
+
+
+
+
+ 10
+ 10
+ 81
+ 21
+
+
+
+ Max history
+
+
+
+
+
+ 170
+ 70
+ 71
+ 23
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 10
+ 40
+ 121
+ 18
+
+
+
+ Notify timeout (s)
+
+
+
+
+
+ 170
+ 40
+ 71
+ 21
+
+
+
+ 10000
+
+
+ 7
+
+
+
+
+
+ 10
+ 70
+ 131
+ 18
+
+
+
+ Auto-Sanitize links
+
+
+
+
+
+ URLs
+
+
+
+
+ 0
+ 0
+ 681
+ 171
+
+
+
+ QFrame::Shape::Box
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+hr { height: 1px; border-width: 0; }
+li.unchecked::marker { content: "\2610"; }
+li.checked::marker { content: "\2612"; }
+</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;">
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html>
+
+
+
+
+
+ 10
+ 390
+ 71
+ 26
+
+
+
+ Sanitize
+
+
+
+
+
+ 0
+ 180
+ 681
+ 201
+
+
+
+ QFrame::Shape::Box
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+hr { height: 1px; border-width: 0; }
+li.unchecked::marker { content: "\2610"; }
+li.checked::marker { content: "\2612"; }
+</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;">
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html>
+
+
+
+
+
+ History
+
+
+
+
+ 0
+ 0
+ 681
+ 381
+
+
+
+ QFrame::Shape::Box
+
+
+
+
+
+ 10
+ 390
+ 61
+ 26
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uv.lock b/uv.lock
new file mode 100644
index 0000000..db16327
--- /dev/null
+++ b/uv.lock
@@ -0,0 +1,87 @@
+version = 1
+revision = 3
+requires-python = ">=3.11"
+
+[[package]]
+name = "clipboard-link-cleaner"
+version = "0.1.0"
+source = { virtual = "." }
+dependencies = [
+ { name = "pyperclip" },
+ { name = "pyside6" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "pyperclip", specifier = ">=1.11.0" },
+ { name = "pyside6", specifier = ">=6.10.0" },
+]
+
+[[package]]
+name = "pyperclip"
+version = "1.11.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e8/52/d87eba7cb129b81563019d1679026e7a112ef76855d6159d24754dbd2a51/pyperclip-1.11.0.tar.gz", hash = "sha256:244035963e4428530d9e3a6101a1ef97209c6825edab1567beac148ccc1db1b6", size = 12185, upload-time = "2025-09-26T14:40:37.245Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/df/80/fc9d01d5ed37ba4c42ca2b55b4339ae6e200b456be3a1aaddf4a9fa99b8c/pyperclip-1.11.0-py3-none-any.whl", hash = "sha256:299403e9ff44581cb9ba2ffeed69c7aa96a008622ad0c46cb575ca75b5b84273", size = 11063, upload-time = "2025-09-26T14:40:36.069Z" },
+]
+
+[[package]]
+name = "pyside6"
+version = "6.10.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pyside6-addons" },
+ { name = "pyside6-essentials" },
+ { name = "shiboken6" },
+]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/56/22/f82cfcd1158be502c5741fe67c3fa853f3c1edbd3ac2c2250769dd9722d1/pyside6-6.10.1-cp39-abi3-macosx_13_0_universal2.whl", hash = "sha256:d0e70dd0e126d01986f357c2a555722f9462cf8a942bf2ce180baf69f468e516", size = 558169, upload-time = "2025-11-20T10:09:08.79Z" },
+ { url = "https://files.pythonhosted.org/packages/66/eb/54afe242a25d1c33b04ecd8321a549d9efb7b89eef7690eed92e98ba1dc9/pyside6-6.10.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4053bf51ba2c2cb20e1005edd469997976a02cec009f7c46356a0b65c137f1fa", size = 557818, upload-time = "2025-11-20T10:09:10.132Z" },
+ { url = "https://files.pythonhosted.org/packages/4d/af/5706b1b33587dc2f3dfa3a5000424befba35e4f2d5889284eebbde37138b/pyside6-6.10.1-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:7d3ca20a40139ca5324a7864f1d91cdf2ff237e11bd16354a42670f2a4eeb13c", size = 558358, upload-time = "2025-11-20T10:09:11.288Z" },
+ { url = "https://files.pythonhosted.org/packages/26/41/3f48d724ecc8e42cea8a8442aa9b5a86d394b85093275990038fd1020039/pyside6-6.10.1-cp39-abi3-win_amd64.whl", hash = "sha256:9f89ff994f774420eaa38cec6422fddd5356611d8481774820befd6f3bb84c9e", size = 564424, upload-time = "2025-11-20T10:09:12.677Z" },
+ { url = "https://files.pythonhosted.org/packages/af/30/395411473b433875a82f6b5fdd0cb28f19a0e345bcaac9fbc039400d7072/pyside6-6.10.1-cp39-abi3-win_arm64.whl", hash = "sha256:9c5c1d94387d1a32a6fae25348097918ef413b87dfa3767c46f737c6d48ae437", size = 548866, upload-time = "2025-11-20T10:09:14.174Z" },
+]
+
+[[package]]
+name = "pyside6-addons"
+version = "6.10.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pyside6-essentials" },
+ { name = "shiboken6" },
+]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2d/f9/b72a2578d7dbef7741bb90b5756b4ef9c99a5b40148ea53ce7f048573fe9/pyside6_addons-6.10.1-cp39-abi3-macosx_13_0_universal2.whl", hash = "sha256:4d2b82bbf9b861134845803837011e5f9ac7d33661b216805273cf0c6d0f8e82", size = 322639446, upload-time = "2025-11-20T09:54:50.75Z" },
+ { url = "https://files.pythonhosted.org/packages/94/3b/3ed951c570a15570706a89d39bfd4eaaffdf16d5c2dca17e82fc3ec8aaa6/pyside6_addons-6.10.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:330c229b58d30083a7b99ed22e118eb4f4126408429816a4044ccd0438ae81b4", size = 170678293, upload-time = "2025-11-20T09:56:40.991Z" },
+ { url = "https://files.pythonhosted.org/packages/22/77/4c780b204d0bf3323a75c184e349d063e208db44c993f1214aa4745d6f47/pyside6_addons-6.10.1-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:56864b5fecd6924187a2d0f7e98d968ed72b6cc267caa5b294cd7e88fff4e54c", size = 166365011, upload-time = "2025-11-20T09:57:20.261Z" },
+ { url = "https://files.pythonhosted.org/packages/04/14/58239776499e6b279fa6ca2e0d47209531454b99f6bd2ad7c96f11109416/pyside6_addons-6.10.1-cp39-abi3-win_amd64.whl", hash = "sha256:b6e249d15407dd33d6a2ffabd9dc6d7a8ab8c95d05f16a71dad4d07781c76341", size = 164864664, upload-time = "2025-11-20T09:57:54.815Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/cd/1b74108671ba4b1ebb2661330665c4898b089e9c87f7ba69fe2438f3d1b6/pyside6_addons-6.10.1-cp39-abi3-win_arm64.whl", hash = "sha256:0de303c0447326cdc6c8be5ab066ef581e2d0baf22560c9362d41b8304fdf2db", size = 34191225, upload-time = "2025-11-20T09:58:04.184Z" },
+]
+
+[[package]]
+name = "pyside6-essentials"
+version = "6.10.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "shiboken6" },
+]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/04/b0/c43209fecef79912e9b1c70a1b5172b1edf76caebcc885c58c60a09613b0/pyside6_essentials-6.10.1-cp39-abi3-macosx_13_0_universal2.whl", hash = "sha256:cd224aff3bb26ff1fca32c050e1c4d0bd9f951a96219d40d5f3d0128485b0bbe", size = 105461499, upload-time = "2025-11-20T09:59:23.733Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/8e/b69ba7fa0c701f3f4136b50460441697ec49ee6ea35c229eb2a5ee4b5952/pyside6_essentials-6.10.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:e9ccbfb58c03911a0bce1f2198605b02d4b5ca6276bfc0cbcf7c6f6393ffb856", size = 76764617, upload-time = "2025-11-20T09:59:38.831Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/83/569d27f4b6c6b9377150fe1a3745d64d02614021bea233636bc936a23423/pyside6_essentials-6.10.1-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:ec8617c9b143b0c19ba1cc5a7e98c538e4143795480cb152aee47802c18dc5d2", size = 75850373, upload-time = "2025-11-20T09:59:56.082Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/64/a8df6333de8ccbf3a320e1346ca30d0f314840aff5e3db9b4b66bf38e26c/pyside6_essentials-6.10.1-cp39-abi3-win_amd64.whl", hash = "sha256:9555a48e8f0acf63fc6a23c250808db841b28a66ed6ad89ee0e4df7628752674", size = 74491180, upload-time = "2025-11-20T10:00:11.215Z" },
+ { url = "https://files.pythonhosted.org/packages/67/da/65cc6c6a870d4ea908c59b2f0f9e2cf3bfc6c0710ebf278ed72f69865e4e/pyside6_essentials-6.10.1-cp39-abi3-win_arm64.whl", hash = "sha256:4d1d248644f1778f8ddae5da714ca0f5a150a5e6f602af2765a7d21b876da05c", size = 55190458, upload-time = "2025-11-20T10:00:26.226Z" },
+]
+
+[[package]]
+name = "shiboken6"
+version = "6.10.1"
+source = { registry = "https://pypi.org/simple" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6f/8b/e5db743d505ceea3efc4cd9634a3bee22a3e2bf6e07cefd28c9b9edabcc6/shiboken6-6.10.1-cp39-abi3-macosx_13_0_universal2.whl", hash = "sha256:9f2990f5b61b0b68ecadcd896ab4441f2cb097eef7797ecc40584107d9850d71", size = 478483, upload-time = "2025-11-20T10:08:52.411Z" },
+ { url = "https://files.pythonhosted.org/packages/56/ba/b50c1a44b3c4643f482afbf1a0ea58f393827307100389ce29404f9ad3b0/shiboken6-6.10.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f4221a52dfb81f24a0d20cc4f8981cb6edd810d5a9fb28287ce10d342573a0e4", size = 271993, upload-time = "2025-11-20T10:08:54.093Z" },
+ { url = "https://files.pythonhosted.org/packages/16/b8/939c24ebd662b0aa5c945443d0973145b3fb7079f0196274ef7bb4b98f73/shiboken6-6.10.1-cp39-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:c095b00f4d6bf578c0b2464bb4e264b351a99345374478570f69e2e679a2a1d0", size = 268691, upload-time = "2025-11-20T10:08:55.639Z" },
+ { url = "https://files.pythonhosted.org/packages/cf/a6/8c65ee0fa5e172ebcca03246b1bc3bd96cdaf1d60537316648536b7072a5/shiboken6-6.10.1-cp39-abi3-win_amd64.whl", hash = "sha256:c1601d3cda1fa32779b141663873741b54e797cb0328458d7466281f117b0a4e", size = 1234704, upload-time = "2025-11-20T10:08:57.417Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/6a/c0fea2f2ac7d9d96618c98156500683a4d1f93fea0e8c5a2bc39913d7ef1/shiboken6-6.10.1-cp39-abi3-win_arm64.whl", hash = "sha256:5cf800917008587b551005a45add2d485cca66f5f7ecd5b320e9954e40448cc9", size = 1795567, upload-time = "2025-11-20T10:08:59.184Z" },
+]