diff --git a/gui/Readme.md b/gui/Readme.md
deleted file mode 100644
index e0ac66c..0000000
--- a/gui/Readme.md
+++ /dev/null
@@ -1,14 +0,0 @@
-## README
-
-###
-
-
-### 收支记录
-
-### 图片处理
-
-### 颜色拾取
-
-### 密码管理
-
-
diff --git a/gui/assets/conf/config.json b/gui/assets/conf/config.json
deleted file mode 100644
index 243886b..0000000
--- a/gui/assets/conf/config.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "username": "admin",
- "login_password": "MkzWVYJoL5o2wDJOsExlS+qCElrJj+P6Rxiy89XwP7I=",
- "unlock_password": "MkzWVYJoL5o2wDJOsExlS+qCElrJj+P6Rxiy89XwP7I=",
- "code_dict": [4, 11, 4, 31, 22, 12, 19, 23, 7, 16, 7, 23, 1, 8, 7, 18, 27, 32, 28, 25, 7, 32, 9, 15, 2, 32, 0, 12, 26, 15, 14, 17],
- "minimum_password_length": 8,
- "maximum_db_number": 10,
- "api_ali": "",
- "api_wechat": ""
-}
\ No newline at end of file
diff --git a/gui/assets/ui/app.ui b/gui/assets/ui/app.ui
deleted file mode 100644
index 27fc8b5..0000000
--- a/gui/assets/ui/app.ui
+++ /dev/null
@@ -1,230 +0,0 @@
-
-
- App
-
-
-
- 0
- 0
- 769
- 356
-
-
-
-
- 0
- 0
-
-
-
-
- Consolas
- 12
-
-
-
- Toolbox
-
-
-
- -
-
-
-
-
-
-
-
- 个人
-
-
- -
-
- 实用
-
-
- -
-
- 效率
-
-
- -
-
- 开发
-
-
- -
-
- 设计
-
-
- -
-
- 工作
-
-
-
-
- -
-
-
- 0
-
-
-
-
-
- 110
- 70
- 54
- 16
-
-
-
- 1
-
-
-
-
-
-
-
- 100
- 130
- 54
- 16
-
-
-
- 2
-
-
-
-
-
-
-
- 130
- 70
- 54
- 16
-
-
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
- toolBar
-
-
- false
-
-
- TopToolBarArea
-
-
- false
-
-
-
-
-
-
-
-
-
-
- 主页
-
-
- Ctrl+Alt+H
-
-
- Ctrl+Alt+H
-
-
- QAction::MenuRole::NoRole
-
-
-
-
- 设置
-
-
- Ctrl+Alt+S
-
-
- Ctrl+Alt+S
-
-
- QAction::MenuRole::NoRole
-
-
-
-
- 日志
-
-
- Ctrl+Alt+L
-
-
- Ctrl+Alt+L
-
-
- QAction::MenuRole::NoRole
-
-
-
-
- 关于
-
-
- Ctrl+Alt+A
-
-
- Ctrl+Alt+A
-
-
- QAction::MenuRole::NoRole
-
-
-
-
- 退出
-
-
- Ctrl+Alt+Q
-
-
- Ctrl+Alt+Q
-
-
- QAction::MenuRole::NoRole
-
-
-
-
- 锁定
-
-
- Ctrl+Alt+C
-
-
- Ctrl+Alt+C
-
-
- QAction::MenuRole::NoRole
-
-
-
-
-
-
diff --git a/gui/assets/ui/login.ui b/gui/assets/ui/login.ui
deleted file mode 100644
index b564388..0000000
--- a/gui/assets/ui/login.ui
+++ /dev/null
@@ -1,218 +0,0 @@
-
-
- login
-
-
-
- 0
- 0
- 450
- 150
-
-
-
-
- 0
- 0
-
-
-
-
- 450
- 150
-
-
-
-
- 450
- 150
-
-
-
- 登录
-
-
- -
-
-
-
-
-
-
-
-
-
- 100
- 100
-
-
-
-
- 105
- 105
-
-
-
-
-
-
- true
-
-
- Qt::AlignmentFlag::AlignCenter
-
-
- 0
-
-
- -1
-
-
-
- -
-
-
-
- 0
- 40
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- Qt::AlignmentFlag::AlignCenter
-
-
- Qt::AlignmentFlag::AlignCenter
-
-
- 30
-
-
- 15
-
-
- 30
-
-
- 15
-
-
-
-
-
-
- Consolas
- 12
- true
-
-
-
- Username
-
-
-
- -
-
-
-
- Consolas
- 12
-
-
-
-
- -
-
-
-
- Consolas
- 12
- true
-
-
-
- Password
-
-
-
- -
-
-
-
- Consolas
- 12
-
-
-
- QLineEdit::EchoMode::Password
-
-
-
-
-
- -
-
-
- 40
-
-
- 0
-
-
- 40
-
-
- 20
-
-
-
-
-
-
- Consolas
- 12
- true
-
-
-
- 登录
-
-
- true
-
-
-
- -
-
-
-
- Consolas
- 12
- true
-
-
-
- 取消
-
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/gui/codes/common/clibs.py b/gui/codes/common/clibs.py
deleted file mode 100644
index 856979e..0000000
--- a/gui/codes/common/clibs.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from pathlib import Path
-from threading import Lock
-
-
-base_path = Path(__file__).resolve().parent.parent.parent
-lock = Lock()
-account = None
diff --git a/gui/codes/ui/app.py b/gui/codes/ui/app.py
deleted file mode 100644
index 17f3e5d..0000000
--- a/gui/codes/ui/app.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# -*- coding: utf-8 -*-
-
-################################################################################
-## Form generated from reading UI file 'app.ui'
-##
-## Created by: Qt User Interface Compiler version 6.9.2
-##
-## 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 (QAction, QBrush, QColor, QConicalGradient,
- QCursor, QFont, QFontDatabase, QGradient,
- QIcon, QImage, QKeySequence, QLinearGradient,
- QPainter, QPalette, QPixmap, QRadialGradient,
- QTransform)
-from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QListWidget,
- QListWidgetItem, QMainWindow, QSizePolicy, QStackedWidget,
- QStatusBar, QToolBar, QVBoxLayout, QWidget)
-
-class Ui_App(object):
- def setupUi(self, App):
- if not App.objectName():
- App.setObjectName(u"App")
- App.resize(769, 356)
- App.setMinimumSize(QSize(0, 0))
- font = QFont()
- font.setFamilies([u"Consolas"])
- font.setPointSize(12)
- App.setFont(font)
- self.ac_homepage = QAction(App)
- self.ac_homepage.setObjectName(u"ac_homepage")
- self.ac_homepage.setMenuRole(QAction.MenuRole.NoRole)
- self.ac_settings = QAction(App)
- self.ac_settings.setObjectName(u"ac_settings")
- self.ac_settings.setMenuRole(QAction.MenuRole.NoRole)
- self.ac_logs = QAction(App)
- self.ac_logs.setObjectName(u"ac_logs")
- self.ac_logs.setMenuRole(QAction.MenuRole.NoRole)
- self.ac_about = QAction(App)
- self.ac_about.setObjectName(u"ac_about")
- self.ac_about.setMenuRole(QAction.MenuRole.NoRole)
- self.ac_quit = QAction(App)
- self.ac_quit.setObjectName(u"ac_quit")
- self.ac_quit.setMenuRole(QAction.MenuRole.NoRole)
- self.ac_caging = QAction(App)
- self.ac_caging.setObjectName(u"ac_caging")
- self.ac_caging.setMenuRole(QAction.MenuRole.NoRole)
- self.centralwidget = QWidget(App)
- self.centralwidget.setObjectName(u"centralwidget")
- self.verticalLayout = QVBoxLayout(self.centralwidget)
- self.verticalLayout.setObjectName(u"verticalLayout")
- self.horizontalLayout = QHBoxLayout()
- self.horizontalLayout.setObjectName(u"horizontalLayout")
- self.lw_navigation = QListWidget(self.centralwidget)
- QListWidgetItem(self.lw_navigation)
- QListWidgetItem(self.lw_navigation)
- QListWidgetItem(self.lw_navigation)
- QListWidgetItem(self.lw_navigation)
- QListWidgetItem(self.lw_navigation)
- QListWidgetItem(self.lw_navigation)
- self.lw_navigation.setObjectName(u"lw_navigation")
-
- self.horizontalLayout.addWidget(self.lw_navigation)
-
- self.sw_pages = QStackedWidget(self.centralwidget)
- self.sw_pages.setObjectName(u"sw_pages")
- self.page = QWidget()
- self.page.setObjectName(u"page")
- self.label_3 = QLabel(self.page)
- self.label_3.setObjectName(u"label_3")
- self.label_3.setGeometry(QRect(110, 70, 54, 16))
- self.sw_pages.addWidget(self.page)
- self.page_2 = QWidget()
- self.page_2.setObjectName(u"page_2")
- self.label_2 = QLabel(self.page_2)
- self.label_2.setObjectName(u"label_2")
- self.label_2.setGeometry(QRect(100, 130, 54, 16))
- self.sw_pages.addWidget(self.page_2)
- self.page_3 = QWidget()
- self.page_3.setObjectName(u"page_3")
- self.label = QLabel(self.page_3)
- self.label.setObjectName(u"label")
- self.label.setGeometry(QRect(130, 70, 54, 16))
- self.sw_pages.addWidget(self.page_3)
-
- self.horizontalLayout.addWidget(self.sw_pages)
-
- self.horizontalLayout.setStretch(0, 1)
- self.horizontalLayout.setStretch(1, 5)
-
- self.verticalLayout.addLayout(self.horizontalLayout)
-
- App.setCentralWidget(self.centralwidget)
- self.statusbar = QStatusBar(App)
- self.statusbar.setObjectName(u"statusbar")
- App.setStatusBar(self.statusbar)
- self.toolBar = QToolBar(App)
- self.toolBar.setObjectName(u"toolBar")
- self.toolBar.setMovable(False)
- App.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.toolBar)
-
- self.toolBar.addAction(self.ac_homepage)
- self.toolBar.addAction(self.ac_settings)
- self.toolBar.addAction(self.ac_logs)
- self.toolBar.addAction(self.ac_about)
- self.toolBar.addAction(self.ac_caging)
- self.toolBar.addAction(self.ac_quit)
-
- self.retranslateUi(App)
-
- self.sw_pages.setCurrentIndex(0)
-
-
- QMetaObject.connectSlotsByName(App)
- # setupUi
-
- def retranslateUi(self, App):
- App.setWindowTitle(QCoreApplication.translate("App", u"Toolbox", None))
- self.ac_homepage.setText(QCoreApplication.translate("App", u"\u4e3b\u9875", None))
-#if QT_CONFIG(tooltip)
- self.ac_homepage.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+H", None))
-#endif // QT_CONFIG(tooltip)
-#if QT_CONFIG(shortcut)
- self.ac_homepage.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+H", None))
-#endif // QT_CONFIG(shortcut)
- self.ac_settings.setText(QCoreApplication.translate("App", u"\u8bbe\u7f6e", None))
-#if QT_CONFIG(tooltip)
- self.ac_settings.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+S", None))
-#endif // QT_CONFIG(tooltip)
-#if QT_CONFIG(shortcut)
- self.ac_settings.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+S", None))
-#endif // QT_CONFIG(shortcut)
- self.ac_logs.setText(QCoreApplication.translate("App", u"\u65e5\u5fd7", None))
-#if QT_CONFIG(tooltip)
- self.ac_logs.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+L", None))
-#endif // QT_CONFIG(tooltip)
-#if QT_CONFIG(shortcut)
- self.ac_logs.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+L", None))
-#endif // QT_CONFIG(shortcut)
- self.ac_about.setText(QCoreApplication.translate("App", u"\u5173\u4e8e", None))
-#if QT_CONFIG(tooltip)
- self.ac_about.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+A", None))
-#endif // QT_CONFIG(tooltip)
-#if QT_CONFIG(shortcut)
- self.ac_about.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+A", None))
-#endif // QT_CONFIG(shortcut)
- self.ac_quit.setText(QCoreApplication.translate("App", u"\u9000\u51fa", None))
-#if QT_CONFIG(tooltip)
- self.ac_quit.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+Q", None))
-#endif // QT_CONFIG(tooltip)
-#if QT_CONFIG(shortcut)
- self.ac_quit.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+Q", None))
-#endif // QT_CONFIG(shortcut)
- self.ac_caging.setText(QCoreApplication.translate("App", u"\u9501\u5b9a", None))
-#if QT_CONFIG(tooltip)
- self.ac_caging.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+C", None))
-#endif // QT_CONFIG(tooltip)
-#if QT_CONFIG(shortcut)
- self.ac_caging.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+C", None))
-#endif // QT_CONFIG(shortcut)
-
- __sortingEnabled = self.lw_navigation.isSortingEnabled()
- self.lw_navigation.setSortingEnabled(False)
- ___qlistwidgetitem = self.lw_navigation.item(0)
- ___qlistwidgetitem.setText(QCoreApplication.translate("App", u"\u4e2a\u4eba", None));
- ___qlistwidgetitem1 = self.lw_navigation.item(1)
- ___qlistwidgetitem1.setText(QCoreApplication.translate("App", u"\u5b9e\u7528", None));
- ___qlistwidgetitem2 = self.lw_navigation.item(2)
- ___qlistwidgetitem2.setText(QCoreApplication.translate("App", u"\u6548\u7387", None));
- ___qlistwidgetitem3 = self.lw_navigation.item(3)
- ___qlistwidgetitem3.setText(QCoreApplication.translate("App", u"\u5f00\u53d1", None));
- ___qlistwidgetitem4 = self.lw_navigation.item(4)
- ___qlistwidgetitem4.setText(QCoreApplication.translate("App", u"\u8bbe\u8ba1", None));
- ___qlistwidgetitem5 = self.lw_navigation.item(5)
- ___qlistwidgetitem5.setText(QCoreApplication.translate("App", u"\u5de5\u4f5c", None));
- self.lw_navigation.setSortingEnabled(__sortingEnabled)
-
- self.label_3.setText(QCoreApplication.translate("App", u"1", None))
- self.label_2.setText(QCoreApplication.translate("App", u"2", None))
- self.label.setText(QCoreApplication.translate("App", u"3", None))
- self.toolBar.setWindowTitle(QCoreApplication.translate("App", u"toolBar", None))
- # retranslateUi
-
diff --git a/gui/codes/ui/login.py b/gui/codes/ui/login.py
deleted file mode 100644
index a4f6b3e..0000000
--- a/gui/codes/ui/login.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# -*- coding: utf-8 -*-
-
-################################################################################
-## Form generated from reading UI file 'login.ui'
-##
-## Created by: Qt User Interface Compiler version 6.9.2
-##
-## 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, QFormLayout, QHBoxLayout, QLabel,
- QLineEdit, QPushButton, QSizePolicy, QVBoxLayout,
- QWidget)
-
-class Ui_login(object):
- def setupUi(self, login):
- if not login.objectName():
- login.setObjectName(u"login")
- login.resize(450, 150)
- sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(login.sizePolicy().hasHeightForWidth())
- login.setSizePolicy(sizePolicy)
- login.setMinimumSize(QSize(450, 150))
- login.setMaximumSize(QSize(450, 150))
- self.verticalLayout_3 = QVBoxLayout(login)
- self.verticalLayout_3.setObjectName(u"verticalLayout_3")
- self.horizontalLayout_2 = QHBoxLayout()
- self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
- self.verticalLayout_2 = QVBoxLayout()
- self.verticalLayout_2.setObjectName(u"verticalLayout_2")
- self.lb_logo = QLabel(login)
- self.lb_logo.setObjectName(u"lb_logo")
- self.lb_logo.setMinimumSize(QSize(100, 100))
- self.lb_logo.setMaximumSize(QSize(105, 105))
- self.lb_logo.setScaledContents(True)
- self.lb_logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
- self.lb_logo.setMargin(0)
- self.lb_logo.setIndent(-1)
-
- self.verticalLayout_2.addWidget(self.lb_logo)
-
- self.lb_none = QLabel(login)
- self.lb_none.setObjectName(u"lb_none")
- self.lb_none.setMinimumSize(QSize(0, 40))
-
- self.verticalLayout_2.addWidget(self.lb_none)
-
-
- self.horizontalLayout_2.addLayout(self.verticalLayout_2)
-
- self.verticalLayout = QVBoxLayout()
- self.verticalLayout.setObjectName(u"verticalLayout")
- self.formLayout = QFormLayout()
- self.formLayout.setObjectName(u"formLayout")
- self.formLayout.setLabelAlignment(Qt.AlignmentFlag.AlignCenter)
- self.formLayout.setFormAlignment(Qt.AlignmentFlag.AlignCenter)
- self.formLayout.setContentsMargins(30, 15, 30, 15)
- self.lb_username = QLabel(login)
- self.lb_username.setObjectName(u"lb_username")
- font = QFont()
- font.setFamilies([u"Consolas"])
- font.setPointSize(12)
- font.setItalic(True)
- self.lb_username.setFont(font)
-
- self.formLayout.setWidget(0, QFormLayout.ItemRole.LabelRole, self.lb_username)
-
- self.le_username = QLineEdit(login)
- self.le_username.setObjectName(u"le_username")
- font1 = QFont()
- font1.setFamilies([u"Consolas"])
- font1.setPointSize(12)
- self.le_username.setFont(font1)
-
- self.formLayout.setWidget(0, QFormLayout.ItemRole.FieldRole, self.le_username)
-
- self.lb_password = QLabel(login)
- self.lb_password.setObjectName(u"lb_password")
- self.lb_password.setFont(font)
-
- self.formLayout.setWidget(1, QFormLayout.ItemRole.LabelRole, self.lb_password)
-
- self.le_password = QLineEdit(login)
- self.le_password.setObjectName(u"le_password")
- self.le_password.setFont(font1)
- self.le_password.setEchoMode(QLineEdit.EchoMode.Password)
-
- self.formLayout.setWidget(1, QFormLayout.ItemRole.FieldRole, self.le_password)
-
-
- self.verticalLayout.addLayout(self.formLayout)
-
- self.horizontalLayout = QHBoxLayout()
- self.horizontalLayout.setObjectName(u"horizontalLayout")
- self.horizontalLayout.setContentsMargins(40, 0, 40, 20)
- self.pb_login = QPushButton(login)
- self.pb_login.setObjectName(u"pb_login")
- font2 = QFont()
- font2.setFamilies([u"Consolas"])
- font2.setPointSize(12)
- font2.setBold(True)
- self.pb_login.setFont(font2)
- self.pb_login.setAutoDefault(True)
-
- self.horizontalLayout.addWidget(self.pb_login)
-
- self.pb_cancel = QPushButton(login)
- self.pb_cancel.setObjectName(u"pb_cancel")
- self.pb_cancel.setFont(font2)
- self.pb_cancel.setAutoDefault(True)
-
- self.horizontalLayout.addWidget(self.pb_cancel)
-
-
- self.verticalLayout.addLayout(self.horizontalLayout)
-
-
- self.horizontalLayout_2.addLayout(self.verticalLayout)
-
-
- self.verticalLayout_3.addLayout(self.horizontalLayout_2)
-
-
- self.retranslateUi(login)
-
- QMetaObject.connectSlotsByName(login)
- # setupUi
-
- def retranslateUi(self, login):
- login.setWindowTitle(QCoreApplication.translate("login", u"\u767b\u5f55", None))
- self.lb_logo.setText("")
- self.lb_none.setText("")
- self.lb_username.setText(QCoreApplication.translate("login", u"Username", None))
- self.lb_password.setText(QCoreApplication.translate("login", u"Password", None))
- self.pb_login.setText(QCoreApplication.translate("login", u"\u767b\u5f55", None))
- self.pb_cancel.setText(QCoreApplication.translate("login", u"\u53d6\u6d88", None))
- # retranslateUi
-
diff --git a/gui/main.py b/gui/main.py
deleted file mode 100644
index 3527e02..0000000
--- a/gui/main.py
+++ /dev/null
@@ -1,223 +0,0 @@
-import json
-import random
-import sys
-from typing import Callable, Any
-from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QMainWindow, QHBoxLayout, QVBoxLayout, QLineEdit, QLabel
-from PySide6.QtGui import QIcon, QPixmap, QShortcut, QResizeEvent, QFont, QKeySequence
-from PySide6.QtCore import Qt,QSize
-from codes.ui.login import Ui_login
-from codes.ui.app import Ui_App
-from codes.common.worker import Worker
-from codes.common import clibs
-from codes.common.secure_encrypt import PassCipher
-from codes.common import db_operation
-
-class LoginWindow(QWidget, Ui_login):
- def __init__(self):
- super().__init__()
- self.setupUi(self)
- self.pre_dos()
-
- def pre_dos(self):
- self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
- self.lb_logo.setPixmap(QPixmap(f"{clibs.base_path}/assets/media/avatar.png"))
- self.lb_logo.setScaledContents(True)
-
- # bindings
- QShortcut("Esc", self).activated.connect(self.close)
- self.pb_login.clicked.connect(self.login)
- self.pb_cancel.clicked.connect(self.close)
- self.le_password.returnPressed.connect(self.login)
-
- def login(self):
- def login_failed():
- QMessageBox.warning(self, "告警", "\n用户名或密码不正确,请重新输入!")
- self.le_username.setText("")
- self.le_password.setText("")
-
- def validate_login():
- nonlocal username, password
- with open(f"{clibs.base_path}/assets/conf/config.json", mode="rt", encoding="utf-8") as f_conf:
- clibs.account = json.load(f_conf)
- if username != clibs.account["username"] or len(password) < clibs.account["minimum_password_length"]:
- login_failed()
- return False
-
- salt = PassCipher.gen_salt(password)
- cipher = PassCipher(salt)
- # password_encrypt = cipher.encrypt(password)
- # print(f"password_encrypt = {password_encrypt}")
- # exit()
- try:
- decrypt_password = cipher.decrypt(clibs.account["login_password"])
- except ValueError:
- login_failed()
- return False
-
- if password != decrypt_password:
- login_failed()
- return False
-
- self.mainWindow = MainWindow()
- self.mainWindow.show()
- self.deleteLater()
- return True
-
- username = self.le_username.text()
- password = self.le_password.text()
- validate_login()
-
-
-class MainWindow(QMainWindow, Ui_App):
- def __init__(self):
- super().__init__()
- self.conn = None
- self.cursor = None
- self.thread = None
- self.setupUi(self)
- self.pre_dos()
- self.lock_overlay = None
-
- def pre_dos(self):
- self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
- db_operation.db_backup()
- self.conn, self.cursor = db_operation.db_conn()
- # bindings
- self.ac_quit.triggered.connect(self.close)
- self.ac_caging.triggered.connect(self.lock_window)
- self.ac_logs.triggered.connect(lambda : print("test ac log"))
-
- def launch(self, func, on_anything: Callable[..., Any] = print, *args, **kwargs):
- self.thread = Worker(func, *args, **kwargs)
- self.thread.started.connect(lambda: on_anything({"started": True}))
- self.thread.result.connect(on_anything)
- self.thread.error.connect(on_anything)
- self.thread.finished.connect(lambda: on_anything({"finished": True}))
- self.thread.start()
-
- def lock_window(self):
- def unlock():
- def check_failed():
- QMessageBox.warning(self, "错误", "\n密码错误,请重新输入!")
- le_password.clear()
- le_password.setFocus()
-
- password = le_password.text()
- if len(password) < clibs.account["minimum_password_length"]:
- check_failed()
- return False
-
- salt = PassCipher.gen_salt(password)
- cipher = PassCipher(salt)
- try:
- decrypt_password = cipher.decrypt(clibs.account["unlock_password"])
- except ValueError:
- check_failed()
- return False
-
- if password != decrypt_password:
- check_failed()
- return False
-
- self.lock_overlay.deleteLater()
- self.lock_overlay = None
- self.set_shortcuts(True)
- return True
-
- def gen_lock_screen():
- # generate lock screen
- v_layout = QVBoxLayout(self.lock_overlay) # v layout
- v_layout.setObjectName(u"v_layout")
- h_layout = QHBoxLayout() # h layout
- h_layout.setObjectName(u"h_layout")
- h_layout.setContentsMargins(-1, -1, 10, 50)
- lb_e_1 = QLabel(self.lock_overlay)
- lb_e_1.setObjectName(u"lb_e_1")
- h_layout.addWidget(lb_e_1)
-
- lb_password = QLabel(self.lock_overlay)
- lb_password.setObjectName(u"lb_password")
- lb_password.setMinimumSize(QSize(100, 0))
- lb_password.setMaximumSize(QSize(100, 16777215))
- font = QFont()
- font.setFamilies([u"Consolas"])
- font.setPointSize(14)
- font.setBold(True)
- font.setItalic(True)
- lb_password.setFont(font)
- lb_password.setAlignment(Qt.AlignmentFlag.AlignCenter)
- lb_password.setText("Password")
- h_layout.addWidget(lb_password)
-
- le_password = QLineEdit(self.lock_overlay)
- le_password.setObjectName(u"le_password")
- le_password.setMinimumSize(QSize(200, 0))
- le_password.setFont(font)
- le_password.setEchoMode(QLineEdit.EchoMode.Password)
- h_layout.addWidget(le_password)
-
- lb_e_2 = QLabel(self.lock_overlay)
- lb_e_2.setObjectName(u"lb_e_2")
- h_layout.addWidget(lb_e_2)
-
- h_layout.setStretch(0, 5)
- h_layout.setStretch(1, 2)
- h_layout.setStretch(2, 3)
- h_layout.setStretch(3, 5)
- v_layout.addLayout(h_layout)
- return le_password
-
- self.set_shortcuts(False)
- if not self.lock_overlay:
- self.lock_overlay = QWidget(self)
-
- self.lock_overlay.setObjectName("w_overlay")
- cx = random.random()
- cy = random.random()
- stop1 = random.random()
- stop2 = random.random()
- angle = random.randint(0, 360)
- self.lock_overlay.setStyleSheet(f"""background: qconicalgradient(cx:{cx}, cy:{cy}, angle:{angle}, stop:0 #f6f8fa, stop:{stop1} #eef1f5, stop:{stop2} #dce1e8);""")
- # self.lock_overlay.setStyleSheet("""background: qconicalgradient(cx:0.5, cy:0.5, angle:45, stop:0 #f6f8fa, stop:0.5 #eef1f5, stop:1 #dce1e8);""")
-
- le_password = gen_lock_screen()
- le_password.returnPressed.connect(unlock)
- self.lock_overlay.setGeometry(self.rect())
- self.lock_overlay.show()
- le_password.setFocus()
-
- def set_shortcuts(self, stat: bool = True):
- if stat:
- self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H"))
- self.ac_settings.setShortcut(QKeySequence("Ctrl+Alt+S"))
- self.ac_logs.setShortcut(QKeySequence("Ctrl+Alt+L"))
- self.ac_about.setShortcut(QKeySequence("Ctrl+Alt+A"))
- self.ac_caging.setShortcut(QKeySequence("Ctrl+Alt+C"))
- self.ac_quit.setShortcut(QKeySequence("Ctrl+Alt+Q"))
- else:
- self.ac_homepage.setShortcut(QKeySequence())
- self.ac_settings.setShortcut(QKeySequence())
- self.ac_logs.setShortcut(QKeySequence())
- self.ac_about.setShortcut(QKeySequence())
- self.ac_caging.setShortcut(QKeySequence())
- self.ac_quit.setShortcut(QKeySequence())
-
- def resizeEvent(self, event: QResizeEvent):
- super().resizeEvent(event)
- if self.lock_overlay:
- self.lock_overlay.setGeometry(self.rect())
-
- def closeEvent(self, event):
- reply = QMessageBox.question(self, "退出", "\n程序可能在运行,确定要退出吗?")
- if reply == QMessageBox.StandardButton.Yes:
- db_operation.db_close(self.conn, self.cursor)
- event.accept()
- else:
- event.ignore()
-
-
-if __name__ == '__main__':
- app = QApplication(sys.argv)
- login = LoginWindow()
- login.show()
- sys.exit(app.exec())
diff --git a/pyproject.toml b/pyproject.toml
index 8beb49d..5fa86c4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -13,4 +13,5 @@ dependencies = [
"pyinstaller>=6.15.0",
"pymodbus>=3.11.1",
"pyside6>=6.9.2",
+ "zhdate>=0.1",
]
diff --git a/rokae/assets/confs/configs.json b/rokae/assets/confs/configs.json
index 4396d36..5f8d5f4 100644
--- a/rokae/assets/confs/configs.json
+++ b/rokae/assets/confs/configs.json
@@ -1,5 +1,5 @@
{
- "ip_addr": "192.168.2.160",
+ "ip_addr": "192.168.0.160",
"ssh_port": "22",
"socket_port": 5050,
"xService_port": 6666,
diff --git a/toolbox/assets/conf/config.json b/toolbox/assets/conf/config.json
new file mode 100644
index 0000000..443c74e
--- /dev/null
+++ b/toolbox/assets/conf/config.json
@@ -0,0 +1,7 @@
+{
+ "minimum_password_length": 8,
+ "maximum_db_number": 10,
+ "database_path": "",
+ "api_ali_pay": "",
+ "api_wechat_pay": ""
+}
\ No newline at end of file
diff --git a/toolbox/assets/database/toolbox.20250925223424.db b/toolbox/assets/database/toolbox.20250925223424.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.20250925223424.db differ
diff --git a/toolbox/assets/database/toolbox.20250925223440.db b/toolbox/assets/database/toolbox.20250925223440.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.20250925223440.db differ
diff --git a/toolbox/assets/database/toolbox.20250925223734.db b/toolbox/assets/database/toolbox.20250925223734.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.20250925223734.db differ
diff --git a/toolbox/assets/database/toolbox.20250925224139.db b/toolbox/assets/database/toolbox.20250925224139.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.20250925224139.db differ
diff --git a/toolbox/assets/database/toolbox.20250925224209.db b/toolbox/assets/database/toolbox.20250925224209.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.20250925224209.db differ
diff --git a/toolbox/assets/database/toolbox.20250926081402.db b/toolbox/assets/database/toolbox.20250926081402.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.20250926081402.db differ
diff --git a/toolbox/assets/database/toolbox.20250926081500.db b/toolbox/assets/database/toolbox.20250926081500.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.20250926081500.db differ
diff --git a/toolbox/assets/database/toolbox.20250926081844.db b/toolbox/assets/database/toolbox.20250926081844.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.20250926081844.db differ
diff --git a/toolbox/assets/database/toolbox.20250926082105.db b/toolbox/assets/database/toolbox.20250926082105.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.20250926082105.db differ
diff --git a/toolbox/assets/database/toolbox.db b/toolbox/assets/database/toolbox.db
new file mode 100644
index 0000000..2e6b258
Binary files /dev/null and b/toolbox/assets/database/toolbox.db differ
diff --git a/toolbox/assets/media/avatar.jpg b/toolbox/assets/media/avatar.jpg
new file mode 100644
index 0000000..a3f13fd
Binary files /dev/null and b/toolbox/assets/media/avatar.jpg differ
diff --git a/toolbox/assets/media/avatar/0.jpg b/toolbox/assets/media/avatar/0.jpg
new file mode 100644
index 0000000..744946b
Binary files /dev/null and b/toolbox/assets/media/avatar/0.jpg differ
diff --git a/toolbox/assets/media/avatar/1.jpg b/toolbox/assets/media/avatar/1.jpg
new file mode 100644
index 0000000..920641b
Binary files /dev/null and b/toolbox/assets/media/avatar/1.jpg differ
diff --git a/toolbox/assets/media/avatar/10.jpg b/toolbox/assets/media/avatar/10.jpg
new file mode 100644
index 0000000..fda9fff
Binary files /dev/null and b/toolbox/assets/media/avatar/10.jpg differ
diff --git a/toolbox/assets/media/avatar/100.jpg b/toolbox/assets/media/avatar/100.jpg
new file mode 100644
index 0000000..ef255a7
Binary files /dev/null and b/toolbox/assets/media/avatar/100.jpg differ
diff --git a/toolbox/assets/media/avatar/101.jpg b/toolbox/assets/media/avatar/101.jpg
new file mode 100644
index 0000000..2fb2ea5
Binary files /dev/null and b/toolbox/assets/media/avatar/101.jpg differ
diff --git a/toolbox/assets/media/avatar/102.jpg b/toolbox/assets/media/avatar/102.jpg
new file mode 100644
index 0000000..6064735
Binary files /dev/null and b/toolbox/assets/media/avatar/102.jpg differ
diff --git a/toolbox/assets/media/avatar/103.jpg b/toolbox/assets/media/avatar/103.jpg
new file mode 100644
index 0000000..1fd182f
Binary files /dev/null and b/toolbox/assets/media/avatar/103.jpg differ
diff --git a/toolbox/assets/media/avatar/104.jpg b/toolbox/assets/media/avatar/104.jpg
new file mode 100644
index 0000000..7daec45
Binary files /dev/null and b/toolbox/assets/media/avatar/104.jpg differ
diff --git a/toolbox/assets/media/avatar/105.jpg b/toolbox/assets/media/avatar/105.jpg
new file mode 100644
index 0000000..7a6420d
Binary files /dev/null and b/toolbox/assets/media/avatar/105.jpg differ
diff --git a/toolbox/assets/media/avatar/106.jpg b/toolbox/assets/media/avatar/106.jpg
new file mode 100644
index 0000000..783e288
Binary files /dev/null and b/toolbox/assets/media/avatar/106.jpg differ
diff --git a/toolbox/assets/media/avatar/107.jpg b/toolbox/assets/media/avatar/107.jpg
new file mode 100644
index 0000000..da36deb
Binary files /dev/null and b/toolbox/assets/media/avatar/107.jpg differ
diff --git a/toolbox/assets/media/avatar/108.jpg b/toolbox/assets/media/avatar/108.jpg
new file mode 100644
index 0000000..73c5b01
Binary files /dev/null and b/toolbox/assets/media/avatar/108.jpg differ
diff --git a/toolbox/assets/media/avatar/109.jpg b/toolbox/assets/media/avatar/109.jpg
new file mode 100644
index 0000000..8c69e2a
Binary files /dev/null and b/toolbox/assets/media/avatar/109.jpg differ
diff --git a/toolbox/assets/media/avatar/11.jpg b/toolbox/assets/media/avatar/11.jpg
new file mode 100644
index 0000000..c7e8bad
Binary files /dev/null and b/toolbox/assets/media/avatar/11.jpg differ
diff --git a/toolbox/assets/media/avatar/110.jpg b/toolbox/assets/media/avatar/110.jpg
new file mode 100644
index 0000000..1a8ae12
Binary files /dev/null and b/toolbox/assets/media/avatar/110.jpg differ
diff --git a/toolbox/assets/media/avatar/111.jpg b/toolbox/assets/media/avatar/111.jpg
new file mode 100644
index 0000000..f572864
Binary files /dev/null and b/toolbox/assets/media/avatar/111.jpg differ
diff --git a/toolbox/assets/media/avatar/112.jpg b/toolbox/assets/media/avatar/112.jpg
new file mode 100644
index 0000000..cf527ee
Binary files /dev/null and b/toolbox/assets/media/avatar/112.jpg differ
diff --git a/toolbox/assets/media/avatar/113.jpg b/toolbox/assets/media/avatar/113.jpg
new file mode 100644
index 0000000..4f7fa99
Binary files /dev/null and b/toolbox/assets/media/avatar/113.jpg differ
diff --git a/toolbox/assets/media/avatar/114.jpg b/toolbox/assets/media/avatar/114.jpg
new file mode 100644
index 0000000..7d7fdac
Binary files /dev/null and b/toolbox/assets/media/avatar/114.jpg differ
diff --git a/toolbox/assets/media/avatar/115.jpg b/toolbox/assets/media/avatar/115.jpg
new file mode 100644
index 0000000..7e97ee1
Binary files /dev/null and b/toolbox/assets/media/avatar/115.jpg differ
diff --git a/toolbox/assets/media/avatar/116.jpg b/toolbox/assets/media/avatar/116.jpg
new file mode 100644
index 0000000..aae630f
Binary files /dev/null and b/toolbox/assets/media/avatar/116.jpg differ
diff --git a/toolbox/assets/media/avatar/117.jpg b/toolbox/assets/media/avatar/117.jpg
new file mode 100644
index 0000000..ce41f55
Binary files /dev/null and b/toolbox/assets/media/avatar/117.jpg differ
diff --git a/toolbox/assets/media/avatar/118.jpg b/toolbox/assets/media/avatar/118.jpg
new file mode 100644
index 0000000..b65ad35
Binary files /dev/null and b/toolbox/assets/media/avatar/118.jpg differ
diff --git a/toolbox/assets/media/avatar/119.jpg b/toolbox/assets/media/avatar/119.jpg
new file mode 100644
index 0000000..7556ff4
Binary files /dev/null and b/toolbox/assets/media/avatar/119.jpg differ
diff --git a/toolbox/assets/media/avatar/12.jpg b/toolbox/assets/media/avatar/12.jpg
new file mode 100644
index 0000000..f79059f
Binary files /dev/null and b/toolbox/assets/media/avatar/12.jpg differ
diff --git a/toolbox/assets/media/avatar/120.jpg b/toolbox/assets/media/avatar/120.jpg
new file mode 100644
index 0000000..00d2e80
Binary files /dev/null and b/toolbox/assets/media/avatar/120.jpg differ
diff --git a/toolbox/assets/media/avatar/121.jpg b/toolbox/assets/media/avatar/121.jpg
new file mode 100644
index 0000000..fd19582
Binary files /dev/null and b/toolbox/assets/media/avatar/121.jpg differ
diff --git a/toolbox/assets/media/avatar/122.jpg b/toolbox/assets/media/avatar/122.jpg
new file mode 100644
index 0000000..cb5d2d1
Binary files /dev/null and b/toolbox/assets/media/avatar/122.jpg differ
diff --git a/toolbox/assets/media/avatar/123.jpg b/toolbox/assets/media/avatar/123.jpg
new file mode 100644
index 0000000..0dbdb95
Binary files /dev/null and b/toolbox/assets/media/avatar/123.jpg differ
diff --git a/toolbox/assets/media/avatar/124.jpg b/toolbox/assets/media/avatar/124.jpg
new file mode 100644
index 0000000..3445037
Binary files /dev/null and b/toolbox/assets/media/avatar/124.jpg differ
diff --git a/toolbox/assets/media/avatar/125.jpg b/toolbox/assets/media/avatar/125.jpg
new file mode 100644
index 0000000..7c2064f
Binary files /dev/null and b/toolbox/assets/media/avatar/125.jpg differ
diff --git a/toolbox/assets/media/avatar/126.jpg b/toolbox/assets/media/avatar/126.jpg
new file mode 100644
index 0000000..e9104b3
Binary files /dev/null and b/toolbox/assets/media/avatar/126.jpg differ
diff --git a/toolbox/assets/media/avatar/127.jpg b/toolbox/assets/media/avatar/127.jpg
new file mode 100644
index 0000000..18054eb
Binary files /dev/null and b/toolbox/assets/media/avatar/127.jpg differ
diff --git a/toolbox/assets/media/avatar/128.jpg b/toolbox/assets/media/avatar/128.jpg
new file mode 100644
index 0000000..da1cc78
Binary files /dev/null and b/toolbox/assets/media/avatar/128.jpg differ
diff --git a/toolbox/assets/media/avatar/129.jpg b/toolbox/assets/media/avatar/129.jpg
new file mode 100644
index 0000000..956bb5d
Binary files /dev/null and b/toolbox/assets/media/avatar/129.jpg differ
diff --git a/toolbox/assets/media/avatar/13.jpg b/toolbox/assets/media/avatar/13.jpg
new file mode 100644
index 0000000..109d258
Binary files /dev/null and b/toolbox/assets/media/avatar/13.jpg differ
diff --git a/toolbox/assets/media/avatar/130.jpg b/toolbox/assets/media/avatar/130.jpg
new file mode 100644
index 0000000..cb0a13e
Binary files /dev/null and b/toolbox/assets/media/avatar/130.jpg differ
diff --git a/toolbox/assets/media/avatar/131.jpg b/toolbox/assets/media/avatar/131.jpg
new file mode 100644
index 0000000..515a3bd
Binary files /dev/null and b/toolbox/assets/media/avatar/131.jpg differ
diff --git a/toolbox/assets/media/avatar/132.jpg b/toolbox/assets/media/avatar/132.jpg
new file mode 100644
index 0000000..77425a3
Binary files /dev/null and b/toolbox/assets/media/avatar/132.jpg differ
diff --git a/toolbox/assets/media/avatar/133.jpg b/toolbox/assets/media/avatar/133.jpg
new file mode 100644
index 0000000..2655e0e
Binary files /dev/null and b/toolbox/assets/media/avatar/133.jpg differ
diff --git a/toolbox/assets/media/avatar/134.jpg b/toolbox/assets/media/avatar/134.jpg
new file mode 100644
index 0000000..41cf43b
Binary files /dev/null and b/toolbox/assets/media/avatar/134.jpg differ
diff --git a/toolbox/assets/media/avatar/135.jpg b/toolbox/assets/media/avatar/135.jpg
new file mode 100644
index 0000000..5087ff9
Binary files /dev/null and b/toolbox/assets/media/avatar/135.jpg differ
diff --git a/toolbox/assets/media/avatar/136.jpg b/toolbox/assets/media/avatar/136.jpg
new file mode 100644
index 0000000..7930913
Binary files /dev/null and b/toolbox/assets/media/avatar/136.jpg differ
diff --git a/toolbox/assets/media/avatar/137.jpg b/toolbox/assets/media/avatar/137.jpg
new file mode 100644
index 0000000..5f62a89
Binary files /dev/null and b/toolbox/assets/media/avatar/137.jpg differ
diff --git a/toolbox/assets/media/avatar/138.jpg b/toolbox/assets/media/avatar/138.jpg
new file mode 100644
index 0000000..270936a
Binary files /dev/null and b/toolbox/assets/media/avatar/138.jpg differ
diff --git a/toolbox/assets/media/avatar/139.jpg b/toolbox/assets/media/avatar/139.jpg
new file mode 100644
index 0000000..f880dae
Binary files /dev/null and b/toolbox/assets/media/avatar/139.jpg differ
diff --git a/toolbox/assets/media/avatar/14.jpg b/toolbox/assets/media/avatar/14.jpg
new file mode 100644
index 0000000..8cc0ecc
Binary files /dev/null and b/toolbox/assets/media/avatar/14.jpg differ
diff --git a/toolbox/assets/media/avatar/140.jpg b/toolbox/assets/media/avatar/140.jpg
new file mode 100644
index 0000000..04b9e50
Binary files /dev/null and b/toolbox/assets/media/avatar/140.jpg differ
diff --git a/toolbox/assets/media/avatar/141.jpg b/toolbox/assets/media/avatar/141.jpg
new file mode 100644
index 0000000..3d5341d
Binary files /dev/null and b/toolbox/assets/media/avatar/141.jpg differ
diff --git a/toolbox/assets/media/avatar/142.jpg b/toolbox/assets/media/avatar/142.jpg
new file mode 100644
index 0000000..dc0f207
Binary files /dev/null and b/toolbox/assets/media/avatar/142.jpg differ
diff --git a/toolbox/assets/media/avatar/143.jpg b/toolbox/assets/media/avatar/143.jpg
new file mode 100644
index 0000000..bdefd03
Binary files /dev/null and b/toolbox/assets/media/avatar/143.jpg differ
diff --git a/toolbox/assets/media/avatar/144.jpg b/toolbox/assets/media/avatar/144.jpg
new file mode 100644
index 0000000..21114fa
Binary files /dev/null and b/toolbox/assets/media/avatar/144.jpg differ
diff --git a/toolbox/assets/media/avatar/145.jpg b/toolbox/assets/media/avatar/145.jpg
new file mode 100644
index 0000000..daa31e1
Binary files /dev/null and b/toolbox/assets/media/avatar/145.jpg differ
diff --git a/toolbox/assets/media/avatar/146.jpg b/toolbox/assets/media/avatar/146.jpg
new file mode 100644
index 0000000..9469640
Binary files /dev/null and b/toolbox/assets/media/avatar/146.jpg differ
diff --git a/toolbox/assets/media/avatar/147.jpg b/toolbox/assets/media/avatar/147.jpg
new file mode 100644
index 0000000..74f2ac4
Binary files /dev/null and b/toolbox/assets/media/avatar/147.jpg differ
diff --git a/toolbox/assets/media/avatar/148.jpg b/toolbox/assets/media/avatar/148.jpg
new file mode 100644
index 0000000..b7d060d
Binary files /dev/null and b/toolbox/assets/media/avatar/148.jpg differ
diff --git a/toolbox/assets/media/avatar/149.jpg b/toolbox/assets/media/avatar/149.jpg
new file mode 100644
index 0000000..dd12709
Binary files /dev/null and b/toolbox/assets/media/avatar/149.jpg differ
diff --git a/toolbox/assets/media/avatar/15.jpg b/toolbox/assets/media/avatar/15.jpg
new file mode 100644
index 0000000..e117151
Binary files /dev/null and b/toolbox/assets/media/avatar/15.jpg differ
diff --git a/toolbox/assets/media/avatar/150.jpg b/toolbox/assets/media/avatar/150.jpg
new file mode 100644
index 0000000..6c00302
Binary files /dev/null and b/toolbox/assets/media/avatar/150.jpg differ
diff --git a/toolbox/assets/media/avatar/151.jpg b/toolbox/assets/media/avatar/151.jpg
new file mode 100644
index 0000000..628c049
Binary files /dev/null and b/toolbox/assets/media/avatar/151.jpg differ
diff --git a/toolbox/assets/media/avatar/152.jpg b/toolbox/assets/media/avatar/152.jpg
new file mode 100644
index 0000000..c823e53
Binary files /dev/null and b/toolbox/assets/media/avatar/152.jpg differ
diff --git a/toolbox/assets/media/avatar/153.jpg b/toolbox/assets/media/avatar/153.jpg
new file mode 100644
index 0000000..f90238c
Binary files /dev/null and b/toolbox/assets/media/avatar/153.jpg differ
diff --git a/toolbox/assets/media/avatar/154.jpg b/toolbox/assets/media/avatar/154.jpg
new file mode 100644
index 0000000..cc4b137
Binary files /dev/null and b/toolbox/assets/media/avatar/154.jpg differ
diff --git a/toolbox/assets/media/avatar/155.jpg b/toolbox/assets/media/avatar/155.jpg
new file mode 100644
index 0000000..9a0927c
Binary files /dev/null and b/toolbox/assets/media/avatar/155.jpg differ
diff --git a/toolbox/assets/media/avatar/156.jpg b/toolbox/assets/media/avatar/156.jpg
new file mode 100644
index 0000000..ceca266
Binary files /dev/null and b/toolbox/assets/media/avatar/156.jpg differ
diff --git a/toolbox/assets/media/avatar/157.jpg b/toolbox/assets/media/avatar/157.jpg
new file mode 100644
index 0000000..ba67351
Binary files /dev/null and b/toolbox/assets/media/avatar/157.jpg differ
diff --git a/toolbox/assets/media/avatar/158.jpg b/toolbox/assets/media/avatar/158.jpg
new file mode 100644
index 0000000..3b82459
Binary files /dev/null and b/toolbox/assets/media/avatar/158.jpg differ
diff --git a/toolbox/assets/media/avatar/159.jpg b/toolbox/assets/media/avatar/159.jpg
new file mode 100644
index 0000000..f2f0cf6
Binary files /dev/null and b/toolbox/assets/media/avatar/159.jpg differ
diff --git a/toolbox/assets/media/avatar/16.jpg b/toolbox/assets/media/avatar/16.jpg
new file mode 100644
index 0000000..3b899fa
Binary files /dev/null and b/toolbox/assets/media/avatar/16.jpg differ
diff --git a/toolbox/assets/media/avatar/160.jpg b/toolbox/assets/media/avatar/160.jpg
new file mode 100644
index 0000000..6f81597
Binary files /dev/null and b/toolbox/assets/media/avatar/160.jpg differ
diff --git a/toolbox/assets/media/avatar/161.jpg b/toolbox/assets/media/avatar/161.jpg
new file mode 100644
index 0000000..ee53ec5
Binary files /dev/null and b/toolbox/assets/media/avatar/161.jpg differ
diff --git a/toolbox/assets/media/avatar/162.jpg b/toolbox/assets/media/avatar/162.jpg
new file mode 100644
index 0000000..3e6bc44
Binary files /dev/null and b/toolbox/assets/media/avatar/162.jpg differ
diff --git a/toolbox/assets/media/avatar/163.jpg b/toolbox/assets/media/avatar/163.jpg
new file mode 100644
index 0000000..06031a3
Binary files /dev/null and b/toolbox/assets/media/avatar/163.jpg differ
diff --git a/toolbox/assets/media/avatar/164.jpg b/toolbox/assets/media/avatar/164.jpg
new file mode 100644
index 0000000..4a5ef8e
Binary files /dev/null and b/toolbox/assets/media/avatar/164.jpg differ
diff --git a/toolbox/assets/media/avatar/165.jpg b/toolbox/assets/media/avatar/165.jpg
new file mode 100644
index 0000000..ad20bd2
Binary files /dev/null and b/toolbox/assets/media/avatar/165.jpg differ
diff --git a/toolbox/assets/media/avatar/166.jpg b/toolbox/assets/media/avatar/166.jpg
new file mode 100644
index 0000000..c3bf7fe
Binary files /dev/null and b/toolbox/assets/media/avatar/166.jpg differ
diff --git a/toolbox/assets/media/avatar/167.jpg b/toolbox/assets/media/avatar/167.jpg
new file mode 100644
index 0000000..6bf5d35
Binary files /dev/null and b/toolbox/assets/media/avatar/167.jpg differ
diff --git a/toolbox/assets/media/avatar/168.jpg b/toolbox/assets/media/avatar/168.jpg
new file mode 100644
index 0000000..fac6c22
Binary files /dev/null and b/toolbox/assets/media/avatar/168.jpg differ
diff --git a/toolbox/assets/media/avatar/169.jpg b/toolbox/assets/media/avatar/169.jpg
new file mode 100644
index 0000000..0724088
Binary files /dev/null and b/toolbox/assets/media/avatar/169.jpg differ
diff --git a/toolbox/assets/media/avatar/17.jpg b/toolbox/assets/media/avatar/17.jpg
new file mode 100644
index 0000000..21f74d3
Binary files /dev/null and b/toolbox/assets/media/avatar/17.jpg differ
diff --git a/toolbox/assets/media/avatar/170.jpg b/toolbox/assets/media/avatar/170.jpg
new file mode 100644
index 0000000..e1db457
Binary files /dev/null and b/toolbox/assets/media/avatar/170.jpg differ
diff --git a/toolbox/assets/media/avatar/171.jpg b/toolbox/assets/media/avatar/171.jpg
new file mode 100644
index 0000000..46a1124
Binary files /dev/null and b/toolbox/assets/media/avatar/171.jpg differ
diff --git a/toolbox/assets/media/avatar/172.jpg b/toolbox/assets/media/avatar/172.jpg
new file mode 100644
index 0000000..e2cd2d1
Binary files /dev/null and b/toolbox/assets/media/avatar/172.jpg differ
diff --git a/toolbox/assets/media/avatar/173.jpg b/toolbox/assets/media/avatar/173.jpg
new file mode 100644
index 0000000..835af24
Binary files /dev/null and b/toolbox/assets/media/avatar/173.jpg differ
diff --git a/toolbox/assets/media/avatar/174.jpg b/toolbox/assets/media/avatar/174.jpg
new file mode 100644
index 0000000..5e632e8
Binary files /dev/null and b/toolbox/assets/media/avatar/174.jpg differ
diff --git a/toolbox/assets/media/avatar/175.jpg b/toolbox/assets/media/avatar/175.jpg
new file mode 100644
index 0000000..d06ba82
Binary files /dev/null and b/toolbox/assets/media/avatar/175.jpg differ
diff --git a/toolbox/assets/media/avatar/176.jpg b/toolbox/assets/media/avatar/176.jpg
new file mode 100644
index 0000000..bfda168
Binary files /dev/null and b/toolbox/assets/media/avatar/176.jpg differ
diff --git a/toolbox/assets/media/avatar/177.jpg b/toolbox/assets/media/avatar/177.jpg
new file mode 100644
index 0000000..06d5f66
Binary files /dev/null and b/toolbox/assets/media/avatar/177.jpg differ
diff --git a/toolbox/assets/media/avatar/178.jpg b/toolbox/assets/media/avatar/178.jpg
new file mode 100644
index 0000000..e3f5373
Binary files /dev/null and b/toolbox/assets/media/avatar/178.jpg differ
diff --git a/toolbox/assets/media/avatar/179.jpg b/toolbox/assets/media/avatar/179.jpg
new file mode 100644
index 0000000..bd3e2ef
Binary files /dev/null and b/toolbox/assets/media/avatar/179.jpg differ
diff --git a/toolbox/assets/media/avatar/18.jpg b/toolbox/assets/media/avatar/18.jpg
new file mode 100644
index 0000000..1a61079
Binary files /dev/null and b/toolbox/assets/media/avatar/18.jpg differ
diff --git a/toolbox/assets/media/avatar/180.jpg b/toolbox/assets/media/avatar/180.jpg
new file mode 100644
index 0000000..56aa1de
Binary files /dev/null and b/toolbox/assets/media/avatar/180.jpg differ
diff --git a/toolbox/assets/media/avatar/181.jpg b/toolbox/assets/media/avatar/181.jpg
new file mode 100644
index 0000000..53fece2
Binary files /dev/null and b/toolbox/assets/media/avatar/181.jpg differ
diff --git a/toolbox/assets/media/avatar/182.jpg b/toolbox/assets/media/avatar/182.jpg
new file mode 100644
index 0000000..61d40de
Binary files /dev/null and b/toolbox/assets/media/avatar/182.jpg differ
diff --git a/toolbox/assets/media/avatar/183.jpg b/toolbox/assets/media/avatar/183.jpg
new file mode 100644
index 0000000..12bb31c
Binary files /dev/null and b/toolbox/assets/media/avatar/183.jpg differ
diff --git a/toolbox/assets/media/avatar/184.jpg b/toolbox/assets/media/avatar/184.jpg
new file mode 100644
index 0000000..bdddeef
Binary files /dev/null and b/toolbox/assets/media/avatar/184.jpg differ
diff --git a/toolbox/assets/media/avatar/185.jpg b/toolbox/assets/media/avatar/185.jpg
new file mode 100644
index 0000000..75b0e46
Binary files /dev/null and b/toolbox/assets/media/avatar/185.jpg differ
diff --git a/toolbox/assets/media/avatar/186.jpg b/toolbox/assets/media/avatar/186.jpg
new file mode 100644
index 0000000..f9b00cf
Binary files /dev/null and b/toolbox/assets/media/avatar/186.jpg differ
diff --git a/toolbox/assets/media/avatar/187.jpg b/toolbox/assets/media/avatar/187.jpg
new file mode 100644
index 0000000..07de5dd
Binary files /dev/null and b/toolbox/assets/media/avatar/187.jpg differ
diff --git a/toolbox/assets/media/avatar/188.jpg b/toolbox/assets/media/avatar/188.jpg
new file mode 100644
index 0000000..52e72f7
Binary files /dev/null and b/toolbox/assets/media/avatar/188.jpg differ
diff --git a/toolbox/assets/media/avatar/189.jpg b/toolbox/assets/media/avatar/189.jpg
new file mode 100644
index 0000000..fe10f43
Binary files /dev/null and b/toolbox/assets/media/avatar/189.jpg differ
diff --git a/toolbox/assets/media/avatar/19.jpg b/toolbox/assets/media/avatar/19.jpg
new file mode 100644
index 0000000..24c36b4
Binary files /dev/null and b/toolbox/assets/media/avatar/19.jpg differ
diff --git a/toolbox/assets/media/avatar/190.jpg b/toolbox/assets/media/avatar/190.jpg
new file mode 100644
index 0000000..8e7ec62
Binary files /dev/null and b/toolbox/assets/media/avatar/190.jpg differ
diff --git a/toolbox/assets/media/avatar/191.jpg b/toolbox/assets/media/avatar/191.jpg
new file mode 100644
index 0000000..1dcf1a6
Binary files /dev/null and b/toolbox/assets/media/avatar/191.jpg differ
diff --git a/toolbox/assets/media/avatar/192.jpg b/toolbox/assets/media/avatar/192.jpg
new file mode 100644
index 0000000..cef5a31
Binary files /dev/null and b/toolbox/assets/media/avatar/192.jpg differ
diff --git a/toolbox/assets/media/avatar/193.jpg b/toolbox/assets/media/avatar/193.jpg
new file mode 100644
index 0000000..f140174
Binary files /dev/null and b/toolbox/assets/media/avatar/193.jpg differ
diff --git a/toolbox/assets/media/avatar/194.jpg b/toolbox/assets/media/avatar/194.jpg
new file mode 100644
index 0000000..7b68c2c
Binary files /dev/null and b/toolbox/assets/media/avatar/194.jpg differ
diff --git a/toolbox/assets/media/avatar/195.jpg b/toolbox/assets/media/avatar/195.jpg
new file mode 100644
index 0000000..79f3b43
Binary files /dev/null and b/toolbox/assets/media/avatar/195.jpg differ
diff --git a/toolbox/assets/media/avatar/196.jpg b/toolbox/assets/media/avatar/196.jpg
new file mode 100644
index 0000000..eef9716
Binary files /dev/null and b/toolbox/assets/media/avatar/196.jpg differ
diff --git a/toolbox/assets/media/avatar/197.jpg b/toolbox/assets/media/avatar/197.jpg
new file mode 100644
index 0000000..921aa55
Binary files /dev/null and b/toolbox/assets/media/avatar/197.jpg differ
diff --git a/toolbox/assets/media/avatar/198.jpg b/toolbox/assets/media/avatar/198.jpg
new file mode 100644
index 0000000..e756348
Binary files /dev/null and b/toolbox/assets/media/avatar/198.jpg differ
diff --git a/toolbox/assets/media/avatar/199.jpg b/toolbox/assets/media/avatar/199.jpg
new file mode 100644
index 0000000..663b97b
Binary files /dev/null and b/toolbox/assets/media/avatar/199.jpg differ
diff --git a/toolbox/assets/media/avatar/2.jpg b/toolbox/assets/media/avatar/2.jpg
new file mode 100644
index 0000000..14fa332
Binary files /dev/null and b/toolbox/assets/media/avatar/2.jpg differ
diff --git a/toolbox/assets/media/avatar/20.jpg b/toolbox/assets/media/avatar/20.jpg
new file mode 100644
index 0000000..6a443c4
Binary files /dev/null and b/toolbox/assets/media/avatar/20.jpg differ
diff --git a/toolbox/assets/media/avatar/200.jpg b/toolbox/assets/media/avatar/200.jpg
new file mode 100644
index 0000000..3a4232f
Binary files /dev/null and b/toolbox/assets/media/avatar/200.jpg differ
diff --git a/toolbox/assets/media/avatar/201.jpg b/toolbox/assets/media/avatar/201.jpg
new file mode 100644
index 0000000..54f2a4d
Binary files /dev/null and b/toolbox/assets/media/avatar/201.jpg differ
diff --git a/toolbox/assets/media/avatar/202.jpg b/toolbox/assets/media/avatar/202.jpg
new file mode 100644
index 0000000..2555a61
Binary files /dev/null and b/toolbox/assets/media/avatar/202.jpg differ
diff --git a/toolbox/assets/media/avatar/203.jpg b/toolbox/assets/media/avatar/203.jpg
new file mode 100644
index 0000000..1e3b4bd
Binary files /dev/null and b/toolbox/assets/media/avatar/203.jpg differ
diff --git a/toolbox/assets/media/avatar/204.jpg b/toolbox/assets/media/avatar/204.jpg
new file mode 100644
index 0000000..4893d0d
Binary files /dev/null and b/toolbox/assets/media/avatar/204.jpg differ
diff --git a/toolbox/assets/media/avatar/205.jpg b/toolbox/assets/media/avatar/205.jpg
new file mode 100644
index 0000000..1bd54c1
Binary files /dev/null and b/toolbox/assets/media/avatar/205.jpg differ
diff --git a/toolbox/assets/media/avatar/206.jpg b/toolbox/assets/media/avatar/206.jpg
new file mode 100644
index 0000000..a1c27bf
Binary files /dev/null and b/toolbox/assets/media/avatar/206.jpg differ
diff --git a/toolbox/assets/media/avatar/207.jpg b/toolbox/assets/media/avatar/207.jpg
new file mode 100644
index 0000000..d4255ff
Binary files /dev/null and b/toolbox/assets/media/avatar/207.jpg differ
diff --git a/toolbox/assets/media/avatar/208.jpg b/toolbox/assets/media/avatar/208.jpg
new file mode 100644
index 0000000..d4537bc
Binary files /dev/null and b/toolbox/assets/media/avatar/208.jpg differ
diff --git a/toolbox/assets/media/avatar/209.jpg b/toolbox/assets/media/avatar/209.jpg
new file mode 100644
index 0000000..0fca5ac
Binary files /dev/null and b/toolbox/assets/media/avatar/209.jpg differ
diff --git a/toolbox/assets/media/avatar/21.jpg b/toolbox/assets/media/avatar/21.jpg
new file mode 100644
index 0000000..031be1b
Binary files /dev/null and b/toolbox/assets/media/avatar/21.jpg differ
diff --git a/toolbox/assets/media/avatar/210.jpg b/toolbox/assets/media/avatar/210.jpg
new file mode 100644
index 0000000..fb7d5ad
Binary files /dev/null and b/toolbox/assets/media/avatar/210.jpg differ
diff --git a/toolbox/assets/media/avatar/211.jpg b/toolbox/assets/media/avatar/211.jpg
new file mode 100644
index 0000000..d5d8f14
Binary files /dev/null and b/toolbox/assets/media/avatar/211.jpg differ
diff --git a/toolbox/assets/media/avatar/212.jpg b/toolbox/assets/media/avatar/212.jpg
new file mode 100644
index 0000000..99733a2
Binary files /dev/null and b/toolbox/assets/media/avatar/212.jpg differ
diff --git a/toolbox/assets/media/avatar/213.jpg b/toolbox/assets/media/avatar/213.jpg
new file mode 100644
index 0000000..44dab3e
Binary files /dev/null and b/toolbox/assets/media/avatar/213.jpg differ
diff --git a/toolbox/assets/media/avatar/214.jpg b/toolbox/assets/media/avatar/214.jpg
new file mode 100644
index 0000000..ad9606e
Binary files /dev/null and b/toolbox/assets/media/avatar/214.jpg differ
diff --git a/toolbox/assets/media/avatar/215.jpg b/toolbox/assets/media/avatar/215.jpg
new file mode 100644
index 0000000..f4d1991
Binary files /dev/null and b/toolbox/assets/media/avatar/215.jpg differ
diff --git a/toolbox/assets/media/avatar/216.jpg b/toolbox/assets/media/avatar/216.jpg
new file mode 100644
index 0000000..51d40ca
Binary files /dev/null and b/toolbox/assets/media/avatar/216.jpg differ
diff --git a/toolbox/assets/media/avatar/217.jpg b/toolbox/assets/media/avatar/217.jpg
new file mode 100644
index 0000000..9bdb67b
Binary files /dev/null and b/toolbox/assets/media/avatar/217.jpg differ
diff --git a/toolbox/assets/media/avatar/218.jpg b/toolbox/assets/media/avatar/218.jpg
new file mode 100644
index 0000000..dbb1a69
Binary files /dev/null and b/toolbox/assets/media/avatar/218.jpg differ
diff --git a/toolbox/assets/media/avatar/219.jpg b/toolbox/assets/media/avatar/219.jpg
new file mode 100644
index 0000000..fe0e58c
Binary files /dev/null and b/toolbox/assets/media/avatar/219.jpg differ
diff --git a/toolbox/assets/media/avatar/22.jpg b/toolbox/assets/media/avatar/22.jpg
new file mode 100644
index 0000000..8af9df0
Binary files /dev/null and b/toolbox/assets/media/avatar/22.jpg differ
diff --git a/toolbox/assets/media/avatar/220.jpg b/toolbox/assets/media/avatar/220.jpg
new file mode 100644
index 0000000..578a7ec
Binary files /dev/null and b/toolbox/assets/media/avatar/220.jpg differ
diff --git a/toolbox/assets/media/avatar/23.jpg b/toolbox/assets/media/avatar/23.jpg
new file mode 100644
index 0000000..32acfb0
Binary files /dev/null and b/toolbox/assets/media/avatar/23.jpg differ
diff --git a/toolbox/assets/media/avatar/24.jpg b/toolbox/assets/media/avatar/24.jpg
new file mode 100644
index 0000000..6c99835
Binary files /dev/null and b/toolbox/assets/media/avatar/24.jpg differ
diff --git a/toolbox/assets/media/avatar/25.jpg b/toolbox/assets/media/avatar/25.jpg
new file mode 100644
index 0000000..a9e53e7
Binary files /dev/null and b/toolbox/assets/media/avatar/25.jpg differ
diff --git a/toolbox/assets/media/avatar/26.jpg b/toolbox/assets/media/avatar/26.jpg
new file mode 100644
index 0000000..656aaca
Binary files /dev/null and b/toolbox/assets/media/avatar/26.jpg differ
diff --git a/toolbox/assets/media/avatar/27.jpg b/toolbox/assets/media/avatar/27.jpg
new file mode 100644
index 0000000..0bd0c73
Binary files /dev/null and b/toolbox/assets/media/avatar/27.jpg differ
diff --git a/toolbox/assets/media/avatar/28.jpg b/toolbox/assets/media/avatar/28.jpg
new file mode 100644
index 0000000..05478e9
Binary files /dev/null and b/toolbox/assets/media/avatar/28.jpg differ
diff --git a/toolbox/assets/media/avatar/29.jpg b/toolbox/assets/media/avatar/29.jpg
new file mode 100644
index 0000000..35562e3
Binary files /dev/null and b/toolbox/assets/media/avatar/29.jpg differ
diff --git a/toolbox/assets/media/avatar/3.jpg b/toolbox/assets/media/avatar/3.jpg
new file mode 100644
index 0000000..1949f15
Binary files /dev/null and b/toolbox/assets/media/avatar/3.jpg differ
diff --git a/toolbox/assets/media/avatar/30.jpg b/toolbox/assets/media/avatar/30.jpg
new file mode 100644
index 0000000..57b4d93
Binary files /dev/null and b/toolbox/assets/media/avatar/30.jpg differ
diff --git a/toolbox/assets/media/avatar/31.jpg b/toolbox/assets/media/avatar/31.jpg
new file mode 100644
index 0000000..4d9d0d0
Binary files /dev/null and b/toolbox/assets/media/avatar/31.jpg differ
diff --git a/toolbox/assets/media/avatar/32.jpg b/toolbox/assets/media/avatar/32.jpg
new file mode 100644
index 0000000..874d4d1
Binary files /dev/null and b/toolbox/assets/media/avatar/32.jpg differ
diff --git a/toolbox/assets/media/avatar/33.jpg b/toolbox/assets/media/avatar/33.jpg
new file mode 100644
index 0000000..f20f84e
Binary files /dev/null and b/toolbox/assets/media/avatar/33.jpg differ
diff --git a/toolbox/assets/media/avatar/34.jpg b/toolbox/assets/media/avatar/34.jpg
new file mode 100644
index 0000000..c0fb502
Binary files /dev/null and b/toolbox/assets/media/avatar/34.jpg differ
diff --git a/toolbox/assets/media/avatar/35.jpg b/toolbox/assets/media/avatar/35.jpg
new file mode 100644
index 0000000..9cef75b
Binary files /dev/null and b/toolbox/assets/media/avatar/35.jpg differ
diff --git a/toolbox/assets/media/avatar/36.jpg b/toolbox/assets/media/avatar/36.jpg
new file mode 100644
index 0000000..c3dffa8
Binary files /dev/null and b/toolbox/assets/media/avatar/36.jpg differ
diff --git a/toolbox/assets/media/avatar/37.jpg b/toolbox/assets/media/avatar/37.jpg
new file mode 100644
index 0000000..ca22094
Binary files /dev/null and b/toolbox/assets/media/avatar/37.jpg differ
diff --git a/toolbox/assets/media/avatar/38.jpg b/toolbox/assets/media/avatar/38.jpg
new file mode 100644
index 0000000..e0c3d00
Binary files /dev/null and b/toolbox/assets/media/avatar/38.jpg differ
diff --git a/toolbox/assets/media/avatar/39.jpg b/toolbox/assets/media/avatar/39.jpg
new file mode 100644
index 0000000..cc9690e
Binary files /dev/null and b/toolbox/assets/media/avatar/39.jpg differ
diff --git a/toolbox/assets/media/avatar/4.jpg b/toolbox/assets/media/avatar/4.jpg
new file mode 100644
index 0000000..02aef6f
Binary files /dev/null and b/toolbox/assets/media/avatar/4.jpg differ
diff --git a/toolbox/assets/media/avatar/40.jpg b/toolbox/assets/media/avatar/40.jpg
new file mode 100644
index 0000000..8dbea0e
Binary files /dev/null and b/toolbox/assets/media/avatar/40.jpg differ
diff --git a/toolbox/assets/media/avatar/41.jpg b/toolbox/assets/media/avatar/41.jpg
new file mode 100644
index 0000000..b64884a
Binary files /dev/null and b/toolbox/assets/media/avatar/41.jpg differ
diff --git a/toolbox/assets/media/avatar/42.jpg b/toolbox/assets/media/avatar/42.jpg
new file mode 100644
index 0000000..a4b5fe6
Binary files /dev/null and b/toolbox/assets/media/avatar/42.jpg differ
diff --git a/toolbox/assets/media/avatar/43.jpg b/toolbox/assets/media/avatar/43.jpg
new file mode 100644
index 0000000..b4d8716
Binary files /dev/null and b/toolbox/assets/media/avatar/43.jpg differ
diff --git a/toolbox/assets/media/avatar/44.jpg b/toolbox/assets/media/avatar/44.jpg
new file mode 100644
index 0000000..d10b4a2
Binary files /dev/null and b/toolbox/assets/media/avatar/44.jpg differ
diff --git a/toolbox/assets/media/avatar/45.jpg b/toolbox/assets/media/avatar/45.jpg
new file mode 100644
index 0000000..38a4e17
Binary files /dev/null and b/toolbox/assets/media/avatar/45.jpg differ
diff --git a/toolbox/assets/media/avatar/46.jpg b/toolbox/assets/media/avatar/46.jpg
new file mode 100644
index 0000000..3e34c52
Binary files /dev/null and b/toolbox/assets/media/avatar/46.jpg differ
diff --git a/toolbox/assets/media/avatar/47.jpg b/toolbox/assets/media/avatar/47.jpg
new file mode 100644
index 0000000..9d35664
Binary files /dev/null and b/toolbox/assets/media/avatar/47.jpg differ
diff --git a/toolbox/assets/media/avatar/48.jpg b/toolbox/assets/media/avatar/48.jpg
new file mode 100644
index 0000000..dc37128
Binary files /dev/null and b/toolbox/assets/media/avatar/48.jpg differ
diff --git a/toolbox/assets/media/avatar/49.jpg b/toolbox/assets/media/avatar/49.jpg
new file mode 100644
index 0000000..e8de33d
Binary files /dev/null and b/toolbox/assets/media/avatar/49.jpg differ
diff --git a/toolbox/assets/media/avatar/5.jpg b/toolbox/assets/media/avatar/5.jpg
new file mode 100644
index 0000000..60dc73a
Binary files /dev/null and b/toolbox/assets/media/avatar/5.jpg differ
diff --git a/toolbox/assets/media/avatar/50.jpg b/toolbox/assets/media/avatar/50.jpg
new file mode 100644
index 0000000..8af0a21
Binary files /dev/null and b/toolbox/assets/media/avatar/50.jpg differ
diff --git a/toolbox/assets/media/avatar/51.jpg b/toolbox/assets/media/avatar/51.jpg
new file mode 100644
index 0000000..58acda3
Binary files /dev/null and b/toolbox/assets/media/avatar/51.jpg differ
diff --git a/toolbox/assets/media/avatar/52.jpg b/toolbox/assets/media/avatar/52.jpg
new file mode 100644
index 0000000..bc6a8a1
Binary files /dev/null and b/toolbox/assets/media/avatar/52.jpg differ
diff --git a/toolbox/assets/media/avatar/53.jpg b/toolbox/assets/media/avatar/53.jpg
new file mode 100644
index 0000000..e1f779a
Binary files /dev/null and b/toolbox/assets/media/avatar/53.jpg differ
diff --git a/toolbox/assets/media/avatar/54.jpg b/toolbox/assets/media/avatar/54.jpg
new file mode 100644
index 0000000..e377ecf
Binary files /dev/null and b/toolbox/assets/media/avatar/54.jpg differ
diff --git a/toolbox/assets/media/avatar/55.jpg b/toolbox/assets/media/avatar/55.jpg
new file mode 100644
index 0000000..c5343af
Binary files /dev/null and b/toolbox/assets/media/avatar/55.jpg differ
diff --git a/toolbox/assets/media/avatar/56.jpg b/toolbox/assets/media/avatar/56.jpg
new file mode 100644
index 0000000..0f66cfa
Binary files /dev/null and b/toolbox/assets/media/avatar/56.jpg differ
diff --git a/toolbox/assets/media/avatar/57.jpg b/toolbox/assets/media/avatar/57.jpg
new file mode 100644
index 0000000..6c59ba5
Binary files /dev/null and b/toolbox/assets/media/avatar/57.jpg differ
diff --git a/toolbox/assets/media/avatar/58.jpg b/toolbox/assets/media/avatar/58.jpg
new file mode 100644
index 0000000..26a84e7
Binary files /dev/null and b/toolbox/assets/media/avatar/58.jpg differ
diff --git a/toolbox/assets/media/avatar/59.jpg b/toolbox/assets/media/avatar/59.jpg
new file mode 100644
index 0000000..d7a0297
Binary files /dev/null and b/toolbox/assets/media/avatar/59.jpg differ
diff --git a/toolbox/assets/media/avatar/6.jpg b/toolbox/assets/media/avatar/6.jpg
new file mode 100644
index 0000000..7df5b02
Binary files /dev/null and b/toolbox/assets/media/avatar/6.jpg differ
diff --git a/toolbox/assets/media/avatar/60.jpg b/toolbox/assets/media/avatar/60.jpg
new file mode 100644
index 0000000..0cf22a0
Binary files /dev/null and b/toolbox/assets/media/avatar/60.jpg differ
diff --git a/toolbox/assets/media/avatar/61.jpg b/toolbox/assets/media/avatar/61.jpg
new file mode 100644
index 0000000..769042d
Binary files /dev/null and b/toolbox/assets/media/avatar/61.jpg differ
diff --git a/toolbox/assets/media/avatar/62.jpg b/toolbox/assets/media/avatar/62.jpg
new file mode 100644
index 0000000..6b1b1a2
Binary files /dev/null and b/toolbox/assets/media/avatar/62.jpg differ
diff --git a/toolbox/assets/media/avatar/63.jpg b/toolbox/assets/media/avatar/63.jpg
new file mode 100644
index 0000000..7a9f934
Binary files /dev/null and b/toolbox/assets/media/avatar/63.jpg differ
diff --git a/toolbox/assets/media/avatar/64.jpg b/toolbox/assets/media/avatar/64.jpg
new file mode 100644
index 0000000..5c7680e
Binary files /dev/null and b/toolbox/assets/media/avatar/64.jpg differ
diff --git a/toolbox/assets/media/avatar/65.jpg b/toolbox/assets/media/avatar/65.jpg
new file mode 100644
index 0000000..4a651be
Binary files /dev/null and b/toolbox/assets/media/avatar/65.jpg differ
diff --git a/toolbox/assets/media/avatar/66.jpg b/toolbox/assets/media/avatar/66.jpg
new file mode 100644
index 0000000..920fb25
Binary files /dev/null and b/toolbox/assets/media/avatar/66.jpg differ
diff --git a/toolbox/assets/media/avatar/67.jpg b/toolbox/assets/media/avatar/67.jpg
new file mode 100644
index 0000000..0f68a32
Binary files /dev/null and b/toolbox/assets/media/avatar/67.jpg differ
diff --git a/toolbox/assets/media/avatar/68.jpg b/toolbox/assets/media/avatar/68.jpg
new file mode 100644
index 0000000..cb686ca
Binary files /dev/null and b/toolbox/assets/media/avatar/68.jpg differ
diff --git a/toolbox/assets/media/avatar/69.jpg b/toolbox/assets/media/avatar/69.jpg
new file mode 100644
index 0000000..8bb772e
Binary files /dev/null and b/toolbox/assets/media/avatar/69.jpg differ
diff --git a/toolbox/assets/media/avatar/7.jpg b/toolbox/assets/media/avatar/7.jpg
new file mode 100644
index 0000000..46f5b54
Binary files /dev/null and b/toolbox/assets/media/avatar/7.jpg differ
diff --git a/toolbox/assets/media/avatar/70.jpg b/toolbox/assets/media/avatar/70.jpg
new file mode 100644
index 0000000..75099db
Binary files /dev/null and b/toolbox/assets/media/avatar/70.jpg differ
diff --git a/toolbox/assets/media/avatar/71.jpg b/toolbox/assets/media/avatar/71.jpg
new file mode 100644
index 0000000..51558b5
Binary files /dev/null and b/toolbox/assets/media/avatar/71.jpg differ
diff --git a/toolbox/assets/media/avatar/72.jpg b/toolbox/assets/media/avatar/72.jpg
new file mode 100644
index 0000000..a72fa24
Binary files /dev/null and b/toolbox/assets/media/avatar/72.jpg differ
diff --git a/toolbox/assets/media/avatar/73.jpg b/toolbox/assets/media/avatar/73.jpg
new file mode 100644
index 0000000..f52484a
Binary files /dev/null and b/toolbox/assets/media/avatar/73.jpg differ
diff --git a/toolbox/assets/media/avatar/74.jpg b/toolbox/assets/media/avatar/74.jpg
new file mode 100644
index 0000000..2e72de7
Binary files /dev/null and b/toolbox/assets/media/avatar/74.jpg differ
diff --git a/toolbox/assets/media/avatar/75.jpg b/toolbox/assets/media/avatar/75.jpg
new file mode 100644
index 0000000..4c36142
Binary files /dev/null and b/toolbox/assets/media/avatar/75.jpg differ
diff --git a/toolbox/assets/media/avatar/76.jpg b/toolbox/assets/media/avatar/76.jpg
new file mode 100644
index 0000000..05b22a9
Binary files /dev/null and b/toolbox/assets/media/avatar/76.jpg differ
diff --git a/toolbox/assets/media/avatar/77.jpg b/toolbox/assets/media/avatar/77.jpg
new file mode 100644
index 0000000..3e91007
Binary files /dev/null and b/toolbox/assets/media/avatar/77.jpg differ
diff --git a/toolbox/assets/media/avatar/78.jpg b/toolbox/assets/media/avatar/78.jpg
new file mode 100644
index 0000000..48b84fa
Binary files /dev/null and b/toolbox/assets/media/avatar/78.jpg differ
diff --git a/toolbox/assets/media/avatar/79.jpg b/toolbox/assets/media/avatar/79.jpg
new file mode 100644
index 0000000..a3f13fd
Binary files /dev/null and b/toolbox/assets/media/avatar/79.jpg differ
diff --git a/toolbox/assets/media/avatar/8.jpg b/toolbox/assets/media/avatar/8.jpg
new file mode 100644
index 0000000..020ca9d
Binary files /dev/null and b/toolbox/assets/media/avatar/8.jpg differ
diff --git a/toolbox/assets/media/avatar/80.jpg b/toolbox/assets/media/avatar/80.jpg
new file mode 100644
index 0000000..52cc978
Binary files /dev/null and b/toolbox/assets/media/avatar/80.jpg differ
diff --git a/toolbox/assets/media/avatar/81.jpg b/toolbox/assets/media/avatar/81.jpg
new file mode 100644
index 0000000..fe925ed
Binary files /dev/null and b/toolbox/assets/media/avatar/81.jpg differ
diff --git a/toolbox/assets/media/avatar/82.jpg b/toolbox/assets/media/avatar/82.jpg
new file mode 100644
index 0000000..6a1a2bf
Binary files /dev/null and b/toolbox/assets/media/avatar/82.jpg differ
diff --git a/toolbox/assets/media/avatar/83.jpg b/toolbox/assets/media/avatar/83.jpg
new file mode 100644
index 0000000..dc9ee38
Binary files /dev/null and b/toolbox/assets/media/avatar/83.jpg differ
diff --git a/toolbox/assets/media/avatar/84.jpg b/toolbox/assets/media/avatar/84.jpg
new file mode 100644
index 0000000..d9b9209
Binary files /dev/null and b/toolbox/assets/media/avatar/84.jpg differ
diff --git a/toolbox/assets/media/avatar/85.jpg b/toolbox/assets/media/avatar/85.jpg
new file mode 100644
index 0000000..e8c2b90
Binary files /dev/null and b/toolbox/assets/media/avatar/85.jpg differ
diff --git a/toolbox/assets/media/avatar/86.jpg b/toolbox/assets/media/avatar/86.jpg
new file mode 100644
index 0000000..ea58c52
Binary files /dev/null and b/toolbox/assets/media/avatar/86.jpg differ
diff --git a/toolbox/assets/media/avatar/87.jpg b/toolbox/assets/media/avatar/87.jpg
new file mode 100644
index 0000000..48f7c11
Binary files /dev/null and b/toolbox/assets/media/avatar/87.jpg differ
diff --git a/toolbox/assets/media/avatar/88.jpg b/toolbox/assets/media/avatar/88.jpg
new file mode 100644
index 0000000..2741d30
Binary files /dev/null and b/toolbox/assets/media/avatar/88.jpg differ
diff --git a/toolbox/assets/media/avatar/89.jpg b/toolbox/assets/media/avatar/89.jpg
new file mode 100644
index 0000000..42d764d
Binary files /dev/null and b/toolbox/assets/media/avatar/89.jpg differ
diff --git a/toolbox/assets/media/avatar/9.jpg b/toolbox/assets/media/avatar/9.jpg
new file mode 100644
index 0000000..49791a8
Binary files /dev/null and b/toolbox/assets/media/avatar/9.jpg differ
diff --git a/toolbox/assets/media/avatar/90.jpg b/toolbox/assets/media/avatar/90.jpg
new file mode 100644
index 0000000..e746407
Binary files /dev/null and b/toolbox/assets/media/avatar/90.jpg differ
diff --git a/toolbox/assets/media/avatar/91.jpg b/toolbox/assets/media/avatar/91.jpg
new file mode 100644
index 0000000..9a0c558
Binary files /dev/null and b/toolbox/assets/media/avatar/91.jpg differ
diff --git a/toolbox/assets/media/avatar/92.jpg b/toolbox/assets/media/avatar/92.jpg
new file mode 100644
index 0000000..00db807
Binary files /dev/null and b/toolbox/assets/media/avatar/92.jpg differ
diff --git a/toolbox/assets/media/avatar/93.jpg b/toolbox/assets/media/avatar/93.jpg
new file mode 100644
index 0000000..e5d00bc
Binary files /dev/null and b/toolbox/assets/media/avatar/93.jpg differ
diff --git a/toolbox/assets/media/avatar/94.jpg b/toolbox/assets/media/avatar/94.jpg
new file mode 100644
index 0000000..4f67f59
Binary files /dev/null and b/toolbox/assets/media/avatar/94.jpg differ
diff --git a/toolbox/assets/media/avatar/95.jpg b/toolbox/assets/media/avatar/95.jpg
new file mode 100644
index 0000000..2f266fd
Binary files /dev/null and b/toolbox/assets/media/avatar/95.jpg differ
diff --git a/toolbox/assets/media/avatar/96.jpg b/toolbox/assets/media/avatar/96.jpg
new file mode 100644
index 0000000..ea21118
Binary files /dev/null and b/toolbox/assets/media/avatar/96.jpg differ
diff --git a/toolbox/assets/media/avatar/97.jpg b/toolbox/assets/media/avatar/97.jpg
new file mode 100644
index 0000000..5589a4a
Binary files /dev/null and b/toolbox/assets/media/avatar/97.jpg differ
diff --git a/toolbox/assets/media/avatar/98.jpg b/toolbox/assets/media/avatar/98.jpg
new file mode 100644
index 0000000..d989f5b
Binary files /dev/null and b/toolbox/assets/media/avatar/98.jpg differ
diff --git a/toolbox/assets/media/avatar/99.jpg b/toolbox/assets/media/avatar/99.jpg
new file mode 100644
index 0000000..f9e114c
Binary files /dev/null and b/toolbox/assets/media/avatar/99.jpg differ
diff --git a/toolbox/assets/media/bg.jpg b/toolbox/assets/media/bg.jpg
new file mode 100644
index 0000000..a470e54
Binary files /dev/null and b/toolbox/assets/media/bg.jpg differ
diff --git a/toolbox/assets/media/bg/20250810.jpg b/toolbox/assets/media/bg/20250810.jpg
new file mode 100644
index 0000000..1cc8814
Binary files /dev/null and b/toolbox/assets/media/bg/20250810.jpg differ
diff --git a/toolbox/assets/media/bg/20250917.jpg b/toolbox/assets/media/bg/20250917.jpg
new file mode 100644
index 0000000..9278843
Binary files /dev/null and b/toolbox/assets/media/bg/20250917.jpg differ
diff --git a/toolbox/assets/media/bg/20250918.jpg b/toolbox/assets/media/bg/20250918.jpg
new file mode 100644
index 0000000..d834987
Binary files /dev/null and b/toolbox/assets/media/bg/20250918.jpg differ
diff --git a/toolbox/assets/media/bg/20250919.jpg b/toolbox/assets/media/bg/20250919.jpg
new file mode 100644
index 0000000..cb04da9
Binary files /dev/null and b/toolbox/assets/media/bg/20250919.jpg differ
diff --git a/toolbox/assets/media/bg/20250920.jpg b/toolbox/assets/media/bg/20250920.jpg
new file mode 100644
index 0000000..a470e54
Binary files /dev/null and b/toolbox/assets/media/bg/20250920.jpg differ
diff --git a/toolbox/assets/media/bg/20250921.jpg b/toolbox/assets/media/bg/20250921.jpg
new file mode 100644
index 0000000..32c00a3
Binary files /dev/null and b/toolbox/assets/media/bg/20250921.jpg differ
diff --git a/toolbox/assets/media/bg/20250922.jpg b/toolbox/assets/media/bg/20250922.jpg
new file mode 100644
index 0000000..f5ee45f
Binary files /dev/null and b/toolbox/assets/media/bg/20250922.jpg differ
diff --git a/toolbox/assets/media/bg/20250923.jpg b/toolbox/assets/media/bg/20250923.jpg
new file mode 100644
index 0000000..b9a3329
Binary files /dev/null and b/toolbox/assets/media/bg/20250923.jpg differ
diff --git a/toolbox/assets/media/bg/20250924.jpg b/toolbox/assets/media/bg/20250924.jpg
new file mode 100644
index 0000000..df7c533
Binary files /dev/null and b/toolbox/assets/media/bg/20250924.jpg differ
diff --git a/toolbox/assets/media/bg/20250925.jpg b/toolbox/assets/media/bg/20250925.jpg
new file mode 100644
index 0000000..9081130
Binary files /dev/null and b/toolbox/assets/media/bg/20250925.jpg differ
diff --git a/toolbox/assets/media/font/OldEnglishTextMT/OldEnglishTextMT.ttf b/toolbox/assets/media/font/OldEnglishTextMT/OldEnglishTextMT.ttf
new file mode 100644
index 0000000..189aecc
Binary files /dev/null and b/toolbox/assets/media/font/OldEnglishTextMT/OldEnglishTextMT.ttf differ
diff --git a/toolbox/assets/media/hitokoto.json b/toolbox/assets/media/hitokoto.json
new file mode 100644
index 0000000..b4a30ac
--- /dev/null
+++ b/toolbox/assets/media/hitokoto.json
@@ -0,0 +1 @@
+[{"id": 5108, "uuid": "a9f006a9-8af6-4f2b-a4d7-03f50c70ffd6", "hitokoto": "多巴胺不等于爱情,爱情却一定有多巴胺!", "type": "j", "from": "网易热评", "from_who": "不在爱里迷失", "creator": "小忧忧", "creator_uid": 4701, "reviewer": 4756, "commit_from": "web", "created_at": "1582646685", "length": 19}, {"id": 7342, "uuid": "cb4eda79-40c8-414f-b601-427ea7d13030", "hitokoto": "嗯呐......软绵绵的人偶,来治愈你们的哟。", "type": "b", "from": "来自深渊", "from_who": "娜娜奇", "creator": "娜娜奇", "creator_uid": 9423, "reviewer": 4756, "commit_from": "web", "created_at": "1622370925", "length": 23}, {"id": 9060, "uuid": "57ae88f9-af1d-4f9e-882d-0c4410570809", "hitokoto": "何以窥不破,何以辜负卿。", "type": "d", "from": "二哈和他的白猫师尊", "from_who": "肉包不吃肉", "creator": "明年丶明月", "creator_uid": 13255, "reviewer": 1044, "commit_from": "web", "created_at": "1666155697", "length": 12}, {"id": 8035, "uuid": "d4ea5c57-bd64-4b9c-81a1-3035bc059b43", "hitokoto": "没有BUG的代码是不完美的!", "type": "l", "from": "Sodium_Sulfate", "from_who": "Sodium_Sulfate", "creator": "Sodium_Sulfate", "creator_uid": 12666, "reviewer": 1, "commit_from": "web", "created_at": "1658485841", "length": 14}, {"id": 8503, "uuid": "09f20c2e-9424-43f0-be24-8b7e5b8718cc", "hitokoto": "我曾以为自己终能超脱,却没想到存在如此真实而温暖。", "type": "g", "from": "月影歌", "from_who": "阿靥", "creator": "黡如", "creator_uid": 10359, "reviewer": 1, "commit_from": "web", "created_at": "1631106582", "length": 25}, {"id": 5738, "uuid": "4ec1e9df-6baa-4a7d-908c-4e217d0bc15d", "hitokoto": "迟日江山丽,春风花草香。", "type": "i", "from": "绝句二首", "from_who": "杜甫", "creator": "a632079", "creator_uid": 1044, "reviewer": 4756, "commit_from": "web", "created_at": "1586333495", "length": 12}, {"id": 7889, "uuid": "0ffc06be-b3dd-40ef-8a5b-0b6663ecdefb", "hitokoto": "风带来故事的种子,时间使其发芽。", "type": "c", "from": "原神", "from_who": "温迪", "creator": "神在白天做梦", "creator_uid": 12651, "reviewer": 1, "commit_from": "web", "created_at": "1658136113", "length": 16}, {"id": 8239, "uuid": "b61c8177-327f-4e7d-b5ad-4cea6ae946d7", "hitokoto": "有情人终成眷属,没钱人亲眼目睹。", "type": "l", "from": "互联网", "from_who": "快手评论", "creator": "•᷄ࡇ•᷅", "creator_uid": 11568, "reviewer": 1, "commit_from": "app", "created_at": "1650442453", "length": 16}, {"id": 1007, "uuid": "c3c6cce4-f56c-4e7c-b9a1-2b2fcfbe2a6d", "hitokoto": "为什么妈妈就不明白无所事事的忙碌呢。", "type": "a", "from": "白熊咖啡屋", "from_who": "熊猫君", "creator": "458146168", "creator_uid": 0, "reviewer": 0, "commit_from": "web", "created_at": "1481086547", "length": 18}, {"id": 9305, "uuid": "4f0032f7-60e9-429b-ba2c-82ccb8553f17", "hitokoto": "我只希望我的死,比我的生更有意义。", "type": "h", "from": "小丑", "from_who": "亚瑟", "creator": "空吧", "creator_uid": 14633, "reviewer": 4756, "commit_from": "web", "created_at": "1682848724", "length": 17}, {"id": 7986, "uuid": "dfb55668-8bad-40fc-aaa5-f81d964496b1", "hitokoto": "莫叹明月笑多情,天涯尽头看流光飞去。", "type": "g", "from": "相思引", "from_who": "董贞", "creator": "•᷄ࡇ•᷅", "creator_uid": 11568, "reviewer": 1, "commit_from": "app", "created_at": "1651913087", "length": 18}, {"id": 8303, "uuid": "e0da5bce-55b6-44b0-82e0-d8a92681dfe4", "hitokoto": "变好的过程都不太舒服,试试再努力点。", "type": "j", "from": "网易云音乐", "from_who": "pony", "creator": "collin", "creator_uid": 12365, "reviewer": 1, "commit_from": "web", "created_at": "1653642510", "length": 18}, {"id": 5117, "uuid": "c9739bcc-2d6e-482b-bc6e-ac158e2524b1", "hitokoto": "为众人抱薪者,不可使其冻毙于风雪。", "type": "i", "from": "微博", "from_who": "慕容雪村", "creator": "小黑猫", "creator_uid": 4856, "reviewer": 1044, "commit_from": "web", "created_at": "1581333219", "length": 17}, {"id": 6316, "uuid": "0d571fa5-5933-40db-a628-3113b44d9d80", "hitokoto": "于是悲欢起落人静默,等一等这些伤会自由。", "type": "g", "from": "口是心非", "from_who": "张雨生", "creator": "PaulWong", "creator_uid": 6535, "reviewer": 1, "commit_from": "web", "created_at": "1592982247", "length": 20}, {"id": 7297, "uuid": "ed9119a0-0051-421a-8863-710e82edba79", "hitokoto": "就算天塌下来变成一片废墟,他的脸色也不会有丝毫变化。", "type": "k", "from": "人生的智慧", "from_who": "叔本华", "creator": "折影轻梦", "creator_uid": 9975, "reviewer": 9975, "commit_from": "web", "created_at": "1628421050", "length": 26}, {"id": 6527, "uuid": "fddf5bb3-f3ec-499b-b637-0ea093250c76", "hitokoto": "哪有顷刻之间的心灰意冷,有的,只是日积月累的看透罢了。", "type": "j", "from": "觅楽-语录", "from_who": "觅楽", "creator": "悟空", "creator_uid": 7256, "reviewer": 6844, "commit_from": "web", "created_at": "1601175266", "length": 27}, {"id": 7759, "uuid": "ca05d8f0-f60e-4587-985b-5b69277183b5", "hitokoto": "哪一场仗不难打,越难打,就更要打。", "type": "h", "from": "长津湖之水门桥", "from_who": "余从戎", "creator": "sansko", "creator_uid": 11374, "reviewer": 4756, "commit_from": "web", "created_at": "1643855215", "length": 17}, {"id": 8065, "uuid": "c4786aa6-95b8-4631-9a10-13d170615cdf", "hitokoto": "内心湛然,则无往而不乐。", "type": "k", "from": "人生不过如此", "from_who": "梁实秋先生", "creator": "=w=", "creator_uid": 9709, "reviewer": 1, "commit_from": "web", "created_at": "1626145223", "length": 12}, {"id": 9417, "uuid": "8a92c8a6-14cf-4eb8-b75d-280363fcbfde", "hitokoto": "这不是玩笑,不要吃掉梦想啊。", "type": "j", "from": "萨姆沙", "from_who": "初音未来", "creator": "Day_Dreamer", "creator_uid": 15278, "reviewer": 4756, "commit_from": "web", "created_at": "1689334735", "length": 14}, {"id": 4736, "uuid": "c93823ee-47ae-46f3-ac59-538fd2cf3d0d", "hitokoto": "希望你永远都笑的像一束阳光,你是我的阳光。", "type": "d", "from": "撒野", "from_who": "巫哲", "creator": "卑微网友.", "creator_uid": 4776, "reviewer": 1044, "commit_from": "web", "created_at": "1580563521", "length": 21}, {"id": 7276, "uuid": "a3aad3af-9ae9-46af-9296-ceedca152d34", "hitokoto": "忘掉一个人的劣根性就像把千辛万苦赚来的钱扔掉一样。", "type": "k", "from": "人生的智慧", "from_who": "叔本华", "creator": "折影轻梦", "creator_uid": 9975, "reviewer": 9975, "commit_from": "web", "created_at": "1628306472", "length": 25}, {"id": 9291, "uuid": "1c90b430-8ded-432a-8828-43a7af8a8092", "hitokoto": "平凡的起起落落、漂浮的因果对错,都可以向风诉说。", "type": "g", "from": "让风告诉你", "from_who": "Chilichill", "creator": "rinictianyide", "creator_uid": 14187, "reviewer": 1, "commit_from": "web", "created_at": "1676040721", "length": 24}, {"id": 5820, "uuid": "09fbd777-3011-4a1a-9a21-db890c5e3a6e", "hitokoto": "此生此夜不长好,明月明年何处看。", "type": "i", "from": "阳关曲 / 中秋月", "from_who": "苏轼", "creator": "a632079", "creator_uid": 1044, "reviewer": 1044, "commit_from": "api", "created_at": "1586395492", "length": 16}, {"id": 5109, "uuid": "0b9533fc-3850-43f6-bb03-423a5dbf2fa5", "hitokoto": "荷尔蒙决定一见钟情,多巴胺决定天长地久。", "type": "j", "from": "网易云", "from_who": "不自爱里迷失", "creator": "小忧忧", "creator_uid": 4701, "reviewer": 4756, "commit_from": "web", "created_at": "1582646766", "length": 20}, {"id": 9122, "uuid": "51d2a015-6df3-4507-8d75-a5e48863d1a5", "hitokoto": "神即道,道即法,道法自然,如来。", "type": "l", "from": "遥远的救世主", "from_who": "豆豆", "creator": "erfie", "creator_uid": 13776, "reviewer": 1044, "commit_from": "web", "created_at": "1671076363", "length": 16}, {"id": 7364, "uuid": "efedcfa7-8fad-4fc2-ae88-f15ba32a9526", "hitokoto": "这雨生于天,死于地,中间的过程就是人生。", "type": "f", "from": "仙逆", "from_who": "耳根", "creator": "余空", "creator_uid": 9621, "reviewer": 4756, "commit_from": "web", "created_at": "1625303511", "length": 20}, {"id": 6235, "uuid": "b61c43d6-e531-4f96-98a1-995ebc2c3702", "hitokoto": "呐~~凯利,你想成为怎样的大人。", "type": "a", "from": "Fate/Zero", "from_who": "夏丽", "creator": "pythonworld", "creator_uid": 6391, "reviewer": 1044, "commit_from": "web", "created_at": "1591368561", "length": 16}, {"id": 8304, "uuid": "42396512-6aa1-49e0-bd26-44c9cbb4b457", "hitokoto": "慢慢来,谁还没有一个努力的过程。", "type": "j", "from": "网易云音乐", "from_who": "pony", "creator": "collin", "creator_uid": 12365, "reviewer": 1, "commit_from": "web", "created_at": "1653642489", "length": 16}, {"id": 8081, "uuid": "ba8451c0-dae3-4cc0-9f6b-d0e8b3a606db", "hitokoto": "人生三大错觉,我能反杀,下一发能出金,她喜欢我。", "type": "l", "from": "现实", "from_who": "林清凝", "creator": "Soiltary、K", "creator_uid": 3915, "reviewer": 1, "commit_from": "app", "created_at": "1630990186", "length": 24}, {"id": 6409, "uuid": "c8c0a7a2-8f00-408b-bcfa-ced794b3a53e", "hitokoto": "每个人都应该学会如何编程,因为它教会你如何思考。", "type": "g", "from": "史蒂夫·乔布斯", "from_who": "史蒂夫·乔布斯", "creator": "suxin", "creator_uid": 6790, "reviewer": 1, "commit_from": "web", "created_at": "1595592954", "length": 24}, {"id": 8431, "uuid": "10afb3d1-450a-4f0f-9cdb-96b52775d774", "hitokoto": "人是要整活的——没活了,可不就是死了么?", "type": "l", "from": "互联网", "from_who": "佚名", "creator": "Assault Blyat", "creator_uid": 9349, "reviewer": 1, "commit_from": "web", "created_at": "1648135471", "length": 20}, {"id": 7362, "uuid": "54f7cf49-b228-428c-8ef9-f12e0e2eb2df", "hitokoto": "人间忽晚,山河已秋。", "type": "j", "from": "人间忽晚", "from_who": "亦沫不吃鱼", "creator": "GL", "creator_uid": 9589, "reviewer": 4756, "commit_from": "web", "created_at": "1624861348", "length": 10}, {"id": 6259, "uuid": "874496cc-f3f9-4c5f-bab8-4cc290d6a99d", "hitokoto": "真正走掉那次,关门声最小。", "type": "j", "from": "网易云", "from_who": "@-南得你-", "creator": "Irony", "creator_uid": 4464, "reviewer": 1044, "commit_from": "web", "created_at": "1592125903", "length": 13}, {"id": 8257, "uuid": "fe98627a-6e1d-4354-ab91-64dfa20721fd", "hitokoto": "阶砖不会拒绝磨蚀,窗花不可幽禁落霞。", "type": "h", "from": "喜帖街", "from_who": "黄伟文", "creator": "hitoha", "creator_uid": 12720, "reviewer": 1, "commit_from": "web", "created_at": "1658848518", "length": 18}, {"id": 8620, "uuid": "dbd58aaf-93fc-4321-818e-41281f90d5ab", "hitokoto": "生活,就是生出来活下去,其它都是浮云,活的潇洒一点。", "type": "h", "from": "爱情公寓", "from_who": "吕小布", "creator": "小柒ing", "creator_uid": 3783, "reviewer": 1, "commit_from": "web", "created_at": "1636006723", "length": 26}, {"id": 7823, "uuid": "aa24ef8a-ef33-4b11-9442-f709bc2e4c89", "hitokoto": "长生非我愿,但求达慕垂鞭。", "type": "d", "from": "花近江国", "from_who": "孔恰", "creator": "chenyu", "creator_uid": 11793, "reviewer": 4756, "commit_from": "web", "created_at": "1647850073", "length": 13}, {"id": 6810, "uuid": "c0cfe4e0-517e-427a-a006-23bef2b5280b", "hitokoto": "Stay hungry, Stay foolish.", "type": "k", "from": "乔布斯斯坦福大学毕业演讲", "from_who": "史蒂夫-乔布斯", "creator": "Abyss", "creator_uid": 8803, "reviewer": 9016, "commit_from": "web", "created_at": "1616846581", "length": 26}, {"id": 8072, "uuid": "75107d7d-f11e-4c28-9602-9290c36b8cd3", "hitokoto": "猛兽是单独的,牛羊则结队。", "type": "d", "from": "坟", "from_who": "鲁迅", "creator": "Ender_hz", "creator_uid": 10115, "reviewer": 1, "commit_from": "web", "created_at": "1628998057", "length": 13}, {"id": 5703, "uuid": "6ee66a84-6559-4dd2-a467-4ff9676172ce", "hitokoto": "绿蚁新醅酒,红泥小火炉。", "type": "i", "from": "问刘十九", "from_who": "白居易", "creator": "a632079", "creator_uid": 1044, "reviewer": 1044, "commit_from": "api", "created_at": "1586271536", "length": 12}, {"id": 6697, "uuid": "5d054917-0f24-4df1-ac08-e819f5fbd9f0", "hitokoto": "自身拥有越丰富,他在别人身上所能发现得到的就越少。", "type": "k", "from": "人类的智慧", "from_who": "亚瑟・叔本华", "creator": "草生出来了", "creator_uid": 7674, "reviewer": 1044, "commit_from": "web", "created_at": "1604800688", "length": 25}, {"id": 8642, "uuid": "f93da842-4ff8-4dd2-8c0f-648a5587f53c", "hitokoto": "爱情没有那么多借口,如果最终没能在一起,只能说明爱的不够。", "type": "g", "from": "恋恋笔记本", "from_who": "恋恋笔记本", "creator": "陈先生", "creator_uid": 11120, "reviewer": 1, "commit_from": "web", "created_at": "1640626481", "length": 29}, {"id": 782, "uuid": "fffa7498-8d1a-49d0-8037-3dc660db6a91", "hitokoto": "如何得与凉风约,不共尘沙一并来!", "type": "g", "from": "中牟道中", "from_who": "陈与义", "creator": "hitokoto", "creator_uid": 1775, "reviewer": 0, "commit_from": "web", "created_at": "1478787580", "length": 16}, {"id": 6105, "uuid": "78f1d91c-d69e-446a-bfd3-c3b3ea5d047c", "hitokoto": "如果温柔是罪,那就只能用拳头来洗清我们犯下的罪孽。", "type": "h", "from": "镇魂街", "from_who": "曹玄亮", "creator": "PercyDan", "creator_uid": 6125, "reviewer": 1, "commit_from": "web", "created_at": "1588658329", "length": 25}, {"id": 5733, "uuid": "c740188b-4b6a-4a78-b0e7-5db72b481280", "hitokoto": "昭昭若日月之明,离离如星辰之行。", "type": "i", "from": "文心雕龙·宗经", "from_who": "刘勰", "creator": "a632079", "creator_uid": 1044, "reviewer": 4756, "commit_from": "web", "created_at": "1586333494", "length": 16}, {"id": 1013, "uuid": "a280f1ba-bb6d-4d85-a6a2-c07698895c2b", "hitokoto": "最最好的,与最最痛苦的,是一样的。", "type": "b", "from": "文学与少女", "from_who": "玛德莱娜", "creator": "863885806", "creator_uid": 0, "reviewer": 0, "commit_from": "web", "created_at": "1481086547", "length": 17}, {"id": 5949, "uuid": "529454f8-32b7-4074-ac21-48dd6d767945", "hitokoto": "不管风吹浪打,胜似闲庭信步。", "type": "k", "from": "毛泽东语录精选", "from_who": "毛泽东", "creator": "微笑阿猪", "creator_uid": 5861, "reviewer": 4756, "commit_from": "web", "created_at": "1586611853", "length": 14}, {"id": 7324, "uuid": "483c691a-d898-428c-8ebc-51efe05f9e7a", "hitokoto": "那些听不见音乐的人认为那些跳舞的人疯了。", "type": "k", "from": "笑:论滑稽的意义", "from_who": "亨利·柏格森", "creator": "折影轻梦", "creator_uid": 9975, "reviewer": 9975, "commit_from": "web", "created_at": "1628510764", "length": 20}, {"id": 8041, "uuid": "66f56dd0-f367-426f-95b9-908a2be37429", "hitokoto": "戏会落幕,人生却不会。", "type": "c", "from": "原神", "from_who": "云堇", "creator": "神在白天做梦", "creator_uid": 12651, "reviewer": 1, "commit_from": "web", "created_at": "1658136776", "length": 11}, {"id": 7279, "uuid": "e689f682-5334-474b-8be6-8911407a6bf9", "hitokoto": "装作拥有某样品质,实际上就等于承认了自己并没有这样品质。", "type": "k", "from": "人生的智慧", "from_who": "叔本华", "creator": "折影轻梦", "creator_uid": 9975, "reviewer": 9975, "commit_from": "web", "created_at": "1628306360", "length": 28}, {"id": 9529, "uuid": "e6dfb3c6-6f08-469b-a127-7412e6ea84ba", "hitokoto": "我的另一个灵魂正在离家出走。", "type": "e", "from": "心情", "from_who": "九幽之下", "creator": "有匪", "creator_uid": 9088, "reviewer": 4756, "commit_from": "web", "created_at": "1695350470", "length": 14}, {"id": 8287, "uuid": "a7f2aab8-92c1-4866-a1e0-c161a56baf7e", "hitokoto": "你,对,你,就是你,你是你。", "type": "l", "from": "什", "from_who": "不到啊", "creator": "老z", "creator_uid": 12291, "reviewer": 1, "commit_from": "web", "created_at": "1652018955", "length": 14}, {"id": 8544, "uuid": "efa9a32c-4004-4ded-97e6-3b7213cab0af", "hitokoto": "天赋不能带来的东西,努力或许可以。", "type": "f", "from": "青春杂货铺", "from_who": "佚名", "creator": "雅涵凝", "creator_uid": 4692, "reviewer": 1, "commit_from": "web", "created_at": "1632637518", "length": 17}, {"id": 6823, "uuid": "d8e938c8-7240-4e8e-a5a0-02eb0071a9ba", "hitokoto": "星球鳞片闪闪的躯体形成蜿蜒的宇宙之蛇。", "type": "d", "from": "另一个人", "from_who": "雨果", "creator": "Enderfga", "creator_uid": 7920, "reviewer": 1044, "commit_from": "web", "created_at": "1606924048", "length": 19}, {"id": 6503, "uuid": "6c7697d2-46e1-413b-a40c-11a999bfd0db", "hitokoto": "我们把世界看错,反说它欺骗了我们。", "type": "k", "from": "飞鸟集", "from_who": "泰戈尔", "creator": "恏戋余", "creator_uid": 7045, "reviewer": 6844, "commit_from": "app", "created_at": "1598342433", "length": 17}, {"id": 7321, "uuid": "0458669a-bec5-4781-8b21-c739c3435da2", "hitokoto": "似水流年是一个人所有的一切,只有这个东西,才真正归你所有。", "type": "k", "from": "似水流年", "from_who": "王小波", "creator": "Damianyang", "creator_uid": 9192, "reviewer": 9975, "commit_from": "web", "created_at": "1620184899", "length": 29}, {"id": 8870, "uuid": "7733ec16-4af0-4ae0-9ebf-1a0f14eff91b", "hitokoto": "你背朝太阳,就只能看到自己的影子。", "type": "k", "from": "纪伯伦语录", "from_who": "纪伯伦", "creator": "Soul_collecter", "creator_uid": 13051, "reviewer": 1, "commit_from": "web", "created_at": "1663490513", "length": 17}, {"id": 5448, "uuid": "d09096b2-1a6d-4721-abeb-13b4018cee70", "hitokoto": "入我相思门,知我相思苦。", "type": "i", "from": "三五七言 / 秋风词", "from_who": "李白", "creator": "a632079", "creator_uid": 1044, "reviewer": 4756, "commit_from": "web", "created_at": "1586198948", "length": 12}, {"id": 8288, "uuid": "6e18e2d3-7b73-436f-a180-691fc2b619a5", "hitokoto": "真正的大师永远怀着一颗学徒的心。", "type": "c", "from": "英雄联盟", "from_who": "无极剑圣", "creator": "月光、雲海与星", "creator_uid": 12281, "reviewer": 1, "commit_from": "web", "created_at": "1651931719", "length": 16}, {"id": 6243, "uuid": "88e25418-a6a3-404a-818b-a8f3c31ba0f9", "hitokoto": "人总是贪婪的,就像最开始,我也只是想知道你的名字。", "type": "b", "from": "你的名字", "from_who": "新海诚", "creator": "世见", "creator_uid": 6367, "reviewer": 1044, "commit_from": "web", "created_at": "1591148603", "length": 25}, {"id": 7275, "uuid": "48a1ad9c-54eb-4dd9-a389-c2e12c7244a8", "hitokoto": "不管人生呈现出什么样貌,人生的构成要素都是一样的。", "type": "k", "from": "人生的智慧", "from_who": "叔本华", "creator": "折影轻梦", "creator_uid": 9975, "reviewer": 9975, "commit_from": "web", "created_at": "1628306484", "length": 25}, {"id": 5613, "uuid": "fecc2820-2329-4cc0-aa4e-5c7a29b52a37", "hitokoto": "兰有秀兮菊有芳,怀佳人兮不能忘。", "type": "i", "from": "秋风辞", "from_who": "刘彻", "creator": "a632079", "creator_uid": 1044, "reviewer": 1044, "commit_from": "api", "created_at": "1586266486", "length": 16}, {"id": 8247, "uuid": "0c0030d1-eed7-4a19-b499-32ccc3e9a032", "hitokoto": "慢也好,步伐小也罢,是往前走就好。", "type": "j", "from": "网易云音乐热评", "from_who": "佚名", "creator": "collin", "creator_uid": 12365, "reviewer": 1, "commit_from": "web", "created_at": "1653642582", "length": 17}, {"id": 5967, "uuid": "bad64921-c8b6-433f-b058-8120906eeef2", "hitokoto": "世界之大为何我们相遇,难道是缘分,难道是天意。", "type": "j", "from": "我的歌声里", "from_who": "曲婉婷", "creator": "陈树凤", "creator_uid": 5678, "reviewer": 4756, "commit_from": "web", "created_at": "1587181370", "length": 23}, {"id": 9016, "uuid": "b50ae69e-d2e3-4cd5-9298-65985e03ce09", "hitokoto": "最短的捷径就是绕远路。", "type": "b", "from": "STEEL BALL RUN", "from_who": "杰洛·齐贝林", "creator": "柳宇", "creator_uid": 13682, "reviewer": 4756, "commit_from": "web", "created_at": "1670306333", "length": 11}, {"id": 5817, "uuid": "6e7cc075-3fa1-42c3-b215-fdfe6cc56988", "hitokoto": "若似月轮终皎洁,不辞冰雪为卿热。", "type": "i", "from": "蝶恋花·辛苦最怜天上月", "from_who": "纳兰性德", "creator": "a632079", "creator_uid": 1044, "reviewer": 1044, "commit_from": "api", "created_at": "1586395491", "length": 16}, {"id": 7219, "uuid": "e0c4ef75-18a0-4926-9806-08c1ed175aa5", "hitokoto": "下次见到你时,希望你也能成为永不凋零的希望之花。", "type": "a", "from": "火影忍者", "from_who": "小南", "creator": "亚亚努阿", "creator_uid": 8848, "reviewer": 1, "commit_from": "web", "created_at": "1617030126", "length": 24}, {"id": 5547, "uuid": "0c329aae-e0c8-4ac7-a2ff-08dedac04f12", "hitokoto": "日日思君不见君,共饮长江水。", "type": "i", "from": "卜算子·我住长江头", "from_who": "李之仪", "creator": "a632079", "creator_uid": 1044, "reviewer": 1044, "commit_from": "api", "created_at": "1586266393", "length": 14}, {"id": 5226, "uuid": "830b7fb7-49f8-4bda-b061-379223677d54", "hitokoto": "光,火交错,诞生了夕阳。", "type": "e", "from": "无", "from_who": "GoodChing", "creator": "GoodChing", "creator_uid": 5257, "reviewer": 4756, "commit_from": "web", "created_at": "1583718511", "length": 12}, {"id": 8191, "uuid": "742876d2-c9df-453f-8a58-059e8eed5c79", "hitokoto": "千万生灵,唯你有权看到我脆弱。", "type": "d", "from": "伤害", "from_who": "聂鲁达", "creator": "桂", "creator_uid": 11290, "reviewer": 1, "commit_from": "web", "created_at": "1642578158", "length": 15}, {"id": 5358, "uuid": "d6e59b5a-6a12-4d14-ac64-fc0977de6853", "hitokoto": "曾盛开过一朵,曾不会败落,曾在他眼中流淌过浩瀚的银河。", "type": "h", "from": "不痛", "from_who": "南语", "creator": "Muzi.言寺", "creator_uid": 5655, "reviewer": 4756, "commit_from": "web", "created_at": "1585293655", "length": 27}, {"id": 7721, "uuid": "f364f18b-4c9b-4c0a-8d1b-8400477b55d6", "hitokoto": "人生如逆旅,我亦是行人。", "type": "i", "from": "临江仙·送钱穆父", "from_who": "苏轼", "creator": "陈弋函", "creator_uid": 10950, "reviewer": 1, "commit_from": "web", "created_at": "1638544510", "length": 12}, {"id": 7311, "uuid": "9a17c193-9922-4bce-baea-d4c27caf17cc", "hitokoto": "有些人光是遇到就已经赚到了。", "type": "j", "from": "网易云", "from_who": "赵紫骅", "creator": "James", "creator_uid": 9109, "reviewer": 9975, "commit_from": "web", "created_at": "1619272123", "length": 14}, {"id": 8738, "uuid": "dad02ff7-6ae7-4ed7-8afe-bf0c984aaeda", "hitokoto": "一山还比一山高,强中更有强中手!", "type": "c", "from": "坎公骑冠剑", "from_who": "兽人剑士蕾伊", "creator": "飞小RAN", "creator_uid": 10481, "reviewer": 1, "commit_from": "web", "created_at": "1661316734", "length": 16}, {"id": 8305, "uuid": "fafc831b-4054-45dd-b72f-3b113bdae37d", "hitokoto": "经过上千年的修炼,你学到的就是这个吗?", "type": "h", "from": "神龙许愿", "from_who": "神龙许愿", "creator": "os7blue", "creator_uid": 1209, "reviewer": 1, "commit_from": "web", "created_at": "1646283736", "length": 19}, {"id": 8609, "uuid": "24659d20-0582-4f35-9078-b42b5ca9b63d", "hitokoto": "大本钟下送快递——上面摆,下面寄。", "type": "l", "from": "饭堂周末夜", "from_who": "记得", "creator": "luckygaogao", "creator_uid": 11358, "reviewer": 1, "commit_from": "web", "created_at": "1643334990", "length": 17}, {"id": 5355, "uuid": "ec21ccfe-4e48-4b1a-95c4-9b5ae0c5200d", "hitokoto": "当人们做不到一些事情的时候,他们会对你说你也同样不能。", "type": "h", "from": "当幸福来敲门", "from_who": "克里斯·加德纳", "creator": "橘子_ORANGE", "creator_uid": 5229, "reviewer": 4756, "commit_from": "web", "created_at": "1585296454", "length": 27}, {"id": 7251, "uuid": "43574bd6-b563-45ab-9398-b09f33234f7a", "hitokoto": "我们登上并非我们所选择的舞台,演出并非我们所选择的剧本。", "type": "k", "from": "Enchiridion", "from_who": "爱比克泰德", "creator": "Damon", "creator_uid": 9899, "reviewer": 9975, "commit_from": "web", "created_at": "1627354139", "length": 28}, {"id": 9527, "uuid": "aaeb4cbb-911b-42d5-94bb-8c9c8a702286", "hitokoto": "博文天下,遍理人间!", "type": "l", "from": "自己", "from_who": "沐风", "creator": "沐风", "creator_uid": 15876, "reviewer": 4756, "commit_from": "web", "created_at": "1695279683", "length": 10}, {"id": 8705, "uuid": "b45db165-111b-4ef8-a171-193c09ec2ae7", "hitokoto": "记忆是痛苦的根源。", "type": "h", "from": "功夫", "from_who": "周星驰", "creator": "acheing", "creator_uid": 11190, "reviewer": 1, "commit_from": "web", "created_at": "1644460005", "length": 9}, {"id": 5942, "uuid": "d7e791d8-0236-4df9-98e7-a9397e4aff3a", "hitokoto": "北方有佳人,绝世而独立。", "type": "i", "from": "李延年歌", "from_who": "李延年", "creator": "a632079", "creator_uid": 1044, "reviewer": 1044, "commit_from": "api", "created_at": "1586398491", "length": 12}, {"id": 7616, "uuid": "68548e22-8906-4835-b543-e98f56363a52", "hitokoto": "枝头有新花,树才能长青不老啊。", "type": "c", "from": "原神", "from_who": "萍姥姥", "creator": "Hytf233", "creator_uid": 7017, "reviewer": 4756, "commit_from": "web", "created_at": "1635825578", "length": 15}, {"id": 7924, "uuid": "40ea3088-6d6c-4b4f-b210-f22d54f30694", "hitokoto": "自童年起,我便独自一人,照顾着历代星辰。", "type": "d", "from": "独白", "from_who": "白鹤林", "creator": "桉", "creator_uid": 12620, "reviewer": 1, "commit_from": "web", "created_at": "1657958505", "length": 20}, {"id": 7919, "uuid": "a1fc8540-a087-47d3-bb65-49c828e19b70", "hitokoto": "一切已失去,不可以再追。", "type": "h", "from": "梦伴", "from_who": "梅艳芳", "creator": "泠洋", "creator_uid": 12623, "reviewer": 1, "commit_from": "web", "created_at": "1657937208", "length": 12}, {"id": 5439, "uuid": "c27b5554-6d5d-4146-80c8-5d2fa8538e7b", "hitokoto": "任尘世繁华,唯有守护你的一切,才是我此生唯一的使命。", "type": "b", "from": "次元战争·红龙", "from_who": "初启源", "creator": "Rain", "creator_uid": 5767, "reviewer": 4756, "commit_from": "web", "created_at": "1586109411", "length": 26}, {"id": 7727, "uuid": "550590e3-8595-452f-907b-db87f6e10780", "hitokoto": "时间是存在者的时间。", "type": "k", "from": "存在与时间", "from_who": "海德格尔", "creator": "Kyanite", "creator_uid": 8042, "reviewer": 1044, "commit_from": "web", "created_at": "1620992190", "length": 10}, {"id": 8242, "uuid": "187d89de-170f-4425-9eae-270535867fc4", "hitokoto": "所有的努力不过是延缓必将到来的坍塌。", "type": "e", "from": "原创", "from_who": "heiheihei", "creator": "heiheihei", "creator_uid": 12105, "reviewer": 1, "commit_from": "web", "created_at": "1650449487", "length": 18}, {"id": 8384, "uuid": "cafe0dc5-570b-4631-b398-630aa5f638cb", "hitokoto": "不管是烈火还是深海,都取不走我的命。", "type": "c", "from": "英雄联盟", "from_who": "海洋之灾·普朗克", "creator": "xcc", "creator_uid": 10404, "reviewer": 1, "commit_from": "web", "created_at": "1642645254", "length": 18}]
\ No newline at end of file
diff --git a/gui/assets/media/icon.ico b/toolbox/assets/media/icon.ico
similarity index 100%
rename from gui/assets/media/icon.ico
rename to toolbox/assets/media/icon.ico
diff --git a/gui/assets/media/avatar.png b/toolbox/assets/media/logo.png
similarity index 100%
rename from gui/assets/media/avatar.png
rename to toolbox/assets/media/logo.png
diff --git a/gui/codes/__init__.py b/toolbox/codes/__init__.py
similarity index 100%
rename from gui/codes/__init__.py
rename to toolbox/codes/__init__.py
diff --git a/gui/codes/apps/__init__.py b/toolbox/codes/app/__init__.py
similarity index 100%
rename from gui/codes/apps/__init__.py
rename to toolbox/codes/app/__init__.py
diff --git a/gui/codes/common/__init__.py b/toolbox/codes/common/__init__.py
similarity index 100%
rename from gui/codes/common/__init__.py
rename to toolbox/codes/common/__init__.py
diff --git a/toolbox/codes/common/clibs.py b/toolbox/codes/common/clibs.py
new file mode 100644
index 0000000..fac20b8
--- /dev/null
+++ b/toolbox/codes/common/clibs.py
@@ -0,0 +1,20 @@
+from pathlib import Path
+from threading import Lock
+
+base_path = Path(__file__).resolve().parent.parent.parent
+lock = Lock()
+account = None
+code_dict = [4, 11, 4, 31, 22, 12, 19, 23, 7, 16, 7, 23, 1, 8, 7, 18, 27, 32, 28, 25, 7, 32, 9, 15, 2, 32, 0, 12, 26, 15, 14, 17]
+username, password = "", ""
+avatar = f"{base_path}/assets/media/avatar.jpg"
+proverb = "佛曰:Time will say~"
+bg = f"{base_path}/assets/media/bg.jpg"
+win_width, win_height = 1100, 500
+def delete_files_in_directory(directory):
+ path = Path(directory)
+ if path.exists() and path.is_dir():
+ for child in path.iterdir():
+ if child.is_file():
+ child.unlink()
+ elif child.is_dir():
+ delete_files_in_directory(child)
\ No newline at end of file
diff --git a/gui/codes/common/db_operation.py b/toolbox/codes/common/db_operation.py
similarity index 82%
rename from gui/codes/common/db_operation.py
rename to toolbox/codes/common/db_operation.py
index 7c8f71d..6ec7f22 100644
--- a/gui/codes/common/db_operation.py
+++ b/toolbox/codes/common/db_operation.py
@@ -1,6 +1,7 @@
import sqlite3
import time
from codes.common import clibs
+from pathlib import Path
def db_init(db_file):
@@ -23,6 +24,17 @@ def db_init(db_file):
)
"""
)
+ cursor.execute(
+ """
+ create table if not exists users(
+ id integer primary key autoincrement,
+ timestamp DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW', 'localtime')),
+ username text not null unique,
+ password text not null,
+ salt text not null
+ )
+ """
+ )
cursor.close()
conn.close()
@@ -51,7 +63,7 @@ def db_backup():
def db_conn():
db_file = clibs.base_path / "assets/database/toolbox.db"
- conn = sqlite3.connect(db_file, isolation_level=None, check_same_thread=False, cached_statements=2048, timeout=10.0)
+ conn = sqlite3.connect(db_file, isolation_level=None, check_same_thread=False, cached_statements=2048, timeout=3.0)
cursor = conn.cursor()
cursor.execute("PRAGMA journal_mode=wal")
cursor.execute("PRAGMA wal_checkpoint=TRUNCATE")
@@ -64,4 +76,5 @@ def db_conn():
@db_lock
def db_close(conn, cursor):
cursor.close()
- conn.close()
\ No newline at end of file
+ conn.close()
+
diff --git a/gui/codes/common/secure_encrypt.py b/toolbox/codes/common/secure_encrypt.py
similarity index 89%
rename from gui/codes/common/secure_encrypt.py
rename to toolbox/codes/common/secure_encrypt.py
index 16b7567..2cff50a 100644
--- a/gui/codes/common/secure_encrypt.py
+++ b/toolbox/codes/common/secure_encrypt.py
@@ -31,7 +31,7 @@ class PassCipher:
key = ""
passwd = {idx: char for idx, char in enumerate(text * 4)}
for idx in range(32):
- char_i = 0 if ord(passwd[idx]) - clibs.account["code_dict"][idx] < 0 else ord(passwd[idx]) - clibs.account["code_dict"][idx]
+ char_i = 0 if ord(passwd[idx]) - clibs.code_dict[idx] < 0 else ord(passwd[idx]) - clibs.code_dict[idx]
key += chr(char_i)
salt = base64.urlsafe_b64encode(key.encode()).decode()
return salt
diff --git a/gui/codes/common/ui2py.py b/toolbox/codes/common/ui2py.py
similarity index 100%
rename from gui/codes/common/ui2py.py
rename to toolbox/codes/common/ui2py.py
diff --git a/gui/codes/common/worker.py b/toolbox/codes/common/worker.py
similarity index 100%
rename from gui/codes/common/worker.py
rename to toolbox/codes/common/worker.py
diff --git a/toolbox/codes/ui/login_ui.py b/toolbox/codes/ui/login_ui.py
new file mode 100644
index 0000000..010838f
--- /dev/null
+++ b/toolbox/codes/ui/login_ui.py
@@ -0,0 +1,238 @@
+import sys
+from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QListWidget, QStackedWidget, QCheckBox, QSpinBox, QToolBox, QLineEdit, QTableWidget, QTreeWidget, QCalendarWidget, QMessageBox, QToolBar, QSizePolicy
+from PySide6.QtCore import Qt, QTime, QSize, QRect,QEvent, QThread
+from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut
+from codes.common import clibs, db_operation
+from codes.common.secure_encrypt import PassCipher
+from codes.ui import main_ui
+
+class LoginWindow(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.init_ui()
+ self.setup_slot()
+ self.predos()
+ self.le_username.setFocus()
+
+ def init_ui(self):
+ self.setMinimumSize(420, 200)
+ self.setMaximumSize(500, 240)
+ self.resize(480, 200)
+ self.setWindowTitle("登录")
+ self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
+ self.setFont(QFont("Consolas", 14))
+
+ self.layout_outter = QHBoxLayout()
+ self.lb_logo = QLabel()
+ self.lb_logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.lb_logo.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
+ self.lb_logo.setPixmap(QPixmap(f"{clibs.base_path}/assets/media/logo.png"))
+ self.lb_logo.setFixedSize(QSize(120, 120))
+ self.lb_logo.setScaledContents(True)
+ self.layout_outter.addWidget(self.lb_logo)
+
+ self.tabW_login = QTabWidget()
+ self.tab_login = QWidget()
+ self.tabW_login.addTab(self.tab_login, "登录")
+ self.tab_register = QWidget()
+ self.tabW_login.addTab(self.tab_register, "注册")
+ self.layout_outter.addWidget(self.tabW_login)
+
+ # 登陆页面
+ self.layout_H_username = QHBoxLayout()
+ self.lb_username = QLabel("账号")
+ self.lb_username.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.layout_H_username.addWidget(self.lb_username)
+ self.le_username = QLineEdit()
+ self.le_username.setFocus()
+ self.layout_H_username.addWidget(self.le_username)
+
+ self.layout_H_password = QHBoxLayout()
+ self.lb_password = QLabel("密码")
+ self.lb_password.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.layout_H_password.addWidget(self.lb_password)
+ self.le_password = QLineEdit()
+ self.le_password.setEchoMode(QLineEdit.EchoMode.Password)
+ self.layout_H_password.addWidget(self.le_password)
+
+ self.layout_H_button = QHBoxLayout()
+ self.btn_login = QPushButton("登录")
+ self.btn_login.setAutoDefault(True)
+ self.btn_cancel = QPushButton("取消")
+ self.btn_cancel.setAutoDefault(True)
+ self.layout_H_button.addWidget(self.btn_login)
+ self.layout_H_button.addWidget(self.btn_cancel)
+
+ self.layout_V_user_pass = QVBoxLayout()
+ self.layout_V_user_pass.addLayout(self.layout_H_username)
+ self.layout_V_user_pass.addLayout(self.layout_H_password)
+ self.layout_V_user_pass.addLayout(self.layout_H_button)
+ self.tab_login.setLayout(self.layout_V_user_pass)
+
+ # 注册页面
+ self.layout_H_username_reg = QHBoxLayout()
+ self.lb_username_reg = QLabel("账号设定")
+ self.lb_username_reg.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.layout_H_username_reg.addWidget(self.lb_username_reg)
+ self.le_username_reg = QLineEdit()
+ self.le_username_reg.setFocus()
+ self.layout_H_username_reg.addWidget(self.le_username_reg)
+
+ self.layout_H_password_reg = QHBoxLayout()
+ self.lb_password_reg = QLabel("密码设定")
+ self.lb_password_reg.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.layout_H_password_reg.addWidget(self.lb_password_reg)
+ self.le_password_reg = QLineEdit()
+ self.le_password_reg.setEchoMode(QLineEdit.EchoMode.Password)
+ self.layout_H_password_reg.addWidget(self.le_password_reg)
+
+ self.layout_H_password_reg_confirm = QHBoxLayout()
+ self.lb_password_reg_confirm = QLabel("密码确认")
+ self.lb_password_reg_confirm.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.layout_H_password_reg_confirm.addWidget(self.lb_password_reg_confirm)
+ self.le_password_reg_confirm = QLineEdit()
+ self.le_password_reg_confirm.setEchoMode(QLineEdit.EchoMode.Password)
+ self.layout_H_password_reg_confirm.addWidget(self.le_password_reg_confirm)
+
+ self.layout_H_button_reg = QHBoxLayout()
+ self.btn_login_reg = QPushButton("确认")
+ self.btn_login_reg.setAutoDefault(True)
+ self.btn_cancel_reg = QPushButton("取消")
+ self.btn_cancel_reg.setAutoDefault(True)
+ self.layout_H_button_reg.addWidget(self.btn_login_reg)
+ self.layout_H_button_reg.addWidget(self.btn_cancel_reg)
+
+ self.layout_V_user_pass_reg = QVBoxLayout()
+ self.layout_V_user_pass_reg.addLayout(self.layout_H_username_reg)
+ self.layout_V_user_pass_reg.addLayout(self.layout_H_password_reg)
+ self.layout_V_user_pass_reg.addLayout(self.layout_H_password_reg_confirm)
+ self.layout_V_user_pass_reg.addLayout(self.layout_H_button_reg)
+ self.tab_register.setLayout(self.layout_V_user_pass_reg)
+
+ self.setLayout(self.layout_outter)
+
+ def setup_slot(self):
+ self.tabW_login.currentChanged.connect(self.onChange_tabW)
+ self.btn_login.clicked.connect(self.login_check)
+ self.btn_cancel.clicked.connect(self.close)
+ self.btn_login_reg.clicked.connect(self.register_check)
+ self.btn_cancel_reg.clicked.connect(self.close)
+ QShortcut("Esc", self).activated.connect(self.close)
+ self.le_password.returnPressed.connect(self.login_check)
+ self.le_password_reg_confirm.returnPressed.connect(self.register_check)
+
+ def predos(self):
+ db_file = clibs.base_path / "assets/database/toolbox.db"
+ if not db_file.exists():
+ db_operation.db_init(db_file)
+
+ def onChange_tabW(self):
+ text = self.tabW_login.tabText(self.tabW_login.currentIndex())
+ if text == "登录":
+ self.le_username.clear()
+ self.le_password.clear()
+ self.le_username.setFocus()
+ elif text == "注册":
+ self.le_username_reg.clear()
+ self.le_password_reg.clear()
+ self.le_password_reg_confirm.clear()
+ self.le_username_reg.setFocus()
+ else:
+ raise Exception(f"Unknown TabWidget Name: {text}")
+
+ def login_check(self):
+ def login_failed():
+ self.le_username.clear()
+ self.le_password.clear()
+ self.le_username.setFocus()
+ QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!")
+
+ def validate_login():
+ nonlocal username, password
+ conn, cursor = db_operation.db_conn()
+ cursor.execute(f""" SELECT * FROM users where username = "{username}" """)
+ record = cursor.fetchall()
+ if len(record) == 0:
+ login_failed()
+ elif len(record) == 1:
+ keys = ["id", "timestamp", "username", "password", "salt"]
+ login_info = dict(zip(keys, record[0]))
+ salt = PassCipher.gen_salt("@".join([username, password]))
+ cipher = PassCipher(salt)
+ # password_encrypt = cipher.encrypt("@".join([username, password]))
+ # print(f"password_encrypt = {password_encrypt}")
+ # exit()
+ try:
+ decrypt_password = cipher.decrypt(login_info["password"])
+ if password != decrypt_password:
+ login_failed()
+ return False
+ else:
+ self.mainWindow = main_ui.MainWindow()
+ self.mainWindow.show()
+ db_operation.db_close(conn, cursor)
+ clibs.username = username
+ clibs.password = password
+ self.close()
+ return True
+ except ValueError:
+ login_failed()
+ return False
+ else:
+ raise Exception(f"username duplicated: {username}")
+
+ username = self.le_username.text()
+ password = self.le_password.text()
+
+ validate_login()
+
+ def register_check(self):
+ def register_failed(flag: int = 0):
+ self.le_username_reg.clear()
+ self.le_password_reg.clear()
+ self.le_password_reg_confirm.clear()
+ self.le_username_reg.setFocus()
+ if flag == 0:
+ QMessageBox.critical(self, "错误", "账号已存在,或两次输入密码不一致,请重新输入!")
+ elif flag == 1:
+ QMessageBox.critical(self, "错误", "密码长度不符合要求,请重新输入!")
+
+ def validate_register():
+ nonlocal username, password, password_confirm, record, conn, cursor
+ if password != password_confirm:
+ register_failed()
+ return False
+
+ if len(password) < clibs.account["minimum_password_length"]:
+ register_failed(flag=1)
+ return False
+
+ if len(record) == 0:
+ salt = PassCipher.gen_salt("@".join([username, password]))
+ cipher = PassCipher(salt)
+ password_encrypted = cipher.encrypt(password)
+ cursor.execute("INSERT INTO users (username, password, salt) VALUES (?, ?, ?)", (username, password_encrypted, salt))
+ QMessageBox.information(self, "成功", "注册成功,切换至登录窗口进行登录!")
+ self.tabW_login.setCurrentIndex(self.tabW_login.indexOf(self.tab_login))
+ return True
+ elif len(record) == 1:
+ register_failed()
+ return False
+ else:
+ raise Exception(f"username duplicated: {username}")
+
+ username = self.le_username_reg.text()
+ password = self.le_password_reg.text()
+ password_confirm = self.le_password_reg_confirm.text()
+ conn, cursor = db_operation.db_conn()
+ cursor.execute(f""" SELECT * FROM users where username = "{username}" """)
+ record = cursor.fetchall()
+ validate_register()
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ window = LoginWindow()
+ window.show()
+ sys.exit(app.exec())
+
diff --git a/toolbox/codes/ui/main_ui.py b/toolbox/codes/ui/main_ui.py
new file mode 100644
index 0000000..04c9f55
--- /dev/null
+++ b/toolbox/codes/ui/main_ui.py
@@ -0,0 +1,208 @@
+import json
+from math import lgamma
+from shutil import copy
+from random import choice
+from pathlib import Path
+import sys
+import requests
+from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QListWidget, QStackedWidget, QCheckBox, QSpinBox, QToolBox, QLineEdit, QTableWidget, QTreeWidget, QCalendarWidget, QMessageBox, QToolBar, QSizePolicy, QMainWindow, QStatusBar
+from PySide6.QtCore import Qt, QTime, QSize, QRect,QEvent, QThread
+from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut, QAction, QKeySequence, QResizeEvent
+from codes.common import clibs, db_operation
+from codes.ui.widget_bg_ui import WidgetWithBg
+from codes.common.worker import Worker
+from typing import Callable, Any
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super().__init__()
+ self.init_ui()
+ self.setup_slot()
+ self.predos()
+
+ def init_ui(self):
+ self.setMinimumSize(clibs.win_width, clibs.win_height)
+ self.resize(clibs.win_width, clibs.win_height)
+ self.setWindowTitle("Toolbox")
+ self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
+ self.setFont(QFont("Consolas", 14))
+ # 任务栏/主窗口/状态栏
+ self.toolBar = QToolBar()
+ self.addToolBar(self.toolBar)
+ self.toolBar.setMovable(False)
+ self.centralW = QWidget()
+ self.setCentralWidget(self.centralW)
+ self.statusBar = QStatusBar()
+ self.setStatusBar(self.statusBar)
+
+ # toolbar
+ self.ac_homepage = QAction()
+ self.ac_homepage.setMenuRole(QAction.MenuRole.NoRole)
+ self.ac_homepage.setStatusTip("Go to homepage")
+ self.ac_homepage.setToolTip("Ctrl+Alt+H")
+ self.ac_homepage.setText("主页")
+ self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H"))
+ self.toolBar.addAction(self.ac_homepage)
+
+ def setup_slot(self):
+ self.ac_homepage.triggered.connect(self.ac_hp)
+ # QShortcut("Esc", self).activated.connect(self.close)
+
+ def predos(self):
+ self.home_overlay = None
+ db_operation.db_backup()
+ self.conn, self.cursor = db_operation.db_conn()
+
+ def ac_hp(self):
+ def get_files(dir_path):
+ folder = Path(dir_path)
+ files = [p for p in folder.rglob("*") if p.is_file()]
+ return choice(files), files
+
+ def del_repeat_proverb(proverbs: list):
+ _proverbs = []
+ for proverb in proverbs:
+ if proverb not in _proverbs:
+ _proverbs.append(proverb)
+ return _proverbs
+
+ def get_resources():
+ # background image
+ bing = "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=8"
+ req = requests.get(bing)
+ res = req.json()
+ _, files = get_files(f"{clibs.base_path}/assets/media/bg")
+ image_names = []
+ for file in files:
+ image_names.append(file.name.removesuffix(".jpg"))
+ for image in res["images"]:
+ startdate = image["startdate"]
+ if startdate in image_names:
+ continue
+ else:
+ image_url = f"""https://www.bing.com{image["url"]}"""
+ file = Path(f"{clibs.base_path}/assets/media/bg/{startdate}.jpg")
+ try:
+ req = requests.get(image_url, stream=True, timeout=10)
+ with open(file, "wb") as f:
+ for chunk in req.iter_content(chunk_size=8192):
+ f.write(chunk)
+ except Exception as e:
+ pass
+ # proverbs
+ hitokoto = "https://v1.hitokoto.cn/"
+ proverbs = []
+ try:
+ req = requests.get(hitokoto)
+ with open(f"{clibs.base_path}/assets/media/hitokoto.json", mode="rt", encoding="utf-8") as f:
+ proverbs = json.load(f)
+ proverbs.append(eval(req.text))
+ proverbs = del_repeat_proverb(proverbs)
+ with open(f"{clibs.base_path}/assets/media/hitokoto.json", mode="wt", encoding="utf-8") as f:
+ json.dump(proverbs, f, ensure_ascii=False)
+ except Exception as e:
+ pass
+
+ def change_resources():
+ # avatar
+ src, _ = get_files(f"{clibs.base_path}/assets/media/avatar")
+ dst = f"{clibs.base_path}/assets/media/avatar.jpg"
+ copy(src, dst)
+ # proverbs
+ with open(f"{clibs.base_path}/assets/media/hitokoto.json", mode="r", encoding="utf-8") as f:
+ proverbs = json.load(f)
+ res = choice(proverbs)
+ sentence = res["hitokoto"]
+ from_where = res["from"]
+ from_who = res["from_who"]
+ clibs.proverb = f"{sentence}\t\t※⌈{from_where}⌋ | {from_who}※"
+ # bg
+ src, _ = get_files(f"{clibs.base_path}/assets/media/bg")
+ dst = f"{clibs.base_path}/assets/media/bg.jpg"
+ copy(src, dst)
+
+ def gen_page():
+ self.set_shortcuts(False)
+ self.home_overlay = WidgetWithBg(parent=self)
+ self.home_overlay.on_closed.connect(self.exit_overlay)
+ self.home_overlay.on_full_screen.connect(self.full_screen)
+ self.home_overlay.show()
+ width, height = self.width(), self.height()
+ if width > clibs.win_width:
+ self.resize(self.width()-1, self.height()-1)
+ else:
+ self.resize(clibs.win_width+1, clibs.win_height+1)
+
+ change_resources()
+ self.launch_get_resources(get_resources)
+ gen_page()
+
+ def full_screen(self, flag: bool):
+ if flag == 0:
+ if self.isFullScreen():
+ self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint)
+ self.show()
+ self.showMaximized()
+ else:
+ self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
+ self.showFullScreen()
+ elif flag == 1:
+ self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint)
+ self.show()
+ self.showMaximized()
+
+ def exit_overlay(self):
+ self.set_shortcuts(True)
+ if self.isFullScreen():
+ self.setWindowFlags(self.windowFlags() ^ Qt.WindowType.WindowStaysOnTopHint)
+ self.show()
+ self.showMaximized()
+
+ def set_shortcuts(self, stat: bool = True):
+ if stat:
+ self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H"))
+ # self.ac_settings.setShortcut(QKeySequence("Ctrl+Alt+S"))
+ # self.ac_logs.setShortcut(QKeySequence("Ctrl+Alt+L"))
+ # self.ac_about.setShortcut(QKeySequence("Ctrl+Alt+A"))
+ # self.ac_caging.setShortcut(QKeySequence("Ctrl+Alt+C"))
+ # self.ac_quit.setShortcut(QKeySequence("Ctrl+Alt+Q"))
+ else:
+ self.ac_homepage.setShortcut(QKeySequence())
+ # self.ac_settings.setShortcut(QKeySequence())
+ # self.ac_logs.setShortcut(QKeySequence())
+ # self.ac_about.setShortcut(QKeySequence())
+ # self.ac_caging.setShortcut(QKeySequence())
+ # self.ac_quit.setShortcut(QKeySequence())
+
+ def launch_get_resources(self, func, on_anything: Callable[..., Any] = None, *args, **kwargs):
+ self.td_get_resources = Worker(func, *args, **kwargs)
+ self.td_get_resources.started.connect(lambda: None)
+ self.td_get_resources.result.connect(lambda: None)
+ self.td_get_resources.error.connect(lambda: None)
+ self.td_get_resources.finished.connect(lambda: None)
+ self.td_get_resources.start()
+
+ def resizeEvent(self, event: QResizeEvent):
+ super().resizeEvent(event)
+ if self.home_overlay:
+ self.home_overlay.setGeometry(self.rect())
+
+ def closeEvent(self, event):
+ if self.isFullScreen():
+ event.ignore()
+ return
+
+ reply = QMessageBox.question(self, "退出", "\n程序可能在运行,确定要退出吗?")
+ if reply == QMessageBox.StandardButton.Yes:
+ db_operation.db_close(self.conn, self.cursor)
+ event.accept()
+ else:
+ event.ignore()
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ window = MainWindow()
+ window.show()
+ sys.exit(app.exec())
diff --git a/toolbox/codes/ui/untitled.ui b/toolbox/codes/ui/untitled.ui
new file mode 100644
index 0000000..c2b32c8
--- /dev/null
+++ b/toolbox/codes/ui/untitled.ui
@@ -0,0 +1,145 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 602
+ 376
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
+ TextLabel
+
+
+
+ -
+
+
+
+ 125
+ 125
+
+
+
+
+ 125
+ 125
+
+
+
+
+
+
+ ../../assets/media/avatar.png
+
+
+ true
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+
+ -
+
+
+ Manford Fan · Code Create Life
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+
+ -
+
+
+
+ 400
+ 0
+
+
+
+
+ 400
+ 16777215
+
+
+
+ Qt::LayoutDirection::LeftToRight
+
+
+ false
+
+
+ QFrame::Shadow::Sunken
+
+
+ 0
+
+
+ Qt::Orientation::Horizontal
+
+
+
+ -
+
+
+ QFrame::Shadow::Sunken
+
+
+ memo
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+
+ -
+
+
-
+
+
+ TextLabel
+
+
+ Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter
+
+
+
+ -
+
+
+
+ 200
+ 16777215
+
+
+
+
+
+
+ -
+
+
+ TextLabel
+
+
+
+
+
+
+
+
+
+
diff --git a/toolbox/codes/ui/widget_bg_ui.py b/toolbox/codes/ui/widget_bg_ui.py
new file mode 100644
index 0000000..38a90c3
--- /dev/null
+++ b/toolbox/codes/ui/widget_bg_ui.py
@@ -0,0 +1,216 @@
+import sys
+from PySide6.QtWidgets import QWidget, QApplication, QSizePolicy, QVBoxLayout, QLabel, QFrame, QHBoxLayout, QLineEdit, QMessageBox
+from PySide6.QtGui import QPixmap, QPainter, QFontDatabase, QFont, QBrush, QShortcut, QKeySequence, QColor
+from PySide6.QtCore import Qt, QPoint, QDateTime, Signal, QTimer
+from zhdate import ZhDate
+from codes.common import clibs
+
+
+class LunarClockLabel(QLabel):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setMinimumWidth(350)
+ timer = QTimer(self)
+ timer.timeout.connect(self.update_time)
+ timer.start(1000)
+ self.update_time()
+
+ def update_time(self):
+ dt = QDateTime.currentDateTime()
+ g = dt.date()
+ z = ZhDate.today()
+ week = "一二三四五六日"[g.dayOfWeek() - 1]
+ text = f"{g.year()}年{g.month()}月{g.day()}日 {z.chinese()[5:]} 星期{week} {dt.toString('hh:mm:ss')}"
+ self.setText(text)
+
+
+class DoubleClickLabel(QLabel):
+ doubleClicked = Signal()
+
+ def mouseDoubleClickEvent(self, event):
+ super().mouseDoubleClickEvent(event)
+ self.doubleClicked.emit()
+
+
+class WidgetWithBg(QWidget):
+ on_closed = Signal()
+ on_full_screen = Signal(int)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.predos()
+ self.init_ui()
+ self.setup_slot()
+
+ def predos(self):
+ font_id = QFontDatabase.addApplicationFont(f"{clibs.base_path}/assets/media/font/OldEnglishTextMT/OldEnglishTextMT.ttf")
+ family = QFontDatabase.applicationFontFamilies(font_id)[0]
+ self.lb_font = QFont(family, 28, QFont.Weight.Medium)
+ self.background_pixmap = QPixmap(clibs.bg)
+
+ def init_ui(self):
+ layout_v = QVBoxLayout()
+ # 最上层的空白区
+ self.lb_empty_up = QLabel(self)
+ layout_v.addWidget(self.lb_empty_up)
+ # 头像区
+ self.lb_avatar = DoubleClickLabel(self)
+ self.lb_avatar.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ avatar = QPixmap(clibs.avatar)
+ avatar = self.circle_pixmap(avatar, 200)
+ self.lb_avatar.setPixmap(avatar)
+ self.lb_avatar.setScaledContents(True)
+ self.lb_avatar.setFixedSize(144, 144)
+ layout_v.addWidget(self.lb_avatar, alignment=Qt.AlignmentFlag.AlignCenter)
+ # 艺术字区
+ self.lb_name = QLabel(self)
+ self.lb_name.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.lb_name.setText("Manford Fan · Code Create Life")
+ self.lb_name.setStyleSheet("color: rgba(255,255,255,255);")
+ self.lb_name.setFont(self.lb_font)
+ layout_v.addWidget(self.lb_name)
+ # 时间区-左横线
+ layout_h = QHBoxLayout()
+ self.line_left = QFrame(self)
+ self.line_left.setFrameShape(QFrame.Shape.HLine)
+ self.line_left.setFrameShadow(QFrame.Shadow.Plain)
+ self.line_left.setStyleSheet("""
+ QFrame {
+ border: none;
+ background-color: rgba(255, 255, 255, 40);
+ }
+ """)
+ policy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
+ self.line_left.setSizePolicy(policy)
+ self.line_left.setLineWidth(1)
+ self.line_left.setFixedWidth(100)
+ # 时间区-右横线
+ self.line_right = QFrame(self)
+ self.line_right.setFrameShape(QFrame.Shape.HLine)
+ self.line_right.setFrameShadow(QFrame.Shadow.Plain)
+ self.line_right.setStyleSheet("""
+ QFrame {
+ border: none;
+ background-color: rgba(255, 255, 255, 40);
+ }
+ """)
+ policy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
+ self.line_right.setSizePolicy(policy)
+ self.line_right.setLineWidth(1)
+ self.line_right.setFixedWidth(100)
+ # 时间区-时间
+ self.lb_time = LunarClockLabel(self)
+ self.lb_time.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.lb_time.setStyleSheet("color: rgba(255,255,255,255);")
+ self.lb_time.setFont(QFont("Consolas", 12, QFont.Weight.Bold))
+ layout_h.addStretch(1)
+ layout_h.addWidget(self.line_left)
+ layout_h.addWidget(self.lb_time)
+ layout_h.addWidget(self.line_right)
+ layout_h.addStretch(1)
+ layout_v.addLayout(layout_h)
+ # layout_v.addWidget(self.line, alignment=Qt.AlignmentFlag.AlignCenter)
+
+ self.lb_proverb = QLabel(self)
+ self.lb_proverb.setAlignment(Qt.AlignmentFlag.AlignCenter)
+ self.lb_proverb.setText(clibs.proverb)
+ self.lb_proverb.setStyleSheet("color: rgba(255,255,255,255);")
+ self.lb_proverb.setFont(QFont("Consolas", 14, QFont.Weight.Bold))
+ layout_v.addWidget(self.lb_proverb)
+
+ self.le_password = QLineEdit(self)
+ self.le_password.setEchoMode(QLineEdit.EchoMode.Password)
+ self.le_password.setFont(QFont("Consolas", 12, QFont.Weight.Normal))
+ self.le_password.setMinimumWidth(300)
+ self.le_password.setFixedHeight(30)
+ self.hide_le_password()
+ layout_v.addWidget(self.le_password, alignment=Qt.AlignmentFlag.AlignCenter)
+
+ self.lb_empty_down = QLabel(self)
+ layout_v.addWidget(self.lb_empty_down)
+
+ layout_v.setStretch(0, 2) # empty up
+ layout_v.setStretch(1, 2) # avatar
+ layout_v.setStretch(2, 1) # name
+ layout_v.setStretch(3, 2) # time
+ layout_v.setStretch(4, 1) # proverb
+ layout_v.setStretch(5, 1) # password
+ layout_v.setStretch(6, 2) # empty down
+ self.setLayout(layout_v)
+
+ def setup_slot(self):
+ self.lb_avatar.doubleClicked.connect(self.auth_show)
+ self.le_password.returnPressed.connect(self.validate_password)
+ QShortcut(QKeySequence("Ctrl+Alt+L"), self, self.auth_show)
+ QShortcut(QKeySequence("Ctrl+Alt+S"), self, lambda: self.on_full_screen.emit(0))
+ # QShortcut(QKeySequence("Esc"), self).activated.connect(lambda: self.on_full_screen.emit(1))
+
+ def auth_show(self):
+ if self.input_hide:
+ self.show_le_password()
+ else:
+ self.hide_le_password()
+
+ def show_le_password(self):
+ self.input_hide = False
+ self.le_password.clear()
+ self.le_password.setPlaceholderText("Password")
+ self.le_password.setStyleSheet("")
+ self.le_password.setDisabled(False)
+ self.le_password.setFocus()
+
+ def hide_le_password(self):
+ self.input_hide = True
+ self.le_password.clear()
+ self.le_password.setDisabled(True)
+ self.le_password.setPlaceholderText("")
+ self.le_password.setStyleSheet("background:transparent; color:rgba(0,0,0,0); border:none; ")
+
+ def validate_password(self):
+ password = self.le_password.text()
+ if password == clibs.password:
+ self.on_closed.emit()
+ self.close()
+ elif password == "":
+ self.hide_le_password()
+ return
+ else:
+ QMessageBox.critical(self, "错误", "密码不正确,请确认后重新输入!")
+ self.show_le_password()
+
+ @staticmethod
+ def circle_pixmap(src: QPixmap, diameter: int) -> QPixmap:
+ dst = QPixmap(diameter, diameter)
+ dst.fill(Qt.GlobalColor.transparent)
+ painter = QPainter(dst)
+ painter.setRenderHint(QPainter.RenderHint.Antialiasing)
+ painter.setPen(Qt.PenStyle.NoPen)
+ painter.setBrush(QBrush(src))
+ painter.drawEllipse(dst.rect())
+ painter.end()
+ return dst
+
+ def paintEvent(self, event):
+ if not self.background_pixmap.isNull():
+ painter = QPainter(self)
+ painter.setRenderHint(QPainter.RenderHint.Antialiasing)
+
+ scaled_pixmap = self.background_pixmap.scaled(self.size(), Qt.AspectRatioMode.IgnoreAspectRatio, Qt.TransformationMode.SmoothTransformation)
+ x = (self.width() - scaled_pixmap.width()) // 2
+ y = (self.height() - scaled_pixmap.height()) // 2
+ painter.drawPixmap(QPoint(x, y), scaled_pixmap)
+
+ painter.setBrush(QColor(0, 0, 0, 144)) # 144 ≈ 50% 暗度,越大越暗
+ painter.setPen(Qt.PenStyle.NoPen)
+ painter.drawRect(self.rect())
+ painter.end()
+
+ super().paintEvent(event)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ your_widget = WidgetWithBg()
+ your_widget.resize(1000, 450)
+ your_widget.show()
+ sys.exit(app.exec())
diff --git a/toolbox/main.py b/toolbox/main.py
new file mode 100644
index 0000000..5479a6b
--- /dev/null
+++ b/toolbox/main.py
@@ -0,0 +1,26 @@
+import sys
+import json
+from PySide6.QtWidgets import QMainWindow, QApplication
+
+from codes.ui import login_ui, main_ui
+from codes.common import clibs
+
+
+class LoginWindow(login_ui.LoginWindow):
+ def __init__(self):
+ super().__init__()
+
+class MainWindow(main_ui.MainWindow):
+ def __init__(self):
+ super().__init__()
+
+
+if __name__ == '__main__':
+ with open(f"{clibs.base_path}/assets/conf/config.json", mode="rt", encoding="utf-8") as f:
+ clibs.account = json.load(f)
+
+ app = QApplication(sys.argv)
+ window = LoginWindow()
+ # window = MainWindow()
+ window.show()
+ sys.exit(app.exec())
\ No newline at end of file
diff --git a/gui/codes/ui/__init__.py b/toolbox/readme.md
similarity index 100%
rename from gui/codes/ui/__init__.py
rename to toolbox/readme.md
diff --git a/uv.lock b/uv.lock
index 7921cc9..efadf1f 100644
--- a/uv.lock
+++ b/uv.lock
@@ -409,6 +409,7 @@ dependencies = [
{ name = "pyinstaller" },
{ name = "pymodbus" },
{ name = "pyside6" },
+ { name = "zhdate" },
]
[package.metadata]
@@ -421,6 +422,7 @@ requires-dist = [
{ name = "pyinstaller", specifier = ">=6.15.0" },
{ name = "pymodbus", specifier = ">=3.11.1" },
{ name = "pyside6", specifier = ">=6.9.2" },
+ { name = "zhdate", specifier = ">=0.1" },
]
[[package]]
@@ -464,7 +466,7 @@ wheels = [
[[package]]
name = "pyinstaller"
-version = "6.15.0"
+version = "6.16.0"
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple/" }
dependencies = [
{ name = "altgraph" },
@@ -475,19 +477,19 @@ dependencies = [
{ name = "pywin32-ctypes", marker = "sys_platform == 'win32'" },
{ name = "setuptools" },
]
-sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/64/17/b2bb4de22650adbeef401fa82a1b43028976547a8728602e4d29735b455e/pyinstaller-6.15.0.tar.gz", hash = "sha256:a48fc4644ee4aa2aa2a35e7b51f496f8fbd7eecf6a2150646bbf1613ad07bc2d", size = 4331521, upload-time = "2025-08-03T18:33:35.709Z" }
+sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/94/1f62e95e4a28b64cfbb5b922ef3046f968b47170d37a1e1a029f56ac9cb4/pyinstaller-6.16.0.tar.gz", hash = "sha256:53559fe1e041a234f2b4dcc3288ea8bdd57f7cad8a6644e422c27bb407f3edef", size = 4008473, upload-time = "2025-09-13T20:07:01.733Z" }
wheels = [
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/24/dd/d5c8a127446adda954f68ea7fac22772f7ab8656ad4b06df396d82574ca9/pyinstaller-6.15.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:9f00c71c40148cd1e61695b2c6f1e086693d3bcf9bfa22ab513aa4254c3b966f", size = 1016981, upload-time = "2025-08-03T18:31:52.034Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/2a/7b50593b419db43e48d9bdeebaac0ff92a5fe035f3c30f87ca3e1650d7e2/pyinstaller-6.15.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:cbcc8eb77320c60722030ac875883b564e00768fe3ff1721c7ba3ad0e0a277e9", size = 726337, upload-time = "2025-08-03T18:31:57.592Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/77/83/7f498fba0154c57eb5fc93eb9680a2dbadb9f780a3389fb85b8d79683378/pyinstaller-6.15.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c33e6302bc53db2df1104ed5566bd980b3e0ee7f18416a6e3caa908c12a54542", size = 737539, upload-time = "2025-08-03T18:32:02.221Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/d6/e4477feab7c8379fb49e7ec95c82d0a69ad88f6ccc247f76bef3cb0e3432/pyinstaller-6.15.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:eb902d0fed3bb1f8b7190dc4df5c11f3b59505767e0d56d1ed782b853938bbf3", size = 735426, upload-time = "2025-08-03T18:32:06.485Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/32/7e/ff25648276f15e2e77fc563d36d8cfcd917e077bf2a172420df3588601b4/pyinstaller-6.15.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:b4df862adae7cf1f08eff53c43ace283822447f7f528f72e4f94749062712f15", size = 732210, upload-time = "2025-08-03T18:32:21.667Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/db/3d/267a7dddd0647de95d260780050ccd8228ab29d2b9edea54ed1f56800967/pyinstaller-6.15.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:b9ebf16ed0f99016ae8ae5746dee4cb244848a12941539e62ce2eea1df5a3f95", size = 732194, upload-time = "2025-08-03T18:32:29.536Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4d/61/962b2eb79ef225233e2d6e04600e998935328011dfb2fa775b1dd16b943a/pyinstaller-6.15.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:22193489e6a22435417103f61e7950363bba600ef36ec3ab1487303668c81092", size = 731256, upload-time = "2025-08-03T18:32:36.069Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/5e/4e20e1c0e5791b09b69bef3ac921fd0cd25551b56879324ad999b92fa045/pyinstaller-6.15.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:18f743069849dbaee3e10900385f35795a5743eabab55e99dcc42f204e40a0db", size = 731148, upload-time = "2025-08-03T18:32:41.269Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/88/31/28956c534991f289e2f981c715730b6241e75dc6295737a8cbd050a0cc8c/pyinstaller-6.15.0-py3-none-win32.whl", hash = "sha256:60da8f1b5071766b45c0f607d8bc3d7e59ba2c3b262d08f2e4066ba65f3544a2", size = 1312297, upload-time = "2025-08-03T18:32:50.572Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/ab/6a45186c7f8e34c422faecd72580116a67d068158c57faa2d2f6d01faa7f/pyinstaller-6.15.0-py3-none-win_amd64.whl", hash = "sha256:cbea297e16eeda30b41c300d6ec2fd2abea4dbd8d8a32650eeec36431c94fcd9", size = 1373091, upload-time = "2025-08-03T18:32:58.133Z" },
- { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/86/72159af032b9db36f2470a3b085f79277ec1c38e7e48f8c5dc1ed16dc4e1/pyinstaller-6.15.0-py3-none-win_arm64.whl", hash = "sha256:f43c035621742cf2d19b84308c60e4e44e72c94786d176b8f6adcde351b5bd98", size = 1314305, upload-time = "2025-08-03T18:33:05.557Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7b/0a/c42ce6e5d3de287f2e9432a074fb209f1fb72a86a72f3903849fdb5e4829/pyinstaller-6.16.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:7fd1c785219a87ca747c21fa92f561b0d2926a7edc06d0a0fe37f3736e00bd7a", size = 1027899, upload-time = "2025-09-13T20:05:59.2Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4e/d0/f18fedde32835d5a758f464c75924e2154065625f09d5456c3c303527654/pyinstaller-6.16.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:b756ddb9007b8141c5476b553351f9d97559b8af5d07f9460869bfae02be26b0", size = 727990, upload-time = "2025-09-13T20:06:03.583Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/db/c8bb47514ce857b24bf9294cf1ff74844b6a489fa0ab4ef6f923288c4e38/pyinstaller-6.16.0-py3-none-manylinux2014_i686.whl", hash = "sha256:0a48f55b85ff60f83169e10050f2759019cf1d06773ad1c4da3a411cd8751058", size = 739238, upload-time = "2025-09-13T20:06:07.69Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c6/3e/451dc784a8fcca0fe9f9b6b802d58555364a95b60f253613a2c83fc6b023/pyinstaller-6.16.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:73ba72e04fcece92e32518bbb1e1fb5ac2892677943dfdff38e01a06e8742851", size = 737142, upload-time = "2025-09-13T20:06:11.732Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/37/2f457479ef8fa2821cdb448acee2421dfb19fbe908bf5499d1930c164084/pyinstaller-6.16.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:b1752488248f7899281b17ca3238eefb5410521291371a686a4f5830f29f52b3", size = 734133, upload-time = "2025-09-13T20:06:15.477Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/63/c4/0f7daac4d062a4d1ac2571d8a8b9b5d6812094fcd914d139af591ca5e1ba/pyinstaller-6.16.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ba618a61627ee674d6d68e5de084ba17c707b59a4f2a856084b3999bdffbd3f0", size = 733817, upload-time = "2025-09-13T20:06:19.683Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/e4/b6127265b42bef883e8873d850becadf748bc5652e5a7029b059328f3c31/pyinstaller-6.16.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:c8b7ef536711617e12fef4673806198872033fa06fa92326ad7fd1d84a9fa454", size = 732912, upload-time = "2025-09-13T20:06:23.46Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/00/c6663107bdf814b2916e71563beabd09f693c47712213bc228994cb2cc65/pyinstaller-6.16.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:d1ebf84d02c51fed19b82a8abb4df536923abd55bb684d694e1356e4ae2a0ce5", size = 732773, upload-time = "2025-09-13T20:06:27.352Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/14/cabe9bc5f60b95d2e70e7d045ab94b0015ff8f6c8b16e2142d3597e30749/pyinstaller-6.16.0-py3-none-win32.whl", hash = "sha256:6d5f8617f3650ff9ef893e2ab4ddbf3c0d23d0c602ef74b5df8fbef4607840c8", size = 1313878, upload-time = "2025-09-13T20:06:33.234Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/99/2005efbc297e7813c1d6f18484aa94a1a81ce87b6a5b497c563681f4c4ea/pyinstaller-6.16.0-py3-none-win_amd64.whl", hash = "sha256:bc10eb1a787f99fea613509f55b902fbd2d8b73ff5f51ff245ea29a481d97d41", size = 1374706, upload-time = "2025-09-13T20:06:39.95Z" },
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ca/f4/4dfcf69b86d60fcaae05a42bbff1616d48a91e71726e5ed795d773dae9b3/pyinstaller-6.16.0-py3-none-win_arm64.whl", hash = "sha256:d0af8a401de792c233c32c44b16d065ca9ab8262ee0c906835c12bdebc992a64", size = 1315923, upload-time = "2025-09-13T20:06:45.846Z" },
]
[[package]]
@@ -661,6 +663,15 @@ wheels = [
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" },
]
+[[package]]
+name = "zhdate"
+version = "0.1"
+source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple/" }
+sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/64/7ba359eab7f61a4852a5125da723544a99d27d37d89b0e3608177195a1cb/zhdate-0.1.tar.gz", hash = "sha256:cf54c07a9a9a027db3a970f7477b7eb7962a0fc0d5f5d5d284a76e953e68993c", size = 6598, upload-time = "2019-02-18T22:48:39.672Z" }
+wheels = [
+ { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e5/5e/5ddf769b1ca31d1e997b94a390279da6892c99702593c1feedb93a70f508/zhdate-0.1-py3-none-any.whl", hash = "sha256:d003657bf49d6722c4c3adcb9a91722f6de1077bf3be0e54c0f4492b5e028fa4", size = 19442, upload-time = "2019-02-18T22:48:37.629Z" },
+]
+
[[package]]
name = "zope-event"
version = "5.1.1"