From 1e8ca2e2d84faae90d59e81e22121db7ed079ef8 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 19 Jan 2023 14:09:06 +0100 Subject: [PATCH 01/56] Refactor project struct to be self contained --- .../public/ScreenPlay/installedlistmodel.h | 4 +- ScreenPlay/qml/Installed/Installed.qml | 2 +- ScreenPlay/src/installedlistmodel.cpp | 85 ++++++--------- ScreenPlayUtil/CMakeLists.txt | 2 +- .../inc/public/ScreenPlayUtil/projectfile.h | 103 ++++-------------- ScreenPlayUtil/src/projectfile.cpp | 90 +++++++++++++++ ScreenPlayWallpaper/src/basewindow.h | 3 - ScreenPlayWorkshop/qml/ScreenPlayItem.qml | 5 +- .../qml/ScreenPlayItemImage.qml | 8 +- .../qml/upload/UploadProject.qml | 2 +- ScreenPlayWorkshop/src/installedlistmodel.cpp | 71 ++++++------ ScreenPlayWorkshop/src/installedlistmodel.h | 11 +- 12 files changed, 197 insertions(+), 189 deletions(-) create mode 100644 ScreenPlayUtil/src/projectfile.cpp diff --git a/ScreenPlay/inc/public/ScreenPlay/installedlistmodel.h b/ScreenPlay/inc/public/ScreenPlay/installedlistmodel.h index 9bfe035f..146ef3f9 100644 --- a/ScreenPlay/inc/public/ScreenPlay/installedlistmodel.h +++ b/ScreenPlay/inc/public/ScreenPlay/installedlistmodel.h @@ -51,7 +51,7 @@ public: Type, Preview, PreviewGIF, - FolderId, + FolderName, FileId, AbsoluteStoragePath, PublishedFileID, @@ -71,7 +71,7 @@ public slots: QVariantMap get(const QString& folderName) const; void loadInstalledContent(); - void append(const QJsonObject&, const QString&, const bool isNew, const QDateTime& lastModified); + void append(const QString& projectJsonFilePath); void reset(); void init(); void deinstallItemAt(const QString& absoluteStoragePath); diff --git a/ScreenPlay/qml/Installed/Installed.qml b/ScreenPlay/qml/Installed/Installed.qml index d47dbdb8..6aa332ef 100644 --- a/ScreenPlay/qml/Installed/Installed.qml +++ b/ScreenPlay/qml/Installed/Installed.qml @@ -229,7 +229,7 @@ Item { customTitle: m_title type: m_type isNew: m_isNew - screenId: m_folderId + screenId: m_folderName absoluteStoragePath: m_absoluteStoragePath publishedFileID: m_publishedFileID itemIndex: index diff --git a/ScreenPlay/src/installedlistmodel.cpp b/ScreenPlay/src/installedlistmodel.cpp index aa36f87a..989ba550 100644 --- a/ScreenPlay/src/installedlistmodel.cpp +++ b/ScreenPlay/src/installedlistmodel.cpp @@ -55,7 +55,7 @@ void InstalledListModel::deinstallItemAt(const QString& absoluteStoragePath) QTimer::singleShot(1000, this, [this, absoluteStoragePath]() { int index = -1; for (int i = 0; i < m_screenPlayFiles.size(); ++i) { - if (m_screenPlayFiles.at(i).m_absoluteStoragePath.toString() == absoluteStoragePath) { + if (m_screenPlayFiles.at(i).projectJsonFilePath.absoluteFilePath() == absoluteStoragePath) { index = i; break; } @@ -135,29 +135,29 @@ QVariant InstalledListModel::data(const QModelIndex& index, int role) const if (row < rowCount()) switch (role) { case static_cast(ScreenPlayItem::Title): - return m_screenPlayFiles.at(row).m_title; + return m_screenPlayFiles.at(row).title; case static_cast(ScreenPlayItem::Preview): - return m_screenPlayFiles.at(row).m_preview; + return m_screenPlayFiles.at(row).preview; case static_cast(ScreenPlayItem::PreviewGIF): - return m_screenPlayFiles.at(row).m_previewGIF; + return m_screenPlayFiles.at(row).previewGIF; case static_cast(ScreenPlayItem::Type): - return QVariant::fromValue(m_screenPlayFiles.at(row).m_type); - case static_cast(ScreenPlayItem::FolderId): - return m_screenPlayFiles.at(row).m_folderId; + return QVariant::fromValue(m_screenPlayFiles.at(row).type); + case static_cast(ScreenPlayItem::FolderName): + return m_screenPlayFiles.at(row).folderName; case static_cast(ScreenPlayItem::FileId): - return m_screenPlayFiles.at(row).m_file; + return m_screenPlayFiles.at(row).file; case static_cast(ScreenPlayItem::AbsoluteStoragePath): - return m_screenPlayFiles.at(row).m_absoluteStoragePath; + return QUrl::fromLocalFile(m_screenPlayFiles.at(row).projectJsonFilePath.dir().path()); case static_cast(ScreenPlayItem::PublishedFileID): - return m_screenPlayFiles.at(row).m_publishedFileID; + return m_screenPlayFiles.at(row).publishedFileID; case static_cast(ScreenPlayItem::Tags): - return m_screenPlayFiles.at(row).m_tags; + return m_screenPlayFiles.at(row).tags; case static_cast(ScreenPlayItem::IsNew): - return m_screenPlayFiles.at(row).m_isNew; + return m_screenPlayFiles.at(row).isNew; case static_cast(ScreenPlayItem::LastModified): - return m_screenPlayFiles.at(row).m_lastModified; + return m_screenPlayFiles.at(row).lastModified; case static_cast(ScreenPlayItem::SearchType): - return QVariant::fromValue(m_screenPlayFiles.at(row).m_searchType); + return QVariant::fromValue(m_screenPlayFiles.at(row).searchType); } qWarning() << "Unable to fetch value for row type:" << role; @@ -174,7 +174,7 @@ QHash InstalledListModel::roleNames() const { static_cast(ScreenPlayItem::Type), "m_type" }, { static_cast(ScreenPlayItem::Preview), "m_preview" }, { static_cast(ScreenPlayItem::PreviewGIF), "m_previewGIF" }, - { static_cast(ScreenPlayItem::FolderId), "m_folderId" }, + { static_cast(ScreenPlayItem::FolderName), "m_folderName" }, { static_cast(ScreenPlayItem::FileId), "m_file" }, { static_cast(ScreenPlayItem::AbsoluteStoragePath), "m_absoluteStoragePath" }, { static_cast(ScreenPlayItem::PublishedFileID), "m_publishedFileID" }, @@ -188,10 +188,16 @@ QHash InstalledListModel::roleNames() const /*! \brief Append an ProjectFile to the list. */ -void InstalledListModel::append(const QJsonObject& obj, const QString& folderName, const bool isNew, const QDateTime& lastModified) +void InstalledListModel::append(const QString& projectJsonFilePath) { beginInsertRows(QModelIndex(), m_screenPlayFiles.size(), m_screenPlayFiles.size()); - m_screenPlayFiles.append(ProjectFile(obj, folderName, m_globalVariables->localStoragePath(), isNew, lastModified)); + ProjectFile projectFile; + projectFile.projectJsonFilePath = QFileInfo(projectJsonFilePath); + if(!projectFile.init()){ + qWarning() << "Invalid project at "<< projectJsonFilePath; + return; + } + m_screenPlayFiles.append(std::move(projectFile)); endInsertRows(); } @@ -211,33 +217,14 @@ void InstalledListModel::loadInstalledContent() QFileInfoList list = QDir(m_globalVariables->localStoragePath().toLocalFile()).entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs); int counter = 0; - for (const auto& item : list) { + for (const QFileInfo& item : list) { const QString absoluteFilePath = m_globalVariables->localStoragePath().toLocalFile() + "/" + item.baseName() + "/project.json"; if (!QFile::exists(absoluteFilePath)) continue; - bool isNew = false; - - if (item.birthTime().date() == QDateTime::currentDateTime().date()) - isNew = true; - - if (auto obj = ScreenPlayUtil::openJsonFileToObject(absoluteFilePath)) { - - if (obj->isEmpty()) - continue; - - if (!obj->contains("type")) - continue; - - if (ScreenPlayUtil::getAvailableTypes().contains(obj->value("type").toString())) { - if (ScreenPlayUtil::getAvailableTypes().contains(obj->value("type").toString(), Qt::CaseInsensitive)) { - append(*obj, item.baseName(), isNew, item.lastModified()); - } - - counter += 1; - } - } + append(absoluteFilePath); + counter += 1; } setCount(counter); emit installedLoadingFinished(); @@ -262,17 +249,17 @@ QVariantMap InstalledListModel::get(const QString& folderName) const } for (const auto& item : m_screenPlayFiles) { - if (item.m_folderId == folderName) { + if (item.folderName == folderName) { QVariantMap map; - map.insert("m_title", item.m_title); - map.insert("m_preview", item.m_preview); - map.insert("m_previewGIF", item.m_previewGIF); - map.insert("m_file", item.m_file); - map.insert("m_type", QVariant::fromValue(item.m_type)); - map.insert("m_absoluteStoragePath", item.m_absoluteStoragePath); - map.insert("m_publishedFileID", item.m_publishedFileID); - map.insert("m_isNew", item.m_isNew); - map.insert("m_lastModified", item.m_lastModified); + map.insert("m_title", item.title); + map.insert("m_preview", item.preview); + map.insert("m_previewGIF", item.previewGIF); + map.insert("m_file", item.file); + map.insert("m_type", QVariant::fromValue(item.type)); + map.insert("m_absoluteStoragePath", QUrl::fromLocalFile(item.projectJsonFilePath.dir().path())); + map.insert("m_publishedFileID", item.publishedFileID); + map.insert("m_isNew", item.isNew); + map.insert("m_lastModified", item.lastModified); return map; } } diff --git a/ScreenPlayUtil/CMakeLists.txt b/ScreenPlayUtil/CMakeLists.txt index a8e52e79..4416d486 100644 --- a/ScreenPlayUtil/CMakeLists.txt +++ b/ScreenPlayUtil/CMakeLists.txt @@ -41,7 +41,7 @@ set(QML qml/TrayIcon.qml) set(SOURCES # cmake-format: sort - inc/public/ScreenPlayUtil/httpfileserver.cpp src/contenttypes.cpp src/util.cpp) + inc/public/ScreenPlayUtil/httpfileserver.cpp src/contenttypes.cpp src/util.cpp src/projectfile.cpp) set(HEADER # cmake-format: sort diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h index 261fbb33..ed39ac83 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h @@ -4,109 +4,50 @@ #include #include +#include #include #include #include #include #include +#include #include #include +#include +#include #include "ScreenPlayUtil/util.h" +#include "ScreenPlayUtil/PropertyHelpers.h" /*! \class ProjectFile - \brief In ScreenPlay every Wallpaper, Scene or Widget has an project.json to store its configuration + \brief In ScreenPlay every Wallpaper, Scene or Widget has an project.json to store its configuration. */ namespace ScreenPlay { struct ProjectFile { - ProjectFile( - const QJsonObject& obj, - const QString& folderName, - const QUrl& absolutePath, - const bool isNew, - const QDateTime& lastModified) - { + bool init(); + bool isValid(); - if (obj.contains("description")) - m_description = obj.value("description").toString(); - - if (obj.contains("file")) - m_file = obj.value("file").toString(); - - if (obj.contains("previewThumbnail")) { - m_preview = obj.value("previewThumbnail").toString(); - } else { - if (obj.contains("preview")) { - m_preview = obj.value("preview").toString(); - } - } - - if (obj.contains("previewGIF")) - m_previewGIF = obj.value("previewGIF").toString(); - - if (obj.contains("title")) - m_title = obj.value("title").toString(); - - if (obj.contains("workshopid")) { - m_publishedFileID = obj.value("workshopid").toInt(0); - } - - if (obj.contains("tags")) { - if (obj.value("tags").isArray()) { - auto tagArray = obj.value("tags").toArray(); - if (tagArray.size() > 0) { - for (const auto& tag : tagArray) { - m_tags.append(tag.toString()); - } - } - } - } - - m_absoluteStoragePath = QUrl(absolutePath.toString() + "/" + folderName); - - m_folderId = folderName; - - if (!obj.contains("type")) - return; - - auto type = ScreenPlayUtil::getInstalledTypeFromString(obj.value("type").toString()); - if (!type) { - qWarning() << "Type could not parsed from: " << *type << folderName; - return; - } - - m_type = *type; - if (m_type == InstalledType::InstalledType::GifWallpaper) { - m_preview = m_previewGIF; - } - m_searchType = ScreenPlayUtil::getSearchTypeFromInstalledType(m_type); - m_isNew = isNew; - m_lastModified = lastModified; - } - - ProjectFile() { } - - QString m_title; - QString m_description; + QString title; + QString description; // Filenames - QString m_file; - QString m_preview; - QString m_previewGIF; - // Path - QUrl m_absoluteStoragePath; + QString file; + QString preview; + QString previewGIF; + // Path to project.json + QFileInfo projectJsonFilePath; // Folder name - QString m_folderId; + QString folderName; - QVariant m_publishedFileID { 0 }; - QStringList m_tags; + QVariant publishedFileID { 0 }; + QStringList tags; - InstalledType::InstalledType m_type = InstalledType::InstalledType::Unknown; - SearchType::SearchType m_searchType = SearchType::SearchType::All; - bool m_isNew = false; - QDateTime m_lastModified; + InstalledType::InstalledType type = InstalledType::InstalledType::Unknown; + SearchType::SearchType searchType = SearchType::SearchType::All; + bool isNew = false; + QDateTime lastModified; }; } diff --git a/ScreenPlayUtil/src/projectfile.cpp b/ScreenPlayUtil/src/projectfile.cpp new file mode 100644 index 00000000..40852f1c --- /dev/null +++ b/ScreenPlayUtil/src/projectfile.cpp @@ -0,0 +1,90 @@ +#include "ScreenPlayUtil/projectfile.h" + +namespace ScreenPlay { + + bool ProjectFile::init() + { + if(!isValid()) + return false; + + const auto jsonObjOpt = ScreenPlayUtil::openJsonFileToObject(projectJsonFilePath.absoluteFilePath()); + QDir folder = projectJsonFilePath.dir(); + folderName = folder.dirName(); + QFileInfo folderInfo(folder.path()); + lastModified = folderInfo.birthTime(); + if (folderInfo.birthTime().date() == QDateTime::currentDateTime().date()) + isNew = true; + + if(!jsonObjOpt.has_value()) + return false; + + const QJsonObject& obj =jsonObjOpt.value(); + if (obj.isEmpty()) + return false; + + //Required: + if (!obj.contains("description")) + return false; + description = obj.value("description").toString(); + + if (!obj.contains("file")) + return false; + file = obj.value("file").toString(); + + + if (!obj.contains("title")) + return false; + title = obj.value("title").toString(); + + if (!obj.contains("type")) + return false; + + // Optional: + if (obj.contains("previewGIF")) + previewGIF = obj.value("previewGIF").toString(); + + if (obj.contains("workshopid")) + publishedFileID = obj.value("workshopid").toInt(0); + + if (obj.contains("previewThumbnail")) { + preview = obj.value("previewThumbnail").toString(); + } else { + if (!obj.contains("preview")) { + return false; + } + preview = obj.value("preview").toString(); + } + + if (obj.contains("tags")) { + if (obj.value("tags").isArray()) { + auto tagArray = obj.value("tags").toArray(); + if (tagArray.size() > 0) { + for (const auto& tag : tagArray) { + tags.append(tag.toString()); + } + } + } + } + + auto typeParsed = ScreenPlayUtil::getInstalledTypeFromString(obj.value("type").toString()); + if (!typeParsed) { + qWarning() << "Type could not parsed from: " << *typeParsed; + return false; + } + + type = *typeParsed; + if (type == InstalledType::InstalledType::GifWallpaper) { + preview = previewGIF; + } + searchType = ScreenPlayUtil::getSearchTypeFromInstalledType(type); + + return true; + } + bool ProjectFile::isValid() + { + if(!projectJsonFilePath.isFile()) + return false; + + return true; + } +} diff --git a/ScreenPlayWallpaper/src/basewindow.h b/ScreenPlayWallpaper/src/basewindow.h index eb2e8c5e..61866910 100644 --- a/ScreenPlayWallpaper/src/basewindow.h +++ b/ScreenPlayWallpaper/src/basewindow.h @@ -117,7 +117,6 @@ signals: void projectPathChanged(const QString& rojectPath); void projectSourceFileChanged(const QString& projectSourceFile); void projectSourceFileAbsoluteChanged(const QUrl& rojectSourceFileAbsolute); - void videoCodecChanged(); public slots: @@ -281,8 +280,6 @@ public slots: if (m_visualsPaused == visualsPaused) return; - qInfo() << "visualsPaused: " << visualsPaused; - m_visualsPaused = visualsPaused; emit visualsPausedChanged(m_visualsPaused); } diff --git a/ScreenPlayWorkshop/qml/ScreenPlayItem.qml b/ScreenPlayWorkshop/qml/ScreenPlayItem.qml index 356127f9..dcf0f666 100644 --- a/ScreenPlayWorkshop/qml/ScreenPlayItem.qml +++ b/ScreenPlayWorkshop/qml/ScreenPlayItem.qml @@ -8,15 +8,14 @@ Item { property alias checkBox: checkBox property string preview: screenPreview property bool isSelected: false - property string customTitle: "name here" property string absoluteStoragePath property string type property bool hasMenuOpen: false property var publishedFileID: 0 property int itemIndex - property string screenId: "" + property string folderName - signal itemClicked(var screenId, var type, var isActive) + signal itemClicked(var folderName, var type, var isActive) width: 320 height: 180 diff --git a/ScreenPlayWorkshop/qml/ScreenPlayItemImage.qml b/ScreenPlayWorkshop/qml/ScreenPlayItemImage.qml index 2f4c1e52..7bd3b67b 100644 --- a/ScreenPlayWorkshop/qml/ScreenPlayItemImage.qml +++ b/ScreenPlayWorkshop/qml/ScreenPlayItemImage.qml @@ -1,7 +1,7 @@ import QtQuick Item { - id: screenPlayItemImage + id: root property string sourceImage property string sourceImageGIF @@ -15,13 +15,13 @@ Item { anchors.fill: parent fillMode: Image.PreserveAspectCrop - source: screenPlayItemImage.sourceImage.trim() + source: root.sourceImage.trim() onStatusChanged: { if (image.status === Image.Ready) { - screenPlayItemImage.state = "loaded"; + root.state = "loaded"; } else if (image.status === Image.Error) { source = "images/missingPreview.png"; - screenPlayItemImage.state = "loaded"; + root.state = "loaded"; } } } diff --git a/ScreenPlayWorkshop/qml/upload/UploadProject.qml b/ScreenPlayWorkshop/qml/upload/UploadProject.qml index d1aeee39..42632cc7 100644 --- a/ScreenPlayWorkshop/qml/upload/UploadProject.qml +++ b/ScreenPlayWorkshop/qml/upload/UploadProject.qml @@ -82,7 +82,7 @@ Item { width: gridView.cellWidth - 30 customTitle: m_title type: m_type - screenId: m_folderId + screenId: m_folderName absoluteStoragePath: m_absoluteStoragePath publishedFileID: m_publishedFileID preview: m_preview diff --git a/ScreenPlayWorkshop/src/installedlistmodel.cpp b/ScreenPlayWorkshop/src/installedlistmodel.cpp index 0c0dbe28..565aaab4 100644 --- a/ScreenPlayWorkshop/src/installedlistmodel.cpp +++ b/ScreenPlayWorkshop/src/installedlistmodel.cpp @@ -39,25 +39,25 @@ QVariant InstalledListModel::data(const QModelIndex& index, int role) const if (row < rowCount()) switch (role) { case static_cast(ScreenPlayItem::Title): - return m_screenPlayFiles.at(row).m_title; + return m_screenPlayFiles.at(row).title; case static_cast(ScreenPlayItem::Preview): - return m_screenPlayFiles.at(row).m_preview; + return m_screenPlayFiles.at(row).preview; case static_cast(ScreenPlayItem::PreviewGIF): - return m_screenPlayFiles.at(row).m_previewGIF; + return m_screenPlayFiles.at(row).previewGIF; case static_cast(ScreenPlayItem::Type): - return QVariant::fromValue(m_screenPlayFiles.at(row).m_type); - case static_cast(ScreenPlayItem::FolderId): - return m_screenPlayFiles.at(row).m_folderId; + return QVariant::fromValue(m_screenPlayFiles.at(row).type); + case static_cast(ScreenPlayItem::FolderName): + return m_screenPlayFiles.at(row).folderName; case static_cast(ScreenPlayItem::FileId): - return m_screenPlayFiles.at(row).m_file; - case static_cast(ScreenPlayItem::AbsoluteStoragePath): - return m_screenPlayFiles.at(row).m_absoluteStoragePath; + return m_screenPlayFiles.at(row).file; + case static_cast(ScreenPlayItem::AbsoluteStoragePath): + return QUrl::fromLocalFile(m_screenPlayFiles.at(row).projectJsonFilePath.dir().path()); case static_cast(ScreenPlayItem::PublishedFileID): - return m_screenPlayFiles.at(row).m_publishedFileID; + return m_screenPlayFiles.at(row).publishedFileID; case static_cast(ScreenPlayItem::Tags): - return m_screenPlayFiles.at(row).m_tags; + return m_screenPlayFiles.at(row).tags; case static_cast(ScreenPlayItem::SearchType): - return QVariant::fromValue(m_screenPlayFiles.at(row).m_searchType); + return QVariant::fromValue(m_screenPlayFiles.at(row).searchType); default: return QVariant(); } @@ -71,7 +71,7 @@ QHash InstalledListModel::roleNames() const { static_cast(ScreenPlayItem::Type), "m_type" }, { static_cast(ScreenPlayItem::Preview), "m_preview" }, { static_cast(ScreenPlayItem::PreviewGIF), "m_previewGIF" }, - { static_cast(ScreenPlayItem::FolderId), "m_folderId" }, + { static_cast(ScreenPlayItem::FolderName), "m_folderName" }, { static_cast(ScreenPlayItem::FileId), "m_file" }, { static_cast(ScreenPlayItem::AbsoluteStoragePath), "m_absoluteStoragePath" }, { static_cast(ScreenPlayItem::PublishedFileID), "m_publishedFileID" }, @@ -80,10 +80,17 @@ QHash InstalledListModel::roleNames() const }; } -void InstalledListModel::append(const QJsonObject& obj, const QString& folderName, const QDateTime& lastModified) +void InstalledListModel::append(const QString& projectJsonFilePath) { beginInsertRows(QModelIndex(), m_screenPlayFiles.size(), m_screenPlayFiles.size()); - m_screenPlayFiles.append(ScreenPlay::ProjectFile(obj, folderName, m_absoluteStoragePath, false, lastModified)); + using namespace ScreenPlay; + ProjectFile projectFile; + projectFile.projectJsonFilePath = QFileInfo(projectJsonFilePath); + if(!projectFile.init()){ + qWarning() << "Invalid project at "<< projectJsonFilePath; + return; + } + m_screenPlayFiles.append(std::move(projectFile)); endInsertRows(); } @@ -96,26 +103,12 @@ void InstalledListModel::loadInstalledContent() QFileInfoList list = QDir(m_absoluteStoragePath.toLocalFile()).entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs); for (const auto& item : list) { - const QString absoluteFilePath = m_absoluteStoragePath.toLocalFile() + "/" + item.baseName() + "/project.json"; if (!QFile::exists(absoluteFilePath)) continue; - if (auto obj = ScreenPlayUtil::openJsonFileToObject(absoluteFilePath)) { - - if (obj->isEmpty()) - continue; - - if (!obj->contains("type")) - continue; - - if (obj->contains("workshopid")) - continue; - - if (ScreenPlayUtil::getAvailableTypes().contains(obj->value("type").toString(), Qt::CaseSensitivity::CaseInsensitive)) - append(*obj, item.baseName(), item.lastModified()); - } + append(absoluteFilePath); } emit installedLoadingFinished(); @@ -123,7 +116,7 @@ void InstalledListModel::loadInstalledContent() m_loadContentFutureWatcher.setFuture(m_loadContentFuture); } -QVariantMap InstalledListModel::get(QString folderId) +QVariantMap InstalledListModel::get(QString folderName) { if (m_screenPlayFiles.count() == 0) @@ -133,14 +126,14 @@ QVariantMap InstalledListModel::get(QString folderId) for (int i = 0; i < m_screenPlayFiles.count(); i++) { - if (m_screenPlayFiles[i].m_folderId == folderId) { - map.insert("m_title", m_screenPlayFiles[i].m_title); - map.insert("m_preview", m_screenPlayFiles[i].m_preview); - map.insert("m_previewGIF", m_screenPlayFiles[i].m_previewGIF); - map.insert("m_file", m_screenPlayFiles[i].m_file); - map.insert("m_type", QVariant::fromValue(m_screenPlayFiles[i].m_type)); - map.insert("m_absoluteStoragePath", m_screenPlayFiles[i].m_absoluteStoragePath); - map.insert("m_publishedFileID", m_screenPlayFiles[i].m_publishedFileID); + if (m_screenPlayFiles[i].folderName == folderName) { + map.insert("m_title", m_screenPlayFiles[i].title); + map.insert("m_preview", m_screenPlayFiles[i].preview); + map.insert("m_previewGIF", m_screenPlayFiles[i].previewGIF); + map.insert("m_file", m_screenPlayFiles[i].file); + map.insert("m_type", QVariant::fromValue(m_screenPlayFiles[i].type)); + map.insert("m_absoluteStoragePath", QUrl::fromLocalFile(m_screenPlayFiles[i].projectJsonFilePath.dir().path())); + map.insert("m_publishedFileID", m_screenPlayFiles[i].publishedFileID); return map; } } diff --git a/ScreenPlayWorkshop/src/installedlistmodel.h b/ScreenPlayWorkshop/src/installedlistmodel.h index cd69da24..85c893bf 100644 --- a/ScreenPlayWorkshop/src/installedlistmodel.h +++ b/ScreenPlayWorkshop/src/installedlistmodel.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,7 @@ class InstalledListModel : public QAbstractListModel { Q_OBJECT QML_ELEMENT - Q_PROPERTY(QUrl absoluteStoragePath READ absoluteStoragePath WRITE setabsoluteStoragePath NOTIFY absoluteStoragePathChanged) + Q_PROPERTY(QUrl absoluteStoragePath READ absoluteStoragePath WRITE setAbsoluteStoragePath NOTIFY absoluteStoragePathChanged) public: explicit InstalledListModel(QObject* parent = nullptr); @@ -49,7 +50,7 @@ public: Type, Preview, PreviewGIF, - FolderId, + FolderName, FileId, AbsoluteStoragePath, PublishedFileID, @@ -66,9 +67,9 @@ public: public slots: void loadInstalledContent(); - QVariantMap get(QString folderId); - void append(const QJsonObject&, const QString&, const QDateTime& lastModified); - void setabsoluteStoragePath(QUrl absoluteStoragePath) + QVariantMap get(QString folderName); + void append(const QString& projectJsonFilePath); + void setAbsoluteStoragePath(QUrl absoluteStoragePath) { if (m_absoluteStoragePath == absoluteStoragePath) return; From c5ec7e7bff3b9e3982d9338bba78eb8e6ba79bc8 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 20 Jan 2023 14:42:48 +0100 Subject: [PATCH 02/56] WIP refactor ScreenPlayWallpaper This is Windows only for now: Make Classes default constructible. We now have: setup(): - Can return status of the input data. This is most important, because we can now properly exit if this fails - We now use the same ProjectFile struct as we do in InstalledListModel - Gets called on all platforms start(): - Platform specific code Move argument parsing into main --- .vscode/launch.json | 21 ++- ScreenPlay/inc/public/ScreenPlay/util.h | 7 +- ScreenPlay/main.cpp | 8 +- ScreenPlay/src/installedlistmodel.cpp | 4 +- ScreenPlay/src/screenplaywallpaper.cpp | 3 +- ScreenPlaySDK/src/screenplaysdk.cpp | 5 + .../inc/public/ScreenPlayUtil/projectfile.h | 6 +- ScreenPlayUtil/src/projectfile.cpp | 166 ++++++++++-------- ScreenPlayWallpaper/main.cpp | 138 ++++++++------- ScreenPlayWallpaper/src/basewindow.cpp | 104 ++++------- ScreenPlayWallpaper/src/basewindow.h | 21 ++- .../src/windowsdesktopproperties.cpp | 2 +- .../src/windowsdesktopproperties.h | 2 +- ScreenPlayWallpaper/src/winwindow.cpp | 92 +++------- ScreenPlayWallpaper/src/winwindow.h | 11 +- 15 files changed, 274 insertions(+), 316 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 1949243e..9ce73c3f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,7 +18,7 @@ }, { - "name": "Windows Debug ScreenPlay", + "name": "ScreenPlay Windows Debug", "type": "cppvsdbg", "request": "launch", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlay.exe", @@ -34,7 +34,7 @@ "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml" }, { - "name": "Windows RelWithDebInfo ScreenPlay", + "name": "ScreenPlay Windows RelWithDebInfo", "type": "cppvsdbg", "request": "launch", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_RelWithDebInfo/bin/ScreenPlay.exe", @@ -48,6 +48,23 @@ } ], "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml" + }, + { + + "name": "ScreenPlayWallpaper Windows Debug", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlayWallpaper.exe", + "args": [], + "preLaunchTask": "CMake: build", + "cwd": "${workspaceFolder}", + "environment": [ + { + "name": "Path", + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + } + ], + "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml" } ] } \ No newline at end of file diff --git a/ScreenPlay/inc/public/ScreenPlay/util.h b/ScreenPlay/inc/public/ScreenPlay/util.h index 8a6be3b3..15cf3e78 100644 --- a/ScreenPlay/inc/public/ScreenPlay/util.h +++ b/ScreenPlay/inc/public/ScreenPlay/util.h @@ -31,8 +31,8 @@ #include namespace QArchive { - class DiskCompressor; - class DiskExtractor; +class DiskCompressor; +class DiskExtractor; } namespace ScreenPlay { @@ -84,7 +84,7 @@ public slots: QString toLocal(const QString& url) const; bool exportProject(QString contentPath, QString exportFileName); bool importProject(QString archivePath, QString extractionPath); - void requestAllLicenses() ; + void requestAllLicenses(); void requestDataProtection(); bool fileExists(const QString& filePath) const; @@ -121,7 +121,6 @@ public slots: emit debugMessagesChanged(m_debugMessages); } - private: QString m_debugMessages {}; QFuture m_requestAllLicensesFuture; diff --git a/ScreenPlay/main.cpp b/ScreenPlay/main.cpp index f6a640bf..0120e010 100644 --- a/ScreenPlay/main.cpp +++ b/ScreenPlay/main.cpp @@ -17,10 +17,10 @@ Q_IMPORT_QML_PLUGIN(ScreenPlayWorkshopPlugin) int main(int argc, char* argv[]) { - #if defined(Q_OS_WIN) - // https://bugreports.qt.io/browse/QTBUG-72028 - qputenv("QT_QPA_PLATFORM", "windows:darkmode=2"); - #endif +#if defined(Q_OS_WIN) + // https://bugreports.qt.io/browse/QTBUG-72028 + qputenv("QT_QPA_PLATFORM", "windows:darkmode=2"); +#endif QApplication qtGuiApp(argc, argv); ScreenPlay::App app; diff --git a/ScreenPlay/src/installedlistmodel.cpp b/ScreenPlay/src/installedlistmodel.cpp index 989ba550..6ce6014c 100644 --- a/ScreenPlay/src/installedlistmodel.cpp +++ b/ScreenPlay/src/installedlistmodel.cpp @@ -193,8 +193,8 @@ void InstalledListModel::append(const QString& projectJsonFilePath) beginInsertRows(QModelIndex(), m_screenPlayFiles.size(), m_screenPlayFiles.size()); ProjectFile projectFile; projectFile.projectJsonFilePath = QFileInfo(projectJsonFilePath); - if(!projectFile.init()){ - qWarning() << "Invalid project at "<< projectJsonFilePath; + if (!projectFile.init()) { + qWarning() << "Invalid project at " << projectJsonFilePath; return; } m_screenPlayFiles.append(std::move(projectFile)); diff --git a/ScreenPlay/src/screenplaywallpaper.cpp b/ScreenPlay/src/screenplaywallpaper.cpp index 9359b8e4..3a51cd06 100644 --- a/ScreenPlay/src/screenplaywallpaper.cpp +++ b/ScreenPlay/src/screenplaywallpaper.cpp @@ -158,9 +158,8 @@ void ScreenPlayWallpaper::close() */ void ScreenPlayWallpaper::processExit(int exitCode, QProcess::ExitStatus exitStatus) { - Q_UNUSED(exitStatus) if (exitCode != 0) - qWarning() << "WARNING EXIT CODE: " << exitCode; + qWarning() << "WARNING EXIT CODE: " << exitCode << exitStatus; } /*! diff --git a/ScreenPlaySDK/src/screenplaysdk.cpp b/ScreenPlaySDK/src/screenplaysdk.cpp index fe036e7f..6a7bf1da 100644 --- a/ScreenPlaySDK/src/screenplaysdk.cpp +++ b/ScreenPlaySDK/src/screenplaysdk.cpp @@ -54,6 +54,11 @@ void ScreenPlaySDK::sendMessage(const QJsonObject& obj) void ScreenPlaySDK::connected() { m_firstConnectionTimer.stop(); + if (m_appID.isEmpty() || m_type.isEmpty()) { + qCritical() << "Unable to connect with empyt: " << m_appID << m_type; + emit disconnected(); + return; + } QByteArray welcomeMessage = QString(m_appID + "," + m_type).toUtf8(); m_socket.write(welcomeMessage); diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h index ed39ac83..c1cfe5c9 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h @@ -34,13 +34,17 @@ struct ProjectFile { QString title; QString description; // Filenames - QString file; + QString file; // myFancyVideo.mp QString preview; QString previewGIF; // Path to project.json QFileInfo projectJsonFilePath; // Folder name QString folderName; + // Website Wallpaper + QUrl url; + // Video Wallpaper + ScreenPlay::VideoCodec::VideoCodec videoCodec; QVariant publishedFileID { 0 }; QStringList tags; diff --git a/ScreenPlayUtil/src/projectfile.cpp b/ScreenPlayUtil/src/projectfile.cpp index 40852f1c..d84c141e 100644 --- a/ScreenPlayUtil/src/projectfile.cpp +++ b/ScreenPlayUtil/src/projectfile.cpp @@ -2,89 +2,111 @@ namespace ScreenPlay { - bool ProjectFile::init() - { - if(!isValid()) +bool ProjectFile::init() +{ + if (!isValid()) + return false; + + const auto jsonObjOpt = ScreenPlayUtil::openJsonFileToObject(projectJsonFilePath.absoluteFilePath()); + QDir folder = projectJsonFilePath.dir(); + folderName = folder.dirName(); + QFileInfo folderInfo(folder.path()); + lastModified = folderInfo.birthTime(); + if (folderInfo.birthTime().date() == QDateTime::currentDateTime().date()) + isNew = true; + + if (!jsonObjOpt.has_value()) + return false; + + const QJsonObject& obj = jsonObjOpt.value(); + if (obj.isEmpty()) + return false; + + // Required: + if (!obj.contains("description")) + return false; + description = obj.value("description").toString(); + + if (!obj.contains("file")) + return false; + file = obj.value("file").toString(); + + if (!obj.contains("title")) + return false; + title = obj.value("title").toString(); + + if (!obj.contains("type")) + return false; + + // Optional: + if (obj.contains("previewGIF")) + previewGIF = obj.value("previewGIF").toString(); + + if (obj.contains("url")) + url = QUrl(obj.value("url").toString()); + + if (obj.contains("workshopid")) + publishedFileID = obj.value("workshopid").toInt(0); + + if (obj.contains("previewThumbnail")) { + preview = obj.value("previewThumbnail").toString(); + } else { + if (!obj.contains("preview")) { return false; - - const auto jsonObjOpt = ScreenPlayUtil::openJsonFileToObject(projectJsonFilePath.absoluteFilePath()); - QDir folder = projectJsonFilePath.dir(); - folderName = folder.dirName(); - QFileInfo folderInfo(folder.path()); - lastModified = folderInfo.birthTime(); - if (folderInfo.birthTime().date() == QDateTime::currentDateTime().date()) - isNew = true; - - if(!jsonObjOpt.has_value()) - return false; - - const QJsonObject& obj =jsonObjOpt.value(); - if (obj.isEmpty()) - return false; - - //Required: - if (!obj.contains("description")) - return false; - description = obj.value("description").toString(); - - if (!obj.contains("file")) - return false; - file = obj.value("file").toString(); - - - if (!obj.contains("title")) - return false; - title = obj.value("title").toString(); - - if (!obj.contains("type")) - return false; - - // Optional: - if (obj.contains("previewGIF")) - previewGIF = obj.value("previewGIF").toString(); - - if (obj.contains("workshopid")) - publishedFileID = obj.value("workshopid").toInt(0); - - if (obj.contains("previewThumbnail")) { - preview = obj.value("previewThumbnail").toString(); - } else { - if (!obj.contains("preview")) { - return false; - } - preview = obj.value("preview").toString(); } + preview = obj.value("preview").toString(); + } - if (obj.contains("tags")) { - if (obj.value("tags").isArray()) { - auto tagArray = obj.value("tags").toArray(); - if (tagArray.size() > 0) { - for (const auto& tag : tagArray) { - tags.append(tag.toString()); - } + if (obj.contains("tags")) { + if (obj.value("tags").isArray()) { + auto tagArray = obj.value("tags").toArray(); + if (tagArray.size() > 0) { + for (const auto& tag : tagArray) { + tags.append(tag.toString()); } } } + } - auto typeParsed = ScreenPlayUtil::getInstalledTypeFromString(obj.value("type").toString()); - if (!typeParsed) { - qWarning() << "Type could not parsed from: " << *typeParsed; + auto typeParsed = ScreenPlayUtil::getInstalledTypeFromString(obj.value("type").toString()); + if (!typeParsed) { + qWarning() << "Type could not parsed from: " << *typeParsed; + return false; + } + + type = typeParsed.value(); + if (type == InstalledType::InstalledType::GifWallpaper) { + preview = previewGIF; + } + if (type == ScreenPlay::InstalledType::InstalledType::WebsiteWallpaper) { + if (url.isEmpty()) { + qWarning() << "No url was specified for a websiteWallpaper!"; return false; } + } - type = *typeParsed; - if (type == InstalledType::InstalledType::GifWallpaper) { - preview = previewGIF; + searchType = ScreenPlayUtil::getSearchTypeFromInstalledType(type); + + if (obj.contains("codec")) { + if (auto videoCodecOpt = ScreenPlayUtil::getVideoCodecFromString(obj.value("codec").toString())) { + videoCodec = videoCodecOpt.value(); + } + } else if (type == ScreenPlay::InstalledType::InstalledType::VideoWallpaper) { + qWarning("No videoCodec was specified inside the json object!"); + if (file.endsWith(".mp4")) { + videoCodec = ScreenPlay::VideoCodec::VideoCodec::H264; + } else if (file.endsWith(".webm")) { + videoCodec = ScreenPlay::VideoCodec::VideoCodec::VP8; } - searchType = ScreenPlayUtil::getSearchTypeFromInstalledType(type); - - return true; } - bool ProjectFile::isValid() - { - if(!projectJsonFilePath.isFile()) - return false; - return true; - } + return true; +} +bool ProjectFile::isValid() +{ + if (!projectJsonFilePath.isFile()) + return false; + + return true; +} } diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index 936d49b9..d2e9d5f4 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -25,8 +25,13 @@ int main(int argc, char* argv[]) QApplication app(argc, argv); - // This gives us nice clickable output in QtCreator - qSetMessagePattern("%{if-category}%{category}: %{endif}%{message}\n Loc: [%{file}:%{line}]"); +#if defined(Q_OS_WIN) + WinWindow window; +#elif defined(Q_OS_LINUX) + LinuxWindow window; +#elif defined(Q_OS_OSX) + MacWindow window; +#endif // If we start with only one argument (app path) // It means we want to test a single wallpaper @@ -34,74 +39,73 @@ int main(int argc, char* argv[]) // For testing purposes when starting the ScreenPlayWallpaper directly. if (argumentList.length() == 1) { -#if defined(Q_OS_WIN) - // WinWindow window1({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", true, true); - WinWindow window1({ 1 }, "C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/26092021185017", "appID=test", "1", "fill", "videoWallpaper", true, true); -#elif defined(Q_OS_LINUX) - LinuxWindow window({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", false, true); -#elif defined(Q_OS_OSX) - MacWindow window({ 0 }, "test", "appID=test", "1", "fill", "videoWallpaper", true, true); -#endif - return app.exec(); + window.setActiveScreensList({ 0 }); + // window.setProjectPath("test"); + window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/1958068741"); + window.setAppID("test"); + window.setVolume(1); + window.setFillMode("fill"); + window.setType(ScreenPlay::InstalledType::InstalledType::VideoWallpaper); + window.setCheckWallpaperVisible(true); + window.setDebugMode(true); + } else { + // 8 parameter + 1 OS working directory as the first default paramter + if (argumentList.length() != 9) { + return -3; + } + + const auto activeScreensList = ScreenPlayUtil::parseStringToIntegerList(argumentList.at(1)); + + if (!activeScreensList.has_value()) { + qCritical("Could not activeScreensList"); + return -1; + } + + auto installedType = ScreenPlay::InstalledType::InstalledType::Unknown; + if (auto typeOpt = ScreenPlayUtil::getInstalledTypeFromString(argumentList.at(6))) { + installedType = typeOpt.value(); + } else { + qCritical() << "Cannot parse Wallpaper type from value" << argumentList.at(6); + return -6; + } + + bool okParseCheckWallpaperVisible = false; + const bool checkWallpaperVisible = argumentList.at(7).toInt(&okParseCheckWallpaperVisible); + if (!okParseCheckWallpaperVisible) { + qCritical("Could not parse checkWallpaperVisible"); + return -5; + } + bool okParseVolume = 0.0f; + const float volume = argumentList.at(4).toFloat(&okParseVolume); + if (!okParseVolume) { + qCritical("Could not parse Volume"); + return -6; + } + + QString appID = argumentList.at(3); + if (!appID.startsWith("appID=")) { + qCritical("Invalid appID"); + return -6; + } + appID = appID.remove("appID="); + + window.setActiveScreensList(activeScreensList.value()); + window.setProjectPath(argumentList.at(2)); + window.setAppID(appID); + window.setVolume(volume); + window.setFillMode(argumentList.at(5)); + window.setType(installedType); + window.setCheckWallpaperVisible(checkWallpaperVisible); + window.setDebugMode(false); } - // 8 parameter + 1 OS working directory as the first default paramter - if (argumentList.length() != 9) { - return -3; + const auto setupStatus = window.setup(); + if (setupStatus != BaseWindow::ExitCode::Success) { + return static_cast(setupStatus); } - - const bool debugMode = false; - - const auto activeScreensList = ScreenPlayUtil::parseStringToIntegerList(argumentList.at(1)); - - if (!activeScreensList.has_value()) - return -4; - - // See ScreenPlayWallpaper m_appArgumentsList constructor how the args get created - const QString projectFilePath = argumentList.at(2); - const QString appID = argumentList.at(3); - const QString volume = argumentList.at(4); - const QString fillmode = argumentList.at(5); - const QString type = argumentList.at(6); - - bool okParseCheckWallpaperVisible = false; - bool checkWallpaperVisible = argumentList.at(7).toInt(&okParseCheckWallpaperVisible); - if (!okParseCheckWallpaperVisible) { - qFatal("Could not parse checkWallpaperVisible"); - return -5; + const auto startStatus = window.start(); + if (startStatus != BaseWindow::ExitCode::Success) { + return static_cast(startStatus); } - -#if defined(Q_OS_WIN) - WinWindow window( - activeScreensList.value(), - projectFilePath, - appID, - volume, - fillmode, - type, - checkWallpaperVisible, - debugMode); -#elif defined(Q_OS_LINUX) - LinuxWindow window( - activeScreensList.value(), - projectFilePath, - appID, - volume, - fillmode, - type, - checkWallpaperVisible, - debugMode); -#elif defined(Q_OS_OSX) - MacWindow window( - activeScreensList.value(), - projectFilePath, - appID, - volume, - fillmode, - type, - checkWallpaperVisible, - debugMode); -#endif - return app.exec(); } diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index ed4e67f6..9582c9b4 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -1,6 +1,7 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "basewindow.h" +#include "ScreenPlayUtil/projectfile.h" #include "ScreenPlayUtil/util.h" /*! @@ -15,23 +16,7 @@ \brief . */ -BaseWindow::BaseWindow(QObject* parent) - : QObject(parent) -{ -} - -BaseWindow::BaseWindow( - const QVector activeScreensList, - const QString& projectFilePath, - const QString& type, - const bool checkWallpaperVisible, - const QString& appID, - const bool debugMode) - : QObject(nullptr) - , m_checkWallpaperVisible(checkWallpaperVisible) - , m_activeScreensList(activeScreensList) - , m_debugMode(debugMode) - , m_sdk(std::make_unique(appID, type)) +BaseWindow::BaseWindow() { QApplication::instance()->installEventFilter(this); @@ -50,74 +35,49 @@ BaseWindow::BaseWindow( qmlRegisterType("ScreenPlay.Wallpaper", 1, 0, "Wallpaper"); - if (!appID.contains("appID=")) { - qInfo() << "Invalid appID: " << appID; - qFatal("AppID does not contain appID="); - } - - setAppID(appID); - setProjectPath(projectFilePath); setOSVersion(QSysInfo::productVersion()); +} - if (projectFilePath == "test") { +BaseWindow::ExitCode BaseWindow::setup() +{ + + if (projectPath() == "test") { setType(ScreenPlay::InstalledType::InstalledType::QMLWallpaper); setProjectSourceFileAbsolute({ "qrc:/qml/ScreenPlayWallpaper/qml/Test.qml" }); setupLiveReloading(); - return; + return BaseWindow::Success; + } + ScreenPlay::ProjectFile projectFile; + projectFile.projectJsonFilePath = QFileInfo(projectPath() + "/project.json"); + if (!projectFile.init()) { + qWarning() << "Invalid project at " << projectPath(); + return BaseWindow::ParsingError; } - auto projectOpt = ScreenPlayUtil::openJsonFileToObject(projectFilePath + "/project.json"); - - if (!projectOpt.has_value()) { - QApplication::exit(-5); - } - const QJsonObject project = projectOpt.value(); - - if (!project.contains("type")) { - qFatal("No type was specified inside the json object!"); - QApplication::exit(-3); - } - - if (!project.contains("file") && !project.contains("url")) { - qFatal("No file was specified inside the json object!"); - QApplication::exit(-4); - } - - if (auto typeOpt = ScreenPlayUtil::getInstalledTypeFromString(project.value("type").toString())) { - setType(typeOpt.value()); - - if (this->type() == ScreenPlay::InstalledType::InstalledType::VideoWallpaper) { - if (auto videoCodecOpt = ScreenPlayUtil::getVideoCodecFromString(project.value("videoCodec").toString())) { - setVideoCodec(videoCodecOpt.value()); - } else { - qCritical() << "Cannot parse Wallpaper video codec from value" << project.value("type"); - } - } else if (!project.contains("videoCodec") && this->type() == ScreenPlay::InstalledType::InstalledType::VideoWallpaper) { - qWarning("No videoCodec was specified inside the json object!"); - const QString filename = project.value("file").toString(); - if (filename.endsWith(".mp4")) { - setVideoCodec(ScreenPlay::VideoCodec::VideoCodec::H264); - } else if (filename.endsWith(".webm")) { - setVideoCodec(ScreenPlay::VideoCodec::VideoCodec::VP8); - } - } - - } else { - qCritical() << "Cannot parse Wallpaper type from value" << project.value("type"); - } + setProjectSourceFile(projectFile.file); if (m_type == ScreenPlay::InstalledType::InstalledType::WebsiteWallpaper) { - if (!project.contains("url")) { - qFatal("No url was specified for a websiteWallpaper!"); - QApplication::exit(-5); - } - setProjectSourceFileAbsolute(project.value("url").toString()); + setProjectSourceFileAbsolute(projectFile.url); } else { - setProjectSourceFile(project.value("file").toString()); - setProjectSourceFileAbsolute(QUrl::fromLocalFile(projectFilePath + "/" + projectSourceFile())); + setProjectSourceFileAbsolute(QUrl::fromLocalFile(projectPath() + "/" + projectSourceFile())); } setupLiveReloading(); + + // Debug mode means we start the ScreenPlayWallpaper + // directly without an running ScreenPlay + if (!debugMode()) { + m_sdk = std::make_unique(appID(), QVariant::fromValue(type()).toString()); + // QObject::connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, [this]() { + // destroyThis(); + // }); + connect(sdk(), &ScreenPlaySDK::sdkDisconnected, this, &BaseWindow::destroyThis); + connect(sdk(), &ScreenPlaySDK::incommingMessage, this, &BaseWindow::messageReceived); + connect(sdk(), &ScreenPlaySDK::replaceWallpaper, this, &BaseWindow::replaceWallpaper); + sdk()->start(); + } + + return BaseWindow::Success; } /*! diff --git a/ScreenPlayWallpaper/src/basewindow.h b/ScreenPlayWallpaper/src/basewindow.h index 61866910..aa1c4f7b 100644 --- a/ScreenPlayWallpaper/src/basewindow.h +++ b/ScreenPlayWallpaper/src/basewindow.h @@ -24,14 +24,18 @@ class BaseWindow : public QObject { Q_OBJECT public: - BaseWindow(QObject* parent = nullptr); - BaseWindow( - const QVector activeScreensList, - const QString& projectFilePath, - const QString& type, - const bool checkWallpaperVisible, - const QString& appID, - const bool debugMode); + BaseWindow(); + + enum ExitCode { + Success = 0, + ParsingError = 1, + Error = 3, + }; + Q_ENUM(ExitCode) + + virtual BaseWindow::ExitCode setup() final; + + virtual BaseWindow::ExitCode start() = 0; Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged) @@ -339,7 +343,6 @@ private: float m_playbackRate { 1.0f }; float m_currentTime { 0.0f }; - QString m_contentBasePath; QString m_projectPath; QString m_projectSourceFile; QString m_appID; diff --git a/ScreenPlayWallpaper/src/windowsdesktopproperties.cpp b/ScreenPlayWallpaper/src/windowsdesktopproperties.cpp index effeb774..ed07b3c0 100644 --- a/ScreenPlayWallpaper/src/windowsdesktopproperties.cpp +++ b/ScreenPlayWallpaper/src/windowsdesktopproperties.cpp @@ -20,7 +20,7 @@ WindowsDesktopProperties::WindowsDesktopProperties(QObject* parent) setIsTiled(settings.value("TileWallpaper").toBool()); QFileInfo defaultBackgroundImageInfo(m_wallpaperPath); - if(defaultBackgroundImageInfo.exists()){ + if (defaultBackgroundImageInfo.exists()) { QImage backgroundImage(defaultBackgroundImageInfo.absoluteFilePath()); setDefaultWallpaperSize(backgroundImage.size()); } diff --git a/ScreenPlayWallpaper/src/windowsdesktopproperties.h b/ScreenPlayWallpaper/src/windowsdesktopproperties.h index bd2ede90..79a805be 100644 --- a/ScreenPlayWallpaper/src/windowsdesktopproperties.h +++ b/ScreenPlayWallpaper/src/windowsdesktopproperties.h @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include #include diff --git a/ScreenPlayWallpaper/src/winwindow.cpp b/ScreenPlayWallpaper/src/winwindow.cpp index f9dbb920..6c059e9c 100644 --- a/ScreenPlayWallpaper/src/winwindow.cpp +++ b/ScreenPlayWallpaper/src/winwindow.cpp @@ -1,10 +1,17 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "winwindow.h" +#include "ScreenPlayUtil/projectfile.h" #include "qqml.h" #include #include #include +/*! + \class WinWindow + \inmodule ScreenPlayWallpaper + \brief ScreenPlayWindow used for the Windows implementation. +*/ + /*! \brief Searches for the worker window for our window to parent to. */ @@ -104,68 +111,21 @@ void WinWindow::setupWindowMouseHook() } } -/*! - \class WinWindow - \inmodule ScreenPlayWallpaper - \brief ScreenPlayWindow used for the Windows implementation. -*/ - -/*! - \brief Creates a window on Windows from the give parameters: - \a activeScreensList - \a projectFilePath - \a appID - \a volume - \a fillmode - \a type - \a checkWallpaperVisible - \a debugMode - */ -WinWindow::WinWindow( - const QVector& activeScreensList, - const QString& projectFilePath, - const QString& appID, - const QString& volume, - const QString& fillmode, - const QString& type, - const bool checkWallpaperVisible, - const bool debugMode) - : BaseWindow( - activeScreensList, - projectFilePath, - type, - checkWallpaperVisible, - appID, - debugMode) - +BaseWindow::ExitCode WinWindow::start() { - auto* guiAppInst = dynamic_cast(QApplication::instance()); - connect(this, &BaseWindow::reloadQML, this, [this]() { - clearComponentCache(); - }); connect( - &m_window, &QQuickView::statusChanged, - this, [](auto status) { - if (status == QQuickView::Status::Error) - QCoreApplication::exit(-1); - }, - Qt::QueuedConnection); - connect(guiAppInst, &QApplication::screenAdded, this, &WinWindow::configureWindowGeometry); - connect(guiAppInst, &QApplication::screenRemoved, this, &WinWindow::configureWindowGeometry); - connect(guiAppInst, &QApplication::primaryScreenChanged, this, &WinWindow::configureWindowGeometry); - connect(sdk(), &ScreenPlaySDK::sdkDisconnected, this, &WinWindow::destroyThis); - connect(sdk(), &ScreenPlaySDK::incommingMessage, this, &WinWindow::messageReceived); - connect(sdk(), &ScreenPlaySDK::replaceWallpaper, this, &WinWindow::replaceWallpaper); - connect(&m_checkForFullScreenWindowTimer, &QTimer::timeout, this, &WinWindow::checkForFullScreenWindow); - connect( - &m_window, &QQuickView::statusChanged, - this, [](auto status) { + &m_window, &QQuickView::statusChanged, this, [this](auto status) { if (status == QQuickView::Status::Error) { - qInfo() << status; - QCoreApplication::exit(-1); + destroyThis(); } }, Qt::QueuedConnection); + auto* guiAppInst = dynamic_cast(QApplication::instance()); + connect(guiAppInst, &QApplication::screenAdded, this, &WinWindow::configureWindowGeometry); + connect(guiAppInst, &QApplication::screenRemoved, this, &WinWindow::configureWindowGeometry); + connect(guiAppInst, &QApplication::primaryScreenChanged, this, &WinWindow::configureWindowGeometry); + connect(this, &BaseWindow::reloadQML, this, &WinWindow::clearComponentCache); + connect(&m_checkForFullScreenWindowTimer, &QTimer::timeout, this, &WinWindow::checkForFullScreenWindow); const auto screens = QApplication::screens(); for (const auto& screen : screens) { @@ -175,27 +135,18 @@ WinWindow::WinWindow( m_windowsDesktopProperties = std::make_unique(); m_windowHandle = reinterpret_cast(m_window.winId()); if (!IsWindow(m_windowHandle)) { - qFatal("Could not get a valid window handle!"); + qCritical("Could not get a valid window handle!"); + return BaseWindow::ExitCode::Error; } qRegisterMetaType(); qRegisterMetaType(); - - bool ok = false; - float volumeParsed = volume.toFloat(&ok); - if (!ok) { - qFatal("Could not parse volume"); - } - - setVolume(volumeParsed); - setFillMode(fillmode); - qmlRegisterSingletonInstance("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); configureWindowGeometry(); // We do not support autopause for multi monitor wallpaper if (this->activeScreensList().length() == 1) { - if (checkWallpaperVisible) { + if (checkWallpaperVisible()) { m_checkForFullScreenWindowTimer.start(10); } } @@ -204,9 +155,9 @@ WinWindow::WinWindow( setupWindowMouseHook(); }); - if (!debugMode) - sdk()->start(); + return BaseWindow::ExitCode::Success; } + /*! \brief Calls ShowWindow function to set the main window in/visible. */ @@ -228,6 +179,7 @@ void WinWindow::setVisible(bool show) nice fade out animation first. Then the UI is responsible for calling WinWindow::terminate(). */ + void WinWindow::destroyThis() { emit qmlExit(); diff --git a/ScreenPlayWallpaper/src/winwindow.h b/ScreenPlayWallpaper/src/winwindow.h index 3231bf76..1bee0fa7 100644 --- a/ScreenPlayWallpaper/src/winwindow.h +++ b/ScreenPlayWallpaper/src/winwindow.h @@ -26,17 +26,10 @@ class WinWindow : public BaseWindow { Q_PROPERTY(WindowsDesktopProperties* windowsDesktopProperties READ windowsDesktopProperties WRITE setWindowsDesktopProperties NOTIFY windowsDesktopPropertiesChanged) public: - explicit WinWindow( - const QVector& activeScreensList, - const QString& projectFilePath, - const QString& appID, - const QString& volume, - const QString& fillmode, const QString& type, - const bool checkWallpaperVisible, - const bool debugMode = false); - WindowsDesktopProperties* windowsDesktopProperties() const { return m_windowsDesktopProperties.get(); } + BaseWindow::ExitCode start() override; + public slots: void setVisible(bool show) override; void destroyThis() override; From 9fcae648067d2c2cdf15741740da7b882f2ac4ff Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 20 Jan 2023 15:55:17 +0100 Subject: [PATCH 03/56] Adapt changes for osx --- .vscode/launch.json | 34 ++++++++----------- ScreenPlayWallpaper/src/macwindow.cpp | 49 ++++----------------------- ScreenPlayWallpaper/src/macwindow.h | 9 +---- 3 files changed, 22 insertions(+), 70 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 9ce73c3f..5eb193a5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -17,8 +17,19 @@ "MIMode": "lldb" }, { - - "name": "ScreenPlay Windows Debug", + "name": "Wallpaper MacOS (lldb) Debug", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "lldb" + }, + { + "name": "Windows Debug ScreenPlay", "type": "cppvsdbg", "request": "launch", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlay.exe", @@ -34,7 +45,7 @@ "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml" }, { - "name": "ScreenPlay Windows RelWithDebInfo", + "name": "Windows RelWithDebInfo ScreenPlay", "type": "cppvsdbg", "request": "launch", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_RelWithDebInfo/bin/ScreenPlay.exe", @@ -48,23 +59,6 @@ } ], "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml" - }, - { - - "name": "ScreenPlayWallpaper Windows Debug", - "type": "cppvsdbg", - "request": "launch", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlayWallpaper.exe", - "args": [], - "preLaunchTask": "CMake: build", - "cwd": "${workspaceFolder}", - "environment": [ - { - "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" - } - ], - "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml" } ] } \ No newline at end of file diff --git a/ScreenPlayWallpaper/src/macwindow.cpp b/ScreenPlayWallpaper/src/macwindow.cpp index 29e20fe3..69cdbe3e 100644 --- a/ScreenPlayWallpaper/src/macwindow.cpp +++ b/ScreenPlayWallpaper/src/macwindow.cpp @@ -1,47 +1,14 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "macwindow.h" -MacWindow::MacWindow( - const QVector& activeScreensList, - const QString& projectFilePath, - const QString& appID, - const QString& volume, - const QString& fillmode, - const QString& type, - const bool checkWallpaperVisible, - const bool debugMode) - : BaseWindow( - activeScreensList, - projectFilePath, - type, - checkWallpaperVisible, - appID, - debugMode) + +BaseWindow::ExitCode MacWindow::start() { - - connect(sdk(), &ScreenPlaySDK::sdkDisconnected, this, &MacWindow::destroyThis); - connect(sdk(), &ScreenPlaySDK::incommingMessage, this, &MacWindow::messageReceived); - connect(sdk(), &ScreenPlaySDK::replaceWallpaper, this, &MacWindow::replaceWallpaper); - - bool ok = false; - float volumeParsed = volume.toFloat(&ok); - if (!ok) { - qFatal("Could not parse volume"); - } - setVolume(volumeParsed); - setFillMode(fillmode); - - // Ether for one Screen or for all - if ((QApplication::screens().length() == activeScreensList.length()) && (activeScreensList.length() != 1)) { - // setupWallpaperForAllScreens(); - } else if (activeScreensList.length() == 1) { - auto* screen = QGuiApplication::screens().at(activeScreensList.at(0)); - m_window.setGeometry(screen->geometry()); - } else if (activeScreensList.length() > 1) { - } - + auto* screen = QGuiApplication::screens().at(activeScreensList().at(0)); + m_window.setGeometry(screen->geometry()); + qmlRegisterSingletonInstance("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); -#if defined(Q_OS_OSX) + QDir workingDir(QGuiApplication::instance()->applicationDirPath()); workingDir.cdUp(); workingDir.cdUp(); @@ -50,7 +17,6 @@ MacWindow::MacWindow( // This folder needs then to be copied into the .app/Contents/MacOS/ // for the deploy version. m_window.engine()->addImportPath(workingDir.path() + "/qml"); -#endif // WARNING: Setting Window flags must be called *here*! Qt::WindowFlags flags = m_window.flags(); @@ -62,8 +28,7 @@ MacWindow::MacWindow( MacIntegration* macIntegration = new MacIntegration(this); macIntegration->SetBackgroundLevel(&m_window); - if (!debugMode) - sdk()->start(); + return BaseWindow::ExitCode::Success; } void MacWindow::setVisible(bool show) diff --git a/ScreenPlayWallpaper/src/macwindow.h b/ScreenPlayWallpaper/src/macwindow.h index 2e19d099..299044cc 100644 --- a/ScreenPlayWallpaper/src/macwindow.h +++ b/ScreenPlayWallpaper/src/macwindow.h @@ -19,14 +19,7 @@ class MacWindow : public BaseWindow { Q_OBJECT public: - explicit MacWindow(const QVector& activeScreensList, - const QString& projectFilePath, - const QString& appID, - const QString& volume, - const QString& fillmode, - const QString& type, - const bool checkWallpaperVisible, - const bool debugMode); + BaseWindow::ExitCode start() override; signals: From 8ba7c62f1b5618f1f321033b493dff4a90ca2e4a Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 21 Jan 2023 11:11:32 +0100 Subject: [PATCH 04/56] Fix missing appID --- .../inc/public/ScreenPlaySDK/screenplaysdk.h | 1 - ScreenPlaySDK/src/screenplaysdk.cpp | 15 ++++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ScreenPlaySDK/inc/public/ScreenPlaySDK/screenplaysdk.h b/ScreenPlaySDK/inc/public/ScreenPlaySDK/screenplaysdk.h index df394809..3631f9df 100644 --- a/ScreenPlaySDK/inc/public/ScreenPlaySDK/screenplaysdk.h +++ b/ScreenPlaySDK/inc/public/ScreenPlaySDK/screenplaysdk.h @@ -99,5 +99,4 @@ private: QString m_appID; QTimer m_pingAliveTimer; - QTimer m_firstConnectionTimer; }; diff --git a/ScreenPlaySDK/src/screenplaysdk.cpp b/ScreenPlaySDK/src/screenplaysdk.cpp index 6a7bf1da..4d088bea 100644 --- a/ScreenPlaySDK/src/screenplaysdk.cpp +++ b/ScreenPlaySDK/src/screenplaysdk.cpp @@ -29,14 +29,15 @@ void ScreenPlaySDK::start() global_sdkPtr = this; qInstallMessageHandler(ScreenPlaySDK::redirectMessageOutputToMainWindow); - m_socket.setServerName("ScreenPlay"); connect(&m_socket, &QLocalSocket::connected, this, &ScreenPlaySDK::connected); connect(&m_socket, &QLocalSocket::disconnected, this, &ScreenPlaySDK::disconnected); connect(&m_socket, &QLocalSocket::readyRead, this, &ScreenPlaySDK::readyRead); - connect(&m_firstConnectionTimer, &QTimer::timeout, this, &ScreenPlaySDK::disconnected); - // When we do not establish a connection in the first 5 seconds we abort. - m_firstConnectionTimer.start(5000); - m_socket.connectToServer(); + + m_socket.connectToServer("ScreenPlay"); + if (!m_socket.waitForConnected(1000)){ + emit disconnected(); + } + } ScreenPlaySDK::~ScreenPlaySDK() @@ -53,14 +54,14 @@ void ScreenPlaySDK::sendMessage(const QJsonObject& obj) void ScreenPlaySDK::connected() { - m_firstConnectionTimer.stop(); + if (m_appID.isEmpty() || m_type.isEmpty()) { qCritical() << "Unable to connect with empyt: " << m_appID << m_type; emit disconnected(); return; } - QByteArray welcomeMessage = QString(m_appID + "," + m_type).toUtf8(); + QByteArray welcomeMessage = QString("appID="+m_appID + "," + m_type).toUtf8(); m_socket.write(welcomeMessage); if (!m_socket.waitForBytesWritten()) { disconnected(); From 9cfc4bb154b509f11fa4b0e6464642612b6588e3 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 21 Jan 2023 11:12:04 +0100 Subject: [PATCH 05/56] Formatting with clang 15 --- .../ScreenPlayUtil/AutoPropertyHelpers.h | 9 +++-- .../ScreenPlayUtil/ConstRefPropertyHelpers.h | 9 +++-- .../ScreenPlayUtil/ListPropertyHelper.h | 17 +++++---- .../public/ScreenPlayUtil/PropertyHelpers.h | 9 +++-- .../ScreenPlayUtil/PtrPropertyHelpers.h | 18 ++++++---- .../inc/public/ScreenPlayUtil/projectfile.h | 10 +++--- ScreenPlayWallpaper/src/basewindow.cpp | 9 ++--- ScreenPlayWidget/main.cpp | 4 +-- ScreenPlayWidget/src/widgetwindow.cpp | 7 ++-- .../SteamSDK/public/steam/isteaminventory.h | 36 +++++++++---------- .../public/steam/steam_api_internal.h | 20 ++++++++--- ScreenPlayWorkshop/src/installedlistmodel.cpp | 6 ++-- ScreenPlayWorkshop/src/installedlistmodel.h | 2 +- 13 files changed, 91 insertions(+), 65 deletions(-) diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/AutoPropertyHelpers.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/AutoPropertyHelpers.h index eca0a787..b6cecf09 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/AutoPropertyHelpers.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/AutoPropertyHelpers.h @@ -4,9 +4,12 @@ #include "HelpersCommon.h" -#define AUTO_GETTER(type, name) \ -public: \ - CheapestType::type_def MAKE_GETTER_NAME(name)() const { return m_##name; } +#define AUTO_GETTER(type, name) \ +public: \ + CheapestType::type_def MAKE_GETTER_NAME(name)() const \ + { \ + return m_##name; \ + } #define AUTO_SETTER(type, name) \ public: \ diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/ConstRefPropertyHelpers.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/ConstRefPropertyHelpers.h index ea3ef2a5..90b4b398 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/ConstRefPropertyHelpers.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/ConstRefPropertyHelpers.h @@ -14,9 +14,12 @@ public: \ } \ } -#define CONST_GETTER(type, name) \ -public: \ - const type& MAKE_GETTER_NAME(name)() const { return m_##name; } +#define CONST_GETTER(type, name) \ +public: \ + const type& MAKE_GETTER_NAME(name)() const \ + { \ + return m_##name; \ + } #define W_CREF_PROPERTY(type, name) \ protected: \ diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/ListPropertyHelper.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/ListPropertyHelper.h index b63381b0..725b5ded 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/ListPropertyHelper.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/ListPropertyHelper.h @@ -56,11 +56,14 @@ private: CppListType m_items; }; -#define LIST_PROPERTY(TYPE, NAME) \ -private: \ - Q_PROPERTY(QQmlListProperty NAME READ MAKE_GETTER_NAME(NAME) CONSTANT) \ -public: \ - const QQmlSmartListWrapper& MAKE_GETTER_NAME(NAME)() const { return m_##NAME; } \ - \ -private: \ +#define LIST_PROPERTY(TYPE, NAME) \ +private: \ + Q_PROPERTY(QQmlListProperty NAME READ MAKE_GETTER_NAME(NAME) CONSTANT) \ +public: \ + const QQmlSmartListWrapper& MAKE_GETTER_NAME(NAME)() const \ + { \ + return m_##NAME; \ + } \ + \ +private: \ QQmlSmartListWrapper m_##NAME; diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/PropertyHelpers.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/PropertyHelpers.h index 908d563f..2d0f9c3e 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/PropertyHelpers.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/PropertyHelpers.h @@ -4,9 +4,12 @@ #include "HelpersCommon.h" -#define PROP_GETTER(type, name) \ -public: \ - type MAKE_GETTER_NAME(name)() const { return m_##name; } +#define PROP_GETTER(type, name) \ +public: \ + type MAKE_GETTER_NAME(name)() const \ + { \ + return m_##name; \ + } #define PROP_SETTER(type, name) \ public: \ diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/PtrPropertyHelpers.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/PtrPropertyHelpers.h index 7df55db5..1249adeb 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/PtrPropertyHelpers.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/PtrPropertyHelpers.h @@ -5,9 +5,12 @@ #include "HelpersCommon.h" -#define PTR_GETTER(type, name) \ -public: \ - type* MAKE_GETTER_NAME(name)() const { return m_##name; } +#define PTR_GETTER(type, name) \ +public: \ + type* MAKE_GETTER_NAME(name)() const \ + { \ + return m_##name; \ + } #define PTR_SETTER(type, name) \ public: \ @@ -19,9 +22,12 @@ public: \ } \ } -#define SMART_PTR_GETTER(type, name) \ -public: \ - type* MAKE_GETTER_NAME(name)() const { return m_##name.get(); } +#define SMART_PTR_GETTER(type, name) \ +public: \ + type* MAKE_GETTER_NAME(name)() const \ + { \ + return m_##name.get(); \ + } #define SMART_PTR_SETTER(type, name) \ public: \ diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h index c1cfe5c9..c951c694 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/projectfile.h @@ -4,20 +4,20 @@ #include #include -#include +#include +#include #include #include #include +#include +#include #include #include -#include #include #include -#include -#include -#include "ScreenPlayUtil/util.h" #include "ScreenPlayUtil/PropertyHelpers.h" +#include "ScreenPlayUtil/util.h" /*! \class ProjectFile diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index 9582c9b4..12c3aa3e 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -68,12 +68,9 @@ BaseWindow::ExitCode BaseWindow::setup() // directly without an running ScreenPlay if (!debugMode()) { m_sdk = std::make_unique(appID(), QVariant::fromValue(type()).toString()); - // QObject::connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, [this]() { - // destroyThis(); - // }); - connect(sdk(), &ScreenPlaySDK::sdkDisconnected, this, &BaseWindow::destroyThis); - connect(sdk(), &ScreenPlaySDK::incommingMessage, this, &BaseWindow::messageReceived); - connect(sdk(), &ScreenPlaySDK::replaceWallpaper, this, &BaseWindow::replaceWallpaper); + connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &BaseWindow::destroyThis); + connect(m_sdk.get(), &ScreenPlaySDK::incommingMessage, this, &BaseWindow::messageReceived); + connect(m_sdk.get(), &ScreenPlaySDK::replaceWallpaper, this, &BaseWindow::replaceWallpaper); sdk()->start(); } diff --git a/ScreenPlayWidget/main.cpp b/ScreenPlayWidget/main.cpp index ea48b42a..a777bda3 100644 --- a/ScreenPlayWidget/main.cpp +++ b/ScreenPlayWidget/main.cpp @@ -24,8 +24,8 @@ int main(int argc, char* argv[]) // If we start with only one argument (path, appID, type), // it means we want to test a single widget if (argumentList.length() == 1) { - WidgetWindow spwmw("test", "appid", "qmlWidget", { 100, 100 }, true); - //WidgetWindow spwmw("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/2136442401", "appid", "qmlWidget", { 0, 0 }, true); + WidgetWindow spwmw("test", "appid", "qmlWidget", { 100, 100 }, true); + // WidgetWindow spwmw("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/2136442401", "appid", "qmlWidget", { 0, 0 }, true); return app.exec(); } diff --git a/ScreenPlayWidget/src/widgetwindow.cpp b/ScreenPlayWidget/src/widgetwindow.cpp index 6ba68b62..bf7b9bb6 100644 --- a/ScreenPlayWidget/src/widgetwindow.cpp +++ b/ScreenPlayWidget/src/widgetwindow.cpp @@ -40,10 +40,10 @@ WidgetWindow::WidgetWindow( "Error: only enums"); Qt::WindowFlags flags = m_window.flags(); - if(QSysInfo::productType() == "macos") { + if (QSysInfo::productType() == "macos") { // Setting it as a SlashScreen causes the window to hide on focus lost - m_window.setFlags(flags | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint ); - } else if(QSysInfo::productType() == "windows") { + m_window.setFlags(flags | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint); + } else if (QSysInfo::productType() == "windows") { // Must be splash screen to not show up in the taskbar m_window.setFlags(flags | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint | Qt::BypassWindowManagerHint | Qt::SplashScreen); } @@ -220,4 +220,3 @@ void WidgetWindow::setupLiveReloading() QObject::connect(&m_liveReloadLimiter, &QTimer::timeout, this, reloadQMLLambda); m_fileSystemWatcher.addPaths({ projectPath() }); } - diff --git a/ScreenPlayWorkshop/SteamSDK/public/steam/isteaminventory.h b/ScreenPlayWorkshop/SteamSDK/public/steam/isteaminventory.h index fc1e6b1f..37baf67b 100644 --- a/ScreenPlayWorkshop/SteamSDK/public/steam/isteaminventory.h +++ b/ScreenPlayWorkshop/SteamSDK/public/steam/isteaminventory.h @@ -364,9 +364,9 @@ STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR(ISteamInventory*, SteamGameServerInve // results transition from "Pending" to "OK" or an error state. There will // always be exactly one callback per handle. struct SteamInventoryResultReady_t { - enum { k_iCallback = k_iSteamInventoryCallbacks + 0 }; - SteamInventoryResult_t m_handle; - EResult m_result; + enum { k_iCallback = k_iSteamInventoryCallbacks + 0 }; + SteamInventoryResult_t m_handle; + EResult m_result; }; // SteamInventoryFullUpdate_t callbacks are triggered when GetAllItems @@ -377,8 +377,8 @@ struct SteamInventoryResultReady_t { // The normal ResultReady callback will still be triggered immediately // afterwards; this is an additional notification for your convenience. struct SteamInventoryFullUpdate_t { - enum { k_iCallback = k_iSteamInventoryCallbacks + 1 }; - SteamInventoryResult_t m_handle; + enum { k_iCallback = k_iSteamInventoryCallbacks + 1 }; + SteamInventoryResult_t m_handle; }; // A SteamInventoryDefinitionUpdate_t callback is triggered whenever @@ -386,31 +386,31 @@ struct SteamInventoryFullUpdate_t { // LoadItemDefinitions() or any other async request which required // a definition update in order to process results from the server. struct SteamInventoryDefinitionUpdate_t { - enum { k_iCallback = k_iSteamInventoryCallbacks + 2 }; + enum { k_iCallback = k_iSteamInventoryCallbacks + 2 }; }; // Returned struct SteamInventoryEligiblePromoItemDefIDs_t { - enum { k_iCallback = k_iSteamInventoryCallbacks + 3 }; - EResult m_result; - CSteamID m_steamID; - int m_numEligiblePromoItemDefs; - bool m_bCachedData; // indicates that the data was retrieved from the cache and not the server + enum { k_iCallback = k_iSteamInventoryCallbacks + 3 }; + EResult m_result; + CSteamID m_steamID; + int m_numEligiblePromoItemDefs; + bool m_bCachedData; // indicates that the data was retrieved from the cache and not the server }; // Triggered from StartPurchase call struct SteamInventoryStartPurchaseResult_t { - enum { k_iCallback = k_iSteamInventoryCallbacks + 4 }; - EResult m_result; - uint64 m_ulOrderID; - uint64 m_ulTransID; + enum { k_iCallback = k_iSteamInventoryCallbacks + 4 }; + EResult m_result; + uint64 m_ulOrderID; + uint64 m_ulTransID; }; // Triggered from RequestPrices struct SteamInventoryRequestPricesResult_t { - enum { k_iCallback = k_iSteamInventoryCallbacks + 5 }; - EResult m_result; - char m_rgchCurrency[4]; + enum { k_iCallback = k_iSteamInventoryCallbacks + 5 }; + EResult m_result; + char m_rgchCurrency[4]; }; #pragma pack(pop) diff --git a/ScreenPlayWorkshop/SteamSDK/public/steam/steam_api_internal.h b/ScreenPlayWorkshop/SteamSDK/public/steam/steam_api_internal.h index 1f4b52b9..218a040d 100644 --- a/ScreenPlayWorkshop/SteamSDK/public/steam/steam_api_internal.h +++ b/ScreenPlayWorkshop/SteamSDK/public/steam/steam_api_internal.h @@ -31,7 +31,10 @@ S_API void* S_CALLTYPE SteamInternal_FindOrCreateGameServerInterface(HSteamUser // struct { void (*pFn)(void* pCtx); uintptr_t counter; void *ptr; } // Do not change layout or add non-pointer aligned data! #define STEAM_DEFINE_INTERFACE_ACCESSOR(type, name, expr, kind, version) \ - inline void S_CALLTYPE SteamInternal_Init_##name(type* p) { *p = (type)(expr); } \ + inline void S_CALLTYPE SteamInternal_Init_##name(type* p) \ + { \ + *p = (type)(expr); \ + } \ STEAM_CLANG_ATTR("interface_accessor_kind:" kind ";interface_accessor_version:" version ";") \ inline type name() \ { \ @@ -66,9 +69,18 @@ S_API void S_CALLTYPE SteamAPI_UnregisterCallResult(class CCallbackBase* pCallba #define _STEAM_CALLBACK_SELECT(X, Y) _STEAM_CALLBACK_HELPER X Y #define _STEAM_CALLBACK_3(extra_code, thisclass, func, param) \ struct CCallbackInternal_##func : private CCallbackImpl { \ - CCallbackInternal_##func() { extra_code SteamAPI_RegisterCallback(this, param::k_iCallback); } \ - CCallbackInternal_##func(const CCallbackInternal_##func&) { extra_code SteamAPI_RegisterCallback(this, param::k_iCallback); } \ - CCallbackInternal_##func& operator=(const CCallbackInternal_##func&) { return *this; } \ + CCallbackInternal_##func() \ + { \ + extra_code SteamAPI_RegisterCallback(this, param::k_iCallback); \ + } \ + CCallbackInternal_##func(const CCallbackInternal_##func&) \ + { \ + extra_code SteamAPI_RegisterCallback(this, param::k_iCallback); \ + } \ + CCallbackInternal_##func& operator=(const CCallbackInternal_##func&) \ + { \ + return *this; \ + } \ \ private: \ virtual void Run(void* pvParam) \ diff --git a/ScreenPlayWorkshop/src/installedlistmodel.cpp b/ScreenPlayWorkshop/src/installedlistmodel.cpp index 565aaab4..31110257 100644 --- a/ScreenPlayWorkshop/src/installedlistmodel.cpp +++ b/ScreenPlayWorkshop/src/installedlistmodel.cpp @@ -50,7 +50,7 @@ QVariant InstalledListModel::data(const QModelIndex& index, int role) const return m_screenPlayFiles.at(row).folderName; case static_cast(ScreenPlayItem::FileId): return m_screenPlayFiles.at(row).file; - case static_cast(ScreenPlayItem::AbsoluteStoragePath): + case static_cast(ScreenPlayItem::AbsoluteStoragePath): return QUrl::fromLocalFile(m_screenPlayFiles.at(row).projectJsonFilePath.dir().path()); case static_cast(ScreenPlayItem::PublishedFileID): return m_screenPlayFiles.at(row).publishedFileID; @@ -86,8 +86,8 @@ void InstalledListModel::append(const QString& projectJsonFilePath) using namespace ScreenPlay; ProjectFile projectFile; projectFile.projectJsonFilePath = QFileInfo(projectJsonFilePath); - if(!projectFile.init()){ - qWarning() << "Invalid project at "<< projectJsonFilePath; + if (!projectFile.init()) { + qWarning() << "Invalid project at " << projectJsonFilePath; return; } m_screenPlayFiles.append(std::move(projectFile)); diff --git a/ScreenPlayWorkshop/src/installedlistmodel.h b/ScreenPlayWorkshop/src/installedlistmodel.h index 85c893bf..7603c259 100644 --- a/ScreenPlayWorkshop/src/installedlistmodel.h +++ b/ScreenPlayWorkshop/src/installedlistmodel.h @@ -19,9 +19,9 @@ #include #include #include -#include #include #include +#include #include "ScreenPlayUtil/projectfile.h" From cbc4ad7757de6de0116f74012b94b8f0a8e259ff Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 22 Jan 2023 16:25:04 +0100 Subject: [PATCH 06/56] Refactor launch.json for better multi os usage --- .vscode/launch.json | 112 ++++++++++++++++++++++++++++++-------------- CMakePresets.json | 24 ++++++++-- 2 files changed, 97 insertions(+), 39 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 5eb193a5..c81bfc42 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,60 +5,100 @@ "version": "0.2.0", "configurations": [ { - "name": "MacOS (lldb) Debug", - "type": "cppdbg", + "name": "ScreenPlay Debug", "request": "launch", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", - "args": [], + "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "externalConsole": false, - "MIMode": "lldb" + "console": false, + "windows": { + "environment": [ + { + "name": "Path", + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + } + ], + "type": "cppvsdbg", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlay.exe" + }, + "osx": { + "MIMode": "lldb", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_Debug/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", + "type": "cppdbg" + } }, { - "name": "Wallpaper MacOS (lldb) Debug", - "type": "cppdbg", + "name": "ScreenPlay RelWithDebInfo", "request": "launch", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", - "args": [], + "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "externalConsole": false, - "MIMode": "lldb" + "console": false, + "windows": { + "environment": [ + { + "name": "Path", + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + } + ], + "type": "cppvsdbg", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_RelWithDebInfo/bin/ScreenPlay.exe" + }, + "osx": { + "MIMode": "lldb", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_RelWithDebInfo/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", + "type": "cppdbg" + } }, { - "name": "Windows Debug ScreenPlay", - "type": "cppvsdbg", + "name": "ScreenPlayWallpaper Debug", "request": "launch", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlay.exe", - "args": [], - "preLaunchTask": "CMake: build", + "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ + "stopAtEntry": false, "cwd": "${workspaceFolder}", - "environment": [ - { - "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" - } - ], - "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml" + "environment": [], + "console": false, + "windows": { + "environment": [ + { + "name": "Path", + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + } + ], + "type": "cppvsdbg", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlayWallpaper.exe" + }, + "osx": { + "MIMode": "lldb", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_Debug/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", + "type": "cppdbg" + } }, { - "name": "Windows RelWithDebInfo ScreenPlay", - "type": "cppvsdbg", + "name": "ScreenPlayWallpaper RelWithDebInfo", "request": "launch", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_RelWithDebInfo/bin/ScreenPlay.exe", - "args": [], - "preLaunchTask": "CMake: build", + "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ + "stopAtEntry": false, "cwd": "${workspaceFolder}", - "environment": [ - { - "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" - } - ], - "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml" + "environment": [], + "console": false, + "windows": { + "environment": [ + { + "name": "Path", + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + } + ], + "type": "cppvsdbg", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_RelWithDebInfo/bin/ScreenPlayWallpaper.exe" + }, + "osx": { + "MIMode": "lldb", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_RelWithDebInfo/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", + "type": "cppdbg" + } } ] } \ No newline at end of file diff --git a/CMakePresets.json b/CMakePresets.json index 39e0d990..2dd30d4a 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -58,7 +58,7 @@ } }, { - "name": "windows-debug-qt-6.4.2", + "name": "windows-relwithdebinfo-qt-6.4.2", "inherits": "default-windows", "displayName": "MSVC K3000 Qt 6.4.2 RelWithDebInfo", "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_MSVC_RelWithDebInfo", @@ -74,7 +74,7 @@ "displayName": "ScreenPlay 64bit Debug Linux", "description": "Linux only!", "generator": "Ninja", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_GCC", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_GCC_Debug", "condition": { "type": "equals", "lhs": "${hostSystemName}", @@ -96,12 +96,21 @@ "VCPKG_TARGET_TRIPLET": "x64-linux" } }, + { + "name": "linux-relwithdebinfo", + "displayName": "ScreenPlay 64bit RelWithDebInfo Linux", + "inherits":"linux-debug", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_GCC_RelWithDebInfo", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, { "name": "osx-debug", "displayName": "ScreenPlay 64bit Debug osx", "description": "Osx only!", "generator": "Ninja", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.3.2_Clang", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.3.2_Clang_Debug", "condition": { "type": "equals", "lhs": "${hostSystemName}", @@ -121,6 +130,15 @@ "CMAKE_PREFIX_PATH": "$env{qt_path}/6.3.2/macos", "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/../vcpkg/scripts/buildsystems/vcpkg.cmake" } + }, + { + "name": "osx-relwithdebinfo", + "displayName": "ScreenPlay 64bit RelWithDebInfo osx", + "inherits": "osx-debug", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.3.2_Clang_RelWithDebInfo", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } } ], "buildPresets": [ From 1590be77db10659bbab3c5561c2ced8444326e4f Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 22 Jan 2023 16:25:23 +0100 Subject: [PATCH 07/56] Add missing license --- Docs/Legal/agpl-3.0-only.txt | 661 +++++++++++++++++++++++++++++++++++ 1 file changed, 661 insertions(+) create mode 100644 Docs/Legal/agpl-3.0-only.txt diff --git a/Docs/Legal/agpl-3.0-only.txt b/Docs/Legal/agpl-3.0-only.txt new file mode 100644 index 00000000..be3f7b28 --- /dev/null +++ b/Docs/Legal/agpl-3.0-only.txt @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. From a6eb6b06607bfd017908d50be13db68a71d465f2 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 22 Jan 2023 16:27:18 +0100 Subject: [PATCH 08/56] Add fadeIn not working workaround See https://bugreports.qt.io/browse/QTBUG-110456 Add exit codes --- ScreenPlayUtil/CMakeLists.txt | 1 + .../inc/public/ScreenPlayUtil/exitcodes.h | 20 ++ ScreenPlayWallpaper/main.cpp | 16 +- ScreenPlayWallpaper/qml/Wallpaper.qml | 201 +++++++++--------- ScreenPlayWallpaper/src/basewindow.cpp | 9 +- ScreenPlayWallpaper/src/basewindow.h | 15 +- ScreenPlayWallpaper/src/macwindow.cpp | 4 +- ScreenPlayWallpaper/src/macwindow.h | 2 +- ScreenPlayWallpaper/src/winwindow.cpp | 14 +- ScreenPlayWallpaper/src/winwindow.h | 2 +- 10 files changed, 144 insertions(+), 140 deletions(-) create mode 100644 ScreenPlayUtil/inc/public/ScreenPlayUtil/exitcodes.h diff --git a/ScreenPlayUtil/CMakeLists.txt b/ScreenPlayUtil/CMakeLists.txt index 4416d486..9e6a6620 100644 --- a/ScreenPlayUtil/CMakeLists.txt +++ b/ScreenPlayUtil/CMakeLists.txt @@ -45,6 +45,7 @@ set(SOURCES # cmake-format: sort set(HEADER # cmake-format: sort + inc/public/ScreenPlayUtil/exitcodes.h inc/public/ScreenPlayUtil/AutoPropertyHelpers.h inc/public/ScreenPlayUtil/ConstRefPropertyHelpers.h inc/public/ScreenPlayUtil/contenttypes.h diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/exitcodes.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/exitcodes.h new file mode 100644 index 00000000..ec0ad8e0 --- /dev/null +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/exitcodes.h @@ -0,0 +1,20 @@ +#pragma once + +namespace ScreenPlay { + + Q_NAMESPACE + +enum class WallpaperExitCode { + Ok = 0, + Invalid_ArgumentSize, + Invalid_ActiveScreensList, + Invalid_InstalledType , + Invalid_CheckWallpaperVisible , + Invalid_Volume , + Invalid_AppID , + Invalid_Setup_ProjectParsingError , + Invalid_Setup_Error , + Invalid_Start_Windows_HandleError , +}; +Q_ENUM_NS(WallpaperExitCode) +} \ No newline at end of file diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index d2e9d5f4..4747c55b 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -51,14 +51,14 @@ int main(int argc, char* argv[]) } else { // 8 parameter + 1 OS working directory as the first default paramter if (argumentList.length() != 9) { - return -3; + return static_cast(ScreenPlay::WallpaperExitCode::Invalid_ArgumentSize); } const auto activeScreensList = ScreenPlayUtil::parseStringToIntegerList(argumentList.at(1)); if (!activeScreensList.has_value()) { qCritical("Could not activeScreensList"); - return -1; + return static_cast(ScreenPlay::WallpaperExitCode::Invalid_ActiveScreensList); } auto installedType = ScreenPlay::InstalledType::InstalledType::Unknown; @@ -66,26 +66,26 @@ int main(int argc, char* argv[]) installedType = typeOpt.value(); } else { qCritical() << "Cannot parse Wallpaper type from value" << argumentList.at(6); - return -6; + return static_cast(ScreenPlay::WallpaperExitCode::Invalid_InstalledType); } bool okParseCheckWallpaperVisible = false; const bool checkWallpaperVisible = argumentList.at(7).toInt(&okParseCheckWallpaperVisible); if (!okParseCheckWallpaperVisible) { qCritical("Could not parse checkWallpaperVisible"); - return -5; + return static_cast(ScreenPlay::WallpaperExitCode::Invalid_CheckWallpaperVisible); } bool okParseVolume = 0.0f; const float volume = argumentList.at(4).toFloat(&okParseVolume); if (!okParseVolume) { qCritical("Could not parse Volume"); - return -6; + return static_cast(ScreenPlay::WallpaperExitCode::Invalid_Volume); } QString appID = argumentList.at(3); if (!appID.startsWith("appID=")) { qCritical("Invalid appID"); - return -6; + return static_cast(ScreenPlay::WallpaperExitCode::Invalid_AppID); } appID = appID.remove("appID="); @@ -100,11 +100,11 @@ int main(int argc, char* argv[]) } const auto setupStatus = window.setup(); - if (setupStatus != BaseWindow::ExitCode::Success) { + if (setupStatus != ScreenPlay::WallpaperExitCode::Ok) { return static_cast(setupStatus); } const auto startStatus = window.start(); - if (startStatus != BaseWindow::ExitCode::Success) { + if (startStatus != ScreenPlay::WallpaperExitCode::Ok) { return static_cast(startStatus); } return app.exec(); diff --git a/ScreenPlayWallpaper/qml/Wallpaper.qml b/ScreenPlayWallpaper/qml/Wallpaper.qml index c05f372a..d822ae73 100644 --- a/ScreenPlayWallpaper/qml/Wallpaper.qml +++ b/ScreenPlayWallpaper/qml/Wallpaper.qml @@ -11,6 +11,7 @@ Rectangle { property bool canFadeByWallpaperFillMode: true function init() { + fadeInImageSetup() switch (Wallpaper.type) { case InstalledType.VideoWallpaper: if (Wallpaper.videoCodec === VideoCodec.Unknown) { @@ -31,7 +32,6 @@ Rectangle { loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml" } - fadeIn() break case InstalledType.HTMLWallpaper: loader.setSource( @@ -43,7 +43,6 @@ Rectangle { break case InstalledType.QMLWallpaper: loader.source = Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) - fadeIn() break case InstalledType.WebsiteWallpaper: loader.setSource( @@ -51,7 +50,6 @@ Rectangle { { "url": Wallpaper.projectSourceFileAbsolute }) - fadeIn() break case InstalledType.GifWallpaper: loader.setSource( @@ -59,116 +57,18 @@ Rectangle { "source": Qt.resolvedUrl( Wallpaper.projectSourceFileAbsolute) }) - fadeIn() break } } - function fadeIn() { - Wallpaper.setVisible(true) - if (canFadeByWallpaperFillMode && Wallpaper.canFade) - imgCover.state = "hideDefaultBackgroundImage" - else - imgCover.opacity = 0 - } - - anchors.fill: parent - color: { - if (Qt.platform.os !== "windows") - return "black" - else - return Wallpaper.windowsDesktopProperties.color - } - Component.onCompleted: { - init() - } - - Connections { - function onQmlExit() { - if (canFadeByWallpaperFillMode && Wallpaper.canFade) - imgCover.state = "exit" - else - Wallpaper.terminate() - } - - function onQmlSceneValueReceived(key, value) { - var obj2 = 'import QtQuick; Item {Component.onCompleted: loader.item.' - + key + ' = ' + value + '; }' - var newObject = Qt.createQmlObject(obj2.toString(), root, "err") - newObject.destroy(10000) - } - - // Replace wallpaper with QML Scene - function onReloadQML(oldType) { - loader.sourceComponent = undefined - loader.source = "" - Wallpaper.clearComponentCache() - loader.source = Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) - } - - // Replace wallpaper with GIF - function onReloadGIF(oldType) { - init() - } - - // This function only gets called here (the same function - // is inside the MultimediaWebView.qml) when the previous Wallpaper type - // was not a video - function onReloadVideo(oldType) { - // We need to check if the old type - // was also Video not get called twice - if (oldType === InstalledType.VideoWallpaper) - return - - loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml" - } - - target: Wallpaper - } - - Loader { - id: loader - - anchors.fill: parent - // QML Engine deadlocks in 5.15.2 when a loader cannot load - // an item. QApplication::quit(); waits for the destruction forever. - //asynchronous: true - onStatusChanged: { - if (loader.status === Loader.Error) { - loader.source = "" - // Wallpaper.terminate(); - } - } - - Connections { - function onRequestFadeIn() { - fadeIn() - } - - ignoreUnknownSignals: true - target: loader.item - } - } - - Image { - id: imgCover - - state: "showDefaultBackgroundImage" - sourceSize.width: Wallpaper.width - sourceSize.height: Wallpaper.height - source: { - if (Qt.platform.os === "windows") - return Qt.resolvedUrl( - "file:///" + Wallpaper.windowsDesktopProperties.wallpaperPath) - else - return "" - } - - Component.onCompleted: { + function fadeInImageSetup(){ if (Qt.platform.os !== "windows") { root.canFadeByWallpaperFillMode = false return } + + imgCover.source = Qt.resolvedUrl("file:///" + Wallpaper.windowsDesktopProperties.wallpaperPath) + switch (Wallpaper.windowsDesktopProperties.wallpaperStyle) { case 10: imgCover.fillMode = Image.PreserveAspectCrop @@ -231,8 +131,99 @@ Rectangle { root.canFadeByWallpaperFillMode = false break } + } + + function fadeIn() { + Wallpaper.setVisible(true) + + if (canFadeByWallpaperFillMode && Wallpaper.canFade) + imgCover.state = "hideDefaultBackgroundImage" + else + imgCover.opacity = 0 + } + + anchors.fill: parent + color: { + if (Qt.platform.os !== "windows") + return "black" + else + return Wallpaper.windowsDesktopProperties.color + } + + Component.onCompleted: { + init() + } + + Connections { + function onQmlExit() { + if (canFadeByWallpaperFillMode && Wallpaper.canFade) + imgCover.state = "exit" + else + Wallpaper.terminate() } + function onQmlSceneValueReceived(key, value) { + var obj2 = 'import QtQuick; Item {Component.onCompleted: loader.item.' + + key + ' = ' + value + '; }' + var newObject = Qt.createQmlObject(obj2.toString(), root, "err") + newObject.destroy(10000) + } + + // Replace wallpaper with QML Scene + function onReloadQML(oldType) { + loader.sourceComponent = undefined + loader.source = "" + Wallpaper.clearComponentCache() + loader.source = Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) + } + + // Replace wallpaper with GIF + function onReloadGIF(oldType) { + init() + } + + // This function only gets called here (the same function + // is inside the MultimediaWebView.qml) when the previous Wallpaper type + // was not a video + function onReloadVideo(oldType) { + // We need to check if the old type + // was also Video not get called twice + if (oldType === InstalledType.VideoWallpaper) + return + + loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml" + } + + target: Wallpaper + } + + + Loader { + id: loader + anchors.fill: parent + // QML Engine deadlocks in 5.15.2 when a loader cannot load + // an item. QApplication::quit(); waits for the destruction forever. + //asynchronous: true + onStatusChanged: { + if (loader.status === Loader.Ready ) { + if(loader.item.ready) + root.fadeIn() + } + if (loader.status === Loader.Error) { + loader.source = "" + imgCover.state = "exit" + } + } + + + } + + Image { + id: imgCover + state: "showDefaultBackgroundImage" + sourceSize.width: Wallpaper.width + sourceSize.height: Wallpaper.height + anchors { top: parent.top left: parent.left diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index 12c3aa3e..b2c0cfab 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -38,20 +38,20 @@ BaseWindow::BaseWindow() setOSVersion(QSysInfo::productVersion()); } -BaseWindow::ExitCode BaseWindow::setup() +ScreenPlay::WallpaperExitCode BaseWindow::setup() { if (projectPath() == "test") { setType(ScreenPlay::InstalledType::InstalledType::QMLWallpaper); setProjectSourceFileAbsolute({ "qrc:/qml/ScreenPlayWallpaper/qml/Test.qml" }); setupLiveReloading(); - return BaseWindow::Success; + return ScreenPlay::WallpaperExitCode::Ok; } ScreenPlay::ProjectFile projectFile; projectFile.projectJsonFilePath = QFileInfo(projectPath() + "/project.json"); if (!projectFile.init()) { qWarning() << "Invalid project at " << projectPath(); - return BaseWindow::ParsingError; + return ScreenPlay::WallpaperExitCode::Invalid_Setup_ProjectParsingError; } setProjectSourceFile(projectFile.file); @@ -68,13 +68,12 @@ BaseWindow::ExitCode BaseWindow::setup() // directly without an running ScreenPlay if (!debugMode()) { m_sdk = std::make_unique(appID(), QVariant::fromValue(type()).toString()); - connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &BaseWindow::destroyThis); connect(m_sdk.get(), &ScreenPlaySDK::incommingMessage, this, &BaseWindow::messageReceived); connect(m_sdk.get(), &ScreenPlaySDK::replaceWallpaper, this, &BaseWindow::replaceWallpaper); sdk()->start(); } - return BaseWindow::Success; + return ScreenPlay::WallpaperExitCode::Ok; } /*! diff --git a/ScreenPlayWallpaper/src/basewindow.h b/ScreenPlayWallpaper/src/basewindow.h index aa1c4f7b..89668b69 100644 --- a/ScreenPlayWallpaper/src/basewindow.h +++ b/ScreenPlayWallpaper/src/basewindow.h @@ -15,7 +15,7 @@ #include #include "ScreenPlayUtil/util.h" - +#include "ScreenPlayUtil/exitcodes.h" #include "ScreenPlaySDK/screenplaysdk.h" #include @@ -26,16 +26,9 @@ class BaseWindow : public QObject { public: BaseWindow(); - enum ExitCode { - Success = 0, - ParsingError = 1, - Error = 3, - }; - Q_ENUM(ExitCode) + virtual ScreenPlay::WallpaperExitCode setup() final; - virtual BaseWindow::ExitCode setup() final; - - virtual BaseWindow::ExitCode start() = 0; + virtual ScreenPlay::WallpaperExitCode start() = 0; Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged) @@ -330,7 +323,7 @@ public slots: private: void setupLiveReloading(); -private: +protected: bool m_checkWallpaperVisible { false }; bool m_visualsPaused { false }; bool m_loops { true }; diff --git a/ScreenPlayWallpaper/src/macwindow.cpp b/ScreenPlayWallpaper/src/macwindow.cpp index 69cdbe3e..83c09622 100644 --- a/ScreenPlayWallpaper/src/macwindow.cpp +++ b/ScreenPlayWallpaper/src/macwindow.cpp @@ -2,7 +2,7 @@ #include "macwindow.h" -BaseWindow::ExitCode MacWindow::start() +ScreenPlay::WallpaperExitCode MacWindow::start() { auto* screen = QGuiApplication::screens().at(activeScreensList().at(0)); m_window.setGeometry(screen->geometry()); @@ -28,7 +28,7 @@ BaseWindow::ExitCode MacWindow::start() MacIntegration* macIntegration = new MacIntegration(this); macIntegration->SetBackgroundLevel(&m_window); - return BaseWindow::ExitCode::Success; + return ScreenPlay::WallpaperExitCode::Ok; } void MacWindow::setVisible(bool show) diff --git a/ScreenPlayWallpaper/src/macwindow.h b/ScreenPlayWallpaper/src/macwindow.h index 299044cc..0000a556 100644 --- a/ScreenPlayWallpaper/src/macwindow.h +++ b/ScreenPlayWallpaper/src/macwindow.h @@ -19,7 +19,7 @@ class MacWindow : public BaseWindow { Q_OBJECT public: - BaseWindow::ExitCode start() override; + ScreenPlay::WallpaperExitCode start() override; signals: diff --git a/ScreenPlayWallpaper/src/winwindow.cpp b/ScreenPlayWallpaper/src/winwindow.cpp index 6c059e9c..f0bfde24 100644 --- a/ScreenPlayWallpaper/src/winwindow.cpp +++ b/ScreenPlayWallpaper/src/winwindow.cpp @@ -111,7 +111,7 @@ void WinWindow::setupWindowMouseHook() } } -BaseWindow::ExitCode WinWindow::start() +ScreenPlay::WallpaperExitCode WinWindow::start() { connect( &m_window, &QQuickView::statusChanged, this, [this](auto status) { @@ -121,6 +121,9 @@ BaseWindow::ExitCode WinWindow::start() }, Qt::QueuedConnection); auto* guiAppInst = dynamic_cast(QApplication::instance()); + if(!debugMode()){ + connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &WinWindow::destroyThis); + } connect(guiAppInst, &QApplication::screenAdded, this, &WinWindow::configureWindowGeometry); connect(guiAppInst, &QApplication::screenRemoved, this, &WinWindow::configureWindowGeometry); connect(guiAppInst, &QApplication::primaryScreenChanged, this, &WinWindow::configureWindowGeometry); @@ -136,7 +139,7 @@ BaseWindow::ExitCode WinWindow::start() m_windowHandle = reinterpret_cast(m_window.winId()); if (!IsWindow(m_windowHandle)) { qCritical("Could not get a valid window handle!"); - return BaseWindow::ExitCode::Error; + return ScreenPlay::WallpaperExitCode::Invalid_Start_Windows_HandleError; } qRegisterMetaType(); qRegisterMetaType(); @@ -155,7 +158,7 @@ BaseWindow::ExitCode WinWindow::start() setupWindowMouseHook(); }); - return BaseWindow::ExitCode::Success; + return ScreenPlay::WallpaperExitCode::Ok; } /*! @@ -174,12 +177,12 @@ void WinWindow::setVisible(bool show) } } } + /*! \brief This function fires a qmlExit() signal to the UI for it to handle nice fade out animation first. Then the UI is responsible for calling WinWindow::terminate(). */ - void WinWindow::destroyThis() { emit qmlExit(); @@ -371,9 +374,6 @@ bool WinWindow::hasWindowScaling() */ void WinWindow::configureWindowGeometry() { - qInfo() << "configureWindowGeometry"; - setVisible(false); - if (!searchWorkerWindowToParentTo()) { qFatal("No worker window found"); } diff --git a/ScreenPlayWallpaper/src/winwindow.h b/ScreenPlayWallpaper/src/winwindow.h index 1bee0fa7..01e577b6 100644 --- a/ScreenPlayWallpaper/src/winwindow.h +++ b/ScreenPlayWallpaper/src/winwindow.h @@ -28,7 +28,7 @@ class WinWindow : public BaseWindow { public: WindowsDesktopProperties* windowsDesktopProperties() const { return m_windowsDesktopProperties.get(); } - BaseWindow::ExitCode start() override; + ScreenPlay::WallpaperExitCode start() override; public slots: void setVisible(bool show) override; From 0669e2d1bf631a784136465288519e8eaa6c0d44 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 22 Jan 2023 16:27:59 +0100 Subject: [PATCH 09/56] Add explicit send quit command to connection Make it more robust instead of waiting for a timeout --- ScreenPlay/src/screenplaywallpaper.cpp | 6 ++++-- ScreenPlay/src/sdkconnection.cpp | 4 ++++ ScreenPlaySDK/src/screenplaysdk.cpp | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ScreenPlay/src/screenplaywallpaper.cpp b/ScreenPlay/src/screenplaywallpaper.cpp index 3a51cd06..fbe3e8e8 100644 --- a/ScreenPlay/src/screenplaywallpaper.cpp +++ b/ScreenPlay/src/screenplaywallpaper.cpp @@ -149,9 +149,11 @@ void ScreenPlayWallpaper::close() return; } - if (m_connection->close()) { - m_isExiting = true; + if (!m_connection->close()) { + qCritical() << "Cannot close wallpaper!"; + return; } + m_isExiting = true; } /*! \brief Prints the exit code if != 0. diff --git a/ScreenPlay/src/sdkconnection.cpp b/ScreenPlay/src/sdkconnection.cpp index dd1c1cac..5652b401 100644 --- a/ScreenPlay/src/sdkconnection.cpp +++ b/ScreenPlay/src/sdkconnection.cpp @@ -113,6 +113,10 @@ bool ScreenPlay::SDKConnection::close() qWarning() << "Cannot close invalid socket."; return false; } + QJsonObject obj; + obj.insert("command", "quit"); + m_socket->write(QByteArray(QJsonDocument(obj).toJson(QJsonDocument::Compact))); + m_socket->flush(); qInfo() << "Close " << m_type << m_appID << m_socket->state(); m_socket->disconnectFromServer(); diff --git a/ScreenPlaySDK/src/screenplaysdk.cpp b/ScreenPlaySDK/src/screenplaysdk.cpp index 4d088bea..6a982053 100644 --- a/ScreenPlaySDK/src/screenplaysdk.cpp +++ b/ScreenPlaySDK/src/screenplaysdk.cpp @@ -32,6 +32,9 @@ void ScreenPlaySDK::start() connect(&m_socket, &QLocalSocket::connected, this, &ScreenPlaySDK::connected); connect(&m_socket, &QLocalSocket::disconnected, this, &ScreenPlaySDK::disconnected); connect(&m_socket, &QLocalSocket::readyRead, this, &ScreenPlaySDK::readyRead); + connect(&m_socket, &QLocalSocket::errorOccurred, this, [this](){ + emit disconnected(); + }); m_socket.connectToServer("ScreenPlay"); if (!m_socket.waitForConnected(1000)){ From ae845d2604db169c5178c4f9c58f237354a7ba2d Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 22 Jan 2023 16:28:15 +0100 Subject: [PATCH 10/56] Add missing include --- ScreenPlayWallpaper/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index 4747c55b..c1a78244 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -6,6 +6,7 @@ #include #include "ScreenPlayUtil/util.h" +#include "ScreenPlayUtil/exitcodes.h" #if defined(Q_OS_WIN) #include "src/winwindow.h" From d06f5b04c14e85a6bb24413dd2a012a82eb1f5dc Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 22 Jan 2023 16:28:41 +0100 Subject: [PATCH 11/56] Add fadeIn workaround #2 --- ScreenPlayWallpaper/qml/MultimediaView.qml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ScreenPlayWallpaper/qml/MultimediaView.qml b/ScreenPlayWallpaper/qml/MultimediaView.qml index bf1f11d2..a957d158 100644 --- a/ScreenPlayWallpaper/qml/MultimediaView.qml +++ b/ScreenPlayWallpaper/qml/MultimediaView.qml @@ -24,7 +24,7 @@ Item { onIsPlayingChanged: isPlaying ? mediaPlayer.play() : mediaPlayer.pause() property bool isWindows: Qt.platform.os === "windows" - signal requestFadeIn + property bool ready: false property string source: Wallpaper.projectSourceFileAbsolute onSourceChanged: { @@ -36,10 +36,11 @@ Item { MediaPlayer { id: mediaPlayer - Component.onCompleted: { - mediaPlayer.play() - root.requestFadeIn() - } + onPlaybackStateChanged:{ + if( mediaPlayer.playbackState == MediaPlayer.PlayingState){ + root.ready = true + } + } loops: root.loops ? MediaPlayer.Infinite : 1 videoOutput: vo audioOutput: ao From 97b05c5ff9813f716861f0dee099ed4886925aff Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 22 Jan 2023 16:29:20 +0100 Subject: [PATCH 12/56] Refactor qml format script Lets not add the changes now, but later, because this was a flyby work. --- Tools/defines.py | 16 +++++++++++----- Tools/format_util.py | 28 +++------------------------- Tools/qml_format.py | 10 +++------- 3 files changed, 17 insertions(+), 37 deletions(-) diff --git a/Tools/defines.py b/Tools/defines.py index 2bfbe9c8..b15c60b2 100644 --- a/Tools/defines.py +++ b/Tools/defines.py @@ -6,11 +6,6 @@ from sys import stdout stdout.reconfigure(encoding='utf-8') -VCPKG_VERSION = "2871ddd" # Master 11.11.2022 -QT_VERSION = "6.4.2" if sys.platform != "darwin" else "6.3.2" -QT_IFW_VERSION = "4.5" -SCREENPLAY_VERSION = "0.15.0-RC4" -QT_PATH = Path.cwd().parent.parent.joinpath("aqt") # Defined by Qt if sys.platform == "win32": OS = "windows" @@ -22,5 +17,16 @@ elif sys.platform == "linux": OS = "linux" QT_PLATFORM = "gcc_64" +SCREENPLAY_VERSION = "0.15.0-RC4" + + +QT_PATH = Path.cwd().parent.parent.joinpath("aqt") +QT_VERSION = "6.4.2" if sys.platform != "darwin" else "6.3.2" +QT_BIN_PATH = QT_PATH.joinpath(f"{QT_VERSION}/{QT_PLATFORM}/bin") +QT_TOOLS_PATH = QT_PATH.joinpath("Tools/") +QT_IFW_VERSION = "4.5" + +VCPKG_VERSION = "2871ddd" # Master 11.11.2022 + PYTHON_EXECUTABLE = "python" if sys.platform == "win32" else "python3" FFMPEG_VERSION = "5.0.1" \ No newline at end of file diff --git a/Tools/format_util.py b/Tools/format_util.py index 9592670a..15f91f40 100644 --- a/Tools/format_util.py +++ b/Tools/format_util.py @@ -12,7 +12,7 @@ from sys import stdout stdout.reconfigure(encoding='utf-8') -def find_all_files(path) -> []: +def find_all_files(path): file_list = [] for root, dirnames, files in os.walk(path): for filename in files: @@ -20,7 +20,7 @@ def find_all_files(path) -> []: return file_list -def find_all_git_staged_files() -> []: +def find_all_git_staged_files(): process = subprocess.run("git diff --name-only --staged", capture_output=True, shell=True) out = process.stdout.decode("utf-8") @@ -28,7 +28,7 @@ def find_all_git_staged_files() -> []: return out -def find_files(file_endings_tuple, path="", git_staged_only=False) -> []: +def find_files(file_endings_tuple, path="", git_staged_only=False): file_list = [] # Get the root folder by moving one up root = Path(__file__).parent.absolute() @@ -71,25 +71,3 @@ def check_git_exit(caller_name): # print(out) sys.exit(1) - -def find_absolute_qt_path(qt_version) -> os.path: - compiler = "" - if os.name != 'nt': - print("find_absolute_qt_path is only implemented for Windows!") - sys.exit(1) - - compiler = "msvc2019_64" - - qt_base_path = "C:\\Qt" - if not os.path.exists(qt_base_path): - print("No suitable Qt version found! Searching for version %s" % qt_version) - print("Path searches the root Qt version folder like: C:/Qt/6.0.0/msvc2019_64") - sys.exit(1) - - absolute_qt_path = os.path.join(qt_base_path, qt_version) - if os.path.exists(absolute_qt_path): - return os.path.join(absolute_qt_path, compiler) - else: - print("No suitable Qt version found! Searching for version %s" % qt_version) - print("Path searches the root Qt version folder like: C:/Qt/6.0.0/msvc2019_64") - sys.exit(1) diff --git a/Tools/qml_format.py b/Tools/qml_format.py index 0ac0d6b2..ab0e94e5 100644 --- a/Tools/qml_format.py +++ b/Tools/qml_format.py @@ -4,10 +4,10 @@ import os import subprocess import argparse import sys +import defines from format_util import find_files from format_util import check_git_exit from format_util import execute_threaded -from format_util import find_absolute_qt_path from sys import stdout stdout.reconfigure(encoding='utf-8') @@ -17,8 +17,8 @@ def format_file_function(file): executable = "qmlformat" if os.name == 'nt': executable = "qmlformat.exe" - qt_bin_path = os.path.join(find_absolute_qt_path("6.1.0"), "bin") - executable = os.path.join(qt_bin_path, executable) + qt_bin_path = defines.QT_BIN_PATH + executable = qt_bin_path.joinpath(executable) process = subprocess.run( "%s -i %s" % (executable, file), capture_output=True, shell=True) @@ -26,10 +26,6 @@ def format_file_function(file): def main(git_staged_only=False): - if "" == find_absolute_qt_path("6.1.0"): - print("No suitable qt version found!") - sys.exit(1) - file_list = find_files(('.qml'), os.path.abspath(os.path.join(os.getcwd(), "../")), git_staged_only) execute_threaded(file_list, format_file_function) if not git_staged_only: From 7b8cea1a3a9875192d3fe353d09e7a26c504ba13 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 26 Jan 2023 12:10:12 +0100 Subject: [PATCH 13/56] Default to debug console on start --- .vscode/launch.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c81bfc42..8d32a568 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "console": false, + "internalConsoleOptions": "openOnSessionStart", "windows": { "environment": [ { @@ -35,7 +35,7 @@ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "console": false, + "internalConsoleOptions": "openOnSessionStart", "windows": { "environment": [ { @@ -59,7 +59,7 @@ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "console": false, + "internalConsoleOptions": "openOnSessionStart", "windows": { "environment": [ { @@ -83,7 +83,7 @@ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "console": false, + "internalConsoleOptions": "openOnSessionStart", "windows": { "environment": [ { From 33f58a93644be80a31c6749f123b64d99d5df79b Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 26 Jan 2023 13:13:04 +0100 Subject: [PATCH 14/56] Add Widgets launch option --- .vscode/launch.json | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 8d32a568..a1c5c1f3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -99,6 +99,30 @@ "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_RelWithDebInfo/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", "type": "cppdbg" } + }, + { + "name": "ScreenPlayWidget Debug", + "request": "launch", + "type": "cppvsdbg", // Must be set otherwise VSCode does not know we want to debug c++ + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "internalConsoleOptions": "openOnSessionStart", + "windows": { + "environment": [ + { + "name": "Path", + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + } + ], + "type": "cppvsdbg", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlayWidget.exe" + }, + "osx": { + "MIMode": "lldb", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_Debug/bin/ScreenPlayWidget.app/Contents/MacOS/ScreenPlayWidget", + "type": "cppdbg" + } } ] } \ No newline at end of file From d1758d16a635e48aa0f31c9d5850d9e0c4566d61 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 26 Jan 2023 13:13:22 +0100 Subject: [PATCH 15/56] Add background to default widget code --- ScreenPlay/qml/Create/WizardsFiles/QMLWidgetMain.qml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ScreenPlay/qml/Create/WizardsFiles/QMLWidgetMain.qml b/ScreenPlay/qml/Create/WizardsFiles/QMLWidgetMain.qml index a5fad5f2..1c7c35a9 100644 --- a/ScreenPlay/qml/Create/WizardsFiles/QMLWidgetMain.qml +++ b/ScreenPlay/qml/Create/WizardsFiles/QMLWidgetMain.qml @@ -5,8 +5,15 @@ Item { implicitWidth: 300 implicitHeight: 200 + Rectangle { + id: background + anchors.fill:parent + opacity: 0.9 + color: "#333333" + } + Text { - id: name + id: text text: qsTr("My Widget 🚀") anchors.centerIn: parent } From f4800ef56302e5dadecbbaea28e4cb4afc3a604b Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 26 Jan 2023 13:14:23 +0100 Subject: [PATCH 16/56] Fix making description optional This is currently not even set in the wizards... --- ScreenPlayUtil/src/projectfile.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/ScreenPlayUtil/src/projectfile.cpp b/ScreenPlayUtil/src/projectfile.cpp index d84c141e..63ff67b0 100644 --- a/ScreenPlayUtil/src/projectfile.cpp +++ b/ScreenPlayUtil/src/projectfile.cpp @@ -23,10 +23,6 @@ bool ProjectFile::init() return false; // Required: - if (!obj.contains("description")) - return false; - description = obj.value("description").toString(); - if (!obj.contains("file")) return false; file = obj.value("file").toString(); @@ -38,7 +34,17 @@ bool ProjectFile::init() if (!obj.contains("type")) return false; + auto typeParsed = ScreenPlayUtil::getInstalledTypeFromString(obj.value("type").toString()); + if (!typeParsed) { + qWarning() << "Type could not parsed from: " << *typeParsed; + return false; + } + type = typeParsed.value(); + // Optional: + if (!obj.contains("description")) + description = obj.value("description").toString(); + if (obj.contains("previewGIF")) previewGIF = obj.value("previewGIF").toString(); @@ -51,10 +57,8 @@ bool ProjectFile::init() if (obj.contains("previewThumbnail")) { preview = obj.value("previewThumbnail").toString(); } else { - if (!obj.contains("preview")) { - return false; - } - preview = obj.value("preview").toString(); + if (obj.contains("preview")) + preview = obj.value("preview").toString(); } if (obj.contains("tags")) { @@ -68,13 +72,7 @@ bool ProjectFile::init() } } - auto typeParsed = ScreenPlayUtil::getInstalledTypeFromString(obj.value("type").toString()); - if (!typeParsed) { - qWarning() << "Type could not parsed from: " << *typeParsed; - return false; - } - type = typeParsed.value(); if (type == InstalledType::InstalledType::GifWallpaper) { preview = previewGIF; } From 71b69e9f0d3df6d9a9525e3a4d6e160bfd3345c1 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 26 Jan 2023 13:15:46 +0100 Subject: [PATCH 17/56] Add missing codec warning --- ScreenPlayUtil/src/projectfile.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ScreenPlayUtil/src/projectfile.cpp b/ScreenPlayUtil/src/projectfile.cpp index d84c141e..7b45fbdb 100644 --- a/ScreenPlayUtil/src/projectfile.cpp +++ b/ScreenPlayUtil/src/projectfile.cpp @@ -95,8 +95,10 @@ bool ProjectFile::init() qWarning("No videoCodec was specified inside the json object!"); if (file.endsWith(".mp4")) { videoCodec = ScreenPlay::VideoCodec::VideoCodec::H264; + qWarning("Eyeball to h264 because of .mp4"); } else if (file.endsWith(".webm")) { videoCodec = ScreenPlay::VideoCodec::VideoCodec::VP8; + qWarning("Eyeball to VP8 because of .webm"); } } From a0b71170cb13f43d7fada1231d11d387ecd44128 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 26 Jan 2023 13:59:36 +0100 Subject: [PATCH 18/56] Re add visualizerFile --- .vscode/launch.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index a1c5c1f3..be4ae1ca 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,6 +12,8 @@ "cwd": "${workspaceFolder}", "environment": [], "internalConsoleOptions": "openOnSessionStart", + "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml", + "showDisplayString": true, "windows": { "environment": [ { @@ -36,6 +38,8 @@ "cwd": "${workspaceFolder}", "environment": [], "internalConsoleOptions": "openOnSessionStart", + "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml", + "showDisplayString": true, "windows": { "environment": [ { @@ -84,6 +88,8 @@ "cwd": "${workspaceFolder}", "environment": [], "internalConsoleOptions": "openOnSessionStart", + "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml", + "showDisplayString": true, "windows": { "environment": [ { @@ -108,6 +114,8 @@ "cwd": "${workspaceFolder}", "environment": [], "internalConsoleOptions": "openOnSessionStart", + "visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml", + "showDisplayString": true, "windows": { "environment": [ { From 3f99f934a97cd3509b7eda370840ee78fecb990e Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 26 Jan 2023 14:24:45 +0100 Subject: [PATCH 19/56] Add missing quit msg implementation for osx --- ScreenPlayWallpaper/src/macwindow.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ScreenPlayWallpaper/src/macwindow.cpp b/ScreenPlayWallpaper/src/macwindow.cpp index 83c09622..41b5c17b 100644 --- a/ScreenPlayWallpaper/src/macwindow.cpp +++ b/ScreenPlayWallpaper/src/macwindow.cpp @@ -8,6 +8,10 @@ ScreenPlay::WallpaperExitCode MacWindow::start() m_window.setGeometry(screen->geometry()); qmlRegisterSingletonInstance("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); + + if(!debugMode()){ + connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &MacWindow::destroyThis); + } QDir workingDir(QGuiApplication::instance()->applicationDirPath()); workingDir.cdUp(); From 64d2c3adb5825a6ce22f18c26ba3981f2c108acb Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 27 Jan 2023 09:01:37 +0100 Subject: [PATCH 20/56] Bump to Qt 6.5.0 and use FFMPEG FFMPEG will become default in 6.6.0 anyways and this fixes the broken rendering on osx and performs better on my AMD Vega VII on Windows --- .vscode/launch.json | 45 ++++++++++++++++++------------------ CMakePresets.json | 30 ++++++++++++------------ ScreenPlay/main.cpp | 1 + ScreenPlayWallpaper/main.cpp | 5 ++-- ScreenPlayWidget/main.cpp | 1 + Tools/defines.py | 2 +- 6 files changed, 43 insertions(+), 41 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index be4ae1ca..3518b41d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,16 +18,16 @@ "environment": [ { "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" } ], "type": "cppvsdbg", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlay.exe" + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug/bin/ScreenPlay.exe" }, "osx": { "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_Debug/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", - "type": "cppdbg" + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", + "type": "lldb" } }, { @@ -44,16 +44,15 @@ "environment": [ { "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" } ], - "type": "cppvsdbg", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_RelWithDebInfo/bin/ScreenPlay.exe" + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_RelWithDebInfo/bin/ScreenPlay.exe" }, "osx": { "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_RelWithDebInfo/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", - "type": "cppdbg" + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_RelWithDebInfo/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", + "type": "lldb" } }, { @@ -68,16 +67,16 @@ "environment": [ { "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" } ], - "type": "cppvsdbg", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlayWallpaper.exe" + "type": "lldb", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug/bin/ScreenPlayWallpaper.exe" }, "osx": { "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_Debug/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", - "type": "cppdbg" + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", + "type": "lldb" } }, { @@ -94,16 +93,16 @@ "environment": [ { "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" } ], - "type": "cppvsdbg", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_RelWithDebInfo/bin/ScreenPlayWallpaper.exe" + "type": "lldb", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_RelWithDebInfo/bin/ScreenPlayWallpaper.exe" }, "osx": { "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_RelWithDebInfo/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", - "type": "cppdbg" + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_RelWithDebInfo/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", + "type": "lldb" } }, { @@ -120,16 +119,16 @@ "environment": [ { "name": "Path", - "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.4.2\\msvc2019_64\\qml\\;" + "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" } ], "type": "cppvsdbg", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug/bin/ScreenPlayWidget.exe" + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug/bin/ScreenPlayWidget.exe" }, "osx": { "MIMode": "lldb", - "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.3.2_Clang_Debug/bin/ScreenPlayWidget.app/Contents/MacOS/ScreenPlayWidget", - "type": "cppdbg" + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug/bin/ScreenPlayWidget.app/Contents/MacOS/ScreenPlayWidget", + "type": "lldb" } } ] diff --git a/CMakePresets.json b/CMakePresets.json index 2dd30d4a..c399fa0a 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -19,7 +19,7 @@ }, "environment" : { "qt_path": "${sourceDir}/../aqt", - "qt_version": "6.4.2", + "qt_version": "6.5.0", "VCToolsVersion": "14.34.31933", "WindowsSDKVersion" : "10.0.22621.0", "VCArch": "x64", @@ -46,24 +46,24 @@ } }, { - "name": "windows-debug-qt-6.4.2", + "name": "windows-debug-qt-6.5.0", "inherits": "default-windows", - "displayName": "MSVC K3000 Qt 6.4.2 Debug", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_MSVC_Debug", + "displayName": "MSVC K3000 Qt 6.5.0 Debug", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug", "environment": { - "qt_version": "6.4.2" + "qt_version": "6.5.0" }, "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } }, { - "name": "windows-relwithdebinfo-qt-6.4.2", + "name": "windows-relwithdebinfo-qt-6.5.0", "inherits": "default-windows", - "displayName": "MSVC K3000 Qt 6.4.2 RelWithDebInfo", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_MSVC_RelWithDebInfo", + "displayName": "MSVC K3000 Qt 6.5.0 RelWithDebInfo", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_MSVC_RelWithDebInfo", "environment": { - "qt_version": "6.4.2" + "qt_version": "6.5.0" }, "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" @@ -74,7 +74,7 @@ "displayName": "ScreenPlay 64bit Debug Linux", "description": "Linux only!", "generator": "Ninja", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_GCC_Debug", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_GCC_Debug", "condition": { "type": "equals", "lhs": "${hostSystemName}", @@ -91,7 +91,7 @@ "CMAKE_CXX_COMPILER": "g++", "CMAKE_C_COMPILER": "gcc", "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_PREFIX_PATH": "$env{qt_path}/6.4.2/gcc_64", + "CMAKE_PREFIX_PATH": "$env{qt_path}/6.5.0/gcc_64", "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/../vcpkg/scripts/buildsystems/vcpkg.cmake", "VCPKG_TARGET_TRIPLET": "x64-linux" } @@ -100,7 +100,7 @@ "name": "linux-relwithdebinfo", "displayName": "ScreenPlay 64bit RelWithDebInfo Linux", "inherits":"linux-debug", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_GCC_RelWithDebInfo", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_GCC_RelWithDebInfo", "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } @@ -110,7 +110,7 @@ "displayName": "ScreenPlay 64bit Debug osx", "description": "Osx only!", "generator": "Ninja", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.3.2_Clang_Debug", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug", "condition": { "type": "equals", "lhs": "${hostSystemName}", @@ -127,7 +127,7 @@ "CMAKE_CXX_COMPILER": "clang++", "CMAKE_C_COMPILER": "clang", "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_PREFIX_PATH": "$env{qt_path}/6.3.2/macos", + "CMAKE_PREFIX_PATH": "$env{qt_path}/6.5.0/macos", "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/../vcpkg/scripts/buildsystems/vcpkg.cmake" } }, @@ -135,7 +135,7 @@ "name": "osx-relwithdebinfo", "displayName": "ScreenPlay 64bit RelWithDebInfo osx", "inherits": "osx-debug", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.3.2_Clang_RelWithDebInfo", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_Clang_RelWithDebInfo", "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } diff --git a/ScreenPlay/main.cpp b/ScreenPlay/main.cpp index 0120e010..ca002e59 100644 --- a/ScreenPlay/main.cpp +++ b/ScreenPlay/main.cpp @@ -17,6 +17,7 @@ Q_IMPORT_QML_PLUGIN(ScreenPlayWorkshopPlugin) int main(int argc, char* argv[]) { + qputenv("QT_MEDIA_BACKEND","ffmpeg"); #if defined(Q_OS_WIN) // https://bugreports.qt.io/browse/QTBUG-72028 qputenv("QT_QPA_PLATFORM", "windows:darkmode=2"); diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index c1a78244..0a88e06b 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -20,7 +20,8 @@ Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin) Q_IMPORT_QML_PLUGIN(ScreenPlayWeatherPlugin) int main(int argc, char* argv[]) -{ +{ + qputenv("QT_MEDIA_BACKEND","ffmpeg"); QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QtWebEngineQuick::initialize(); @@ -42,7 +43,7 @@ int main(int argc, char* argv[]) if (argumentList.length() == 1) { window.setActiveScreensList({ 0 }); // window.setProjectPath("test"); - window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/1958068741"); + window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/19112022140605-Horde 1980"); window.setAppID("test"); window.setVolume(1); window.setFillMode("fill"); diff --git a/ScreenPlayWidget/main.cpp b/ScreenPlayWidget/main.cpp index a777bda3..a72a353b 100644 --- a/ScreenPlayWidget/main.cpp +++ b/ScreenPlayWidget/main.cpp @@ -14,6 +14,7 @@ Q_IMPORT_QML_PLUGIN(ScreenPlayWeatherPlugin) int main(int argc, char* argv[]) { + qputenv("QT_MEDIA_BACKEND","ffmpeg"); QtWebEngineQuick::initialize(); QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); diff --git a/Tools/defines.py b/Tools/defines.py index b15c60b2..f2f4910c 100644 --- a/Tools/defines.py +++ b/Tools/defines.py @@ -21,7 +21,7 @@ SCREENPLAY_VERSION = "0.15.0-RC4" QT_PATH = Path.cwd().parent.parent.joinpath("aqt") -QT_VERSION = "6.4.2" if sys.platform != "darwin" else "6.3.2" +QT_VERSION = "6.5.0" QT_BIN_PATH = QT_PATH.joinpath(f"{QT_VERSION}/{QT_PLATFORM}/bin") QT_TOOLS_PATH = QT_PATH.joinpath("Tools/") QT_IFW_VERSION = "4.5" From 4dab506b4150754b7e8f45c702933599de46ef44 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 27 Jan 2023 10:04:51 +0100 Subject: [PATCH 21/56] Fix linux compilation - Downgrade to stable Qt for now, because linux mirrors are not yet updated - Launch.json linux "type": "lldb" does not work for some reason... --- .vscode/launch.json | 22 ++++++++++- CMakePresets.json | 6 +-- ScreenPlayWallpaper/src/linuxwindow.cpp | 52 ++++++------------------- ScreenPlayWallpaper/src/linuxwindow.h | 12 +----- Tools/defines.py | 2 +- 5 files changed, 38 insertions(+), 56 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 3518b41d..802d17f9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -21,13 +21,17 @@ "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" } ], - "type": "cppvsdbg", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug/bin/ScreenPlay.exe" }, "osx": { "MIMode": "lldb", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", "type": "lldb" + }, + "linux": { + "MIMode": "lldb", + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_Debug/bin/ScreenPlay", + "type": "lldb" } }, { @@ -53,6 +57,10 @@ "MIMode": "lldb", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_RelWithDebInfo/bin/ScreenPlay.app/Contents/MacOS/ScreenPlay", "type": "lldb" + }, + "linux": { + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_RelWithDebInfo/bin/ScreenPlay", + "type": "lldb" } }, { @@ -77,6 +85,10 @@ "MIMode": "lldb", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", "type": "lldb" + }, + "linux": { + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_Debug/bin/ScreenPlayWallpaper", + "type": "lldb" } }, { @@ -103,6 +115,10 @@ "MIMode": "lldb", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_RelWithDebInfo/bin/ScreenPlayWallpaper.app/Contents/MacOS/ScreenPlayWallpaper", "type": "lldb" + }, + "linux": { + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_RelWithDebInfo/bin/ScreenPlayWallpaper", + "type": "lldb" } }, { @@ -129,6 +145,10 @@ "MIMode": "lldb", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_Clang_Debug/bin/ScreenPlayWidget.app/Contents/MacOS/ScreenPlayWidget", "type": "lldb" + }, + "linux": { + "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.4.2_GCC_Debug/bin/ScreenPlayWidget", + "type": "lldb" } } ] diff --git a/CMakePresets.json b/CMakePresets.json index c399fa0a..3f8e07f8 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -74,7 +74,7 @@ "displayName": "ScreenPlay 64bit Debug Linux", "description": "Linux only!", "generator": "Ninja", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_GCC_Debug", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_GCC_Debug", "condition": { "type": "equals", "lhs": "${hostSystemName}", @@ -91,7 +91,7 @@ "CMAKE_CXX_COMPILER": "g++", "CMAKE_C_COMPILER": "gcc", "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_PREFIX_PATH": "$env{qt_path}/6.5.0/gcc_64", + "CMAKE_PREFIX_PATH": "$env{qt_path}/6.4.2/gcc_64", "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/../vcpkg/scripts/buildsystems/vcpkg.cmake", "VCPKG_TARGET_TRIPLET": "x64-linux" } @@ -100,7 +100,7 @@ "name": "linux-relwithdebinfo", "displayName": "ScreenPlay 64bit RelWithDebInfo Linux", "inherits":"linux-debug", - "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_GCC_RelWithDebInfo", + "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.4.2_GCC_RelWithDebInfo", "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } diff --git a/ScreenPlayWallpaper/src/linuxwindow.cpp b/ScreenPlayWallpaper/src/linuxwindow.cpp index 92b79dd8..ee402bea 100644 --- a/ScreenPlayWallpaper/src/linuxwindow.cpp +++ b/ScreenPlayWallpaper/src/linuxwindow.cpp @@ -1,55 +1,25 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "linuxwindow.h" -LinuxWindow::LinuxWindow( - const QVector& activeScreensList, - const QString& projectFilePath, - const QString& appID, - const QString& volume, - const QString& fillmode, - const QString& type, - const bool checkWallpaperVisible, - const bool debugMode, - QObject* parent) - : BaseWindow( - activeScreensList, - projectFilePath, - type, - checkWallpaperVisible, - appID, - debugMode) + +ScreenPlay::WallpaperExitCode LinuxWindow::start() { - m_window.setWidth(1920); - m_window.setHeight(1080); + + if(!debugMode()){ + connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &LinuxWindow::destroyThis); + } + Qt::WindowFlags flags = m_window.flags(); + m_window.setFlags(flags | Qt::FramelessWindowHint | Qt::Desktop); + auto* screen = QGuiApplication::screens().at(activeScreensList().at(0)); + m_window.setGeometry(screen->geometry()); m_window.show(); - bool ok = false; - float volumeParsed = volume.toFloat(&ok); - if (!ok) { - qFatal("Could not parse volume"); - } - - setVolume(volumeParsed); - setFillMode(fillmode); - - // Ether for one Screen or for all - if ((QApplication::screens().length() == activeScreensList.length()) && (activeScreensList.length() != 1)) { - setupWallpaperForAllScreens(); - } else if (activeScreensList.length() == 1) { - setupWallpaperForOneScreen(activeScreensList.at(0)); - setCanFade(true); - } else if (activeScreensList.length() > 1) { - setupWallpaperForMultipleScreens(activeScreensList); - } - - setWidth(m_window.width()); - setHeight(m_window.height()); - m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); qmlRegisterSingletonInstance("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); m_window.setSource(QUrl("qrc:/ScreenPlayWallpaper/qml/Wallpaper.qml")); + return ScreenPlay::WallpaperExitCode::Ok; } void LinuxWindow::setupWallpaperForOneScreen(int activeScreen) diff --git a/ScreenPlayWallpaper/src/linuxwindow.h b/ScreenPlayWallpaper/src/linuxwindow.h index b5bd4d0b..74126521 100644 --- a/ScreenPlayWallpaper/src/linuxwindow.h +++ b/ScreenPlayWallpaper/src/linuxwindow.h @@ -17,17 +17,9 @@ class LinuxWindow : public BaseWindow { Q_OBJECT + public: - explicit LinuxWindow( - const QVector& activeScreensList, - const QString& projectFilePath, - const QString& appID, - const QString& volume, - const QString& fillmode, - const QString& type, - const bool checkWallpaperVisible, - const bool debugMode, - QObject* parent = nullptr); + ScreenPlay::WallpaperExitCode start() override; signals: diff --git a/Tools/defines.py b/Tools/defines.py index f2f4910c..c49773ce 100644 --- a/Tools/defines.py +++ b/Tools/defines.py @@ -21,7 +21,7 @@ SCREENPLAY_VERSION = "0.15.0-RC4" QT_PATH = Path.cwd().parent.parent.joinpath("aqt") -QT_VERSION = "6.5.0" +QT_VERSION = "6.5.0" if sys.platform != "linux" else "6.4.2" QT_BIN_PATH = QT_PATH.joinpath(f"{QT_VERSION}/{QT_PLATFORM}/bin") QT_TOOLS_PATH = QT_PATH.joinpath("Tools/") QT_IFW_VERSION = "4.5" From 37db908db13a24533e2d29f4b2344d1fc68d82c8 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 27 Jan 2023 11:12:45 +0100 Subject: [PATCH 22/56] Refactor linux X11 support Rename LinuxWindow to LinuxX11Window, for kde we use a desktop wallpaper plugin and for Wayland we need something else entirely. --- Docs/DeveloperSetup.md | 2 + ScreenPlay/main.cpp | 4 + ScreenPlayWallpaper/CMakeLists.txt | 6 +- ScreenPlayWallpaper/main.cpp | 12 +- ScreenPlayWallpaper/src/linuxwindow.cpp | 45 ------ ScreenPlayWallpaper/src/linuxx11window.cpp | 136 ++++++++++++++++++ .../src/{linuxwindow.h => linuxx11window.h} | 2 +- ScreenPlayWidget/main.cpp | 4 + 8 files changed, 159 insertions(+), 52 deletions(-) delete mode 100644 ScreenPlayWallpaper/src/linuxwindow.cpp create mode 100644 ScreenPlayWallpaper/src/linuxx11window.cpp rename ScreenPlayWallpaper/src/{linuxwindow.h => linuxx11window.h} (94%) diff --git a/Docs/DeveloperSetup.md b/Docs/DeveloperSetup.md index 1759d67d..2dfd86d2 100644 --- a/Docs/DeveloperSetup.md +++ b/Docs/DeveloperSetup.md @@ -20,6 +20,8 @@ 1. Install dependencies for Debian/Ubuntu: ``` bash sudo apt install build-essential git gpg ffmpeg mesa-common-dev libxkbcommon-* libfontconfig curl zip unzip tar cmake pkg-config apt-transport-https ca-certificates gnupg software-properties-common wget software-properties-common python3 python3-pip libgl1-mesa-dev lld ninja-build qml-module-qt-websockets qtwebengine5-* -y +# Only needed if we want x11 support +sudo apt-get install libx11-dev xserver-xorg-dev xorg-dev ``` ## MacOS diff --git a/ScreenPlay/main.cpp b/ScreenPlay/main.cpp index ca002e59..fd38753c 100644 --- a/ScreenPlay/main.cpp +++ b/ScreenPlay/main.cpp @@ -17,7 +17,11 @@ Q_IMPORT_QML_PLUGIN(ScreenPlayWorkshopPlugin) int main(int argc, char* argv[]) { + +#if !defined(Q_OS_LINUX) qputenv("QT_MEDIA_BACKEND","ffmpeg"); +#endif + #if defined(Q_OS_WIN) // https://bugreports.qt.io/browse/QTBUG-72028 qputenv("QT_QPA_PLATFORM", "windows:darkmode=2"); diff --git a/ScreenPlayWallpaper/CMakeLists.txt b/ScreenPlayWallpaper/CMakeLists.txt index 0bdec414..4bfcbf45 100644 --- a/ScreenPlayWallpaper/CMakeLists.txt +++ b/ScreenPlayWallpaper/CMakeLists.txt @@ -30,8 +30,8 @@ elseif(APPLE) src/macintegration.h src/macwindow.h) elseif(UNIX) - set(SOURCES src/linuxwindow.cpp) - set(HEADER src/linuxwindow.h) + set(SOURCES src/linuxx11window.cpp) + set(HEADER src/linuxx11window.h) endif() set(SOURCES ${SOURCES} main.cpp src/basewindow.cpp) @@ -81,6 +81,8 @@ target_link_libraries( Qt6::WebEngineQuick) if(WIN32) target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySysInfoplugin) +elseif(UNIX) + target_link_libraries( ${PROJECT_NAME} PRIVATE X11) endif() if(UNIX AND NOT APPLE) diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index 0a88e06b..85783472 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -12,7 +12,7 @@ #include "src/winwindow.h" Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin) #elif defined(Q_OS_LINUX) -#include "src/linuxwindow.h" +#include "src/linuxx11window.h" #elif defined(Q_OS_OSX) #include "src/macwindow.h" #endif @@ -21,7 +21,11 @@ Q_IMPORT_QML_PLUGIN(ScreenPlayWeatherPlugin) int main(int argc, char* argv[]) { + +#if !defined(Q_OS_LINUX) qputenv("QT_MEDIA_BACKEND","ffmpeg"); +#endif + QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QtWebEngineQuick::initialize(); @@ -30,7 +34,7 @@ int main(int argc, char* argv[]) #if defined(Q_OS_WIN) WinWindow window; #elif defined(Q_OS_LINUX) - LinuxWindow window; + LinuxX11Window window; #elif defined(Q_OS_OSX) MacWindow window; #endif @@ -42,8 +46,8 @@ int main(int argc, char* argv[]) // For testing purposes when starting the ScreenPlayWallpaper directly. if (argumentList.length() == 1) { window.setActiveScreensList({ 0 }); - // window.setProjectPath("test"); - window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/19112022140605-Horde 1980"); + window.setProjectPath("test"); + //window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/19112022140605-Horde 1980"); window.setAppID("test"); window.setVolume(1); window.setFillMode("fill"); diff --git a/ScreenPlayWallpaper/src/linuxwindow.cpp b/ScreenPlayWallpaper/src/linuxwindow.cpp deleted file mode 100644 index ee402bea..00000000 --- a/ScreenPlayWallpaper/src/linuxwindow.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only -#include "linuxwindow.h" - - -ScreenPlay::WallpaperExitCode LinuxWindow::start() -{ - - if(!debugMode()){ - connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &LinuxWindow::destroyThis); - } - - Qt::WindowFlags flags = m_window.flags(); - m_window.setFlags(flags | Qt::FramelessWindowHint | Qt::Desktop); - auto* screen = QGuiApplication::screens().at(activeScreensList().at(0)); - m_window.setGeometry(screen->geometry()); - m_window.show(); - - m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); - qmlRegisterSingletonInstance("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); - m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); - m_window.setSource(QUrl("qrc:/ScreenPlayWallpaper/qml/Wallpaper.qml")); - return ScreenPlay::WallpaperExitCode::Ok; -} - -void LinuxWindow::setupWallpaperForOneScreen(int activeScreen) -{ -} - -void LinuxWindow::setupWallpaperForAllScreens() -{ -} - -void LinuxWindow::setupWallpaperForMultipleScreens(const QVector& activeScreensList) -{ -} - -void LinuxWindow::setVisible(bool show) -{ - m_window.setVisible(show); -} - -void LinuxWindow::destroyThis() -{ - QCoreApplication::quit(); -} diff --git a/ScreenPlayWallpaper/src/linuxx11window.cpp b/ScreenPlayWallpaper/src/linuxx11window.cpp new file mode 100644 index 00000000..7005db69 --- /dev/null +++ b/ScreenPlayWallpaper/src/linuxx11window.cpp @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only +#include "linuxx11window.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WIDTH 512 +#define HEIGHT 384 +#define OPAQUE 0xffffffff +#define NAME "xwinwrap" +#define ATOM(a) XInternAtom(display, #a, False) + +ScreenPlay::WallpaperExitCode LinuxX11Window::start() +{ + + if (!debugMode()) { + connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &LinuxX11Window::destroyThis); + } + + qmlRegisterSingletonInstance("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); + + auto* screen = QGuiApplication::screens().at(0); + m_window.setGeometry(screen->geometry()); + Window window = m_window.winId(); + + Display* display = XOpenDisplay(""); + + XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0, + Always, 0L, 0L, False, StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask, 0L, False, 0, 0 }; + + XWMHints wmHint; + Atom xa; + int flags; + flags |= CWBorderPixel | CWColormap; + + XChangeWindowAttributes(display, window, flags, &attrs); + + wmHint.flags = InputHint | StateHint; + wmHint.input = true; + wmHint.initial_state = WithdrawnState; + + XSetWMProperties(display, window, NULL, NULL, NULL, + 0, NULL, &wmHint, NULL); + + xa = ATOM(_NET_WM_WINDOW_TYPE); + + Atom prop; + xa = ATOM(_MOTIF_WM_HINTS); + if (xa != None) { + long prop[5] = { 2, 0, 0, 0, 0 }; + XChangeProperty(display, window, xa, xa, 32, + PropModeReplace, (unsigned char*)prop, 5); + } + xa = ATOM(_NET_WM_STATE); + if (xa != None) { + Atom xa_prop = ATOM(_NET_WM_STATE_BELOW); + + XChangeProperty(display, window, xa, XA_ATOM, 32, + PropModeAppend, (unsigned char*)&xa_prop, 1); + } + xa = ATOM(_NET_WM_DESKTOP); + if (xa != None) { + CARD32 xa_prop = 0xFFFFFFFF; + + XChangeProperty(display, window, xa, XA_CARDINAL, 32, + PropModeAppend, (unsigned char*)&xa_prop, 1); + } + + xa = ATOM(_NET_WM_STATE); + if (xa != None) { + Atom xa_prop = ATOM(_NET_WM_STATE_STICKY); + + XChangeProperty(display, window, xa, XA_ATOM, 32, + PropModeAppend, (unsigned char*)&xa_prop, 1); + } + + xa = ATOM(_NET_WM_STATE); + if (xa != None) { + Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_TASKBAR); + + XChangeProperty(display, window, xa, XA_ATOM, 32, + PropModeAppend, (unsigned char*)&xa_prop, 1); + } + xa = ATOM(_NET_WM_STATE); + if (xa != None) { + Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_PAGER); + + XChangeProperty(display, window, xa, XA_ATOM, 32, + PropModeAppend, (unsigned char*)&xa_prop, 1); + } + + XMapWindow(display, window); + + XSync(display, window); + QDir workingDir(QGuiApplication::instance()->applicationDirPath()); + m_window.engine()->addImportPath(workingDir.path() + "/qml"); + m_window.setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); + m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); + m_window.setSource(QUrl("qrc:/qml/ScreenPlayWallpaper/qml/Wallpaper.qml")); + m_window.show(); + return ScreenPlay::WallpaperExitCode::Ok; +} + +void LinuxX11Window::setupWallpaperForOneScreen(int activeScreen) +{ +} + +void LinuxX11Window::setupWallpaperForAllScreens() +{ +} + +void LinuxX11Window::setupWallpaperForMultipleScreens(const QVector& activeScreensList) +{ +} + +void LinuxX11Window::setVisible(bool show) +{ + m_window.setVisible(show); +} + +void LinuxX11Window::destroyThis() +{ + QCoreApplication::quit(); +} diff --git a/ScreenPlayWallpaper/src/linuxwindow.h b/ScreenPlayWallpaper/src/linuxx11window.h similarity index 94% rename from ScreenPlayWallpaper/src/linuxwindow.h rename to ScreenPlayWallpaper/src/linuxx11window.h index 74126521..8c523942 100644 --- a/ScreenPlayWallpaper/src/linuxwindow.h +++ b/ScreenPlayWallpaper/src/linuxx11window.h @@ -15,7 +15,7 @@ #include "basewindow.h" -class LinuxWindow : public BaseWindow { +class LinuxX11Window : public BaseWindow { Q_OBJECT public: diff --git a/ScreenPlayWidget/main.cpp b/ScreenPlayWidget/main.cpp index a72a353b..bcc85c6f 100644 --- a/ScreenPlayWidget/main.cpp +++ b/ScreenPlayWidget/main.cpp @@ -14,7 +14,11 @@ Q_IMPORT_QML_PLUGIN(ScreenPlayWeatherPlugin) int main(int argc, char* argv[]) { + +#if !defined(Q_OS_LINUX) qputenv("QT_MEDIA_BACKEND","ffmpeg"); +#endif + QtWebEngineQuick::initialize(); QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); From 64cde196eb4c3fc97cebc4850659daf7fb927be6 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 28 Jan 2023 11:02:10 +0100 Subject: [PATCH 23/56] Update qdoc and formatting turns out we need the Q_PROPERTY setter in the cpp file for qdoc to recognize it --- Docs/config.qdocconf | 141 +++++++++++----- Docs/css/bootstrap.min.css | 7 +- Docs/js/bootstrap.bundle.min.js | 6 +- ScreenPlay/inc/public/ScreenPlay/app.h | 108 ++---------- ScreenPlay/main.cpp | 2 +- ScreenPlay/src/app.cpp | 158 ++++++++++++++++++ ScreenPlaySDK/src/screenplaysdk.cpp | 9 +- .../inc/public/ScreenPlayUtil/exitcodes.h | 16 +- ScreenPlayUtil/src/projectfile.cpp | 3 +- ScreenPlayWallpaper/main.cpp | 8 +- ScreenPlayWallpaper/src/basewindow.h | 4 +- ScreenPlayWallpaper/src/linuxx11window.h | 2 +- ScreenPlayWallpaper/src/macwindow.cpp | 7 +- ScreenPlayWallpaper/src/winwindow.cpp | 2 +- ScreenPlayWidget/main.cpp | 2 +- Tools/qdoc.py | 16 +- 16 files changed, 309 insertions(+), 182 deletions(-) diff --git a/Docs/config.qdocconf b/Docs/config.qdocconf index fdc786fe..28422e1b 100644 --- a/Docs/config.qdocconf +++ b/Docs/config.qdocconf @@ -2,70 +2,125 @@ # C:\Qt\6.1.0\msvc2019_64\bin\qdoc.exe config.qdocconf # in this directory. You can shift + right click in this explorer # window and select "Open PowerShell Window here" for this. - -include(C:\Qt\6.1.0\msvc2019_64\doc\global\qt-cpp-defines.qdocconf) -include(C:\Qt\6.1.0\msvc2019_64\doc\global\compat.qdocconf) -include(C:\Qt\6.1.0\msvc2019_64\doc\global\fileextensions.qdocconf) +QT_VER = 6.4.1 +QT_VERSION = 6.4.1 +include(C:\Qt\6.4.1\msvc2019_64\doc\global\qt-cpp-defines.qdocconf) +include(C:\Qt\6.4.1\msvc2019_64\doc\global\compat.qdocconf) +include(C:\Qt\6.4.1\msvc2019_64\doc\global\fileextensions.qdocconf) +include(C:\Qt\6.4.1\msvc2019_64\doc\global\macros.qdocconf) descripton = ScreenPlay is an open source cross plattform app for displaying Wallpaper, Widgets and AppDrawer. language = Cpp project = ScreenPlay # Source -sourcedirs += ../ScreenPlay/src/ -sourcedirs += ../ScreenPlay/ -sourcedirs += ../ScreenPlaySDK/ -sourcedirs += ../ScreenPlaySysInfo/ -sourcedirs += ../ScreenPlayWallpaper/src/ -sourcedirs += ../ScreenPlayWallpaper/ -sourcedirs += ../ScreenPlayWidget/src/ -sourcedirs += ../ScreenPlayWidget/ -sourcedirs += ../ScreenPlayShader/ -sourcedirs += ../ScreenPlayUtil/ -sourcedirs += ../ScreenPlayUtil/src/ +sourcedirs += ../ScreenPlay/ +sourcedirs += ../ScreenPlay/inc/public/ScreenPlay/ +sourcedirs += ../ScreenPlay/src/ + +sourcedirs += ../ScreenPlaySDK/ +sourcedirs += ../ScreenPlaySDK/inc/public/ScreenPlaySDK/ +sourcedirs += ../ScreenPlaySDK/src/ + +sourcedirs += ../ScreenPlayShader/ +sourcedirs += ../ScreenPlayShader/src/ + +sourcedirs += ../ScreenPlaySysInfo/ +sourcedirs += ../ScreenPlaySysInfo/src/ + +sourcedirs += ../ScreenPlayUtil/ +sourcedirs += ../ScreenPlayUtil/inc/public/ScreenPlayUtil/ +sourcedirs += ../ScreenPlayUtil/src/ + +sourcedirs += ../ScreenPlayWallpaper/ +sourcedirs += ../ScreenPlayWallpaper/src/ + +sourcedirs += ../ScreenPlayWeather/ +sourcedirs += ../ScreenPlayWeather/src/ + +sourcedirs += ../ScreenPlayWidget/ +sourcedirs += ../ScreenPlayWidget/src/ + +sourcedirs += ../ScreenPlayWorkshop/ +sourcedirs += ../ScreenPlayWorkshop/src/ # Header -headerdirs += ../ScreenPlay/src/ -headerdirs += ../ScreenPlay/ -headerdirs += ../ScreenPlaySDK/ -headerdirs += ../ScreenPlaySDK/inc/ -headerdirs += ../ScreenPlaySysInfo/ -headerdirs += ../ScreenPlayWallpaper/src/ -headerdirs += ../ScreenPlayWallpaper/ -headerdirs += ../ScreenPlayWidget/src/ -headerdirs += ../ScreenPlayWidget/ -headerdirs += ../ScreenPlayShader/ -headerdirs += ../ScreenPlayUtil/inc/ +headerdirs += ../ScreenPlay/ +headerdirs += ../ScreenPlay/inc/public/ScreenPlay/ +headerdirs += ../ScreenPlay/src/ + +headerdirs += ../ScreenPlaySDK/ +headerdirs += ../ScreenPlaySDK/inc/public/ScreenPlaySDK/ +headerdirs += ../ScreenPlaySDK/src/ + +headerdirs += ../ScreenPlayShader/ +headerdirs += ../ScreenPlayShader/src/ + +headerdirs += ../ScreenPlaySysInfo/ +headerdirs += ../ScreenPlaySysInfo/src/ + +headerdirs += ../ScreenPlayUtil/ +headerdirs += ../ScreenPlayUtil/inc/public/ScreenPlayUtil/ +headerdirs += ../ScreenPlayUtil/src/ + +headerdirs += ../ScreenPlayWallpaper/ +headerdirs += ../ScreenPlayWallpaper/src/ + +headerdirs += ../ScreenPlayWeather/ +headerdirs += ../ScreenPlayWeather/src/ + +headerdirs += ../ScreenPlayWidget/ +headerdirs += ../ScreenPlayWidget/src/ + +headerdirs += ../ScreenPlayWorkshop/ +headerdirs += ../ScreenPlayWorkshop/src/ # Include -includepaths += ../ScreenPlay/src/ includepaths += ../ScreenPlay/ +includepaths += ../ScreenPlay/inc/public/ScreenPlay/ +includepaths += ../ScreenPlay/src/ + includepaths += ../ScreenPlaySDK/ +includepaths += ../ScreenPlaySDK/inc/public/ScreenPlaySDK/ includepaths += ../ScreenPlaySDK/src/ -includepaths += ../ScreenPlaySysInfo/ -includepaths += ../ScreenPlayWallpaper/src/ -includepaths += ../ScreenPlayWallpaper/ -includepaths += ../ScreenPlayWidget/src/ -includepaths += ../ScreenPlayWidget/ + includepaths += ../ScreenPlayShader/ +includepaths += ../ScreenPlayShader/src/ + +includepaths += ../ScreenPlaySysInfo/ +includepaths += ../ScreenPlaySysInfo/src/ + includepaths += ../ScreenPlayUtil/ +includepaths += ../ScreenPlayUtil/inc/public/ScreenPlayUtil/ +includepaths += ../ScreenPlayUtil/src/ + +includepaths += ../ScreenPlayWallpaper/ +includepaths += ../ScreenPlayWallpaper/src/ + +includepaths += ../ScreenPlayWeather/ +includepaths += ../ScreenPlayWeather/src/ + +includepaths += ../ScreenPlayWidget/ +includepaths += ../ScreenPlayWidget/src/ + +includepaths += ../ScreenPlayWorkshop/ +includepaths += ../ScreenPlayWorkshop/src/ + # qt -includepaths += C:/Qt/6.1.0/msvc2019_64/include/ -includepaths += C:/Qt/6.1.0/msvc2019_64/include/QtCore/ -includepaths += C:/Qt/6.1.0/msvc2019_64/include/QtGui/ -includepaths += C:/Qt/6.1.0/msvc2019_64/include/QtQml/ -includepaths += C:/Qt/6.1.0/msvc2019_64/include/QtWebEngine/ -includepaths += C:/Qt/6.1.0/msvc2019_64/include/QtNetwork/ -includepaths += C:/Qt/6.1.0/msvc2019_64/include/QtQuick/ -includepaths += C:/Qt/6.1.0/msvc2019_64/include/QtQuickControls2/ - - +QT_INSTALL_HEADERS = C:/Qt/6.4.1/msvc2019_64/include/ +includepaths += C:/Qt/6.4.1/msvc2019_64/include/ +includepaths += C:/Qt/6.4.1/msvc2019_64/include/QtCore/ +includepaths += C:/Qt/6.4.1/msvc2019_64/include/QtGui/ +includepaths += C:/Qt/6.4.1/msvc2019_64/include/QtQml/ +includepaths += C:/Qt/6.4.1/msvc2019_64/include/QtWebEngine/ +includepaths += C:/Qt/6.4.1/msvc2019_64/include/QtNetwork/ +includepaths += C:/Qt/6.4.1/msvc2019_64/include/QtQuick/ +includepaths += C:/Qt/6.4.1/msvc2019_64/include/QtQuickControls2/ # Images imagedirs = ./images - # what kind of sources should be processed sources.fileextensions += "*.qdoc *.cpp *.qml" diff --git a/Docs/css/bootstrap.min.css b/Docs/css/bootstrap.min.css index 08ef66a2..596784f3 100644 --- a/Docs/css/bootstrap.min.css +++ b/Docs/css/bootstrap.min.css @@ -1,7 +1,6 @@ @charset "UTF-8";/*! - * Bootstrap v5.0.0 (https://getbootstrap.com/) - * Copyright 2011-2021 The Bootstrap Authors - * Copyright 2011-2021 Twitter, Inc. + * Bootstrap v5.3.0-alpha1 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0))}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-font-sans-serif);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x,.75rem);padding-left:var(--bs-gutter-x,.75rem);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x)/ -2);margin-left:calc(var(--bs-gutter-x)/ -2)}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x)/ 2);padding-left:calc(var(--bs-gutter-x)/ 2);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.3333333333%}.col-2{flex:0 0 auto;width:16.6666666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.3333333333%}.col-5{flex:0 0 auto;width:41.6666666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.3333333333%}.col-8{flex:0 0 auto;width:66.6666666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.3333333333%}.col-11{flex:0 0 auto;width:91.6666666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.3333333333%}.col-sm-2{flex:0 0 auto;width:16.6666666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.3333333333%}.col-sm-5{flex:0 0 auto;width:41.6666666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.3333333333%}.col-sm-8{flex:0 0 auto;width:66.6666666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.3333333333%}.col-sm-11{flex:0 0 auto;width:91.6666666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.3333333333%}.col-md-2{flex:0 0 auto;width:16.6666666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.3333333333%}.col-md-5{flex:0 0 auto;width:41.6666666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.3333333333%}.col-md-8{flex:0 0 auto;width:66.6666666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.3333333333%}.col-md-11{flex:0 0 auto;width:91.6666666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.3333333333%}.col-lg-2{flex:0 0 auto;width:16.6666666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.3333333333%}.col-lg-5{flex:0 0 auto;width:41.6666666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.3333333333%}.col-lg-8{flex:0 0 auto;width:66.6666666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.3333333333%}.col-lg-11{flex:0 0 auto;width:91.6666666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.3333333333%}.col-xl-2{flex:0 0 auto;width:16.6666666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.3333333333%}.col-xl-5{flex:0 0 auto;width:41.6666666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.3333333333%}.col-xl-8{flex:0 0 auto;width:66.6666666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.3333333333%}.col-xl-11{flex:0 0 auto;width:91.6666666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.3333333333%}.col-xxl-2{flex:0 0 auto;width:16.6666666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.3333333333%}.col-xxl-5{flex:0 0 auto;width:41.6666666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.3333333333%}.col-xxl-8{flex:0 0 auto;width:66.6666666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.3333333333%}.col-xxl-11{flex:0 0 auto;width:91.6666666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.3333333333%}.offset-xxl-2{margin-left:16.6666666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.3333333333%}.offset-xxl-5{margin-left:41.6666666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.3333333333%}.offset-xxl-8{margin-left:66.6666666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.3333333333%}.offset-xxl-11{margin-left:91.6666666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-bg:transparent;--bs-table-striped-color:#212529;--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:#212529;--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:#212529;--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#212529;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:last-child)>:last-child>*{border-bottom-color:currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-striped>tbody>tr:nth-of-type(odd){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg:#cfe2ff;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:#000;border-color:#bacbe6}.table-secondary{--bs-table-bg:#e2e3e5;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:#000;border-color:#cbccce}.table-success{--bs-table-bg:#d1e7dd;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:#000;border-color:#bcd0c7}.table-info{--bs-table-bg:#cff4fc;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:#000;border-color:#badce3}.table-warning{--bs-table-bg:#fff3cd;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:#000;border-color:#e6dbb9}.table-danger{--bs-table-bg:#f8d7da;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:#000;border-color:#dfc2c4}.table-light{--bs-table-bg:#f8f9fa;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:#000;border-color:#dfe0e1}.table-dark{--bs-table-bg:#212529;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:#fff;border-color:#373b3e}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not(:-moz-read-only){cursor:pointer}.form-control[type=file]:not(:disabled):not(:read-only){cursor:pointer}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:-moz-read-only{background-color:#e9ecef;opacity:1}.form-control:disabled,.form-control:read-only{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not(:-moz-read-only)::file-selector-button{background-color:#dde0e3}.form-control:hover:not(:disabled):not(:read-only)::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}}.form-control:hover:not(:disabled):not(:read-only)::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{max-width:3rem;height:auto;padding:.375rem}.form-control-color:not(:disabled):not(:-moz-read-only){cursor:pointer}.form-control-color:not(:disabled):not(:read-only){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.5em;border-radius:.25rem}.form-control-color::-webkit-color-swatch{height:1.5em;border-radius:.25rem}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #212529}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);padding:1rem .75rem}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .75rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#198754}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(25,135,84,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#198754;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#198754}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#198754}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#198754}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#198754}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group .form-control.is-valid,.input-group .form-select.is-valid,.was-validated .input-group .form-control:valid,.was-validated .input-group .form-select:valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#dc3545}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group .form-control.is-invalid,.input-group .form-select.is-invalid,.was-validated .input-group .form-control:invalid,.was-validated .input-group .form-select:invalid{z-index:3}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-primary:hover{color:#fff;background-color:#0b5ed7;border-color:#0a58ca}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#fff;background-color:#0b5ed7;border-color:#0a58ca;box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-check:active+.btn-primary,.btn-check:checked+.btn-primary,.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0a58ca;border-color:#0a53be}.btn-check:active+.btn-primary:focus,.btn-check:checked+.btn-primary:focus,.btn-primary.active:focus,.btn-primary:active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5c636a;border-color:#565e64}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#5c636a;border-color:#565e64;box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-check:active+.btn-secondary,.btn-check:checked+.btn-secondary,.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#565e64;border-color:#51585e}.btn-check:active+.btn-secondary:focus,.btn-check:checked+.btn-secondary:focus,.btn-secondary.active:focus,.btn-secondary:active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-success{color:#fff;background-color:#198754;border-color:#198754}.btn-success:hover{color:#fff;background-color:#157347;border-color:#146c43}.btn-check:focus+.btn-success,.btn-success:focus{color:#fff;background-color:#157347;border-color:#146c43;box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-check:active+.btn-success,.btn-check:checked+.btn-success,.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#146c43;border-color:#13653f}.btn-check:active+.btn-success:focus,.btn-check:checked+.btn-success:focus,.btn-success.active:focus,.btn-success:active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#198754;border-color:#198754}.btn-info{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-info:hover{color:#000;background-color:#31d2f2;border-color:#25cff2}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#31d2f2;border-color:#25cff2;box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-check:active+.btn-info,.btn-check:checked+.btn-info,.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#3dd5f3;border-color:#25cff2}.btn-check:active+.btn-info:focus,.btn-check:checked+.btn-info:focus,.btn-info.active:focus,.btn-info:active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-info.disabled,.btn-info:disabled{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-warning{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#000;background-color:#ffca2c;border-color:#ffc720}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#ffca2c;border-color:#ffc720;box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-check:active+.btn-warning,.btn-check:checked+.btn-warning,.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#ffcd39;border-color:#ffc720}.btn-check:active+.btn-warning:focus,.btn-check:checked+.btn-warning:focus,.btn-warning.active:focus,.btn-warning:active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#bb2d3b;border-color:#b02a37}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#fff;background-color:#bb2d3b;border-color:#b02a37;box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-check:active+.btn-danger,.btn-check:checked+.btn-danger,.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#b02a37;border-color:#a52834}.btn-check:active+.btn-danger:focus,.btn-check:checked+.btn-danger:focus,.btn-danger.active:focus,.btn-danger:active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-light{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:focus+.btn-light,.btn-light:focus{color:#000;background-color:#f9fafb;border-color:#f9fafb;box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-check:active+.btn-light,.btn-check:checked+.btn-light,.btn-light.active,.btn-light:active,.show>.btn-light.dropdown-toggle{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:active+.btn-light:focus,.btn-check:checked+.btn-light:focus,.btn-light.active:focus,.btn-light:active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-light.disabled,.btn-light:disabled{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-dark{color:#fff;background-color:#212529;border-color:#212529}.btn-dark:hover{color:#fff;background-color:#1c1f23;border-color:#1a1e21}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#1c1f23;border-color:#1a1e21;box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-check:active+.btn-dark,.btn-check:checked+.btn-dark,.btn-dark.active,.btn-dark:active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1a1e21;border-color:#191c1f}.btn-check:active+.btn-dark:focus,.btn-check:checked+.btn-dark:focus,.btn-dark.active:focus,.btn-dark:active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#212529;border-color:#212529}.btn-outline-primary{color:#0d6efd;border-color:#0d6efd}.btn-outline-primary:hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-check:active+.btn-outline-primary,.btn-check:checked+.btn-outline-primary,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show,.btn-outline-primary:active{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:active+.btn-outline-primary:focus,.btn-check:checked+.btn-outline-primary:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus,.btn-outline-primary:active:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#0d6efd;background-color:transparent}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-check:active+.btn-outline-secondary,.btn-check:checked+.btn-outline-secondary,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show,.btn-outline-secondary:active{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:active+.btn-outline-secondary:focus,.btn-check:checked+.btn-outline-secondary:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus,.btn-outline-secondary:active:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-success{color:#198754;border-color:#198754}.btn-outline-success:hover{color:#fff;background-color:#198754;border-color:#198754}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-check:active+.btn-outline-success,.btn-check:checked+.btn-outline-success,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show,.btn-outline-success:active{color:#fff;background-color:#198754;border-color:#198754}.btn-check:active+.btn-outline-success:focus,.btn-check:checked+.btn-outline-success:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus,.btn-outline-success:active:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#198754;background-color:transparent}.btn-outline-info{color:#0dcaf0;border-color:#0dcaf0}.btn-outline-info:hover{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-check:active+.btn-outline-info,.btn-check:checked+.btn-outline-info,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show,.btn-outline-info:active{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:active+.btn-outline-info:focus,.btn-check:checked+.btn-outline-info:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus,.btn-outline-info:active:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#0dcaf0;background-color:transparent}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-check:active+.btn-outline-warning,.btn-check:checked+.btn-outline-warning,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show,.btn-outline-warning:active{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:active+.btn-outline-warning:focus,.btn-check:checked+.btn-outline-warning:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus,.btn-outline-warning:active:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-check:active+.btn-outline-danger,.btn-check:checked+.btn-outline-danger,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show,.btn-outline-danger:active{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:active+.btn-outline-danger:focus,.btn-check:checked+.btn-outline-danger:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus,.btn-outline-danger:active:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-check:active+.btn-outline-light,.btn-check:checked+.btn-outline-light,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show,.btn-outline-light:active{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:active+.btn-outline-light:focus,.btn-check:checked+.btn-outline-light:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus,.btn-outline-light:active:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-dark{color:#212529;border-color:#212529}.btn-outline-dark:hover{color:#fff;background-color:#212529;border-color:#212529}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-check:active+.btn-outline-dark,.btn-check:checked+.btn-outline-dark,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show,.btn-outline-dark:active{color:#fff;background-color:#212529;border-color:#212529}.btn-check:active+.btn-outline-dark:focus,.btn-check:checked+.btn-outline-dark:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus,.btn-outline-dark:active:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#212529;background-color:transparent}.btn-link{font-weight:400;color:#0d6efd;text-decoration:underline}.btn-link:hover{color:#0a58ca}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropend,.dropstart,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid rgba(0,0,0,.15)}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#212529;text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#1e2125;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#0d6efd}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:focus,.dropdown-menu-dark .dropdown-item:hover{color:#fff;background-color:rgba(255,255,255,.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:#fff;background-color:#0d6efd}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem;color:#0d6efd;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:#0a58ca}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background:0 0;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6;isolation:isolate}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#0d6efd}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem;transition:box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.55)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.55)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.55);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.55)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.5rem 1rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.5rem;margin-bottom:-.5rem;margin-left:-.5rem;border-bottom:0}.card-header-pills{margin-right:-.5rem;margin-left:-.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:1rem;color:#212529;text-align:left;background-color:#fff;border:0;border-radius:0;overflow-anchor:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:#0c63e4;background-color:#e7f1ff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.125)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform .2s ease-in-out}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:#fff;border:1px solid rgba(0,0,0,.125)}.accordion-item:first-of-type{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.accordion-item:first-of-type .accordion-button{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:1rem;list-style:none}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#0d6efd;text-decoration:none;background-color:#fff;border:1px solid #dee2e6;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:#0a58ca;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;color:#0a58ca;background-color:#e9ecef;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;background-color:#fff;border-color:#dee2e6}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{color:#084298;background-color:#cfe2ff;border-color:#b6d4fe}.alert-primary .alert-link{color:#06357a}.alert-secondary{color:#41464b;background-color:#e2e3e5;border-color:#d3d6d8}.alert-secondary .alert-link{color:#34383c}.alert-success{color:#0f5132;background-color:#d1e7dd;border-color:#badbcc}.alert-success .alert-link{color:#0c4128}.alert-info{color:#055160;background-color:#cff4fc;border-color:#b6effb}.alert-info .alert-link{color:#04414d}.alert-warning{color:#664d03;background-color:#fff3cd;border-color:#ffecb5}.alert-warning .alert-link{color:#523e02}.alert-danger{color:#842029;background-color:#f8d7da;border-color:#f5c2c7}.alert-danger .alert-link{color:#6a1a21}.alert-light{color:#636464;background-color:#fefefe;border-color:#fdfdfe}.alert-light .alert-link{color:#4f5050}.alert-dark{color:#141619;background-color:#d3d3d4;border-color:#bcbebf}.alert-dark .alert-link{color:#101214}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#0d6efd;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#084298;background-color:#cfe2ff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#084298;background-color:#bacbe6}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#084298;border-color:#084298}.list-group-item-secondary{color:#41464b;background-color:#e2e3e5}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#41464b;background-color:#cbccce}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-success{color:#0f5132;background-color:#d1e7dd}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#0f5132;background-color:#bcd0c7}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#0f5132;border-color:#0f5132}.list-group-item-info{color:#055160;background-color:#cff4fc}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#055160;background-color:#badce3}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#055160;border-color:#055160}.list-group-item-warning{color:#664d03;background-color:#fff3cd}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#664d03;background-color:#e6dbb9}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#664d03;border-color:#664d03}.list-group-item-danger{color:#842029;background-color:#f8d7da}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#842029;background-color:#dfc2c4}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#842029;border-color:#842029}.list-group-item-light{color:#636464;background-color:#fefefe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#636464;background-color:#e5e5e5}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#636464;border-color:#636464}.list-group-item-dark{color:#141619;background-color:#d3d3d4}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#141619;background-color:#bebebf}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#141619;border-color:#141619}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#000;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:#000;text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:350px;max-width:100%;font-size:.875rem;pointer-events:auto;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);border-radius:.25rem}.toast:not(.showing):not(.show){opacity:0}.toast.hide{display:none}.toast-container{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:.75rem}.toast-header{display:flex;align-items:center;padding:.5rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-header .btn-close{margin-right:-.375rem;margin-left:.75rem}.toast-body{padding:.75rem;word-wrap:break-word}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1060;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[data-popper-placement^=right],.bs-tooltip-end{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[data-popper-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[data-popper-placement^=left],.bs-tooltip-start{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1070;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f0f0f0}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f0f0f0;border-bottom:1px solid #d8d8d8;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.offcanvas{position:fixed;bottom:0;z-index:1050;display:flex;flex-direction:column;max-width:100%;visibility:hidden;background-color:#fff;background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1rem}.offcanvas-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:1rem 1rem;overflow-y:auto}.offcanvas-start{top:0;left:0;width:400px;border-right:1px solid rgba(0,0,0,.2);transform:translateX(-100%)}.offcanvas-end{top:0;right:0;width:400px;border-left:1px solid rgba(0,0,0,.2);transform:translateX(100%)}.offcanvas-top{top:0;right:0;left:0;height:30vh;max-height:100%;border-bottom:1px solid rgba(0,0,0,.2);transform:translateY(-100%)}.offcanvas-bottom{right:0;left:0;height:30vh;max-height:100%;border-top:1px solid rgba(0,0,0,.2);transform:translateY(100%)}.offcanvas.show{transform:none}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#0d6efd}.link-primary:focus,.link-primary:hover{color:#0a58ca}.link-secondary{color:#6c757d}.link-secondary:focus,.link-secondary:hover{color:#565e64}.link-success{color:#198754}.link-success:focus,.link-success:hover{color:#146c43}.link-info{color:#0dcaf0}.link-info:focus,.link-info:hover{color:#3dd5f3}.link-warning{color:#ffc107}.link-warning:focus,.link-warning:hover{color:#ffcd39}.link-danger{color:#dc3545}.link-danger:focus,.link-danger:hover{color:#b02a37}.link-light{color:#f8f9fa}.link-light:focus,.link-light:hover{color:#f9fafb}.link-dark{color:#212529}.link-dark:focus,.link-dark:hover{color:#1a1e21}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio:calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio:calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:1px solid #dee2e6!important}.border-0{border:0!important}.border-top{border-top:1px solid #dee2e6!important}.border-top-0{border-top:0!important}.border-end{border-right:1px solid #dee2e6!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:1px solid #dee2e6!important}.border-start-0{border-left:0!important}.border-primary{border-color:#0d6efd!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#198754!important}.border-info{border-color:#0dcaf0!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#212529!important}.border-white{border-color:#fff!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{color:#0d6efd!important}.text-secondary{color:#6c757d!important}.text-success{color:#198754!important}.text-info{color:#0dcaf0!important}.text-warning{color:#ffc107!important}.text-danger{color:#dc3545!important}.text-light{color:#f8f9fa!important}.text-dark{color:#212529!important}.text-white{color:#fff!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-reset{color:inherit!important}.bg-primary{background-color:#0d6efd!important}.bg-secondary{background-color:#6c757d!important}.bg-success{background-color:#198754!important}.bg-info{background-color:#0dcaf0!important}.bg-warning{background-color:#ffc107!important}.bg-danger{background-color:#dc3545!important}.bg-light{background-color:#f8f9fa!important}.bg-dark{background-color:#212529!important}.bg-body{background-color:#fff!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:.25rem!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:.2rem!important}.rounded-2{border-radius:.25rem!important}.rounded-3{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-end{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-start{border-bottom-left-radius:.25rem!important;border-top-left-radius:.25rem!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} + */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text:#0a58ca;--bs-secondary-text:#6c757d;--bs-success-text:#146c43;--bs-info-text:#087990;--bs-warning-text:#997404;--bs-danger-text:#b02a37;--bs-light-text:#6c757d;--bs-dark-text:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#f8f9fa;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#e9ecef;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(var(--bs-body-color-rgb), 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(var(--bs-body-color-rgb), 0.075);--bs-emphasis-color:#000;--bs-form-control-bg:var(--bs-body-bg);--bs-form-control-disabled-bg:var(--bs-secondary-bg);--bs-highlight-bg:#fff3cd;--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}[data-bs-theme=dark]{--bs-body-color:#adb5bd;--bs-body-color-rgb:173,181,189;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#f8f9fa;--bs-emphasis-color-rgb:248,249,250;--bs-secondary-color:rgba(173, 181, 189, 0.75);--bs-secondary-color-rgb:173,181,189;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(173, 181, 189, 0.5);--bs-tertiary-color-rgb:173,181,189;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-emphasis-color:#fff;--bs-primary-text:#6ea8fe;--bs-secondary-text:#dee2e6;--bs-success-text:#75b798;--bs-info-text:#6edff6;--bs-warning-text:#ffda6a;--bs-danger-text:#ea868f;--bs-light-text:#f8f9fa;--bs-dark-text:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#212529;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#495057;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#055160;--bs-warning-border-subtle:#664d03;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:#fff;--bs-link-color:#6ea8fe;--bs-link-hover-color:#9ec5fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:158,197,254;--bs-code-color:#e685b5;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15)}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color,inherit)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#bacbe6;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#cbccce;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#bcd0c7;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#badce3;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#e6dbb9;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#dfc2c4;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#dfe0e1;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#373b3e;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);background-color:var(--bs-form-control-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-form-control-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::-moz-placeholder{color:var(--bs-secondary-color);opacity:1}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-form-control-disabled-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);background-color:var(--bs-form-control-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-form-control-disabled-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23adb5bd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-form-control-bg);width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-tertiary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-tertiary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating::before:not(.form-control:disabled){position:absolute;top:var(--bs-border-width);left:var(--bs-border-width);width:calc(100% - (calc(calc(.375em + .1875rem) + calc(.75em + .375rem))));height:1.875em;content:"";background-color:var(--bs-form-control-bg);border-radius:.375rem}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label{color:#6c757d}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(var(--bs-border-width) * -1);border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-success-text)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-success);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-success);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-success)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-success);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-success)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-success-text)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-success-text)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-danger-text)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-danger);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-danger);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-danger)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-danger);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-danger)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-danger-text)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-danger-text)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(0.375rem - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(var(--bs-border-width) * -1)}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(var(--bs-border-width) * -1)}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230a58ca'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#86b7fe;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text)}.alert-success{--bs-alert-color:var(--bs-success-text);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text)}.alert-info{--bs-alert-color:var(--bs-info-text);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text)}.alert-warning{--bs-alert-color:var(--bs-warning-text);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text)}.alert-danger{--bs-alert-color:var(--bs-danger-text);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text)}.alert-light{--bs-alert-color:var(--bs-light-text);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text)}.alert-dark{--bs-alert-color:var(--bs-dark-text);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle)}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle)}.list-group-item-primary.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-primary-text);--bs-list-group-active-border-color:var(--bs-primary-text)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle)}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle)}.list-group-item-secondary.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-secondary-text);--bs-list-group-active-border-color:var(--bs-secondary-text)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle)}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle)}.list-group-item-success.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-success-text);--bs-list-group-active-border-color:var(--bs-success-text)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle)}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle)}.list-group-item-info.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-info-text);--bs-list-group-active-border-color:var(--bs-info-text)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle)}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle)}.list-group-item-warning.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-warning-text);--bs-list-group-active-border-color:var(--bs-warning-text)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle)}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle)}.list-group-item-danger.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-danger-text);--bs-list-group-active-border-color:var(--bs-danger-text)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle)}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle)}.list-group-item-light.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-light-text);--bs-list-group-active-border-color:var(--bs-light-text)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle)}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle)}.list-group-item-dark.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-dark-text);--bs-list-group-active-border-color:var(--bs-dark-text)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;--bs-btn-close-white-filter:invert(1) grayscale(100%) brightness(200%);box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{filter:var(--bs-btn-close-white-filter)}[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark] .carousel .carousel-control-prev-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(13,110,253,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(108,117,125,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(25,135,84,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(13,202,240,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(255,193,7,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(220,53,69,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(248,249,250,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(33,37,41,var(--bs-bg-opacity,1))!important}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(var(--bs-body-color-rgb),.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(var(--bs-body-color-rgb),.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(var(--bs-body-color-rgb),.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text)!important}.text-secondary-emphasis{color:var(--bs-secondary-text)!important}.text-success-emphasis{color:var(--bs-success-text)!important}.text-info-emphasis{color:var(--bs-info-text)!important}.text-warning-emphasis{color:var(--bs-warning-text)!important}.text-danger-emphasis{color:var(--bs-danger-text)!important}.text-light-emphasis{color:var(--bs-light-text)!important}.text-dark-emphasis{color:var(--bs-dark-text)!important}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-emphasis{--bs-bg-opacity:1;background-color:rgba(var(--bs-emphasis-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-2xl)!important;border-top-right-radius:var(--bs-border-radius-2xl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-2xl)!important;border-bottom-right-radius:var(--bs-border-radius-2xl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-2xl)!important;border-bottom-left-radius:var(--bs-border-radius-2xl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-2xl)!important;border-top-left-radius:var(--bs-border-radius-2xl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} /*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/Docs/js/bootstrap.bundle.min.js b/Docs/js/bootstrap.bundle.min.js index 7a59950b..da8d852f 100644 --- a/Docs/js/bootstrap.bundle.min.js +++ b/Docs/js/bootstrap.bundle.min.js @@ -1,7 +1,7 @@ /*! - * Bootstrap v5.0.0 (https://getbootstrap.com/) - * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap v5.3.0-alpha1 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t},e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i="#"+i.split("#")[1]),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0},o=t=>{t.dispatchEvent(new Event("transitionend"))},r=t=>(t[0]||t).nodeType,a=(t,e)=>{let i=!1;const n=e+5;t.addEventListener("transitionend",(function e(){i=!0,t.removeEventListener("transitionend",e)})),setTimeout(()=>{i||o(t)},n)},l=(t,e,i)=>{Object.keys(i).forEach(n=>{const s=i[n],o=e[n],a=o&&r(o)?"element":null==(l=o)?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)})},c=t=>{if(!t)return!1;if(t.style&&t.parentNode&&t.parentNode.style){const e=getComputedStyle(t),i=getComputedStyle(t.parentNode);return"none"!==e.display&&"none"!==i.display&&"hidden"!==e.visibility}return!1},d=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?h(t.parentNode):null},u=()=>{},f=t=>t.offsetHeight,p=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},g=()=>"rtl"===document.documentElement.dir,m=(t,e)=>{var i;i=()=>{const i=p();if(i){const n=i.fn[t];i.fn[t]=e.jQueryInterface,i.fn[t].Constructor=e,i.fn[t].noConflict=()=>(i.fn[t]=n,e.jQueryInterface)}},"loading"===document.readyState?document.addEventListener("DOMContentLoaded",i):i()},_=t=>{"function"==typeof t&&t()},b=new Map;var v={set(t,e,i){b.has(t)||b.set(t,new Map);const n=b.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>b.has(t)&&b.get(t).get(e)||null,remove(t,e){if(!b.has(t))return;const i=b.get(t);i.delete(e),0===i.size&&b.delete(t)}};const y=/[^.]*(?=\..*)\.|.*/,w=/\..*/,E=/::\d+$/,T={};let A=1;const L={mouseenter:"mouseover",mouseleave:"mouseout"},O=/^(mouseenter|mouseleave)/i,k=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function D(t,e){return e&&`${e}::${A++}`||t.uidEvent||A++}function x(t){const e=D(t);return t.uidEvent=e,T[e]=T[e]||{},T[e]}function C(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=S(e,i,n),l=x(t),c=l[a]||(l[a]={}),d=C(c,r,o?i:null);if(d)return void(d.oneOff=d.oneOff&&s);const h=D(r,e.replace(y,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&I.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&I.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=h,c[h]=u,t.addEventListener(a,u,o)}function j(t,e,i,n,s){const o=C(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function P(t){return t=t.replace(w,""),L[t]||t}const I={on(t,e,i,n){N(t,e,i,n,!1)},one(t,e,i,n){N(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=S(e,i,n),a=r!==e,l=x(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void j(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach(i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach(o=>{if(o.includes(n)){const n=s[o];j(t,e,i,n.originalHandler,n.delegationSelector)}})}(t,l,i,e.slice(1))});const d=l[r]||{};Object.keys(d).forEach(i=>{const n=i.replace(E,"");if(!a||e.includes(n)){const e=d[i];j(t,l,r,e.originalHandler,e.delegationSelector)}})},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=p(),s=P(e),o=e!==s,r=k.has(s);let a,l=!0,c=!0,d=!1,h=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),d=a.isDefaultPrevented()),r?(h=document.createEvent("HTMLEvents"),h.initEvent(s,l,!0)):h=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach(t=>{Object.defineProperty(h,t,{get:()=>i[t]})}),d&&h.preventDefault(),c&&t.dispatchEvent(h),h.defaultPrevented&&void 0!==a&&a.preventDefault(),h}};class M{constructor(t){(t="string"==typeof t?document.querySelector(t):t)&&(this._element=t,v.set(this._element,this.constructor.DATA_KEY,this))}dispose(){v.remove(this._element,this.constructor.DATA_KEY),I.off(this._element,"."+this.constructor.DATA_KEY),this._element=null}static getInstance(t){return v.get(t,this.DATA_KEY)}static get VERSION(){return"5.0.0"}}class H extends M{static get DATA_KEY(){return"bs.alert"}close(t){const e=t?this._getRootElement(t):this._element,i=this._triggerCloseEvent(e);null===i||i.defaultPrevented||this._removeElement(e)}_getRootElement(t){return n(t)||t.closest(".alert")}_triggerCloseEvent(t){return I.trigger(t,"close.bs.alert")}_removeElement(t){if(t.classList.remove("show"),!t.classList.contains("fade"))return void this._destroyElement(t);const e=s(t);I.one(t,"transitionend",()=>this._destroyElement(t)),a(t,e)}_destroyElement(t){t.parentNode&&t.parentNode.removeChild(t),I.trigger(t,"closed.bs.alert")}static jQueryInterface(t){return this.each((function(){let e=v.get(this,"bs.alert");e||(e=new H(this)),"close"===t&&e[t](this)}))}static handleDismiss(t){return function(e){e&&e.preventDefault(),t.close(this)}}}I.on(document,"click.bs.alert.data-api",'[data-bs-dismiss="alert"]',H.handleDismiss(new H)),m("alert",H);class R extends M{static get DATA_KEY(){return"bs.button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){let e=v.get(this,"bs.button");e||(e=new R(this)),"toggle"===t&&e[t]()}))}}function B(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function W(t){return t.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}I.on(document,"click.bs.button.data-api",'[data-bs-toggle="button"]',t=>{t.preventDefault();const e=t.target.closest('[data-bs-toggle="button"]');let i=v.get(e,"bs.button");i||(i=new R(e)),i.toggle()}),m("button",R);const z={setDataAttribute(t,e,i){t.setAttribute("data-bs-"+W(e),i)},removeDataAttribute(t,e){t.removeAttribute("data-bs-"+W(e))},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter(t=>t.startsWith("bs")).forEach(i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=B(t.dataset[i])}),e},getDataAttribute:(t,e)=>B(t.getAttribute("data-bs-"+W(e))),offset(t){const e=t.getBoundingClientRect();return{top:e.top+document.body.scrollTop,left:e.left+document.body.scrollLeft}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},U={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter(t=>t.matches(e)),parents(t,e){const i=[];let n=t.parentNode;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]}},$={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},F={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},K="next",Y="prev",q="left",V="right";class X extends M{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=U.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return $}static get DATA_KEY(){return"bs.carousel"}next(){this._isSliding||this._slide(K)}nextWhenVisible(){!document.hidden&&c(this._element)&&this.next()}prev(){this._isSliding||this._slide(Y)}pause(t){t||(this._isPaused=!0),U.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(o(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=U.findOne(".active.carousel-item",this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void I.one(this._element,"slid.bs.carousel",()=>this.to(t));if(e===t)return this.pause(),void this.cycle();const i=t>e?K:Y;this._slide(i,this._items[t])}dispose(){this._items=null,this._config=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null,super.dispose()}_getConfig(t){return t={...$,...t},l("carousel",t,F),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?V:q)}_addEventListeners(){this._config.keyboard&&I.on(this._element,"keydown.bs.carousel",t=>this._keydown(t)),"hover"===this._config.pause&&(I.on(this._element,"mouseenter.bs.carousel",t=>this.pause(t)),I.on(this._element,"mouseleave.bs.carousel",t=>this.cycle(t))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType?this._pointerEvent||(this.touchStartX=t.touches[0].clientX):this.touchStartX=t.clientX},e=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},i=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType||(this.touchDeltaX=t.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(t=>this.cycle(t),500+this._config.interval))};U.find(".carousel-item img",this._element).forEach(t=>{I.on(t,"dragstart.bs.carousel",t=>t.preventDefault())}),this._pointerEvent?(I.on(this._element,"pointerdown.bs.carousel",e=>t(e)),I.on(this._element,"pointerup.bs.carousel",t=>i(t)),this._element.classList.add("pointer-event")):(I.on(this._element,"touchstart.bs.carousel",e=>t(e)),I.on(this._element,"touchmove.bs.carousel",t=>e(t)),I.on(this._element,"touchend.bs.carousel",t=>i(t)))}_keydown(t){/input|textarea/i.test(t.target.tagName)||("ArrowLeft"===t.key?(t.preventDefault(),this._slide(V)):"ArrowRight"===t.key&&(t.preventDefault(),this._slide(q)))}_getItemIndex(t){return this._items=t&&t.parentNode?U.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===K,n=t===Y,s=this._getItemIndex(e),o=this._items.length-1;if((n&&0===s||i&&s===o)&&!this._config.wrap)return e;const r=(s+(n?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),n=this._getItemIndex(U.findOne(".active.carousel-item",this._element));return I.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=U.findOne(".active",this._indicatorsElement);e.classList.remove("active"),e.removeAttribute("aria-current");const i=U.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{r.classList.remove(h,u),r.classList.add("active"),n.classList.remove("active",u,h),this._isSliding=!1,setTimeout(()=>{I.trigger(this._element,"slid.bs.carousel",{relatedTarget:r,direction:p,from:o,to:l})},0)}),a(n,t)}else n.classList.remove("active"),r.classList.add("active"),this._isSliding=!1,I.trigger(this._element,"slid.bs.carousel",{relatedTarget:r,direction:p,from:o,to:l});c&&this.cycle()}}_directionToOrder(t){return[V,q].includes(t)?g()?t===q?Y:K:t===q?K:Y:t}_orderToDirection(t){return[K,Y].includes(t)?g()?t===Y?q:V:t===Y?V:q:t}static carouselInterface(t,e){let i=v.get(t,"bs.carousel"),n={...$,...z.getDataAttributes(t)};"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if(i||(i=new X(t,n)),"number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){X.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=n(this);if(!e||!e.classList.contains("carousel"))return;const i={...z.getDataAttributes(e),...z.getDataAttributes(this)},s=this.getAttribute("data-bs-slide-to");s&&(i.interval=!1),X.carouselInterface(e,i),s&&v.get(e,"bs.carousel").to(s),t.preventDefault()}}I.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",X.dataApiClickHandler),I.on(window,"load.bs.carousel.data-api",()=>{const t=U.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element);null!==s&&o.length&&(this._selector=s,this._triggerArray.push(e))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}static get Default(){return Q}static get DATA_KEY(){return"bs.collapse"}toggle(){this._element.classList.contains("show")?this.hide():this.show()}show(){if(this._isTransitioning||this._element.classList.contains("show"))return;let t,e;this._parent&&(t=U.find(".show, .collapsing",this._parent).filter(t=>"string"==typeof this._config.parent?t.getAttribute("data-bs-parent")===this._config.parent:t.classList.contains("collapse")),0===t.length&&(t=null));const i=U.findOne(this._selector);if(t){const n=t.find(t=>i!==t);if(e=n?v.get(n,"bs.collapse"):null,e&&e._isTransitioning)return}if(I.trigger(this._element,"show.bs.collapse").defaultPrevented)return;t&&t.forEach(t=>{i!==t&&Z.collapseInterface(t,"hide"),e||v.set(t,"bs.collapse",null)});const n=this._getDimension();this._element.classList.remove("collapse"),this._element.classList.add("collapsing"),this._element.style[n]=0,this._triggerArray.length&&this._triggerArray.forEach(t=>{t.classList.remove("collapsed"),t.setAttribute("aria-expanded",!0)}),this.setTransitioning(!0);const o="scroll"+(n[0].toUpperCase()+n.slice(1)),r=s(this._element);I.one(this._element,"transitionend",()=>{this._element.classList.remove("collapsing"),this._element.classList.add("collapse","show"),this._element.style[n]="",this.setTransitioning(!1),I.trigger(this._element,"shown.bs.collapse")}),a(this._element,r),this._element.style[n]=this._element[o]+"px"}hide(){if(this._isTransitioning||!this._element.classList.contains("show"))return;if(I.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=this._element.getBoundingClientRect()[t]+"px",f(this._element),this._element.classList.add("collapsing"),this._element.classList.remove("collapse","show");const e=this._triggerArray.length;if(e>0)for(let t=0;t{this.setTransitioning(!1),this._element.classList.remove("collapsing"),this._element.classList.add("collapse"),I.trigger(this._element,"hidden.bs.collapse")}),a(this._element,i)}setTransitioning(t){this._isTransitioning=t}dispose(){super.dispose(),this._config=null,this._parent=null,this._triggerArray=null,this._isTransitioning=null}_getConfig(t){return(t={...Q,...t}).toggle=Boolean(t.toggle),l("collapse",t,G),t}_getDimension(){return this._element.classList.contains("width")?"width":"height"}_getParent(){let{parent:t}=this._config;r(t)?void 0===t.jquery&&void 0===t[0]||(t=t[0]):t=U.findOne(t);const e=`[data-bs-toggle="collapse"][data-bs-parent="${t}"]`;return U.find(e,t).forEach(t=>{const e=n(t);this._addAriaAndCollapsedClass(e,[t])}),t}_addAriaAndCollapsedClass(t,e){if(!t||!e.length)return;const i=t.classList.contains("show");e.forEach(t=>{i?t.classList.remove("collapsed"):t.classList.add("collapsed"),t.setAttribute("aria-expanded",i)})}static collapseInterface(t,e){let i=v.get(t,"bs.collapse");const n={...Q,...z.getDataAttributes(t),..."object"==typeof e&&e?e:{}};if(!i&&n.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(n.toggle=!1),i||(i=new Z(t,n)),"string"==typeof e){if(void 0===i[e])throw new TypeError(`No method named "${e}"`);i[e]()}}static jQueryInterface(t){return this.each((function(){Z.collapseInterface(this,t)}))}}I.on(document,"click.bs.collapse.data-api",'[data-bs-toggle="collapse"]',(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=z.getDataAttributes(this),n=i(this);U.find(n).forEach(t=>{const i=v.get(t,"bs.collapse");let n;i?(null===i._parent&&"string"==typeof e.parent&&(i._config.parent=e.parent,i._parent=i._getParent()),n="toggle"):n=e,Z.collapseInterface(t,n)})})),m("collapse",Z);var J="top",tt="bottom",et="right",it="left",nt=[J,tt,et,it],st=nt.reduce((function(t,e){return t.concat([e+"-start",e+"-end"])}),[]),ot=[].concat(nt,["auto"]).reduce((function(t,e){return t.concat([e,e+"-start",e+"-end"])}),[]),rt=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function at(t){return t?(t.nodeName||"").toLowerCase():null}function lt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function ct(t){return t instanceof lt(t).Element||t instanceof Element}function dt(t){return t instanceof lt(t).HTMLElement||t instanceof HTMLElement}function ht(t){return"undefined"!=typeof ShadowRoot&&(t instanceof lt(t).ShadowRoot||t instanceof ShadowRoot)}var ut={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];dt(s)&&at(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});dt(n)&&at(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function ft(t){return t.split("-")[0]}function pt(t){var e=t.getBoundingClientRect();return{width:e.width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left,x:e.left,y:e.top}}function gt(t){var e=pt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function mt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&ht(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function _t(t){return lt(t).getComputedStyle(t)}function bt(t){return["table","td","th"].indexOf(at(t))>=0}function vt(t){return((ct(t)?t.ownerDocument:t.document)||window.document).documentElement}function yt(t){return"html"===at(t)?t:t.assignedSlot||t.parentNode||(ht(t)?t.host:null)||vt(t)}function wt(t){return dt(t)&&"fixed"!==_t(t).position?t.offsetParent:null}function Et(t){for(var e=lt(t),i=wt(t);i&&bt(i)&&"static"===_t(i).position;)i=wt(i);return i&&("html"===at(i)||"body"===at(i)&&"static"===_t(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&dt(t)&&"fixed"===_t(t).position)return null;for(var i=yt(t);dt(i)&&["html","body"].indexOf(at(i))<0;){var n=_t(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Tt(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var At=Math.max,Lt=Math.min,Ot=Math.round;function kt(t,e,i){return At(t,Lt(e,i))}function Dt(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function xt(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}var Ct={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=ft(i.placement),l=Tt(a),c=[it,et].indexOf(a)>=0?"height":"width";if(o&&r){var d=function(t,e){return Dt("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:xt(t,nt))}(s.padding,i),h=gt(o),u="y"===l?J:it,f="y"===l?tt:et,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],g=r[l]-i.rects.reference[l],m=Et(o),_=m?"y"===l?m.clientHeight||0:m.clientWidth||0:0,b=p/2-g/2,v=d[u],y=_-h[c]-d[f],w=_/2-h[c]/2+b,E=kt(v,w,y),T=l;i.modifiersData[n]=((e={})[T]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&mt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]},St={top:"auto",right:"auto",bottom:"auto",left:"auto"};function Nt(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.offsets,r=t.position,a=t.gpuAcceleration,l=t.adaptive,c=t.roundOffsets,d=!0===c?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:Ot(Ot(e*n)/n)||0,y:Ot(Ot(i*n)/n)||0}}(o):"function"==typeof c?c(o):o,h=d.x,u=void 0===h?0:h,f=d.y,p=void 0===f?0:f,g=o.hasOwnProperty("x"),m=o.hasOwnProperty("y"),_=it,b=J,v=window;if(l){var y=Et(i),w="clientHeight",E="clientWidth";y===lt(i)&&"static"!==_t(y=vt(i)).position&&(w="scrollHeight",E="scrollWidth"),y=y,s===J&&(b=tt,p-=y[w]-n.height,p*=a?1:-1),s===it&&(_=et,u-=y[E]-n.width,u*=a?1:-1)}var T,A=Object.assign({position:r},l&&St);return a?Object.assign({},A,((T={})[b]=m?"0":"",T[_]=g?"0":"",T.transform=(v.devicePixelRatio||1)<2?"translate("+u+"px, "+p+"px)":"translate3d("+u+"px, "+p+"px, 0)",T)):Object.assign({},A,((e={})[b]=m?p+"px":"",e[_]=g?u+"px":"",e.transform="",e))}var jt={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:ft(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,Nt(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,Nt(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}},Pt={passive:!0},It={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=lt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,Pt)})),a&&l.addEventListener("resize",i.update,Pt),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,Pt)})),a&&l.removeEventListener("resize",i.update,Pt)}},data:{}},Mt={left:"right",right:"left",bottom:"top",top:"bottom"};function Ht(t){return t.replace(/left|right|bottom|top/g,(function(t){return Mt[t]}))}var Rt={start:"end",end:"start"};function Bt(t){return t.replace(/start|end/g,(function(t){return Rt[t]}))}function Wt(t){var e=lt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function zt(t){return pt(vt(t)).left+Wt(t).scrollLeft}function Ut(t){var e=_t(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function $t(t,e){var i;void 0===e&&(e=[]);var n=function t(e){return["html","body","#document"].indexOf(at(e))>=0?e.ownerDocument.body:dt(e)&&Ut(e)?e:t(yt(e))}(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=lt(n),r=s?[o].concat(o.visualViewport||[],Ut(n)?n:[]):n,a=e.concat(r);return s?a:a.concat($t(yt(r)))}function Ft(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Kt(t,e){return"viewport"===e?Ft(function(t){var e=lt(t),i=vt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+zt(t),y:a}}(t)):dt(e)?function(t){var e=pt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Ft(function(t){var e,i=vt(t),n=Wt(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=At(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=At(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+zt(t),l=-n.scrollTop;return"rtl"===_t(s||i).direction&&(a+=At(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(vt(t)))}function Yt(t){return t.split("-")[1]}function qt(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?ft(s):null,r=s?Yt(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case J:e={x:a,y:i.y-n.height};break;case tt:e={x:a,y:i.y+i.height};break;case et:e={x:i.x+i.width,y:l};break;case it:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Tt(o):null;if(null!=c){var d="y"===c?"height":"width";switch(r){case"start":e[c]=e[c]-(i[d]/2-n[d]/2);break;case"end":e[c]=e[c]+(i[d]/2-n[d]/2)}}return e}function Vt(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?"clippingParents":o,a=i.rootBoundary,l=void 0===a?"viewport":a,c=i.elementContext,d=void 0===c?"popper":c,h=i.altBoundary,u=void 0!==h&&h,f=i.padding,p=void 0===f?0:f,g=Dt("number"!=typeof p?p:xt(p,nt)),m="popper"===d?"reference":"popper",_=t.elements.reference,b=t.rects.popper,v=t.elements[u?m:d],y=function(t,e,i){var n="clippingParents"===e?function(t){var e=$t(yt(t)),i=["absolute","fixed"].indexOf(_t(t).position)>=0&&dt(t)?Et(t):t;return ct(i)?e.filter((function(t){return ct(t)&&mt(t,i)&&"body"!==at(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Kt(t,i);return e.top=At(n.top,e.top),e.right=Lt(n.right,e.right),e.bottom=Lt(n.bottom,e.bottom),e.left=At(n.left,e.left),e}),Kt(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}(ct(v)?v:v.contextElement||vt(t.elements.popper),r,l),w=pt(_),E=qt({reference:w,element:b,strategy:"absolute",placement:s}),T=Ft(Object.assign({},b,E)),A="popper"===d?T:w,L={top:y.top-A.top+g.top,bottom:A.bottom-y.bottom+g.bottom,left:y.left-A.left+g.left,right:A.right-y.right+g.right},O=t.modifiersData.offset;if("popper"===d&&O){var k=O[s];Object.keys(L).forEach((function(t){var e=[et,tt].indexOf(t)>=0?1:-1,i=[J,tt].indexOf(t)>=0?"y":"x";L[t]+=k[i]*e}))}return L}function Xt(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ot:l,d=Yt(n),h=d?a?st:st.filter((function(t){return Yt(t)===d})):nt,u=h.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=h);var f=u.reduce((function(e,i){return e[i]=Vt(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[ft(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}var Qt={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,d=i.boundary,h=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,g=i.allowedAutoPlacements,m=e.options.placement,_=ft(m),b=l||(_!==m&&p?function(t){if("auto"===ft(t))return[];var e=Ht(t);return[Bt(t),e,Bt(e)]}(m):[Ht(m)]),v=[m].concat(b).reduce((function(t,i){return t.concat("auto"===ft(i)?Xt(e,{placement:i,boundary:d,rootBoundary:h,padding:c,flipVariations:p,allowedAutoPlacements:g}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,T=!0,A=v[0],L=0;L=0,C=x?"width":"height",S=Vt(e,{placement:O,boundary:d,rootBoundary:h,altBoundary:u,padding:c}),N=x?D?et:it:D?tt:J;y[C]>w[C]&&(N=Ht(N));var j=Ht(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[j]<=0),P.every((function(t){return t}))){A=O,T=!1;break}E.set(O,P)}if(T)for(var I=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return A=e,"break"},M=p?3:1;M>0&&"break"!==I(M);M--);e.placement!==A&&(e.modifiersData[n]._skip=!0,e.placement=A,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function Gt(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Zt(t){return[J,et,tt,it].some((function(e){return t[e]>=0}))}var Jt={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=Vt(e,{elementContext:"reference"}),a=Vt(e,{altBoundary:!0}),l=Gt(r,n),c=Gt(a,s,o),d=Zt(l),h=Zt(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:d,hasPopperEscaped:h},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":d,"data-popper-escaped":h})}},te={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ot.reduce((function(t,i){return t[i]=function(t,e,i){var n=ft(t),s=[it,J].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[it,et].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},ee={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=qt({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},ie={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,d=i.altBoundary,h=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,g=void 0===p?0:p,m=Vt(e,{boundary:l,rootBoundary:c,padding:h,altBoundary:d}),_=ft(e.placement),b=Yt(e.placement),v=!b,y=Tt(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,T=e.rects.reference,A=e.rects.popper,L="function"==typeof g?g(Object.assign({},e.rects,{placement:e.placement})):g,O={x:0,y:0};if(E){if(o||a){var k="y"===y?J:it,D="y"===y?tt:et,x="y"===y?"height":"width",C=E[y],S=E[y]+m[k],N=E[y]-m[D],j=f?-A[x]/2:0,P="start"===b?T[x]:A[x],I="start"===b?-A[x]:-T[x],M=e.elements.arrow,H=f&&M?gt(M):{width:0,height:0},R=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},B=R[k],W=R[D],z=kt(0,T[x],H[x]),U=v?T[x]/2-j-z-B-L:P-z-B-L,$=v?-T[x]/2+j+z+W+L:I+z+W+L,F=e.elements.arrow&&Et(e.elements.arrow),K=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,Y=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,q=E[y]+U-Y-K,V=E[y]+$-Y;if(o){var X=kt(f?Lt(S,q):S,C,f?At(N,V):N);E[y]=X,O[y]=X-C}if(a){var Q="x"===y?J:it,G="x"===y?tt:et,Z=E[w],nt=Z+m[Q],st=Z-m[G],ot=kt(f?Lt(nt,q):nt,Z,f?At(st,V):st);E[w]=ot,O[w]=ot-Z}}e.modifiersData[n]=O}},requiresIfExists:["offset"]};function ne(t,e,i){void 0===i&&(i=!1);var n,s,o=vt(e),r=pt(t),a=dt(e),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(a||!a&&!i)&&(("body"!==at(e)||Ut(o))&&(l=(n=e)!==lt(n)&&dt(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Wt(n)),dt(e)?((c=pt(e)).x+=e.clientLeft,c.y+=e.clientTop):o&&(c.x=zt(o))),{x:r.left+l.scrollLeft-c.x,y:r.top+l.scrollTop-c.y,width:r.width,height:r.height}}var se={placement:"bottom",modifiers:[],strategy:"absolute"};function oe(){for(var t=arguments.length,e=new Array(t),i=0;i"applyStyles"===t.name&&!1===t.enabled);this._popper=ce(e,this._menu,i),n&&z.setDataAttribute(this._menu,"popper","static")}"ontouchstart"in document.documentElement&&!t.closest(".navbar-nav")&&[].concat(...document.body.children).forEach(t=>I.on(t,"mouseover",u)),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.toggle("show"),this._element.classList.toggle("show"),I.trigger(this._element,"shown.bs.dropdown",e)}}hide(){if(d(this._element)||!this._menu.classList.contains("show"))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._menu=null,this._popper&&(this._popper.destroy(),this._popper=null),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_addEventListeners(){I.on(this._element,"click.bs.dropdown",t=>{t.preventDefault(),this.toggle()})}_completeHide(t){I.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>I.off(t,"mouseover",u)),this._popper&&this._popper.destroy(),this._menu.classList.remove("show"),this._element.classList.remove("show"),this._element.setAttribute("aria-expanded","false"),z.removeDataAttribute(this._menu,"popper"),I.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...z.getDataAttributes(this._element),...t},l("dropdown",t,this.constructor.DefaultType),"object"==typeof t.reference&&!r(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError("dropdown".toUpperCase()+': Option "reference" provided type "object" without a required "getBoundingClientRect" method.');return t}_getMenuElement(){return U.next(this._element,".dropdown-menu")[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return me;if(t.classList.contains("dropstart"))return _e;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?fe:ue:e?ge:pe}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem(t){const e=U.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(c);if(!e.length)return;let i=e.indexOf(t.target);"ArrowUp"===t.key&&i>0&&i--,"ArrowDown"===t.key&&ithis.matches('[data-bs-toggle="dropdown"]')?this:U.prev(this,'[data-bs-toggle="dropdown"]')[0];if("Escape"===t.key)return i().focus(),void ye.clearMenus();e||"ArrowUp"!==t.key&&"ArrowDown"!==t.key?e&&"Space"!==t.key?ye.getInstance(i())._selectMenuItem(t):ye.clearMenus():i().click()}}I.on(document,"keydown.bs.dropdown.data-api",'[data-bs-toggle="dropdown"]',ye.dataApiKeydownHandler),I.on(document,"keydown.bs.dropdown.data-api",".dropdown-menu",ye.dataApiKeydownHandler),I.on(document,"click.bs.dropdown.data-api",ye.clearMenus),I.on(document,"keyup.bs.dropdown.data-api",ye.clearMenus),I.on(document,"click.bs.dropdown.data-api",'[data-bs-toggle="dropdown"]',(function(t){t.preventDefault(),ye.dropdownInterface(this)})),m("dropdown",ye);const we=()=>{const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)},Ee=(t=we())=>{Te(),Ae("body","paddingRight",e=>e+t),Ae(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight",e=>e+t),Ae(".sticky-top","marginRight",e=>e-t)},Te=()=>{const t=document.body.style.overflow;t&&z.setDataAttribute(document.body,"overflow",t),document.body.style.overflow="hidden"},Ae=(t,e,i)=>{const n=we();U.find(t).forEach(t=>{if(t!==document.body&&window.innerWidth>t.clientWidth+n)return;const s=t.style[e],o=window.getComputedStyle(t)[e];z.setDataAttribute(t,e,s),t.style[e]=i(Number.parseFloat(o))+"px"})},Le=()=>{Oe("body","overflow"),Oe("body","paddingRight"),Oe(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight"),Oe(".sticky-top","marginRight")},Oe=(t,e)=>{U.find(t).forEach(t=>{const i=z.getDataAttribute(t,e);void 0===i?t.style.removeProperty(e):(z.removeDataAttribute(t,e),t.style[e]=i)})},ke={isVisible:!0,isAnimated:!1,rootElement:document.body,clickCallback:null},De={isVisible:"boolean",isAnimated:"boolean",rootElement:"element",clickCallback:"(function|null)"};class xe{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&f(this._getElement()),this._getElement().classList.add("show"),this._emulateAnimation(()=>{_(t)})):_(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove("show"),this._emulateAnimation(()=>{this.dispose(),_(t)})):_(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className="modal-backdrop",this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return t={...ke,..."object"==typeof t?t:{}},l("backdrop",t,De),t}_append(){this._isAppended||(this._config.rootElement.appendChild(this._getElement()),I.on(this._getElement(),"mousedown.bs.backdrop",()=>{_(this._config.clickCallback)}),this._isAppended=!0)}dispose(){this._isAppended&&(I.off(this._element,"mousedown.bs.backdrop"),this._getElement().parentNode.removeChild(this._element),this._isAppended=!1)}_emulateAnimation(t){if(!this._config.isAnimated)return void _(t);const e=s(this._getElement());I.one(this._getElement(),"transitionend",()=>_(t)),a(this._getElement(),e)}}const Ce={backdrop:!0,keyboard:!0,focus:!0},Se={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"};class Ne extends M{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=U.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1}static get Default(){return Ce}static get DATA_KEY(){return"bs.modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){if(this._isShown||this._isTransitioning)return;this._isAnimated()&&(this._isTransitioning=!0);const e=I.trigger(this._element,"show.bs.modal",{relatedTarget:t});this._isShown||e.defaultPrevented||(this._isShown=!0,Ee(),document.body.classList.add("modal-open"),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),I.on(this._element,"click.dismiss.bs.modal",'[data-bs-dismiss="modal"]',t=>this.hide(t)),I.on(this._dialog,"mousedown.dismiss.bs.modal",()=>{I.one(this._element,"mouseup.dismiss.bs.modal",t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)})}),this._showBackdrop(()=>this._showElement(t)))}hide(t){if(t&&t.preventDefault(),!this._isShown||this._isTransitioning)return;if(I.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const e=this._isAnimated();if(e&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),I.off(document,"focusin.bs.modal"),this._element.classList.remove("show"),I.off(this._element,"click.dismiss.bs.modal"),I.off(this._dialog,"mousedown.dismiss.bs.modal"),e){const t=s(this._element);I.one(this._element,"transitionend",t=>this._hideModal(t)),a(this._element,t)}else this._hideModal()}dispose(){[window,this._dialog].forEach(t=>I.off(t,".bs.modal")),super.dispose(),I.off(document,"focusin.bs.modal"),this._config=null,this._dialog=null,this._backdrop.dispose(),this._backdrop=null,this._isShown=null,this._ignoreBackdropClick=null,this._isTransitioning=null}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new xe({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_getConfig(t){return t={...Ce,...z.getDataAttributes(this._element),...t},l("modal",t,Se),t}_showElement(t){const e=this._isAnimated(),i=U.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,i&&(i.scrollTop=0),e&&f(this._element),this._element.classList.add("show"),this._config.focus&&this._enforceFocus();const n=()=>{this._config.focus&&this._element.focus(),this._isTransitioning=!1,I.trigger(this._element,"shown.bs.modal",{relatedTarget:t})};if(e){const t=s(this._dialog);I.one(this._dialog,"transitionend",n),a(this._dialog,t)}else n()}_enforceFocus(){I.off(document,"focusin.bs.modal"),I.on(document,"focusin.bs.modal",t=>{document===t.target||this._element===t.target||this._element.contains(t.target)||this._element.focus()})}_setEscapeEvent(){this._isShown?I.on(this._element,"keydown.dismiss.bs.modal",t=>{this._config.keyboard&&"Escape"===t.key?(t.preventDefault(),this.hide()):this._config.keyboard||"Escape"!==t.key||this._triggerBackdropTransition()}):I.off(this._element,"keydown.dismiss.bs.modal")}_setResizeEvent(){this._isShown?I.on(window,"resize.bs.modal",()=>this._adjustDialog()):I.off(window,"resize.bs.modal")}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide(()=>{document.body.classList.remove("modal-open"),this._resetAdjustments(),Le(),I.trigger(this._element,"hidden.bs.modal")})}_showBackdrop(t){I.on(this._element,"click.dismiss.bs.modal",t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())}),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(I.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight;t||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");const e=s(this._dialog);I.off(this._element,"transitionend"),I.one(this._element,"transitionend",()=>{this._element.classList.remove("modal-static"),t||(I.one(this._element,"transitionend",()=>{this._element.style.overflowY=""}),a(this._element,e))}),a(this._element,e),this._element.focus()}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=we(),i=e>0;(!i&&t&&!g()||i&&!t&&g())&&(this._element.style.paddingLeft=e+"px"),(i&&!t&&!g()||!i&&t&&g())&&(this._element.style.paddingRight=e+"px")}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Ne.getInstance(this)||new Ne(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}I.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),I.one(e,"show.bs.modal",t=>{t.defaultPrevented||I.one(e,"hidden.bs.modal",()=>{c(this)&&this.focus()})}),(Ne.getInstance(e)||new Ne(e)).toggle(this)})),m("modal",Ne);const je={backdrop:!0,keyboard:!0,scroll:!1},Pe={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"};class Ie extends M{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._addEventListeners()}static get Default(){return je}static get DATA_KEY(){return"bs.offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){if(this._isShown)return;if(I.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented)return;this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(Ee(),this._enforceFocusOnElement(this._element)),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add("show");const e=s(this._element);I.one(this._element,"transitionend",()=>{I.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),a(this._element,e)}hide(){if(!this._isShown)return;if(I.trigger(this._element,"hide.bs.offcanvas").defaultPrevented)return;I.off(document,"focusin.bs.offcanvas"),this._element.blur(),this._isShown=!1,this._element.classList.remove("show"),this._backdrop.hide();const t=s(this._element);I.one(this._element,"transitionend",()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||Le(),I.trigger(this._element,"hidden.bs.offcanvas")}),a(this._element,t)}dispose(){this._backdrop.dispose(),super.dispose(),I.off(document,"focusin.bs.offcanvas"),this._config=null,this._backdrop=null}_getConfig(t){return t={...je,...z.getDataAttributes(this._element),..."object"==typeof t?t:{}},l("offcanvas",t,Pe),t}_initializeBackDrop(){return new xe({isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_enforceFocusOnElement(t){I.off(document,"focusin.bs.offcanvas"),I.on(document,"focusin.bs.offcanvas",e=>{document===e.target||t===e.target||t.contains(e.target)||t.focus()}),t.focus()}_addEventListeners(){I.on(this._element,"click.dismiss.bs.offcanvas",'[data-bs-dismiss="offcanvas"]',()=>this.hide()),I.on(this._element,"keydown.dismiss.bs.offcanvas",t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()})}static jQueryInterface(t){return this.each((function(){const e=v.get(this,"bs.offcanvas")||new Ie(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}I.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),d(this))return;I.one(e,"hidden.bs.offcanvas",()=>{c(this)&&this.focus()});const i=U.findOne(".offcanvas.show");i&&i!==e&&Ie.getInstance(i).hide(),(v.get(e,"bs.offcanvas")||new Ie(e)).toggle(this)})),I.on(window,"load.bs.offcanvas.data-api",()=>{U.find(".offcanvas.show").forEach(t=>(v.get(t,"bs.offcanvas")||new Ie(t)).show())}),m("offcanvas",Ie);const Me=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),He=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i,Re=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Be=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!Me.has(i)||Boolean(He.test(t.nodeValue)||Re.test(t.nodeValue));const n=e.filter(t=>t instanceof RegExp);for(let t=0,e=n.length;t{Be(t,a)||i.removeAttribute(t.nodeName)})}return n.body.innerHTML}const ze=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Ue=new Set(["sanitize","allowList","sanitizeFn"]),$e={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Fe={AUTO:"auto",TOP:"top",RIGHT:g()?"left":"right",BOTTOM:"bottom",LEFT:g()?"right":"left"},Ke={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Ye={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"};class qe extends M{constructor(t,e){if(void 0===de)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return Ke}static get NAME(){return"tooltip"}static get DATA_KEY(){return"bs.tooltip"}static get Event(){return Ye}static get EVENT_KEY(){return".bs.tooltip"}static get DefaultType(){return $e}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),I.off(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.parentNode&&this.tip.parentNode.removeChild(this.tip),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.config=null,this.tip=null,super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const e=I.trigger(this._element,this.constructor.Event.SHOW),i=h(this._element),n=null===i?this._element.ownerDocument.documentElement.contains(this._element):i.contains(this._element);if(e.defaultPrevented||!n)return;const o=this.getTipElement(),r=t(this.constructor.NAME);o.setAttribute("id",r),this._element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&o.classList.add("fade");const l="function"==typeof this.config.placement?this.config.placement.call(this,o,this._element):this.config.placement,c=this._getAttachment(l);this._addAttachmentClass(c);const d=this._getContainer();v.set(o,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(d.appendChild(o),I.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=ce(this._element,o,this._getPopperConfig(c)),o.classList.add("show");const f="function"==typeof this.config.customClass?this.config.customClass():this.config.customClass;f&&o.classList.add(...f.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>{I.on(t,"mouseover",u)});const p=()=>{const t=this._hoverState;this._hoverState=null,I.trigger(this._element,this.constructor.Event.SHOWN),"out"===t&&this._leave(null,this)};if(this.tip.classList.contains("fade")){const t=s(this.tip);I.one(this.tip,"transitionend",p),a(this.tip,t)}else p()}hide(){if(!this._popper)return;const t=this.getTipElement(),e=()=>{this._isWithActiveTrigger()||("show"!==this._hoverState&&t.parentNode&&t.parentNode.removeChild(t),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),I.trigger(this._element,this.constructor.Event.HIDDEN),this._popper&&(this._popper.destroy(),this._popper=null))};if(!I.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented){if(t.classList.remove("show"),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>I.off(t,"mouseover",u)),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this.tip.classList.contains("fade")){const i=s(t);I.one(t,"transitionend",e),a(t,i)}else e();this._hoverState=""}}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");return t.innerHTML=this.config.template,this.tip=t.children[0],this.tip}setContent(){const t=this.getTipElement();this.setElementContent(U.findOne(".tooltip-inner",t),this.getTitle()),t.classList.remove("fade","show")}setElementContent(t,e){if(null!==t)return"object"==typeof e&&r(e)?(e.jquery&&(e=e[0]),void(this.config.html?e.parentNode!==t&&(t.innerHTML="",t.appendChild(e)):t.textContent=e.textContent)):void(this.config.html?(this.config.sanitize&&(e=We(e,this.config.allowList,this.config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){let t=this._element.getAttribute("data-bs-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this._element):this.config.title),t}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){const i=this.constructor.DATA_KEY;return(e=e||v.get(t.delegateTarget,i))||(e=new this.constructor(t.delegateTarget,this._getDelegateConfig()),v.set(t.delegateTarget,i,e)),e}_getOffset(){const{offset:t}=this.config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this.config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this.config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this.config.popperConfig?this.config.popperConfig(e):this.config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add("bs-tooltip-"+this.updateAttachment(t))}_getContainer(){return!1===this.config.container?document.body:r(this.config.container)?this.config.container:U.findOne(this.config.container)}_getAttachment(t){return Fe[t.toUpperCase()]}_setListeners(){this.config.trigger.split(" ").forEach(t=>{if("click"===t)I.on(this._element,this.constructor.Event.CLICK,this.config.selector,t=>this.toggle(t));else if("manual"!==t){const e="hover"===t?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i="hover"===t?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;I.on(this._element,e,this.config.selector,t=>this._enter(t)),I.on(this._element,i,this.config.selector,t=>this._leave(t))}}),this._hideModalHandler=()=>{this._element&&this.hide()},I.on(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.config.selector?this.config={...this.config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout(()=>{"show"===e._hoverState&&e.show()},e.config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(()=>{"out"===e._hoverState&&e.hide()},e.config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=z.getDataAttributes(this._element);return Object.keys(e).forEach(t=>{Ue.has(t)&&delete e[t]}),t&&"object"==typeof t.container&&t.container.jquery&&(t.container=t.container[0]),"number"==typeof(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),l("tooltip",t,this.constructor.DefaultType),t.sanitize&&(t.template=We(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};if(this.config)for(const e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match(ze);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}static jQueryInterface(t){return this.each((function(){let e=v.get(this,"bs.tooltip");const i="object"==typeof t&&t;if((e||!/dispose|hide/.test(t))&&(e||(e=new qe(this,i)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m("tooltip",qe);const Ve=new RegExp("(^|\\s)bs-popover\\S+","g"),Xe={...qe.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},Qe={...qe.DefaultType,content:"(string|element|function)"},Ge={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class Ze extends qe{static get Default(){return Xe}static get NAME(){return"popover"}static get DATA_KEY(){return"bs.popover"}static get Event(){return Ge}static get EVENT_KEY(){return".bs.popover"}static get DefaultType(){return Qe}isWithContent(){return this.getTitle()||this._getContent()}setContent(){const t=this.getTipElement();this.setElementContent(U.findOne(".popover-header",t),this.getTitle());let e=this._getContent();"function"==typeof e&&(e=e.call(this._element)),this.setElementContent(U.findOne(".popover-body",t),e),t.classList.remove("fade","show")}_addAttachmentClass(t){this.getTipElement().classList.add("bs-popover-"+this.updateAttachment(t))}_getContent(){return this._element.getAttribute("data-bs-content")||this.config.content}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match(Ve);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}static jQueryInterface(t){return this.each((function(){let e=v.get(this,"bs.popover");const i="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new Ze(this,i),v.set(this,"bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m("popover",Ze);const Je={offset:10,method:"auto",target:""},ti={offset:"number",method:"string",target:"(string|element)"};class ei extends M{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._selector=`${this._config.target} .nav-link, ${this._config.target} .list-group-item, ${this._config.target} .dropdown-item`,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,I.on(this._scrollElement,"scroll.bs.scrollspy",()=>this._process()),this.refresh(),this._process()}static get Default(){return Je}static get DATA_KEY(){return"bs.scrollspy"}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":"position",e="auto"===this._config.method?t:this._config.method,n="position"===e?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),U.find(this._selector).map(t=>{const s=i(t),o=s?U.findOne(s):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[z[e](o).top+n,s]}return null}).filter(t=>t).sort((t,e)=>t[0]-e[0]).forEach(t=>{this._offsets.push(t[0]),this._targets.push(t[1])})}dispose(){super.dispose(),I.off(this._scrollElement,".bs.scrollspy"),this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null}_getConfig(e){if("string"!=typeof(e={...Je,...z.getDataAttributes(this._element),..."object"==typeof e&&e?e:{}}).target&&r(e.target)){let{id:i}=e.target;i||(i=t("scrollspy"),e.target.id=i),e.target="#"+i}return l("scrollspy",e,ti),e}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`),i=U.findOne(e.join(","));i.classList.contains("dropdown-item")?(U.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add("active"),i.classList.add("active")):(i.classList.add("active"),U.parents(i,".nav, .list-group").forEach(t=>{U.prev(t,".nav-link, .list-group-item").forEach(t=>t.classList.add("active")),U.prev(t,".nav-item").forEach(t=>{U.children(t,".nav-link").forEach(t=>t.classList.add("active"))})})),I.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){U.find(this._selector).filter(t=>t.classList.contains("active")).forEach(t=>t.classList.remove("active"))}static jQueryInterface(t){return this.each((function(){const e=ei.getInstance(this)||new ei(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}I.on(window,"load.bs.scrollspy.data-api",()=>{U.find('[data-bs-spy="scroll"]').forEach(t=>new ei(t))}),m("scrollspy",ei);class ii extends M{static get DATA_KEY(){return"bs.tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains("active"))return;let t;const e=n(this._element),i=this._element.closest(".nav, .list-group");if(i){const e="UL"===i.nodeName||"OL"===i.nodeName?":scope > li > .active":".active";t=U.find(e,i),t=t[t.length-1]}const s=t?I.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(I.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==s&&s.defaultPrevented)return;this._activate(this._element,i);const o=()=>{I.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),I.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?U.children(e,".active"):U.find(":scope > li > .active",e))[0],o=i&&n&&n.classList.contains("fade"),r=()=>this._transitionComplete(t,n,i);if(n&&o){const t=s(n);n.classList.remove("show"),I.one(n,"transitionend",r),a(n,t)}else r()}_transitionComplete(t,e,i){if(e){e.classList.remove("active");const t=U.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),f(t),t.classList.contains("fade")&&t.classList.add("show");let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&U.find(".dropdown-toggle",e).forEach(t=>t.classList.add("active")),t.setAttribute("aria-expanded",!0)}i&&i()}static jQueryInterface(t){return this.each((function(){const e=v.get(this,"bs.tab")||new ii(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}I.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),d(this)||(v.get(this,"bs.tab")||new ii(this)).show()})),m("tab",ii);const ni={animation:"boolean",autohide:"boolean",delay:"number"},si={animation:!0,autohide:!0,delay:5e3};class oi extends M{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._setListeners()}static get DefaultType(){return ni}static get Default(){return si}static get DATA_KEY(){return"bs.toast"}show(){if(I.trigger(this._element,"show.bs.toast").defaultPrevented)return;this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");const t=()=>{this._element.classList.remove("showing"),this._element.classList.add("show"),I.trigger(this._element,"shown.bs.toast"),this._config.autohide&&(this._timeout=setTimeout(()=>{this.hide()},this._config.delay))};if(this._element.classList.remove("hide"),f(this._element),this._element.classList.add("showing"),this._config.animation){const e=s(this._element);I.one(this._element,"transitionend",t),a(this._element,e)}else t()}hide(){if(!this._element.classList.contains("show"))return;if(I.trigger(this._element,"hide.bs.toast").defaultPrevented)return;const t=()=>{this._element.classList.add("hide"),I.trigger(this._element,"hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){const e=s(this._element);I.one(this._element,"transitionend",t),a(this._element,e)}else t()}dispose(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),super.dispose(),this._config=null}_getConfig(t){return t={...si,...z.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},l("toast",t,this.constructor.DefaultType),t}_setListeners(){I.on(this._element,"click.dismiss.bs.toast",'[data-bs-dismiss="toast"]',()=>this.hide())}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){let e=v.get(this,"bs.toast");if(e||(e=new oi(this,"object"==typeof t&&t)),"string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return m("toast",oi),{Alert:H,Button:R,Carousel:X,Collapse:Z,Dropdown:ye,Modal:Ne,Offcanvas:Ie,Popover:Ze,ScrollSpy:ei,Tab:ii,Toast:oi,Tooltip:qe}})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),i=e=>{e.dispatchEvent(new Event(t))},n=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),s=t=>n(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(e(t)):null,o=t=>{if(!n(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},r=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),a=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?a(t.parentNode):null},l=()=>{},c=t=>{t.offsetHeight},h=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,d=[],u=()=>"rtl"===document.documentElement.dir,f=t=>{var e;e=()=>{const e=h();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(d.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of d)t()})),d.push(e)):e()},p=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,m=(e,n,s=!0)=>{if(!s)return void p(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(n)+5;let r=!1;const a=({target:i})=>{i===n&&(r=!0,n.removeEventListener(t,a),p(e))};n.addEventListener(t,a),setTimeout((()=>{r||i(n)}),o)},g=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},_=/[^.]*(?=\..*)\.|.*/,b=/\..*/,v=/::\d+$/,y={};let w=1;const A={mouseenter:"mouseover",mouseleave:"mouseout"},E=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function T(t,e){return e&&`${e}::${w++}`||t.uidEvent||w++}function C(t){const e=T(t);return t.uidEvent=e,y[e]=y[e]||{},y[e]}function O(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function x(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=D(t);return E.has(o)||(o=t),[n,s,o]}function k(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=x(e,i,n);if(e in A){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=C(t),c=l[a]||(l[a]={}),h=O(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=T(r,e.replace(_,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return N(s,{delegateTarget:r}),n.oneOff&&I.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return N(n,{delegateTarget:t}),i.oneOff&&I.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function L(t,e,i,n,s){const o=O(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function S(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&L(t,e,i,r.callable,r.delegationSelector)}function D(t){return t=t.replace(b,""),A[t]||t}const I={on(t,e,i,n){k(t,e,i,n,!1)},one(t,e,i,n){k(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=x(e,i,n),a=r!==e,l=C(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))S(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(v,"");a&&!e.includes(s)||L(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;L(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=h();let s=null,o=!0,r=!0,a=!1;e!==D(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());let l=new Event(e,{bubbles:o,cancelable:!0});return l=N(l,i),a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function N(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}const P=new Map,j={set(t,e,i){P.has(t)||P.set(t,new Map);const n=P.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>P.has(t)&&P.get(t).get(e)||null,remove(t,e){if(!P.has(t))return;const i=P.get(t);i.delete(e),0===i.size&&P.delete(t)}};function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const H={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${F(e)}`))};class ${static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=n(e)?H.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...n(e)?H.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[s,o]of Object.entries(e)){const e=t[s],r=n(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${s}" provided type "${r}" but expected type "${o}".`)}var i}}class W extends ${constructor(t,e){super(),(t=s(t))&&(this._element=t,this._config=this._getConfig(e),j.set(this._element,this.constructor.DATA_KEY,this))}dispose(){j.remove(this._element,this.constructor.DATA_KEY),I.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){m(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return j.get(s(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.0-alpha1"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let i=t.getAttribute("data-bs-target");if(!i||"#"===i){let e=t.getAttribute("href");if(!e||!e.includes("#")&&!e.startsWith("."))return null;e.includes("#")&&!e.startsWith("#")&&(e=`#${e.split("#")[1]}`),i=e&&"#"!==e?e.trim():null}return e(i)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!r(t)&&o(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;I.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),r(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))};class q extends W{static get NAME(){return"alert"}close(){if(I.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),I.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(q,"close"),f(q);const V='[data-bs-toggle="button"]';class K extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=K.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}I.on(document,"click.bs.button.data-api",V,(t=>{t.preventDefault();const e=t.target.closest(V);K.getOrCreateInstance(e).toggle()})),f(K);const Q={endCallback:null,leftCallback:null,rightCallback:null},X={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Y extends ${constructor(t,e){super(),this._element=t,t&&Y.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return Q}static get DefaultType(){return X}static get NAME(){return"swipe"}dispose(){I.off(this._element,".bs.swipe")}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),p(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&p(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(I.on(this._element,"pointerdown.bs.swipe",(t=>this._start(t))),I.on(this._element,"pointerup.bs.swipe",(t=>this._end(t))),this._element.classList.add("pointer-event")):(I.on(this._element,"touchstart.bs.swipe",(t=>this._start(t))),I.on(this._element,"touchmove.bs.swipe",(t=>this._move(t))),I.on(this._element,"touchend.bs.swipe",(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const U="next",G="prev",J="left",Z="right",tt="slid.bs.carousel",et="carousel",it="active",nt={ArrowLeft:Z,ArrowRight:J},st={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class rt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===et&&this.cycle()}static get Default(){return st}static get DefaultType(){return ot}static get NAME(){return"carousel"}next(){this._slide(U)}nextWhenVisible(){!document.hidden&&o(this._element)&&this.next()}prev(){this._slide(G)}pause(){this._isSliding&&i(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?I.one(this._element,tt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void I.one(this._element,tt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?U:G;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&I.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(I.on(this._element,"mouseenter.bs.carousel",(()=>this.pause())),I.on(this._element,"mouseleave.bs.carousel",(()=>this._maybeEnableCycle()))),this._config.touch&&Y.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))I.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(J)),rightCallback:()=>this._slide(this._directionToOrder(Z)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new Y(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=nt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(it),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===U,s=e||g(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>I.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r("slide.bs.carousel").defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",h=n?"carousel-item-next":"carousel-item-prev";s.classList.add(h),c(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,h),s.classList.add(it),i.classList.remove(it,h,l),this._isSliding=!1,r(tt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(".active.carousel-item",this._element)}_getItems(){return z.find(".carousel-item",this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return u()?t===J?G:U:t===J?U:G}_orderToDirection(t){return u()?t===G?J:Z:t===G?Z:J}static jQueryInterface(t){return this.each((function(){const e=rt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}I.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(et))return;t.preventDefault();const i=rt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===H.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),I.on(window,"load.bs.carousel.data-api",(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)rt.getOrCreateInstance(e)})),f(rt);const at="show",lt="collapse",ct="collapsing",ht='[data-bs-toggle="collapse"]',dt={parent:null,toggle:!0},ut={parent:"(null|element)",toggle:"boolean"};class ft extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(ht);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return dt}static get DefaultType(){return ut}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>ft.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(I.trigger(this._element,"show.bs.collapse").defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(lt),this._element.classList.add(ct),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ct),this._element.classList.add(lt,at),this._element.style[e]="",I.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(I.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,c(this._element),this._element.classList.add(ct),this._element.classList.remove(lt,at);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ct),this._element.classList.add(lt),I.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(at)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=s(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(ht);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(":scope .collapse .collapse",this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=ft.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}I.on(document,"click.bs.collapse.data-api",ht,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))ft.getOrCreateInstance(t,{toggle:!1}).toggle()})),f(ft);var pt="top",mt="bottom",gt="right",_t="left",bt="auto",vt=[pt,mt,gt,_t],yt="start",wt="end",At="clippingParents",Et="viewport",Tt="popper",Ct="reference",Ot=vt.reduce((function(t,e){return t.concat([e+"-"+yt,e+"-"+wt])}),[]),xt=[].concat(vt,[bt]).reduce((function(t,e){return t.concat([e,e+"-"+yt,e+"-"+wt])}),[]),kt="beforeRead",Lt="read",St="afterRead",Dt="beforeMain",It="main",Nt="afterMain",Pt="beforeWrite",jt="write",Mt="afterWrite",Ft=[kt,Lt,St,Dt,It,Nt,Pt,jt,Mt];function Ht(t){return t?(t.nodeName||"").toLowerCase():null}function $t(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function Wt(t){return t instanceof $t(t).Element||t instanceof Element}function Bt(t){return t instanceof $t(t).HTMLElement||t instanceof HTMLElement}function zt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof $t(t).ShadowRoot||t instanceof ShadowRoot)}const Rt={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];Bt(s)&&Ht(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});Bt(n)&&Ht(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function qt(t){return t.split("-")[0]}var Vt=Math.max,Kt=Math.min,Qt=Math.round;function Xt(){var t=navigator.userAgentData;return null!=t&&t.brands?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Yt(){return!/^((?!chrome|android).)*safari/i.test(Xt())}function Ut(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&Bt(t)&&(s=t.offsetWidth>0&&Qt(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Qt(n.height)/t.offsetHeight||1);var r=(Wt(t)?$t(t):window).visualViewport,a=!Yt()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Gt(t){var e=Ut(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Jt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&zt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Zt(t){return $t(t).getComputedStyle(t)}function te(t){return["table","td","th"].indexOf(Ht(t))>=0}function ee(t){return((Wt(t)?t.ownerDocument:t.document)||window.document).documentElement}function ie(t){return"html"===Ht(t)?t:t.assignedSlot||t.parentNode||(zt(t)?t.host:null)||ee(t)}function ne(t){return Bt(t)&&"fixed"!==Zt(t).position?t.offsetParent:null}function se(t){for(var e=$t(t),i=ne(t);i&&te(i)&&"static"===Zt(i).position;)i=ne(i);return i&&("html"===Ht(i)||"body"===Ht(i)&&"static"===Zt(i).position)?e:i||function(t){var e=/firefox/i.test(Xt());if(/Trident/i.test(Xt())&&Bt(t)&&"fixed"===Zt(t).position)return null;var i=ie(t);for(zt(i)&&(i=i.host);Bt(i)&&["html","body"].indexOf(Ht(i))<0;){var n=Zt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function oe(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function re(t,e,i){return Vt(t,Kt(e,i))}function ae(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function le(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const ce={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=qt(i.placement),l=oe(a),c=[_t,gt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return ae("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:le(t,vt))}(s.padding,i),d=Gt(o),u="y"===l?pt:_t,f="y"===l?mt:gt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=se(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=re(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Jt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function he(t){return t.split("-")[1]}var de={top:"auto",right:"auto",bottom:"auto",left:"auto"};function ue(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=_t,y=pt,w=window;if(c){var A=se(i),E="clientHeight",T="clientWidth";A===$t(i)&&"static"!==Zt(A=ee(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===pt||(s===_t||s===gt)&&o===wt)&&(y=mt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==_t&&(s!==pt&&s!==mt||o!==wt)||(v=gt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&de),x=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:Qt(e*n)/n||0,y:Qt(i*n)/n||0}}({x:f,y:m}):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const fe={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:qt(e.placement),variation:he(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,ue(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,ue(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var pe={passive:!0};const me={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=$t(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,pe)})),a&&l.addEventListener("resize",i.update,pe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,pe)})),a&&l.removeEventListener("resize",i.update,pe)}},data:{}};var ge={left:"right",right:"left",bottom:"top",top:"bottom"};function _e(t){return t.replace(/left|right|bottom|top/g,(function(t){return ge[t]}))}var be={start:"end",end:"start"};function ve(t){return t.replace(/start|end/g,(function(t){return be[t]}))}function ye(t){var e=$t(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function we(t){return Ut(ee(t)).left+ye(t).scrollLeft}function Ae(t){var e=Zt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Ht(t))>=0?t.ownerDocument.body:Bt(t)&&Ae(t)?t:Ee(ie(t))}function Te(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=$t(n),r=s?[o].concat(o.visualViewport||[],Ae(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Te(ie(r)))}function Ce(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e,i){return e===Et?Ce(function(t,e){var i=$t(t),n=ee(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Yt();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+we(t),y:l}}(t,i)):Wt(e)?function(t,e){var i=Ut(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ce(function(t){var e,i=ee(t),n=ye(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=Vt(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=Vt(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+we(t),l=-n.scrollTop;return"rtl"===Zt(s||i).direction&&(a+=Vt(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(ee(t)))}function xe(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?qt(s):null,r=s?he(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case pt:e={x:a,y:i.y-n.height};break;case mt:e={x:a,y:i.y+i.height};break;case gt:e={x:i.x+i.width,y:l};break;case _t:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?oe(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case yt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case wt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?At:a,c=i.rootBoundary,h=void 0===c?Et:c,d=i.elementContext,u=void 0===d?Tt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=ae("number"!=typeof g?g:le(g,vt)),b=u===Tt?Ct:Tt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Te(ie(t)),i=["absolute","fixed"].indexOf(Zt(t).position)>=0&&Bt(t)?se(t):t;return Wt(i)?e.filter((function(t){return Wt(t)&&Jt(t,i)&&"body"!==Ht(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=Oe(t,i,n);return e.top=Vt(s.top,e.top),e.right=Kt(s.right,e.right),e.bottom=Kt(s.bottom,e.bottom),e.left=Vt(s.left,e.left),e}),Oe(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(Wt(y)?y:y.contextElement||ee(t.elements.popper),l,h,r),A=Ut(t.elements.reference),E=xe({reference:A,element:v,strategy:"absolute",placement:s}),T=Ce(Object.assign({},v,E)),C=u===Tt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Tt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[gt,mt].indexOf(t)>=0?1:-1,i=[pt,mt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?xt:l,h=he(n),d=h?a?Ot:Ot.filter((function(t){return he(t)===h})):vt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[qt(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const Se={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=qt(g),b=l||(_!==g&&p?function(t){if(qt(t)===bt)return[];var e=_e(t);return[ve(t),e,ve(e)]}(g):[_e(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(qt(i)===bt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=ke(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),I=L?k?gt:_t:k?mt:pt;y[S]>w[S]&&(I=_e(I));var N=_e(I),P=[];if(o&&P.push(D[x]<=0),a&&P.push(D[I]<=0,D[N]<=0),P.every((function(t){return t}))){T=O,E=!1;break}A.set(O,P)}if(E)for(var j=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Ie(t){return[pt,gt,mt,_t].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Ie(l),d=Ie(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Pe={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=xt.reduce((function(t,i){return t[i]=function(t,e,i){var n=qt(t),s=[_t,pt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[_t,gt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},je={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=xe({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},Me={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=qt(e.placement),b=he(e.placement),v=!b,y=oe(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?pt:_t,D="y"===y?mt:gt,I="y"===y?"height":"width",N=A[y],P=N+g[S],j=N-g[D],M=f?-T[I]/2:0,F=b===yt?E[I]:T[I],H=b===yt?-T[I]:-E[I],$=e.elements.arrow,W=f&&$?Gt($):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=re(0,E[I],W[I]),V=v?E[I]/2-M-q-z-O.mainAxis:F-q-z-O.mainAxis,K=v?-E[I]/2+M+q+R+O.mainAxis:H+q+R+O.mainAxis,Q=e.elements.arrow&&se(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=N+K-Y,G=re(f?Kt(P,N+V-Y-X):P,N,f?Vt(j,U):j);A[y]=G,k[y]=G-N}if(a){var J,Z="x"===y?pt:_t,tt="x"===y?mt:gt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[pt,_t].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=re(t,e,i);return n>i?i:n}(at,et,lt):re(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function Fe(t,e,i){void 0===i&&(i=!1);var n,s,o=Bt(e),r=Bt(e)&&function(t){var e=t.getBoundingClientRect(),i=Qt(e.width)/t.offsetWidth||1,n=Qt(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=ee(e),l=Ut(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==Ht(e)||Ae(a))&&(c=(n=e)!==$t(n)&&Bt(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:ye(n)),Bt(e)?((h=Ut(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=we(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var $e={placement:"bottom",modifiers:[],strategy:"absolute"};function We(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(H.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...p(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>o(t)));i.length&&g(i,e,t===Xe,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=ci.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ze);for(const i of e){const e=ci.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Qe,Xe].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Je)?this:z.prev(this,Je)[0]||z.next(this,Je)[0]||z.findOne(Je,t.delegateTarget.parentNode),o=ci.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}I.on(document,Ue,Je,ci.dataApiKeydownHandler),I.on(document,Ue,ti,ci.dataApiKeydownHandler),I.on(document,Ye,ci.clearMenus),I.on(document,"keyup.bs.dropdown.data-api",ci.clearMenus),I.on(document,Ye,Je,(function(t){t.preventDefault(),ci.getOrCreateInstance(this).toggle()})),f(ci);const hi=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",di=".sticky-top",ui="padding-right",fi="margin-right";class pi{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,ui,(e=>e+t)),this._setElementAttributes(hi,ui,(e=>e+t)),this._setElementAttributes(di,fi,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,ui),this._resetElementAttributes(hi,ui),this._resetElementAttributes(di,fi)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&H.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=H.getDataAttribute(t,e);null!==i?(H.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(n(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const mi="show",gi="mousedown.bs.backdrop",_i={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},bi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class vi extends ${constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return _i}static get DefaultType(){return bi}static get NAME(){return"backdrop"}show(t){if(!this._config.isVisible)return void p(t);this._append();const e=this._getElement();this._config.isAnimated&&c(e),e.classList.add(mi),this._emulateAnimation((()=>{p(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(mi),this._emulateAnimation((()=>{this.dispose(),p(t)}))):p(t)}dispose(){this._isAppended&&(I.off(this._element,gi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=s(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),I.on(t,gi,(()=>{p(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){m(t,this._getElement(),this._config.isAnimated)}}const yi=".bs.focustrap",wi="backward",Ai={autofocus:!0,trapElement:null},Ei={autofocus:"boolean",trapElement:"element"};class Ti extends ${constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return Ai}static get DefaultType(){return Ei}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),I.off(document,yi),I.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),I.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,I.off(document,yi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===wi?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?wi:"forward")}}const Ci="hidden.bs.modal",Oi="show.bs.modal",xi="modal-open",ki="show",Li="modal-static",Si={backdrop:!0,focus:!0,keyboard:!0},Di={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class Ii extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new pi,this._addEventListeners()}static get Default(){return Si}static get DefaultType(){return Di}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||I.trigger(this._element,Oi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(xi),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(I.trigger(this._element,"hide.bs.modal").defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(ki),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){for(const t of[window,this._dialog])I.off(t,".bs.modal");this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new vi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ti({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),c(this._element),this._element.classList.add(ki),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,I.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){I.on(this._element,"keydown.dismiss.bs.modal",(t=>{if("Escape"===t.key)return this._config.keyboard?(t.preventDefault(),void this.hide()):void this._triggerBackdropTransition()})),I.on(window,"resize.bs.modal",(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),I.on(this._element,"mousedown.dismiss.bs.modal",(t=>{I.one(this._element,"click.dismiss.bs.modal",(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(xi),this._resetAdjustments(),this._scrollBar.reset(),I.trigger(this._element,Ci)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(I.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Li)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Li),this._queueCallback((()=>{this._element.classList.remove(Li),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=u()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=u()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Ii.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}I.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),I.one(e,Oi,(t=>{t.defaultPrevented||I.one(e,Ci,(()=>{o(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&Ii.getInstance(i).hide(),Ii.getOrCreateInstance(e).toggle(this)})),R(Ii),f(Ii);const Ni="show",Pi="showing",ji="hiding",Mi=".offcanvas.show",Fi="hidePrevented.bs.offcanvas",Hi="hidden.bs.offcanvas",$i={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Bi extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return $i}static get DefaultType(){return Wi}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||I.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new pi).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Pi),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Ni),this._element.classList.remove(Pi),I.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(I.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(ji),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Ni,ji),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new pi).reset(),I.trigger(this._element,Hi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new vi({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():I.trigger(this._element,Fi)}:null})}_initializeFocusTrap(){return new Ti({trapElement:this._element})}_addEventListeners(){I.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():I.trigger(this._element,Fi))}))}static jQueryInterface(t){return this.each((function(){const e=Bi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}I.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),r(this))return;I.one(e,Hi,(()=>{o(this)&&this.focus()}));const i=z.findOne(Mi);i&&i!==e&&Bi.getInstance(i).hide(),Bi.getOrCreateInstance(e).toggle(this)})),I.on(window,"load.bs.offcanvas.data-api",(()=>{for(const t of z.find(Mi))Bi.getOrCreateInstance(t).show()})),I.on(window,"resize.bs.offcanvas",(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Bi.getOrCreateInstance(t).hide()})),R(Bi),f(Bi);const zi=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Ri=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,qi=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Vi=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!zi.has(i)||Boolean(Ri.test(t.nodeValue)||qi.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Ki={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Qi={allowList:Ki,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Xi={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Yi={entry:"(string|element|function|null)",selector:"(string|element)"};class Ui extends ${constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Qi}static get DefaultType(){return Xi}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Yi)}_setContent(t,e,i){const o=z.findOne(i,t);o&&((e=this._resolvePossibleFunction(e))?n(e)?this._putElementInTemplate(s(e),o):this._config.html?o.innerHTML=this._maybeSanitize(e):o.textContent=e:o.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Vi(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return p(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Gi=new Set(["sanitize","allowList","sanitizeFn"]),Ji="fade",Zi="show",tn=".modal",en="hide.bs.modal",nn="hover",sn="focus",on={AUTO:"auto",TOP:"top",RIGHT:u()?"left":"right",BOTTOM:"bottom",LEFT:u()?"right":"left"},rn={allowList:Ki,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,0],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},an={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class ln extends W{constructor(t,e){if(void 0===Ve)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return rn}static get DefaultType(){return an}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),I.off(this._element.closest(tn),en,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=I.trigger(this._element,this.constructor.eventName("show")),e=(a(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),I.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(Zi),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))I.on(t,"mouseover",l);this._queueCallback((()=>{I.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!I.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(Zi),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))I.off(t,"mouseover",l);this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),I.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(Ji,Zi),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(Ji),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Ui({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Ji)}_isShown(){return this.tip&&this.tip.classList.contains(Zi)}_createPopper(t){const e=p(this._config.placement,[this,t,this._element]),i=on[e.toUpperCase()];return qe(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return p(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...p(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)I.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===nn?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===nn?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");I.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?sn:nn]=!0,e._enter()})),I.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?sn:nn]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},I.on(this._element.closest(tn),en,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=H.getDataAttributes(this._element);for(const t of Object.keys(e))Gi.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:s(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=ln.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}f(ln);const cn={...ln.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},hn={...ln.DefaultType,content:"(null|string|element|function)"};class dn extends ln{static get Default(){return cn}static get DefaultType(){return hn}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=dn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}f(dn);const un="click.bs.scrollspy",fn="active",pn="[href]",mn={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},gn={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class _n extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return mn}static get DefaultType(){return gn}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=s(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(I.off(this._config.target,un),I.on(this._config.target,un,pn,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(pn,this._config.target);for(const e of t){if(!e.hash||r(e))continue;const t=z.findOne(e.hash,this._element);o(t)&&(this._targetLinks.set(e.hash,e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(fn),this._activateParents(t),I.trigger(this._element,"activate.bs.scrollspy",{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(fn);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,".nav-link, .nav-item > .nav-link, .list-group-item"))t.classList.add(fn)}_clearActiveClass(t){t.classList.remove(fn);const e=z.find("[href].active",t);for(const t of e)t.classList.remove(fn)}static jQueryInterface(t){return this.each((function(){const e=_n.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}I.on(window,"load.bs.scrollspy.data-api",(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))_n.getOrCreateInstance(t)})),f(_n);const bn="ArrowLeft",vn="ArrowRight",yn="ArrowUp",wn="ArrowDown",An="active",En="fade",Tn="show",Cn='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',On=`.nav-link:not(.dropdown-toggle), .list-group-item:not(.dropdown-toggle), [role="tab"]:not(.dropdown-toggle), ${Cn}`;class xn extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),I.on(this._element,"keydown.bs.tab",(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?I.trigger(e,"hide.bs.tab",{relatedTarget:t}):null;I.trigger(t,"show.bs.tab",{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(An),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),I.trigger(t,"shown.bs.tab",{relatedTarget:e})):t.classList.add(Tn)}),t,t.classList.contains(En)))}_deactivate(t,e){t&&(t.classList.remove(An),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),I.trigger(t,"hidden.bs.tab",{relatedTarget:e})):t.classList.remove(Tn)}),t,t.classList.contains(En)))}_keydown(t){if(![bn,vn,yn,wn].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[vn,wn].includes(t.key),i=g(this._getChildren().filter((t=>!r(t))),t.target,e,!0);i&&(i.focus({preventScroll:!0}),xn.getOrCreateInstance(i).show())}_getChildren(){return z.find(On,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`#${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",An),n(".dropdown-menu",Tn),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(An)}_getInnerElement(t){return t.matches(On)?t:z.findOne(On,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}I.on(document,"click.bs.tab",Cn,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),r(this)||xn.getOrCreateInstance(this).show()})),I.on(window,"load.bs.tab",(()=>{for(const t of z.find('.active[data-bs-toggle="tab"], .active[data-bs-toggle="pill"], .active[data-bs-toggle="list"]'))xn.getOrCreateInstance(t)})),f(xn);const kn="hide",Ln="show",Sn="showing",Dn={animation:"boolean",autohide:"boolean",delay:"number"},In={animation:!0,autohide:!0,delay:5e3};class Nn extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return In}static get DefaultType(){return Dn}static get NAME(){return"toast"}show(){I.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(kn),c(this._element),this._element.classList.add(Ln,Sn),this._queueCallback((()=>{this._element.classList.remove(Sn),I.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(I.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(Sn),this._queueCallback((()=>{this._element.classList.add(kn),this._element.classList.remove(Sn,Ln),I.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(Ln),super.dispose()}isShown(){return this._element.classList.contains(Ln)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){I.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),I.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),I.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),I.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Nn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Nn),f(Nn),{Alert:q,Button:K,Carousel:rt,Collapse:ft,Dropdown:ci,Modal:Ii,Offcanvas:Bi,Popover:dn,ScrollSpy:_n,Tab:xn,Toast:Nn,Tooltip:ln}})); //# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/ScreenPlay/inc/public/ScreenPlay/app.h b/ScreenPlay/inc/public/ScreenPlay/app.h index 9c570fe7..8512b7de 100644 --- a/ScreenPlay/inc/public/ScreenPlay/app.h +++ b/ScreenPlay/inc/public/ScreenPlay/app.h @@ -87,105 +87,19 @@ public slots: QString version() const; void showDockIcon(const bool show); void exit(); - QPointF cursorPos() { return QCursor::pos(); } - void setGlobalVariables(GlobalVariables* globalVariables) - { - if (m_globalVariables.get() == globalVariables) - return; - - m_globalVariables.reset(globalVariables); - emit globalVariablesChanged(m_globalVariables.get()); - } - void setScreenPlayManager(ScreenPlayManager* screenPlayManager) - { - if (m_screenPlayManager.get() == screenPlayManager) - return; - - m_screenPlayManager.reset(screenPlayManager); - emit screenPlayManagerChanged(m_screenPlayManager.get()); - } - - void setCreate(Create* create) - { - if (m_create.get() == create) - return; - - m_create.reset(create); - emit createChanged(m_create.get()); - } - - void setUtil(Util* util) - { - if (m_util.get() == util) - return; - - m_util.reset(util); - emit utilChanged(m_util.get()); - } - - void setSettings(Settings* settings) - { - if (m_settings.get() == settings) - return; - - m_settings.reset(settings); - emit settingsChanged(m_settings.get()); - } - - void setInstalledListModel(InstalledListModel* installedListModel) - { - if (m_installedListModel.get() == installedListModel) - return; - - m_installedListModel.reset(installedListModel); - emit installedListModelChanged(m_installedListModel.get()); - } - void setMonitorListModel(MonitorListModel* monitorListModel) - { - if (m_monitorListModel.get() == monitorListModel) - return; - - m_monitorListModel.reset(monitorListModel); - emit monitorListModelChanged(m_monitorListModel.get()); - } - - void setProfileListModel(ProfileListModel* profileListModel) - { - if (m_profileListModel.get() == profileListModel) - return; - - m_profileListModel.reset(profileListModel); - emit profileListModelChanged(m_profileListModel.get()); - } - - void setInstalledListFilter(InstalledListFilter* installedListFilter) - { - if (m_installedListFilter.get() == installedListFilter) - return; - - m_installedListFilter.reset(installedListFilter); - emit installedListFilterChanged(m_installedListFilter.get()); - } - - void setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine) - { - if (m_mainWindowEngine.get() == mainWindowEngine) - return; - - m_mainWindowEngine.reset(mainWindowEngine); - emit mainWindowEngineChanged(m_mainWindowEngine.get()); - } - - void setWizards(Wizards* wizards) - { - if (m_wizards.get() == wizards) - return; - - m_wizards.reset(wizards); - emit wizardsChanged(m_wizards.get()); - } + void setGlobalVariables(GlobalVariables* globalVariables); + void setScreenPlayManager(ScreenPlayManager* screenPlayManager); + void setCreate(Create* create); + void setUtil(Util* util); + void setSettings(Settings* settings); + void setInstalledListModel(InstalledListModel* installedListModel); + void setMonitorListModel(MonitorListModel* monitorListModel); + void setProfileListModel(ProfileListModel* profileListModel); + void setInstalledListFilter(InstalledListFilter* installedListFilter); + void setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine); + void setWizards(Wizards* wizards); private: bool setupKDE(); diff --git a/ScreenPlay/main.cpp b/ScreenPlay/main.cpp index fd38753c..6e364151 100644 --- a/ScreenPlay/main.cpp +++ b/ScreenPlay/main.cpp @@ -19,7 +19,7 @@ int main(int argc, char* argv[]) { #if !defined(Q_OS_LINUX) - qputenv("QT_MEDIA_BACKEND","ffmpeg"); + qputenv("QT_MEDIA_BACKEND", "ffmpeg"); #endif #if defined(Q_OS_WIN) diff --git a/ScreenPlay/src/app.cpp b/ScreenPlay/src/app.cpp index b3253a62..85fe5b72 100644 --- a/ScreenPlay/src/app.cpp +++ b/ScreenPlay/src/app.cpp @@ -5,15 +5,19 @@ #include "ScreenPlayUtil/macutils.h" #endif +#include "app.h" #include "steam/steam_qt_enums_generated.h" #include #include #include namespace ScreenPlay { + /*! \module ScreenPlay + \title ScreenPlay + \brief Module for ScreenPlay. */ /*! @@ -344,4 +348,158 @@ void App::showDockIcon(const bool show) #endif } +/*! + \property App::globalVariables + \brief . + + . +*/ +void App::setGlobalVariables(GlobalVariables* globalVariables) +{ + if (m_globalVariables.get() == globalVariables) + return; + + m_globalVariables.reset(globalVariables); + emit globalVariablesChanged(m_globalVariables.get()); +} +/*! + \property App::screenPlayManager + \brief . + + . +*/ +void App::setScreenPlayManager(ScreenPlayManager* screenPlayManager) +{ + if (m_screenPlayManager.get() == screenPlayManager) + return; + + m_screenPlayManager.reset(screenPlayManager); + emit screenPlayManagerChanged(m_screenPlayManager.get()); +} +/*! + \property App::create + \brief . + + . +*/ +void App::setCreate(Create* create) +{ + if (m_create.get() == create) + return; + + m_create.reset(create); + emit createChanged(m_create.get()); +} +/*! + \property App::util + \brief . + + . +*/ +void App::setUtil(Util* util) +{ + if (m_util.get() == util) + return; + + m_util.reset(util); + emit utilChanged(m_util.get()); +} +/*! + \property App::settings + \brief . + + . +*/ +void App::setSettings(Settings* settings) +{ + if (m_settings.get() == settings) + return; + + m_settings.reset(settings); + emit settingsChanged(m_settings.get()); +} +/*! + \property App::installedListModel + \brief . + + . +*/ +void App::setInstalledListModel(InstalledListModel* installedListModel) +{ + if (m_installedListModel.get() == installedListModel) + return; + + m_installedListModel.reset(installedListModel); + emit installedListModelChanged(m_installedListModel.get()); +} +/*! + \property App::monitorListModel + \brief . + + . +*/ +void App::setMonitorListModel(MonitorListModel* monitorListModel) +{ + if (m_monitorListModel.get() == monitorListModel) + return; + + m_monitorListModel.reset(monitorListModel); + emit monitorListModelChanged(m_monitorListModel.get()); +} +/*! + \property App::profileListModel + \brief . + + . +*/ +void App::setProfileListModel(ProfileListModel* profileListModel) +{ + if (m_profileListModel.get() == profileListModel) + return; + + m_profileListModel.reset(profileListModel); + emit profileListModelChanged(m_profileListModel.get()); +} +/*! + \property App::installedListFilter + \brief . + + . +*/ +void App::setInstalledListFilter(InstalledListFilter* installedListFilter) +{ + if (m_installedListFilter.get() == installedListFilter) + return; + + m_installedListFilter.reset(installedListFilter); + emit installedListFilterChanged(m_installedListFilter.get()); +} +/*! + \property App::mainWindowEngine + \brief . + + . +*/ +void App::setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine) +{ + if (m_mainWindowEngine.get() == mainWindowEngine) + return; + + m_mainWindowEngine.reset(mainWindowEngine); + emit mainWindowEngineChanged(m_mainWindowEngine.get()); +} +/*! + \property App::wizards + \brief . + + . +*/ +void App::setWizards(Wizards* wizards) +{ + if (m_wizards.get() == wizards) + return; + + m_wizards.reset(wizards); + emit wizardsChanged(m_wizards.get()); +} } diff --git a/ScreenPlaySDK/src/screenplaysdk.cpp b/ScreenPlaySDK/src/screenplaysdk.cpp index 6a982053..fb61d76c 100644 --- a/ScreenPlaySDK/src/screenplaysdk.cpp +++ b/ScreenPlaySDK/src/screenplaysdk.cpp @@ -32,15 +32,14 @@ void ScreenPlaySDK::start() connect(&m_socket, &QLocalSocket::connected, this, &ScreenPlaySDK::connected); connect(&m_socket, &QLocalSocket::disconnected, this, &ScreenPlaySDK::disconnected); connect(&m_socket, &QLocalSocket::readyRead, this, &ScreenPlaySDK::readyRead); - connect(&m_socket, &QLocalSocket::errorOccurred, this, [this](){ + connect(&m_socket, &QLocalSocket::errorOccurred, this, [this]() { emit disconnected(); }); m_socket.connectToServer("ScreenPlay"); - if (!m_socket.waitForConnected(1000)){ + if (!m_socket.waitForConnected(1000)) { emit disconnected(); } - } ScreenPlaySDK::~ScreenPlaySDK() @@ -57,14 +56,14 @@ void ScreenPlaySDK::sendMessage(const QJsonObject& obj) void ScreenPlaySDK::connected() { - + if (m_appID.isEmpty() || m_type.isEmpty()) { qCritical() << "Unable to connect with empyt: " << m_appID << m_type; emit disconnected(); return; } - QByteArray welcomeMessage = QString("appID="+m_appID + "," + m_type).toUtf8(); + QByteArray welcomeMessage = QString("appID=" + m_appID + "," + m_type).toUtf8(); m_socket.write(welcomeMessage); if (!m_socket.waitForBytesWritten()) { disconnected(); diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/exitcodes.h b/ScreenPlayUtil/inc/public/ScreenPlayUtil/exitcodes.h index ec0ad8e0..9a3e5c76 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/exitcodes.h +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/exitcodes.h @@ -2,19 +2,19 @@ namespace ScreenPlay { - Q_NAMESPACE +Q_NAMESPACE enum class WallpaperExitCode { Ok = 0, Invalid_ArgumentSize, Invalid_ActiveScreensList, - Invalid_InstalledType , - Invalid_CheckWallpaperVisible , - Invalid_Volume , - Invalid_AppID , - Invalid_Setup_ProjectParsingError , - Invalid_Setup_Error , - Invalid_Start_Windows_HandleError , + Invalid_InstalledType, + Invalid_CheckWallpaperVisible, + Invalid_Volume, + Invalid_AppID, + Invalid_Setup_ProjectParsingError, + Invalid_Setup_Error, + Invalid_Start_Windows_HandleError, }; Q_ENUM_NS(WallpaperExitCode) } \ No newline at end of file diff --git a/ScreenPlayUtil/src/projectfile.cpp b/ScreenPlayUtil/src/projectfile.cpp index 740c321b..4b735168 100644 --- a/ScreenPlayUtil/src/projectfile.cpp +++ b/ScreenPlayUtil/src/projectfile.cpp @@ -57,7 +57,7 @@ bool ProjectFile::init() if (obj.contains("previewThumbnail")) { preview = obj.value("previewThumbnail").toString(); } else { - if (obj.contains("preview")) + if (obj.contains("preview")) preview = obj.value("preview").toString(); } @@ -72,7 +72,6 @@ bool ProjectFile::init() } } - if (type == InstalledType::InstalledType::GifWallpaper) { preview = previewGIF; } diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index 85783472..4f70cada 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -5,8 +5,8 @@ #include #include -#include "ScreenPlayUtil/util.h" #include "ScreenPlayUtil/exitcodes.h" +#include "ScreenPlayUtil/util.h" #if defined(Q_OS_WIN) #include "src/winwindow.h" @@ -20,10 +20,10 @@ Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin) Q_IMPORT_QML_PLUGIN(ScreenPlayWeatherPlugin) int main(int argc, char* argv[]) -{ +{ #if !defined(Q_OS_LINUX) - qputenv("QT_MEDIA_BACKEND","ffmpeg"); + qputenv("QT_MEDIA_BACKEND", "ffmpeg"); #endif QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); @@ -47,7 +47,7 @@ int main(int argc, char* argv[]) if (argumentList.length() == 1) { window.setActiveScreensList({ 0 }); window.setProjectPath("test"); - //window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/19112022140605-Horde 1980"); + // window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/19112022140605-Horde 1980"); window.setAppID("test"); window.setVolume(1); window.setFillMode("fill"); diff --git a/ScreenPlayWallpaper/src/basewindow.h b/ScreenPlayWallpaper/src/basewindow.h index 89668b69..5d7fa842 100644 --- a/ScreenPlayWallpaper/src/basewindow.h +++ b/ScreenPlayWallpaper/src/basewindow.h @@ -14,9 +14,9 @@ #include #include -#include "ScreenPlayUtil/util.h" -#include "ScreenPlayUtil/exitcodes.h" #include "ScreenPlaySDK/screenplaysdk.h" +#include "ScreenPlayUtil/exitcodes.h" +#include "ScreenPlayUtil/util.h" #include diff --git a/ScreenPlayWallpaper/src/linuxx11window.h b/ScreenPlayWallpaper/src/linuxx11window.h index 8c523942..7f6e0860 100644 --- a/ScreenPlayWallpaper/src/linuxx11window.h +++ b/ScreenPlayWallpaper/src/linuxx11window.h @@ -17,7 +17,7 @@ class LinuxX11Window : public BaseWindow { Q_OBJECT - + public: ScreenPlay::WallpaperExitCode start() override; diff --git a/ScreenPlayWallpaper/src/macwindow.cpp b/ScreenPlayWallpaper/src/macwindow.cpp index 41b5c17b..9b1ed75c 100644 --- a/ScreenPlayWallpaper/src/macwindow.cpp +++ b/ScreenPlayWallpaper/src/macwindow.cpp @@ -1,15 +1,14 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "macwindow.h" - ScreenPlay::WallpaperExitCode MacWindow::start() { auto* screen = QGuiApplication::screens().at(activeScreensList().at(0)); m_window.setGeometry(screen->geometry()); - + qmlRegisterSingletonInstance("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); - - if(!debugMode()){ + + if (!debugMode()) { connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &MacWindow::destroyThis); } diff --git a/ScreenPlayWallpaper/src/winwindow.cpp b/ScreenPlayWallpaper/src/winwindow.cpp index f0bfde24..b203ce64 100644 --- a/ScreenPlayWallpaper/src/winwindow.cpp +++ b/ScreenPlayWallpaper/src/winwindow.cpp @@ -121,7 +121,7 @@ ScreenPlay::WallpaperExitCode WinWindow::start() }, Qt::QueuedConnection); auto* guiAppInst = dynamic_cast(QApplication::instance()); - if(!debugMode()){ + if (!debugMode()) { connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &WinWindow::destroyThis); } connect(guiAppInst, &QApplication::screenAdded, this, &WinWindow::configureWindowGeometry); diff --git a/ScreenPlayWidget/main.cpp b/ScreenPlayWidget/main.cpp index bcc85c6f..05dd8f96 100644 --- a/ScreenPlayWidget/main.cpp +++ b/ScreenPlayWidget/main.cpp @@ -16,7 +16,7 @@ int main(int argc, char* argv[]) { #if !defined(Q_OS_LINUX) - qputenv("QT_MEDIA_BACKEND","ffmpeg"); + qputenv("QT_MEDIA_BACKEND", "ffmpeg"); #endif QtWebEngineQuick::initialize(); diff --git a/Tools/qdoc.py b/Tools/qdoc.py index 45fe3f33..42d83db8 100644 --- a/Tools/qdoc.py +++ b/Tools/qdoc.py @@ -4,18 +4,22 @@ import subprocess import os import shutil from sys import stdout +import defines stdout.reconfigure(encoding='utf-8') def main(): - print("\nRuns qdoc with the settings from Docs/config.qdocconf. For this you need to have Qt 6.1 installed!") - + shutil.rmtree('../Docs/html/') os.mkdir('../Docs/html/') - if os.name == "nt": - process = subprocess.Popen("C:\\Qt\\6.1.0\\msvc2019_64\\bin\\qdoc.exe ../Docs/config.qdocconf", stdout=subprocess.PIPE) - else: - process = subprocess.Popen("qdoc ../Docs/configCI.qdocconf", stdout=subprocess.PIPE) + + qt_bin_path = defines.QT_BIN_PATH + executable = "qdoc" + if os.name == 'nt': + executable = "qdoc.exe" + executable = qt_bin_path.joinpath(executable) + + process = subprocess.Popen(f"{executable} ../Docs/config.qdocconf", stdout=subprocess.PIPE) if __name__ == "__main__": main() From 9b97d81e396e73de6450694964ea4d8bed6281ee Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 29 Jan 2023 13:03:03 +0100 Subject: [PATCH 24/56] Bump to 6.5 on all platforms --- Tools/defines.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/defines.py b/Tools/defines.py index c49773ce..f2f4910c 100644 --- a/Tools/defines.py +++ b/Tools/defines.py @@ -21,7 +21,7 @@ SCREENPLAY_VERSION = "0.15.0-RC4" QT_PATH = Path.cwd().parent.parent.joinpath("aqt") -QT_VERSION = "6.5.0" if sys.platform != "linux" else "6.4.2" +QT_VERSION = "6.5.0" QT_BIN_PATH = QT_PATH.joinpath(f"{QT_VERSION}/{QT_PLATFORM}/bin") QT_TOOLS_PATH = QT_PATH.joinpath("Tools/") QT_IFW_VERSION = "4.5" From 31005092beaa0eef452ab050eb68b0fc480ac922 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 29 Jan 2023 13:26:36 +0100 Subject: [PATCH 25/56] Bump version to 0.15.0-RC5 --- .gitignore | 1 + CMakePresets.json | 4 +- ScreenPlay/src/app.cpp | 151 +++++++++--------- .../kde/ScreenPlay/metadata.desktop | 2 +- Tools/Installer/package.xml | 2 +- Tools/Scoop/ScreenPlay.json | 2 +- Tools/build.py | 4 +- Tools/chocolatey/ScreenPlay/ReadMe.md | 4 +- Tools/chocolatey/ScreenPlay/screenplay.nuspec | 2 +- .../ScreenPlay/tools/chocolateyinstall.ps1 | 2 +- Tools/defines.py | 10 +- 11 files changed, 90 insertions(+), 94 deletions(-) diff --git a/.gitignore b/.gitignore index f974367c..1b6b03e3 100644 --- a/.gitignore +++ b/.gitignore @@ -258,3 +258,4 @@ cython_debug/ /Tools/Steam/ContentBuilder/builder_osx/** /tmp_steam_config/** /Tools/Steam/ContentBuilder/output/** +/.vscode/settings.json diff --git a/CMakePresets.json b/CMakePresets.json index 3f8e07f8..6e1b298a 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -48,7 +48,7 @@ { "name": "windows-debug-qt-6.5.0", "inherits": "default-windows", - "displayName": "MSVC K3000 Qt 6.5.0 Debug", + "displayName": "MSVC SP Qt 6.5.0 Debug", "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug", "environment": { "qt_version": "6.5.0" @@ -60,7 +60,7 @@ { "name": "windows-relwithdebinfo-qt-6.5.0", "inherits": "default-windows", - "displayName": "MSVC K3000 Qt 6.5.0 RelWithDebInfo", + "displayName": "MSVC SP Qt 6.5.0 RelWithDebInfo", "binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.5.0_MSVC_RelWithDebInfo", "environment": { "qt_version": "6.5.0" diff --git a/ScreenPlay/src/app.cpp b/ScreenPlay/src/app.cpp index 85fe5b72..b9dbc260 100644 --- a/ScreenPlay/src/app.cpp +++ b/ScreenPlay/src/app.cpp @@ -5,19 +5,19 @@ #include "ScreenPlayUtil/macutils.h" #endif -#include "app.h" #include "steam/steam_qt_enums_generated.h" #include #include #include +#include "app.h" namespace ScreenPlay { -/*! +/*! \module ScreenPlay \title ScreenPlay - + \brief Module for ScreenPlay. */ /*! @@ -362,144 +362,143 @@ void App::setGlobalVariables(GlobalVariables* globalVariables) m_globalVariables.reset(globalVariables); emit globalVariablesChanged(m_globalVariables.get()); } + /*! \property App::screenPlayManager - \brief . - - . + \brief Sets the screen play manager. */ -void App::setScreenPlayManager(ScreenPlayManager* screenPlayManager) -{ - if (m_screenPlayManager.get() == screenPlayManager) - return; + void App::setScreenPlayManager(ScreenPlayManager* screenPlayManager) + { + if (m_screenPlayManager.get() == screenPlayManager) + return; - m_screenPlayManager.reset(screenPlayManager); - emit screenPlayManagerChanged(m_screenPlayManager.get()); -} + m_screenPlayManager.reset(screenPlayManager); + emit screenPlayManagerChanged(m_screenPlayManager.get()); + } /*! \property App::create \brief . . */ -void App::setCreate(Create* create) -{ - if (m_create.get() == create) - return; + void App::setCreate(Create* create) + { + if (m_create.get() == create) + return; - m_create.reset(create); - emit createChanged(m_create.get()); -} + m_create.reset(create); + emit createChanged(m_create.get()); + } /*! \property App::util \brief . . */ -void App::setUtil(Util* util) -{ - if (m_util.get() == util) - return; + void App::setUtil(Util* util) + { + if (m_util.get() == util) + return; - m_util.reset(util); - emit utilChanged(m_util.get()); -} + m_util.reset(util); + emit utilChanged(m_util.get()); + } /*! \property App::settings \brief . . */ -void App::setSettings(Settings* settings) -{ - if (m_settings.get() == settings) - return; + void App::setSettings(Settings* settings) + { + if (m_settings.get() == settings) + return; - m_settings.reset(settings); - emit settingsChanged(m_settings.get()); -} + m_settings.reset(settings); + emit settingsChanged(m_settings.get()); + } /*! \property App::installedListModel \brief . . */ -void App::setInstalledListModel(InstalledListModel* installedListModel) -{ - if (m_installedListModel.get() == installedListModel) - return; + void App::setInstalledListModel(InstalledListModel* installedListModel) + { + if (m_installedListModel.get() == installedListModel) + return; - m_installedListModel.reset(installedListModel); - emit installedListModelChanged(m_installedListModel.get()); -} + m_installedListModel.reset(installedListModel); + emit installedListModelChanged(m_installedListModel.get()); + } /*! \property App::monitorListModel \brief . . */ -void App::setMonitorListModel(MonitorListModel* monitorListModel) -{ - if (m_monitorListModel.get() == monitorListModel) - return; + void App::setMonitorListModel(MonitorListModel* monitorListModel) + { + if (m_monitorListModel.get() == monitorListModel) + return; - m_monitorListModel.reset(monitorListModel); - emit monitorListModelChanged(m_monitorListModel.get()); -} + m_monitorListModel.reset(monitorListModel); + emit monitorListModelChanged(m_monitorListModel.get()); + } /*! \property App::profileListModel \brief . . */ -void App::setProfileListModel(ProfileListModel* profileListModel) -{ - if (m_profileListModel.get() == profileListModel) - return; + void App::setProfileListModel(ProfileListModel* profileListModel) + { + if (m_profileListModel.get() == profileListModel) + return; - m_profileListModel.reset(profileListModel); - emit profileListModelChanged(m_profileListModel.get()); -} + m_profileListModel.reset(profileListModel); + emit profileListModelChanged(m_profileListModel.get()); + } /*! \property App::installedListFilter \brief . . */ -void App::setInstalledListFilter(InstalledListFilter* installedListFilter) -{ - if (m_installedListFilter.get() == installedListFilter) - return; + void App::setInstalledListFilter(InstalledListFilter* installedListFilter) + { + if (m_installedListFilter.get() == installedListFilter) + return; - m_installedListFilter.reset(installedListFilter); - emit installedListFilterChanged(m_installedListFilter.get()); -} + m_installedListFilter.reset(installedListFilter); + emit installedListFilterChanged(m_installedListFilter.get()); + } /*! \property App::mainWindowEngine \brief . . */ -void App::setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine) -{ - if (m_mainWindowEngine.get() == mainWindowEngine) - return; + void App::setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine) + { + if (m_mainWindowEngine.get() == mainWindowEngine) + return; - m_mainWindowEngine.reset(mainWindowEngine); - emit mainWindowEngineChanged(m_mainWindowEngine.get()); -} + m_mainWindowEngine.reset(mainWindowEngine); + emit mainWindowEngineChanged(m_mainWindowEngine.get()); + } /*! \property App::wizards \brief . . */ -void App::setWizards(Wizards* wizards) -{ - if (m_wizards.get() == wizards) - return; + void App::setWizards(Wizards* wizards) + { + if (m_wizards.get() == wizards) + return; - m_wizards.reset(wizards); - emit wizardsChanged(m_wizards.get()); -} + m_wizards.reset(wizards); + emit wizardsChanged(m_wizards.get()); + } } diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop b/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop index 4dbf0710..1d642b0e 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop +++ b/ScreenPlayWallpaper/kde/ScreenPlay/metadata.desktop @@ -3,7 +3,7 @@ Encoding=UTF-8 Name=ScreenPlay Keywords=ScreenPlay Icon=preferences-desktop-wallpaper -Version=0.15.0-RC3 +Version=0.15.0-RC5 Type=Service diff --git a/Tools/Installer/package.xml b/Tools/Installer/package.xml index 9ff4faf5..831215dd 100644 --- a/Tools/Installer/package.xml +++ b/Tools/Installer/package.xml @@ -2,7 +2,7 @@ ScreenPlay ScreenPlay is an Open Source cross-platform app for displaying Video Wallpaper & Widgets. - 0.15.0-RC3 + 0.15.0-RC5 2022-11-02 true diff --git a/Tools/Scoop/ScreenPlay.json b/Tools/Scoop/ScreenPlay.json index e69259ab..3fb8a53f 100644 --- a/Tools/Scoop/ScreenPlay.json +++ b/Tools/Scoop/ScreenPlay.json @@ -1,5 +1,5 @@ { - "version": "0.15.0-RC3", + "version": "0.15.0-RC5", "description": "ScreenPlay is an Open Source Live-Wallpaper app for Windows and OSX. ", "homepage": "https://screen-play.app/", "url": "https://kelteseth.com/releases/$version/ScreenPlay-$version-x64-windows-release.zip", diff --git a/Tools/build.py b/Tools/build.py index 61bdf13b..2ac9efb4 100755 --- a/Tools/build.py +++ b/Tools/build.py @@ -37,9 +37,9 @@ class BuildResult: installer: Path # [...]/build-x64-windows-release/ScreenPlay-Installer.zip installer_zip: Path - # [...]/build-x64-windows-release/ScreenPlay-0.15.0-RC1-x64-windows-release.zip + # [...]/build-x64-windows-release/ScreenPlay-0.X.0-RCX-x64-windows-release.zip build_zip: Path - # [...]/build-x64-windows-release/ScreenPlay-0.15.0-RC1-x64-windows-release.txt :sha256, needed for scoop + # [...]/build-x64-windows-release/ScreenPlay-0.X.0-RCX-x64-windows-release.txt :sha256, needed for scoop build_hash: Path # x64, arm64, universal build_arch: str diff --git a/Tools/chocolatey/ScreenPlay/ReadMe.md b/Tools/chocolatey/ScreenPlay/ReadMe.md index 75dd239d..7da71fcb 100644 --- a/Tools/chocolatey/ScreenPlay/ReadMe.md +++ b/Tools/chocolatey/ScreenPlay/ReadMe.md @@ -7,7 +7,7 @@ choco pack Install the generated nupkg: ``` -choco install screenplay.0.15.0-RC3.nupkg -dv -s . +choco install screenplay.0.15.0-RC5.nupkg -dv -s . ``` Set api key from [https://community.chocolatey.org/account](https://community.chocolatey.org/account): @@ -17,5 +17,5 @@ choco apikey --key AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAA --source https://push.chocol Psuh: ``` -choco push screenplay.0.15.0-RC3.nupkg --source https://push.chocolatey.org/ +choco push screenplay.0.15.0-RC5.nupkg --source https://push.chocolatey.org/ ``` \ No newline at end of file diff --git a/Tools/chocolatey/ScreenPlay/screenplay.nuspec b/Tools/chocolatey/ScreenPlay/screenplay.nuspec index 54f3c2ad..e5150208 100644 --- a/Tools/chocolatey/ScreenPlay/screenplay.nuspec +++ b/Tools/chocolatey/ScreenPlay/screenplay.nuspec @@ -26,7 +26,7 @@ This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Refe - 0.15.0-RC3 + 0.15.0-RC5 https://gitlab.com/kelteseth/ScreenPlay/-/tree/master/Tools/chocolatey/ScreenPlay Elias Steurer diff --git a/Tools/chocolatey/ScreenPlay/tools/chocolateyinstall.ps1 b/Tools/chocolatey/ScreenPlay/tools/chocolateyinstall.ps1 index 3889612f..4c0c93ef 100644 --- a/Tools/chocolatey/ScreenPlay/tools/chocolateyinstall.ps1 +++ b/Tools/chocolatey/ScreenPlay/tools/chocolateyinstall.ps1 @@ -2,7 +2,7 @@ $ErrorActionPreference = 'Stop'; $toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)" $url = '' -$url64 = 'https://kelteseth.com/releases/0.15.0-RC3/ScreenPlay-0.15.0-RC3-x64-windows-release.zip' +$url64 = 'https://kelteseth.com/releases/0.15.0-RC5/ScreenPlay-0.15.0-RC5-x64-windows-release.zip' $packageArgs = @{ packageName = $env:ChocolateyPackageName diff --git a/Tools/defines.py b/Tools/defines.py index f2f4910c..ae370ee3 100644 --- a/Tools/defines.py +++ b/Tools/defines.py @@ -13,20 +13,16 @@ if sys.platform == "win32": elif sys.platform == "darwin": OS = "mac" QT_PLATFORM = "macos" -elif sys.platform == "linux": +elif sys.platform == "linux": OS = "linux" QT_PLATFORM = "gcc_64" -SCREENPLAY_VERSION = "0.15.0-RC4" - - +SCREENPLAY_VERSION = "0.15.0-RC5" QT_PATH = Path.cwd().parent.parent.joinpath("aqt") QT_VERSION = "6.5.0" QT_BIN_PATH = QT_PATH.joinpath(f"{QT_VERSION}/{QT_PLATFORM}/bin") QT_TOOLS_PATH = QT_PATH.joinpath("Tools/") QT_IFW_VERSION = "4.5" - VCPKG_VERSION = "2871ddd" # Master 11.11.2022 - PYTHON_EXECUTABLE = "python" if sys.platform == "win32" else "python3" -FFMPEG_VERSION = "5.0.1" \ No newline at end of file +FFMPEG_VERSION = "5.0.1" From d53dd498bb048ec4b599037dad266e6184e709e1 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 29 Jan 2023 13:26:51 +0100 Subject: [PATCH 26/56] Add VSCode setup to docs --- Docs/DeveloperSetup.md | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/Docs/DeveloperSetup.md b/Docs/DeveloperSetup.md index 2dfd86d2..9f6db6b8 100644 --- a/Docs/DeveloperSetup.md +++ b/Docs/DeveloperSetup.md @@ -14,7 +14,7 @@ 2. Python 3.11+ and select `Add to Path` during the installation. [Download](https://www.python.org/downloads/) 3. Optional if you do not have tools like `git` or `cmake` installed, we recommend `Chocolatey`: 1. Chocolatey via Powershell (Administrator) [Download](https://chocolatey.org/install) - 2. Run `choco.exe install git cmake -y` + 2. Run `choco.exe install git vscode cmake --installargs 'ADD_CMAKE_TO_PATH=System' -y` ## Linux 1. Install dependencies for Debian/Ubuntu: @@ -29,29 +29,40 @@ sudo apt-get install libx11-dev xserver-xorg-dev xorg-dev 1. Install [brew](https://brew.sh) that is needed by some third party vcpkg packages. Do not forget to add brew to your path as outlined at the on of the installation! - `brew install pkg-config git llvm cmake` -# Setup QtCreator and compile ScreenPlay -1. Clone ScreenPlay +# Download ScreenPlay and dependencies ``` bash git clone --recursive https://gitlab.com/kelteseth/ScreenPlay.git ScreenPlay/ScreenPlay +cd ScreenPlay ``` -1. Start the following script to download _all_ needed dependencies automatically. +Downloading dependencies is 100% automated. Simply run the `setup.py` script ``` bash cd Tools # Windows defaults to python, linux and macOS uses python3 python -m pip install -r requirements.txt +# This scrit will: +# 1. Downloads `Qt` and `QtCreator` +# 2. Create a `vcpkg` folder for dependencies +# 3. Compiles the dependencies +# 4. Downloads ffmpeg python setup.py ``` -1. This will: - 1. Download `Qt` and `QtCreator` - 2. Create a `vcpkg` folder for dependencies - 3. Compile the dependencies - 4. Download ffmpeg -2. Open QtCreator or VSCode +Now you can either use VSCode or QtCreator: +# Option 1: Setup VSCode and compile ScreenPlay +1. Open VSCode +1. Install these extentions: + 1. [C/C++ for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) + 1. [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) +2. Press: `CTRL` + `SHIFT` + `P` for every command: + 1. `CMake: Select Configure Preset`. Select one of the listed presets like `MSVC SP Qt 6.4.2 Debug` + 2. `CMake: Configure` +3. Press `F7` to Compile and `F5` to run! +# Option 2: Setup QtCreator and compile ScreenPlay +1. Open QtCreator at: 1. Windows: `..\aqt\Tools\QtCreator\bin\qtcreator.exe` 2. Linux: `../aqt/Tools/QtCreator/bin/qtcreator` 3. MacOS: `../aqt/Qt Creator` -3. Select the imported temporary kit like `ScreenPlay 64bit Debug Windows MSVC 2022 Community` -4. Compile! +2. Select the imported temporary kit like `MSVC SP Qt 6.4.2 Debug` +3. Press `CTRL` + `B` to Compile and `F5` to run! # Developer docs We use qdoc to generate documentation. Qt6 is the minimum version qdoc, because of vastly improved c++ parsing support. From b1986ecd04ee1d37d37d7fa544d92f323e8cf6ec Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 29 Jan 2023 13:39:40 +0100 Subject: [PATCH 27/56] Fix accessing nullopt type if nullopt --- ScreenPlayUtil/src/projectfile.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ScreenPlayUtil/src/projectfile.cpp b/ScreenPlayUtil/src/projectfile.cpp index 4b735168..f66b76b4 100644 --- a/ScreenPlayUtil/src/projectfile.cpp +++ b/ScreenPlayUtil/src/projectfile.cpp @@ -35,8 +35,8 @@ bool ProjectFile::init() return false; auto typeParsed = ScreenPlayUtil::getInstalledTypeFromString(obj.value("type").toString()); - if (!typeParsed) { - qWarning() << "Type could not parsed from: " << *typeParsed; + if (!typeParsed.has_value()) { + qWarning() << "Type could not parsed from string: " << obj.value("type").toString(); return false; } type = typeParsed.value(); @@ -87,6 +87,8 @@ bool ProjectFile::init() if (obj.contains("codec")) { if (auto videoCodecOpt = ScreenPlayUtil::getVideoCodecFromString(obj.value("codec").toString())) { videoCodec = videoCodecOpt.value(); + } else{ + qWarning("Invalid videoCodec was specified inside the json object!"); } } else if (type == ScreenPlay::InstalledType::InstalledType::VideoWallpaper) { qWarning("No videoCodec was specified inside the json object!"); From 960a6db915c4d576f3d8791b43e70e93d189b939 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 29 Jan 2023 13:50:21 +0100 Subject: [PATCH 28/56] Remove unused Particles import --- ScreenPlay/qml/Create/Create.qml | 1 - ScreenPlay/qml/Create/CreateSidebar.qml | 1 - ScreenPlay/qml/Create/StartInfo.qml | 1 - ScreenPlay/qml/Create/StartInfoLinkImage.qml | 1 - ScreenPlayUtil/qml/Background.qml | 1 - ScreenPlayWallpaper/qml/Test.qml | 4 ++-- 6 files changed, 2 insertions(+), 7 deletions(-) diff --git a/ScreenPlay/qml/Create/Create.qml b/ScreenPlay/qml/Create/Create.qml index 4c573022..327477d0 100644 --- a/ScreenPlay/qml/Create/Create.qml +++ b/ScreenPlay/qml/Create/Create.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.Controls.Material -import QtQuick.Particles import Qt5Compat.GraphicalEffects import QtQuick.Controls.Material.impl import ScreenPlayApp diff --git a/ScreenPlay/qml/Create/CreateSidebar.qml b/ScreenPlay/qml/Create/CreateSidebar.qml index 337b27e6..86a9a10b 100644 --- a/ScreenPlay/qml/Create/CreateSidebar.qml +++ b/ScreenPlay/qml/Create/CreateSidebar.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.Controls.Material -import QtQuick.Particles import Qt5Compat.GraphicalEffects import QtQuick.Controls.Material.impl import ScreenPlayApp diff --git a/ScreenPlay/qml/Create/StartInfo.qml b/ScreenPlay/qml/Create/StartInfo.qml index 29dc7d41..3b89dec0 100644 --- a/ScreenPlay/qml/Create/StartInfo.qml +++ b/ScreenPlay/qml/Create/StartInfo.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.Controls.Material -import QtQuick.Particles import Qt5Compat.GraphicalEffects import QtQuick.Controls.Material.impl import ScreenPlayApp diff --git a/ScreenPlay/qml/Create/StartInfoLinkImage.qml b/ScreenPlay/qml/Create/StartInfoLinkImage.qml index 4facab40..b08735f0 100644 --- a/ScreenPlay/qml/Create/StartInfoLinkImage.qml +++ b/ScreenPlay/qml/Create/StartInfoLinkImage.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import QtQuick.Controls.Material -import QtQuick.Particles import Qt5Compat.GraphicalEffects import QtQuick.Controls.Material.impl import ScreenPlayApp diff --git a/ScreenPlayUtil/qml/Background.qml b/ScreenPlayUtil/qml/Background.qml index 64426256..bf1da6e3 100644 --- a/ScreenPlayUtil/qml/Background.qml +++ b/ScreenPlayUtil/qml/Background.qml @@ -1,7 +1,6 @@ import QtQuick import QtQuick.Controls.Material import Qt5Compat.GraphicalEffects -import QtQuick.Particles Rectangle { id: element diff --git a/ScreenPlayWallpaper/qml/Test.qml b/ScreenPlayWallpaper/qml/Test.qml index fd72a923..85264b3d 100644 --- a/ScreenPlayWallpaper/qml/Test.qml +++ b/ScreenPlayWallpaper/qml/Test.qml @@ -1,8 +1,8 @@ import QtQuick import QtQuick.Controls import QtQuick.Controls.Material -import QtQuick.Particles 2.12 -import QtQuick.Shapes 1.12 +import QtQuick.Particles +import QtQuick.Shapes import ScreenPlayWallpaper Rectangle { From f9bc5c71124141a295d9f68da3c2a852f901a240 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sun, 29 Jan 2023 14:07:09 +0100 Subject: [PATCH 29/56] Fix ffmpeg setup deleting wrong file --- Tools/download_ffmpeg.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tools/download_ffmpeg.py b/Tools/download_ffmpeg.py index 1446cede..cf33264b 100644 --- a/Tools/download_ffmpeg.py +++ b/Tools/download_ffmpeg.py @@ -65,9 +65,9 @@ def extract_zip_executables(extraction_path, path_and_filename): # We need the first folder name of a file: # ffmpeg-5.0.1-essentials_build/bin/ffmpeg.exe empty_ffmpeg_folder = os.path.join(extraction_path,os.path.dirname(os.path.dirname(files[0]))) - ffprobe = os.path.join(extraction_path,"ffprobe.exe") - print(f"Delete not needed {ffprobe}") - os.remove(ffprobe) + ffplay = os.path.join(extraction_path,"ffplay.exe") + print(f"Delete not needed {ffplay}") + os.remove(ffplay) print(f"Delete empty folder: {empty_ffmpeg_folder}") rmtree(empty_ffmpeg_folder) From 11d89432a093188307d644a95418769d7c9ba3fd Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Mon, 30 Jan 2023 16:46:39 +0100 Subject: [PATCH 30/56] Fix Linux and OSX compilation --- .gitlab-ci.yml | 2 +- ScreenPlayWallpaper/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f0d8c29f..0fb452c8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,7 +14,7 @@ stages: # Otherwise libglib2 needs interaction - export DEBIAN_FRONTEND=noninteractive - apt update -y - - apt install curl wget zip unzip tar git pkg-config libxcb-* libfontconfig-dev apt-transport-https ca-certificates gnupg software-properties-common python3 python3-pip build-essential libgl1-mesa-dev mesa-common-dev lld ninja-build libxkbcommon-* -y + - apt install curl wget zip unzip tar git pkg-config libxcb-* libfontconfig-dev apt-transport-https ca-certificates gnupg software-properties-common python3 python3-pip build-essential libgl1-mesa-dev mesa-common-dev lld ninja-build libxkbcommon-* libx11-dev xserver-xorg-dev xorg-dev -y - wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null - echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal-rc main' | tee -a /etc/apt/sources.list.d/kitware.list >/dev/null - apt update -y diff --git a/ScreenPlayWallpaper/CMakeLists.txt b/ScreenPlayWallpaper/CMakeLists.txt index 4bfcbf45..ed8ca604 100644 --- a/ScreenPlayWallpaper/CMakeLists.txt +++ b/ScreenPlayWallpaper/CMakeLists.txt @@ -81,8 +81,8 @@ target_link_libraries( Qt6::WebEngineQuick) if(WIN32) target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySysInfoplugin) -elseif(UNIX) - target_link_libraries( ${PROJECT_NAME} PRIVATE X11) +elseif(UNIX AND NOT APPLE) + target_link_libraries(${PROJECT_NAME} PRIVATE X11) endif() if(UNIX AND NOT APPLE) From f942ce16dc6ae1aaab3c5c67530a3a85586b9284 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 2 Feb 2023 09:44:30 +0100 Subject: [PATCH 31/56] Remove dark mode workaround https://bugreports.qt.io/browse/QTBUG-72028?focusedCommentId=704716&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-704716 --- ScreenPlay/main.cpp | 10 +++------- ScreenPlay/qtquickcontrols2.conf | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/ScreenPlay/main.cpp b/ScreenPlay/main.cpp index 6e364151..29472edd 100644 --- a/ScreenPlay/main.cpp +++ b/ScreenPlay/main.cpp @@ -1,9 +1,10 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "ScreenPlay/app.h" -#include +#include #include #include +#include #if defined(Q_OS_WIN) #include @@ -22,12 +23,7 @@ int main(int argc, char* argv[]) qputenv("QT_MEDIA_BACKEND", "ffmpeg"); #endif -#if defined(Q_OS_WIN) - // https://bugreports.qt.io/browse/QTBUG-72028 - qputenv("QT_QPA_PLATFORM", "windows:darkmode=2"); -#endif - - QApplication qtGuiApp(argc, argv); + QGuiApplication qtGuiApp(argc, argv); ScreenPlay::App app; if (app.m_isAnotherScreenPlayInstanceRunning) { diff --git a/ScreenPlay/qtquickcontrols2.conf b/ScreenPlay/qtquickcontrols2.conf index 97b48040..8c73ce36 100644 --- a/ScreenPlay/qtquickcontrols2.conf +++ b/ScreenPlay/qtquickcontrols2.conf @@ -2,6 +2,6 @@ Style=Material [Material] -Theme=Light +Theme=System Accent=Orange Variant=Dense From 83bb652132430318834aa099b4716c859f334233 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 2 Feb 2023 15:25:26 +0100 Subject: [PATCH 32/56] Add tasks.json and format all files --- .vscode/tasks.json | 95 ++++++- ScreenPlay/CMakeLists.txt | 2 +- ScreenPlay/main.cpp | 2 +- ScreenPlay/main.qml | 245 ++++++++--------- ScreenPlay/qml/Community/Community.qml | 17 +- ScreenPlay/qml/Community/CommunityNavItem.qml | 4 - ScreenPlay/qml/Community/XMLNewsfeed.qml | 16 +- ScreenPlay/qml/Create/Create.qml | 9 - ScreenPlay/qml/Create/CreateSidebar.qml | 18 +- ScreenPlay/qml/Create/StartInfo.qml | 7 +- ScreenPlay/qml/Create/StartInfoLinkImage.qml | 11 +- ScreenPlay/qml/Create/Wizard.qml | 19 +- .../qml/Create/Wizards/GifWallpaper.qml | 8 +- .../qml/Create/Wizards/HTMLWallpaper.qml | 4 - ScreenPlay/qml/Create/Wizards/HTMLWidget.qml | 7 - .../ImportVideoAndConvert/CreateWallpaper.qml | 15 +- .../CreateWallpaperInit.qml | 12 +- .../CreateWallpaperResult.qml | 9 - .../CreateWallpaperVideoImportConvert.qml | 108 ++++---- .../Create/Wizards/ImportWebm/ImportWebm.qml | 10 +- .../Wizards/ImportWebm/ImportWebmConvert.qml | 19 +- .../Wizards/ImportWebm/ImportWebmInit.qml | 25 -- .../Create/Wizards/Importh264/Importh264.qml | 10 +- .../Wizards/Importh264/Importh264Convert.qml | 19 +- .../Wizards/Importh264/Importh264Init.qml | 24 +- .../qml/Create/Wizards/QMLWallpaper.qml | 4 - ScreenPlay/qml/Create/Wizards/QMLWidget.qml | 7 - .../qml/Create/Wizards/WebsiteWallpaper.qml | 3 - ScreenPlay/qml/Create/Wizards/WizardPage.qml | 16 +- .../Create/WizardsFiles/QMLWallpaperMain.qml | 1 - .../qml/Create/WizardsFiles/QMLWidgetMain.qml | 2 +- ScreenPlay/qml/Installed/Installed.qml | 152 +++++------ .../qml/Installed/InstalledNavigation.qml | 48 ++-- .../qml/Installed/InstalledWelcomeScreen.qml | 17 +- ScreenPlay/qml/Installed/ScreenPlayItem.qml | 35 ++- .../qml/Installed/ScreenPlayItemImage.qml | 6 - ScreenPlay/qml/Installed/Sidebar.qml | 116 +++----- .../qml/Monitors/DefaultVideoControls.qml | 38 ++- ScreenPlay/qml/Monitors/MonitorSelection.qml | 96 ++++--- .../qml/Monitors/MonitorSelectionItem.qml | 16 +- ScreenPlay/qml/Monitors/Monitors.qml | 58 ++-- .../Monitors/MonitorsProjectSettingItem.qml | 19 +- ScreenPlay/qml/Monitors/SaveNotification.qml | 3 - ScreenPlay/qml/Navigation/ExitPopup.qml | 21 +- ScreenPlay/qml/Navigation/Navigation.qml | 96 ++++--- ScreenPlay/qml/Settings/SettingBool.qml | 18 +- ScreenPlay/qml/Settings/Settings.qml | 98 ++++--- ScreenPlay/qml/Settings/SettingsButton.qml | 6 +- ScreenPlay/qml/Settings/SettingsComboBox.qml | 4 - ScreenPlay/qml/Settings/SettingsExpander.qml | 6 - ScreenPlay/qml/Settings/SettingsHeader.qml | 8 - .../Settings/SettingsHorizontalSeperator.qml | 2 - ScreenPlay/qml/Workshop/Workshop.qml | 9 +- ScreenPlay/src/app.cpp | 146 +++++----- ScreenPlayShader/src/ShadertoyShader.qml | 1 - ScreenPlayShader/src/TestMain.qml | 7 +- ScreenPlaySysInfo/qml/TestMain.qml | 16 +- ScreenPlayUtil/CMakeLists.txt | 10 +- ScreenPlayUtil/qml/Background.qml | 5 - ScreenPlayUtil/qml/CloseIcon.qml | 2 - ScreenPlayUtil/qml/ColorImage.qml | 2 - ScreenPlayUtil/qml/ColorPicker.qml | 57 +--- ScreenPlayUtil/qml/Dialogs/CriticalError.qml | 9 +- .../qml/Dialogs/MonitorConfiguration.qml | 2 +- ScreenPlayUtil/qml/FileSelector.qml | 10 +- ScreenPlayUtil/qml/Grow.qml | 3 - ScreenPlayUtil/qml/GrowIconLink.qml | 2 - ScreenPlayUtil/qml/Headline.qml | 2 - ScreenPlayUtil/qml/ImageSelector.qml | 11 - ScreenPlayUtil/qml/LicenseSelector.qml | 4 - ScreenPlayUtil/qml/RippleEffect.qml | 15 +- ScreenPlayUtil/qml/Search.qml | 3 - ScreenPlayUtil/qml/Shake.qml | 3 - ScreenPlayUtil/qml/Tag.qml | 3 - ScreenPlayUtil/qml/TagSelector.qml | 37 ++- ScreenPlayUtil/qml/TextField.qml | 15 +- ScreenPlayUtil/qml/TrayIcon.qml | 42 ++- ScreenPlayUtil/src/projectfile.cpp | 2 +- .../contents/ui/WaitingForScreenplay.qml | 56 ++-- .../kde/ScreenPlay/contents/ui/Wallpaper.qml | 68 +++-- .../contents/ui/WallpaperContainer.qml | 33 ++- .../kde/ScreenPlay/contents/ui/config.qml | 5 - .../kde/ScreenPlay/contents/ui/main.qml | 103 ++++---- ScreenPlayWallpaper/qml/MultimediaView.qml | 40 ++- ScreenPlayWallpaper/qml/MultimediaWebView.qml | 92 +++---- ScreenPlayWallpaper/qml/Test.qml | 35 ++- ScreenPlayWallpaper/qml/Wallpaper.qml | 250 ++++++++---------- ScreenPlayWallpaper/qml/WebsiteWallpaper.qml | 4 +- ScreenPlayWeather/qml/TestMain.qml | 78 +++--- ScreenPlayWidget/qml/Test.qml | 4 +- ScreenPlayWidget/qml/Widget.qml | 52 ++-- ScreenPlayWorkshop/qml/Background.qml | 18 +- ScreenPlayWorkshop/qml/Forum.qml | 4 +- ScreenPlayWorkshop/qml/Navigation.qml | 9 +- ScreenPlayWorkshop/qml/PopupOffline.qml | 7 +- ScreenPlayWorkshop/qml/ScreenPlayItem.qml | 16 -- .../qml/ScreenPlayItemImage.qml | 3 - ScreenPlayWorkshop/qml/Sidebar.qml | 82 +++--- ScreenPlayWorkshop/qml/SteamProfile.qml | 18 +- ScreenPlayWorkshop/qml/SteamWorkshop.qml | 17 +- .../qml/SteamWorkshopStartPage.qml | 197 ++++++-------- ScreenPlayWorkshop/qml/TestMain.qml | 22 +- ScreenPlayWorkshop/qml/Workshop.qml | 9 +- ScreenPlayWorkshop/qml/WorkshopItem.qml | 19 -- .../upload/PopupSteamWorkshopAgreement.qml | 4 - .../qml/upload/UploadProject.qml | 22 +- .../qml/upload/UploadProjectBigItem.qml | 11 - .../qml/upload/UploadProjectItem.qml | 16 +- 108 files changed, 1383 insertions(+), 1940 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 23afb2ed..95f55792 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -12,6 +12,99 @@ "group": "build", "problemMatcher": [], "detail": "CMake template build task" - } + }, + { + "type": "process", + "label": "Format Cpp files", + "command": "python", + "group": { + "kind": "build", + "isDefault": true + }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, + "args": [ + "clang_format.py" + ] + }, + { + "type": "process", + "label": "Format CMake files", + "command": "python", + "group": { + "kind": "build", + "isDefault": true + }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, + "args": [ + "cmake_format.py" + ] + }, + { + "type": "process", + "label": "Format Qml files", + "command": "python", + "group": { + "kind": "build", + "isDefault": true + }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, + "args": [ + "qml_format.py" + ] + }, + { + "type": "process", + "label": "Run setup.py", + "command": "python", + "group": { + "kind": "build", + "isDefault": true + }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, + "args": [ + "setup.py" + ] + }, + { + "type": "process", + "label": "Export ScreenPlay release, with deploy and steam enabled", + "command": "python", + "group": { + "kind": "build", + "isDefault": true + }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, + "args": [ + "build.py", + "-type=release", + "-deploy_version", + "-steam" + ] + }, + { + "type": "process", + "label": "Update Qt *.ts translations", + "command": "python", + "group": { + "kind": "build", + "isDefault": true + }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, + "args": [ + "update_translations.py" + ] + } ] } \ No newline at end of file diff --git a/ScreenPlay/CMakeLists.txt b/ScreenPlay/CMakeLists.txt index 0ec85f19..2fe5969e 100644 --- a/ScreenPlay/CMakeLists.txt +++ b/ScreenPlay/CMakeLists.txt @@ -219,7 +219,6 @@ set(RESOURCES assets/startinfo/vscode.png assets/wizards/example_html.png assets/wizards/example_qml.png - assets/wizards/QmlProject.qmlproject assets/wizards/License_All_Rights_Reserved_1.0.txt assets/wizards/License_Apache_2.0.txt assets/wizards/License_CC0_1.0.txt @@ -227,6 +226,7 @@ set(RESOURCES assets/wizards/License_CC_Attribution-ShareAlike_4.0.txt assets/wizards/License_CC_Attribution_4.0.txt assets/wizards/License_GPL_3.0.txt + assets/wizards/QmlProject.qmlproject assets/WorkshopPreview.html legal/DataProtection.txt legal/gpl-3.0.txt diff --git a/ScreenPlay/main.cpp b/ScreenPlay/main.cpp index 29472edd..bb3daaa0 100644 --- a/ScreenPlay/main.cpp +++ b/ScreenPlay/main.cpp @@ -1,9 +1,9 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "ScreenPlay/app.h" -#include #include #include +#include #include #if defined(Q_OS_WIN) diff --git a/ScreenPlay/main.qml b/ScreenPlay/main.qml index cabd6268..141dd9c3 100644 --- a/ScreenPlay/main.qml +++ b/ScreenPlay/main.qml @@ -20,40 +20,35 @@ ApplicationWindow { function setTheme(theme) { switch (theme) { case Settings.System: - root.Material.theme = Material.System - break + root.Material.theme = Material.System; + break; case Settings.Dark: - root.Material.theme = Material.Dark - break + root.Material.theme = Material.Dark; + break; case Settings.Light: - root.Material.theme = Material.Light - break + root.Material.theme = Material.Light; + break; } } function switchPage(name) { if (nav.currentNavigationName === name) { if (name === "Installed") - App.installedListModel.reset() + App.installedListModel.reset(); } - if (name === "Installed") { - stackView.replace( - "qrc:/qml/ScreenPlayApp/qml/Installed/Installed.qml", { - "sidebar": sidebar - }) - return + stackView.replace("qrc:/qml/ScreenPlayApp/qml/Installed/Installed.qml", { + "sidebar": sidebar + }); + return; } - stackView.replace( - "qrc:/qml/ScreenPlayApp/qml/" + name + "/" + name + ".qml", - { - "modalSource": content - }) - sidebar.state = "inactive" + stackView.replace("qrc:/qml/ScreenPlayApp/qml/" + name + "/" + name + ".qml", { + "modalSource": content + }); + sidebar.state = "inactive"; } - color: Material.theme === Material.Dark ? Qt.darker( - Material.background) : Material.background + color: Material.theme === Material.Dark ? Qt.darker(Material.background) : Material.background // Set visible if the -silent parameter was not set (see app.cpp end of constructor). visible: false width: 1400 @@ -67,28 +62,23 @@ ApplicationWindow { Material.accent: Material.color(Material.Orange) onVisibilityChanged: { if (root.visibility === 2) - App.installedListModel.reset() + App.installedListModel.reset(); } - onClosing: (close) => { - close.accepted = false - - if (App.screenPlayManager.activeWallpaperCounter === 0 - && App.screenPlayManager.activeWidgetsCounter === 0) { - Qt.quit() + onClosing: close => { + close.accepted = false; + if (App.screenPlayManager.activeWallpaperCounter === 0 && App.screenPlayManager.activeWidgetsCounter === 0) { + Qt.quit(); } - - const alwaysMinimize = settings.value("alwaysMinimize", null) - if(alwaysMinimize === null){ - console.error("Unable to retreive alwaysMinimize setting") + const alwaysMinimize = settings.value("alwaysMinimize", null); + if (alwaysMinimize === null) { + console.error("Unable to retreive alwaysMinimize setting"); } - - if(alwaysMinimize === "true"){ - root.hide() - App.showDockIcon(false); - return + if (alwaysMinimize === "true") { + root.hide(); + App.showDockIcon(false); + return; } - - exitDialog.open() + exitDialog.open(); } Labs.Settings { @@ -102,13 +92,13 @@ ApplicationWindow { } Component.onCompleted: { - setTheme(App.settings.theme) + setTheme(App.settings.theme); stackView.push("qrc:/qml/ScreenPlayApp/qml/Installed/Installed.qml", { - "sidebar": sidebar - }) - if (!App.settings.silentStart){ - App.showDockIcon(true) - root.show() + "sidebar": sidebar + }); + if (!App.settings.silentStart) { + App.showDockIcon(true); + root.show(); } } @@ -139,7 +129,7 @@ ApplicationWindow { Connections { function onThemeChanged(theme) { - setTheme(theme) + setTheme(theme); } target: App.settings @@ -147,7 +137,7 @@ ApplicationWindow { Connections { function onRequestNavigation(nav) { - switchPage(nav) + switchPage(nav); } target: App.util @@ -155,8 +145,8 @@ ApplicationWindow { Connections { function onRequestRaise() { - App.showDockIcon(true) - root.show() + App.showDockIcon(true); + root.show(); } target: App.screenPlayManager @@ -164,98 +154,97 @@ ApplicationWindow { Item { id: content - anchors.fill:parent + anchors.fill: parent + StackView { + id: stackView + objectName: "stackView" + property int duration: 300 - StackView { - id: stackView - objectName: "stackView" - property int duration: 300 - - anchors { - top: nav.bottom - right: parent.right - bottom: parent.bottom - left: parent.left - } - - replaceEnter: Transition { - OpacityAnimator { - from: 0 - to: 1 - duration: stackView.duration - easing.type: Easing.InOutQuart + anchors { + top: nav.bottom + right: parent.right + bottom: parent.bottom + left: parent.left } - ScaleAnimator { - from: 0.8 - to: 1 - duration: stackView.duration - easing.type: Easing.InOutQuart + replaceEnter: Transition { + OpacityAnimator { + from: 0 + to: 1 + duration: stackView.duration + easing.type: Easing.InOutQuart + } + + ScaleAnimator { + from: 0.8 + to: 1 + duration: stackView.duration + easing.type: Easing.InOutQuart + } + } + + replaceExit: Transition { + OpacityAnimator { + from: 1 + to: 0 + duration: stackView.duration + easing.type: Easing.InOutQuart + } + + ScaleAnimator { + from: 1 + to: 0.8 + duration: stackView.duration + easing.type: Easing.InOutQuart + } } } - replaceExit: Transition { - OpacityAnimator { - from: 1 - to: 0 - duration: stackView.duration - easing.type: Easing.InOutQuart + Connections { + function onSetSidebarActive(active) { + if (active) + sidebar.state = "active"; + else + sidebar.state = "inactive"; } - ScaleAnimator { - from: 1 - to: 0.8 - duration: stackView.duration - easing.type: Easing.InOutQuart + function onSetNavigationItem(pos) { + if (pos === 0) + nav.onPageChanged("Create"); + else + nav.onPageChanged("Workshop"); + } + + target: stackView.currentItem + ignoreUnknownSignals: true + } + + Installed.Sidebar { + id: sidebar + objectName: "installedSidebar" + navHeight: nav.height + + anchors { + top: parent.top + right: parent.right + bottom: parent.bottom } } - } - Connections { - function onSetSidebarActive(active) { - if (active) - sidebar.state = "active" - else - sidebar.state = "inactive" - } + Navigation.Navigation { + id: nav + modalSource: content + anchors { + top: parent.top + right: parent.right + left: parent.left + } - function onSetNavigationItem(pos) { - if (pos === 0) - nav.onPageChanged("Create") - else - nav.onPageChanged("Workshop") - } - - target: stackView.currentItem - ignoreUnknownSignals: true - } - - Installed.Sidebar { - id: sidebar - objectName: "installedSidebar" - navHeight: nav.height - - anchors { - top: parent.top - right: parent.right - bottom: parent.bottom - } - } - - Navigation.Navigation { - id: nav - modalSource: content - anchors { - top: parent.top - right: parent.right - left: parent.left - } - - onChangePage: function (name) { - monitors.close() - switchPage(name) + onChangePage: function (name) { + monitors.close(); + switchPage(name); + } } } } -} diff --git a/ScreenPlay/qml/Community/Community.qml b/ScreenPlay/qml/Community/Community.qml index 9b6d67c5..08db5845 100644 --- a/ScreenPlay/qml/Community/Community.qml +++ b/ScreenPlay/qml/Community/Community.qml @@ -42,7 +42,6 @@ Item { Layout.fillWidth: true } - Button { text: qsTr("News") onClicked: Qt.openUrlExternally("https://screen-play.app/blog/") @@ -54,8 +53,7 @@ Item { Button { text: qsTr("Wiki") - onClicked: Qt.openUrlExternally( - "https://kelteseth.gitlab.io/ScreenPlayDocs/") + onClicked: Qt.openUrlExternally("https://kelteseth.gitlab.io/ScreenPlayDocs/") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_help_center.svg" icon.width: 14 icon.height: 14 @@ -64,8 +62,7 @@ Item { Button { text: qsTr("Forum") - onClicked: Qt.openUrlExternally( - "https://forum.screen-play.app/") + onClicked: Qt.openUrlExternally("https://forum.screen-play.app/") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_forum.svg" icon.width: 14 icon.height: 14 @@ -74,8 +71,7 @@ Item { Button { text: qsTr("Reddit") - onClicked: Qt.openUrlExternally( - "https://www.reddit.com/r/ScreenPlayApp/") + onClicked: Qt.openUrlExternally("https://www.reddit.com/r/ScreenPlayApp/") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/brand_reddit.svg" icon.width: 14 icon.height: 14 @@ -84,8 +80,7 @@ Item { Button { text: qsTr("Issue Tracker") - onClicked: Qt.openUrlExternally( - "https://gitlab.com/kelteseth/ScreenPlay/-/issues") + onClicked: Qt.openUrlExternally("https://gitlab.com/kelteseth/ScreenPlay/-/issues") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_report_problem.svg" icon.width: 14 icon.height: 14 @@ -94,8 +89,7 @@ Item { Button { text: qsTr("Contribute") - onClicked: Qt.openUrlExternally( - "https://gitlab.com/kelteseth/ScreenPlay#general-contributing") + onClicked: Qt.openUrlExternally("https://gitlab.com/kelteseth/ScreenPlay#general-contributing") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_supervisor_account.svg" icon.width: 14 icon.height: 14 @@ -115,7 +109,6 @@ Item { Layout.fillHeight: true Layout.fillWidth: true } - } } diff --git a/ScreenPlay/qml/Community/CommunityNavItem.qml b/ScreenPlay/qml/Community/CommunityNavItem.qml index 6c63c31c..e0b61d76 100644 --- a/ScreenPlay/qml/Community/CommunityNavItem.qml +++ b/ScreenPlay/qml/Community/CommunityNavItem.qml @@ -27,7 +27,6 @@ TabButton { right: txt.left verticalCenter: txt.verticalCenter } - } Text { @@ -63,12 +62,9 @@ TabButton { topMargin: 15 right: parent.right } - } - } background: Item { } - } diff --git a/ScreenPlay/qml/Community/XMLNewsfeed.qml b/ScreenPlay/qml/Community/XMLNewsfeed.qml index c5fc8acf..f7cf7a08 100644 --- a/ScreenPlay/qml/Community/XMLNewsfeed.qml +++ b/ScreenPlay/qml/Community/XMLNewsfeed.qml @@ -58,7 +58,6 @@ Item { name: "description" elementName: "description" } - } header: Item { @@ -82,9 +81,7 @@ Item { topMargin: 30 horizontalCenter: parent.horizontalCenter } - } - } delegate: Item { @@ -108,13 +105,11 @@ Item { source: image opacity: status === Image.Ready ? 1 : 0 - Behavior on opacity { + Behavior on opacity { PropertyAnimation { duration: 250 } - } - } LinearGradient { @@ -132,9 +127,7 @@ Item { position: 0 color: "transparent" } - } - } Text { @@ -153,7 +146,6 @@ Item { left: parent.left margins: 20 } - } Text { @@ -173,7 +165,6 @@ Item { left: parent.left leftMargin: 20 } - } MouseArea { @@ -184,7 +175,6 @@ Item { onEntered: delegate.state = "hover" onExited: delegate.state = "" } - } transitions: [ @@ -198,7 +188,6 @@ Item { from: 1 to: 1.05 } - }, Transition { from: "hover" @@ -210,7 +199,6 @@ Item { from: 1.05 to: 1 } - } ] } @@ -219,7 +207,5 @@ Item { snapMode: ScrollBar.SnapOnRelease policy: ScrollBar.AlwaysOn } - } - } diff --git a/ScreenPlay/qml/Create/Create.qml b/ScreenPlay/qml/Create/Create.qml index 327477d0..f9c9c296 100644 --- a/ScreenPlay/qml/Create/Create.qml +++ b/ScreenPlay/qml/Create/Create.qml @@ -29,7 +29,6 @@ Item { left: parent.left bottom: parent.bottom } - } Item { @@ -80,7 +79,6 @@ Item { duration: 400 easing.type: Easing.InOutQuart } - } pushExit: Transition { @@ -99,15 +97,12 @@ Item { duration: 400 easing.type: Easing.InOutQuart } - } - } layer.effect: ElevationEffect { elevation: 6 } - } states: [ @@ -119,7 +114,6 @@ Item { anchors.topMargin: wizardContentWrapper.anchors.margins opacity: 1 } - } ] transitions: [ @@ -141,11 +135,8 @@ Item { wizardContentWrapper.anchors.left = sidebar.right; } } - } - } ] } - } diff --git a/ScreenPlay/qml/Create/CreateSidebar.qml b/ScreenPlay/qml/Create/CreateSidebar.qml index 86a9a10b..bf1ef42b 100644 --- a/ScreenPlay/qml/Create/CreateSidebar.qml +++ b/ScreenPlay/qml/Create/CreateSidebar.qml @@ -37,15 +37,15 @@ Rectangle { id: loaderConnections function onWizardStarted() { - root.expanded = false + root.expanded = false; } function onWizardExited() { - root.expanded = true - stackView.clear(StackView.PushTransition) - stackView.push("qrc:/qml/ScreenPlayApp/qml/Create/StartInfo.qml") - listView.currentIndex = 0 - App.util.setNavigationActive(true) + root.expanded = true; + stackView.clear(StackView.PushTransition); + stackView.push("qrc:/qml/ScreenPlayApp/qml/Create/StartInfo.qml"); + listView.currentIndex = 0; + App.util.setNavigationActive(true); } ignoreUnknownSignals: true @@ -152,9 +152,9 @@ Rectangle { highlighted: ListView.isCurrentItem text: headline onClicked: { - listView.currentIndex = index - const item = stackView.push(source) - loaderConnections.target = item + listView.currentIndex = index; + const item = stackView.push(source); + loaderConnections.target = item; } } } diff --git a/ScreenPlay/qml/Create/StartInfo.qml b/ScreenPlay/qml/Create/StartInfo.qml index 3b89dec0..9de354cf 100644 --- a/ScreenPlay/qml/Create/StartInfo.qml +++ b/ScreenPlay/qml/Create/StartInfo.qml @@ -1,6 +1,6 @@ import QtQuick import QtQuick.Controls -import QtQuick.Layouts +import QtQuick.Layouts import QtQuick.Controls.Material import Qt5Compat.GraphicalEffects import QtQuick.Controls.Material.impl @@ -23,7 +23,6 @@ Item { left: parent.left margins: 20 } - } Text { @@ -40,7 +39,6 @@ Item { left: parent.left margins: 20 } - } GridView { @@ -217,7 +215,6 @@ Item { description: "" category: "Resources" } - } delegate: StartInfoLinkImage { @@ -231,7 +228,5 @@ Item { width: gridView.cellWidth height: gridView.cellHeight } - } - } diff --git a/ScreenPlay/qml/Create/StartInfoLinkImage.qml b/ScreenPlay/qml/Create/StartInfoLinkImage.qml index b08735f0..25f1cc23 100644 --- a/ScreenPlay/qml/Create/StartInfoLinkImage.qml +++ b/ScreenPlay/qml/Create/StartInfoLinkImage.qml @@ -1,6 +1,6 @@ import QtQuick import QtQuick.Controls -import QtQuick.Layouts +import QtQuick.Layouts import QtQuick.Controls.Material import Qt5Compat.GraphicalEffects import QtQuick.Controls.Material.impl @@ -48,9 +48,7 @@ Item { position: 1 color: "#00000000" } - } - } Text { @@ -67,7 +65,6 @@ Item { margins: 15 bottomMargin: 5 } - } Text { @@ -84,7 +81,6 @@ Item { bottom: parent.bottom margins: 15 } - } Rectangle { @@ -108,9 +104,7 @@ Item { fill: parent margins: 5 } - } - } MouseArea { @@ -125,7 +119,6 @@ Item { layer.effect: ElevationEffect { elevation: 4 } - } transitions: [ @@ -139,7 +132,6 @@ Item { from: 1 to: 1.05 } - }, Transition { from: "hover" @@ -151,7 +143,6 @@ Item { from: 1.05 to: 1 } - } ] } diff --git a/ScreenPlay/qml/Create/Wizard.qml b/ScreenPlay/qml/Create/Wizard.qml index 2ce59846..a9c47189 100644 --- a/ScreenPlay/qml/Create/Wizard.qml +++ b/ScreenPlay/qml/Create/Wizard.qml @@ -6,7 +6,7 @@ import QtQuick.Layouts import ScreenPlayApp import ScreenPlay import ScreenPlay.Create -import ScreenPlayUtil +import ScreenPlayUtil Item { id: root @@ -42,7 +42,6 @@ Item { right: wrapper.right topMargin: 3 } - } Rectangle { @@ -53,7 +52,6 @@ Item { radius: 4 width: { // Add small margin left and right - if (parent.width < 1200) return parent.width - 20; else @@ -86,9 +84,7 @@ Item { App.util.setNavigation("Create"); } } - } - } states: [ @@ -105,7 +101,6 @@ Item { target: effect opacity: 0 } - }, State { name: "in" @@ -125,7 +120,6 @@ Item { target: effect opacity: 0.4 } - }, State { name: "error" @@ -146,7 +140,6 @@ Item { opacity: 1 z: 1 } - }, State { name: "success" @@ -167,7 +160,6 @@ Item { opacity: 0 z: 0 } - } ] transitions: [ @@ -206,13 +198,9 @@ Item { property: "opacity" easing.type: Easing.OutQuart } - } - } - } - }, Transition { from: "in" @@ -244,11 +232,8 @@ Item { property: "opacity" easing.type: Easing.OutQuart } - } - } - }, Transition { from: "in" @@ -265,9 +250,7 @@ Item { PauseAnimation { duration: 50 } - } - } ] } diff --git a/ScreenPlay/qml/Create/Wizards/GifWallpaper.qml b/ScreenPlay/qml/Create/Wizards/GifWallpaper.qml index 11c7b63b..fa5cd72d 100644 --- a/ScreenPlay/qml/Create/Wizards/GifWallpaper.qml +++ b/ScreenPlay/qml/Create/Wizards/GifWallpaper.qml @@ -84,7 +84,7 @@ WizardPage { horizontalAlignment: Text.AlignHCenter wrapMode: Text.WrapAtWordBoundaryOrAnywhere width: parent.width - anchors{ + anchors { fill: parent margins: 40 } @@ -97,7 +97,6 @@ WizardPage { fillMode: Image.PreserveAspectCrop source: root.file } - } Item { @@ -113,7 +112,6 @@ WizardPage { fileDialog.nameFilters: ["Gif (*.gif)"] onFileChanged: root.file = file } - } ColumnLayout { @@ -162,11 +160,7 @@ WizardPage { Layout.fillHeight: true Layout.fillWidth: true } - } - } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/HTMLWallpaper.qml b/ScreenPlay/qml/Create/Wizards/HTMLWallpaper.qml index 4d784202..3788ff89 100644 --- a/ScreenPlay/qml/Create/Wizards/HTMLWallpaper.qml +++ b/ScreenPlay/qml/Create/Wizards/HTMLWallpaper.qml @@ -53,7 +53,6 @@ WizardPage { Layout.fillWidth: true placeholderText: qsTr("Created By") } - } Util.TextField { @@ -83,7 +82,6 @@ WizardPage { Layout.fillWidth: true } - } Item { @@ -99,7 +97,5 @@ WizardPage { Layout.fillWidth: true } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/HTMLWidget.qml b/ScreenPlay/qml/Create/Wizards/HTMLWidget.qml index e3231f30..f6532d71 100644 --- a/ScreenPlay/qml/Create/Wizards/HTMLWidget.qml +++ b/ScreenPlay/qml/Create/Wizards/HTMLWidget.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls.Material import QtQuick.Controls import QtQuick.Layouts - import ScreenPlayApp import ScreenPlay import ScreenPlayUtil as Util @@ -52,7 +51,6 @@ WizardPage { anchors.fill: parent fillMode: Image.PreserveAspectCrop } - } Util.ImageSelector { @@ -60,7 +58,6 @@ WizardPage { Layout.fillWidth: true } - } ColumnLayout { @@ -104,11 +101,7 @@ WizardPage { Layout.fillWidth: true } - } - } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml b/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml index 7be3f322..391176c2 100644 --- a/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml +++ b/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml @@ -23,15 +23,15 @@ Item { CreateWallpaperInit { onNext: function (filePath, codec) { - startConvert(filePath, codec) + startConvert(filePath, codec); } function startConvert(filePath, codec) { - root.wizardStarted() - swipeView.currentIndex = 1 - createWallpaperVideoImportConvert.codec = codec - createWallpaperVideoImportConvert.filePath = filePath - App.create.createWallpaperStart(filePath, codec, quality) + root.wizardStarted(); + swipeView.currentIndex = 1; + createWallpaperVideoImportConvert.codec = codec; + createWallpaperVideoImportConvert.filePath = filePath; + App.create.createWallpaperStart(filePath, codec, quality); } } @@ -41,6 +41,7 @@ Item { onAbort: root.wizardExited() } - CreateWallpaperResult {} + CreateWallpaperResult { + } } } diff --git a/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml b/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml index c7ac8606..57cfe5cf 100644 --- a/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml +++ b/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml @@ -8,6 +8,7 @@ import ScreenPlayApp import ScreenPlay import ScreenPlay.Create import ScreenPlayUtil as Util + Item { id: root objectName: "createWallpaperInit" @@ -62,7 +63,6 @@ Item { // text: "AV1 (NVidia 3000, AMD 6000 or newer). ULTRA SLOW ENCODING!" // value: Create.AV1 // } - id: comboBoxCodec Layout.preferredWidth: 400 @@ -84,11 +84,8 @@ Item { value: Create.VP8 } // Import works but the QWebEngine cannot display AV1 :( - } - } - } Util.Slider { @@ -104,9 +101,7 @@ Item { to: 0 stepSize: 1 } - } - } Button { @@ -124,7 +119,6 @@ Item { bottom: parent.bottom margins: 20 } - } Button { @@ -141,7 +135,7 @@ Item { nameFilters: ["Video files (*.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv)"] onAccepted: { - root.next(fileDialogImportVideo.currentFile , model.get(comboBoxCodec.currentIndex).value); + root.next(fileDialogImportVideo.currentFile, model.get(comboBoxCodec.currentIndex).value); } } @@ -150,7 +144,5 @@ Item { bottom: parent.bottom margins: 20 } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml b/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml index 7a3b08c1..3dff9f52 100644 --- a/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml +++ b/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Controls.Material import QtQuick.Layouts - import Qt5Compat.GraphicalEffects import ScreenPlayApp import ScreenPlay @@ -28,7 +27,6 @@ Item { topMargin: 30 horizontalCenter: parent.horizontalCenter } - } Rectangle { @@ -66,7 +64,6 @@ Item { left: parent.left margins: 20 } - } MouseArea { @@ -80,9 +77,7 @@ Item { snapMode: ScrollBar.SnapOnRelease policy: ScrollBar.AlwaysOn } - } - } Menu { @@ -94,7 +89,6 @@ Item { App.util.copyToClipboard(txtFFMPEGDebug.text); } } - } Button { @@ -114,7 +108,6 @@ Item { bottom: parent.bottom margins: 10 } - } states: [ @@ -125,7 +118,6 @@ Item { target: txtFFMPEGDebug text: "Error!" } - }, State { name: "success" @@ -134,7 +126,6 @@ Item { target: txtFFMPEGDebug text: "Success!" } - } ] } diff --git a/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml b/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml index ef8a95a1..d4cc8e97 100644 --- a/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml +++ b/ScreenPlay/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml @@ -21,84 +21,81 @@ Item { signal save function cleanup() { - App.create.cancel() + App.create.cancel(); } function basename(str) { - let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1)) - let filename = filenameWithExtentions.split('.').slice(0, -1).join('.') - return filename + let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1)); + let filename = filenameWithExtentions.split('.').slice(0, -1).join('.'); + return filename; } function checkCanSave() { if (canSave && conversionFinishedSuccessful) - btnSave.enabled = true + btnSave.enabled = true; else - btnSave.enabled = false + btnSave.enabled = false; } onCanSaveChanged: root.checkCanSave() onFilePathChanged: { - textFieldName.text = basename(filePath) + textFieldName.text = basename(filePath); } Connections { function onCreateWallpaperStateChanged(state) { switch (state) { case ImportVideoState.ConvertingPreviewImage: - txtConvert.text = qsTr("Generating preview image...") - break + txtConvert.text = qsTr("Generating preview image..."); + break; case ImportVideoState.ConvertingPreviewThumbnailImage: - txtConvert.text = qsTr("Generating preview thumbnail image...") - break + txtConvert.text = qsTr("Generating preview thumbnail image..."); + break; case ImportVideoState.ConvertingPreviewImageFinished: - imgPreview.source = "file:///" + App.create.workingDir + "/preview.jpg" - imgPreview.visible = true - break + imgPreview.source = "file:///" + App.create.workingDir + "/preview.jpg"; + imgPreview.visible = true; + break; case ImportVideoState.ConvertingPreviewVideo: - txtConvert.text = qsTr("Generating 5 second preview video...") - break + txtConvert.text = qsTr("Generating 5 second preview video..."); + break; case ImportVideoState.ConvertingPreviewGif: - txtConvert.text = qsTr("Generating preview gif...") - break + txtConvert.text = qsTr("Generating preview gif..."); + break; case ImportVideoState.ConvertingPreviewGifFinished: - gifPreview.source = "file:///" + App.create.workingDir + "/preview.gif" - imgPreview.visible = false - gifPreview.visible = true - gifPreview.playing = true - break + gifPreview.source = "file:///" + App.create.workingDir + "/preview.gif"; + imgPreview.visible = false; + gifPreview.visible = true; + gifPreview.playing = true; + break; case ImportVideoState.ConvertingAudio: - txtConvert.text = qsTr("Converting Audio...") - break + txtConvert.text = qsTr("Converting Audio..."); + break; case ImportVideoState.ConvertingVideo: - txtConvert.text = qsTr( - "Converting Video... This can take some time!") - break + txtConvert.text = qsTr("Converting Video... This can take some time!"); + break; case ImportVideoState.ConvertingVideoError: - txtConvert.text = qsTr("Converting Video ERROR!") - break + txtConvert.text = qsTr("Converting Video ERROR!"); + break; case ImportVideoState.AnalyseVideoError: - txtConvert.text = qsTr("Analyse Video ERROR!") - break + txtConvert.text = qsTr("Analyse Video ERROR!"); + break; case ImportVideoState.Finished: - txtConvert.text = "" - conversionFinishedSuccessful = true - busyIndicator.running = false + txtConvert.text = ""; + conversionFinishedSuccessful = true; + busyIndicator.running = false; btnExit.enabled = false; - root.checkCanSave() - break + root.checkCanSave(); + break; } } function onProgressChanged(progress) { - var percentage = Math.floor(progress * 100) + var percentage = Math.floor(progress * 100); if (percentage > 100 || progress > 0.95) - percentage = 100 - + percentage = 100; if (percentage === NaN) - print(progress, percentage) - - txtConvertNumber.text = percentage + "%" + print(progress, percentage); + txtConvertNumber.text = percentage + "%"; } target: App.create @@ -278,9 +275,9 @@ Item { Layout.fillWidth: true onTextChanged: { if (textFieldName.text.length >= 3) - canSave = true + canSave = true; else - canSave = false + canSave = false; } } @@ -330,8 +327,8 @@ Item { highlighted: true font.family: App.settings.font onClicked: { - root.abort() - App.create.cancel() + root.abort(); + App.create.cancel(); } } @@ -345,14 +342,9 @@ Item { font.family: App.settings.font onClicked: { if (conversionFinishedSuccessful) { - btnSave.enabled = false - App.create.saveWallpaper( - textFieldName.text, - textFieldDescription.text, root.filePath, - previewSelector.imageSource, - textFieldYoutubeURL.text, codec, - textFieldTags.getTags()) - savePopup.open() + btnSave.enabled = false; + App.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, codec, textFieldTags.getTags()); + savePopup.open(); } } } @@ -388,9 +380,9 @@ Item { interval: 1000 + Math.random() * 1000 onTriggered: { - savePopup.close() - App.util.setNavigationActive(true) - App.util.setNavigation("Installed") + savePopup.close(); + App.util.setNavigationActive(true); + App.util.setNavigation("Installed"); } } } diff --git a/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebm.qml b/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebm.qml index 5623d34d..71215f30 100644 --- a/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebm.qml +++ b/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebm.qml @@ -23,11 +23,11 @@ Item { ImportWebmInit { onNext: function (filePath) { - root.wizardStarted() - swipeView.currentIndex = 1 - createWallpaperVideoImportConvert.filePath = filePath - App.util.setNavigationActive(false) - App.create.createWallpaperStart(filePath) + root.wizardStarted(); + swipeView.currentIndex = 1; + createWallpaperVideoImportConvert.filePath = filePath; + App.util.setNavigationActive(false); + App.create.createWallpaperStart(filePath); } } diff --git a/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml b/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml index 80cbbbca..9a29f17c 100644 --- a/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml +++ b/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml @@ -16,8 +16,8 @@ Item { property bool canSave: false property string filePath - signal exit() - signal save() + signal exit + signal save function basename(str) { let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1)); @@ -91,10 +91,8 @@ Item { var percentage = Math.floor(progress * 100); if (percentage > 100 || progress > 0.95) percentage = 100; - if (percentage === NaN) print(progress, percentage); - txtConvertNumber.text = percentage + "%"; } @@ -112,7 +110,6 @@ Item { margins: 40 bottomMargin: 0 } - } Item { @@ -182,9 +179,7 @@ Item { position: 1 color: "#00000000" } - } - } BusyIndicator { @@ -206,7 +201,6 @@ Item { bottom: parent.bottom bottomMargin: 40 } - } Text { @@ -222,9 +216,7 @@ Item { bottom: parent.bottom bottomMargin: 20 } - } - } Util.ImageSelector { @@ -238,9 +230,7 @@ Item { left: parent.left bottom: parent.bottom } - } - } Item { @@ -306,7 +296,6 @@ Item { width: parent.width Layout.fillWidth: true } - } Row { @@ -352,9 +341,7 @@ Item { } } } - } - } Popup { @@ -391,7 +378,5 @@ Item { root.exit(); } } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebmInit.qml b/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebmInit.qml index d8480103..f77c22ad 100644 --- a/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebmInit.qml +++ b/ScreenPlay/qml/Create/Wizards/ImportWebm/ImportWebmInit.qml @@ -107,32 +107,10 @@ Item { fill: parent margins: 40 } - } - } - } - - Item { - Layout.fillHeight: true - Layout.preferredWidth: wrapper.width * 0.33 - - StartInfoLinkImage { - text: "Handbreak" - image: "qrc:/qml/ScreenPlayApp/assets/startinfo/handbreak.png" - link: "https://handbrake.fr/" - description: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes," - category: "Tools" - width: 300 - height: parent.height - anchors.centerIn: parent - } - - } - } - } Button { @@ -153,7 +131,6 @@ Item { left: parent.left margins: 20 } - } Button { @@ -178,7 +155,5 @@ Item { bottom: parent.bottom margins: 20 } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/Importh264/Importh264.qml b/ScreenPlay/qml/Create/Wizards/Importh264/Importh264.qml index f509c6ec..6a00209e 100644 --- a/ScreenPlay/qml/Create/Wizards/Importh264/Importh264.qml +++ b/ScreenPlay/qml/Create/Wizards/Importh264/Importh264.qml @@ -23,11 +23,11 @@ Item { Importh264Init { onNext: function (filePath) { - root.wizardStarted() - swipeView.currentIndex = 1 - createWallpaperVideoImportConvert.filePath = filePath - App.util.setNavigationActive(false) - App.create.importH264(filePath) + root.wizardStarted(); + swipeView.currentIndex = 1; + createWallpaperVideoImportConvert.filePath = filePath; + App.util.setNavigationActive(false); + App.create.importH264(filePath); } } diff --git a/ScreenPlay/qml/Create/Wizards/Importh264/Importh264Convert.qml b/ScreenPlay/qml/Create/Wizards/Importh264/Importh264Convert.qml index 64e37a72..b60b7934 100644 --- a/ScreenPlay/qml/Create/Wizards/Importh264/Importh264Convert.qml +++ b/ScreenPlay/qml/Create/Wizards/Importh264/Importh264Convert.qml @@ -16,8 +16,8 @@ Item { property bool canSave: false property string filePath - signal exit() - signal save() + signal exit + signal save function basename(str) { let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1)); @@ -91,10 +91,8 @@ Item { var percentage = Math.floor(progress * 100); if (percentage > 100 || progress > 0.95) percentage = 100; - if (percentage === NaN) print(progress, percentage); - txtConvertNumber.text = percentage + "%"; } @@ -112,7 +110,6 @@ Item { margins: 40 bottomMargin: 0 } - } Item { @@ -182,9 +179,7 @@ Item { position: 1 color: "#00000000" } - } - } BusyIndicator { @@ -206,7 +201,6 @@ Item { bottom: parent.bottom bottomMargin: 40 } - } Text { @@ -222,9 +216,7 @@ Item { bottom: parent.bottom bottomMargin: 20 } - } - } Util.ImageSelector { @@ -238,9 +230,7 @@ Item { left: parent.left bottom: parent.bottom } - } - } Item { @@ -306,7 +296,6 @@ Item { width: parent.width Layout.fillWidth: true } - } Row { @@ -352,9 +341,7 @@ Item { } } } - } - } Popup { @@ -391,7 +378,5 @@ Item { root.exit(); } } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/Importh264/Importh264Init.qml b/ScreenPlay/qml/Create/Wizards/Importh264/Importh264Init.qml index 0c0e5dc4..81fe7d55 100644 --- a/ScreenPlay/qml/Create/Wizards/Importh264/Importh264Init.qml +++ b/ScreenPlay/qml/Create/Wizards/Importh264/Importh264Init.qml @@ -60,22 +60,19 @@ Item { Layout.fillHeight: true Layout.fillWidth: true onExited: { - bg.color = Qt.darker(Material.backgroundColor) + bg.color = Qt.darker(Material.backgroundColor); } onEntered: { - bg.color = Qt.darker(Qt.darker( - Material.backgroundColor)) - drag.accept(Qt.LinkAction) + bg.color = Qt.darker(Qt.darker(Material.backgroundColor)); + drag.accept(Qt.LinkAction); } onDropped: { - let file = App.util.toLocal(drop.urls[0]) - bg.color = Qt.darker(Qt.darker( - Material.backgroundColor)) + let file = App.util.toLocal(drop.urls[0]); + bg.color = Qt.darker(Qt.darker(Material.backgroundColor)); if (file.endsWith(".mp4")) - root.next(drop.urls[0]) + root.next(drop.urls[0]); else - txtFile.text = qsTr( - "Invalid file type. Must be valid h264 (*.mp4)!") + txtFile.text = qsTr("Invalid file type. Must be valid h264 (*.mp4)!"); } Rectangle { @@ -127,8 +124,7 @@ Item { icon.width: 16 icon.height: 16 font.family: App.settings.font - onClicked: Qt.openUrlExternally( - "https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance") + onClicked: Qt.openUrlExternally("https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance") anchors { bottom: parent.bottom @@ -142,7 +138,7 @@ Item { highlighted: true font.family: App.settings.font onClicked: { - fileDialogImportVideo.open() + fileDialogImportVideo.open(); } FileDialog { @@ -150,7 +146,7 @@ Item { nameFilters: ["Video files (*.mp4)"] onAccepted: { - root.next(fileDialogImportVideo.currentFile) + root.next(fileDialogImportVideo.currentFile); } } diff --git a/ScreenPlay/qml/Create/Wizards/QMLWallpaper.qml b/ScreenPlay/qml/Create/Wizards/QMLWallpaper.qml index f85acf5e..afea832c 100644 --- a/ScreenPlay/qml/Create/Wizards/QMLWallpaper.qml +++ b/ScreenPlay/qml/Create/Wizards/QMLWallpaper.qml @@ -53,7 +53,6 @@ WizardPage { Layout.fillWidth: true placeholderText: qsTr("Created By") } - } Util.TextField { @@ -83,7 +82,6 @@ WizardPage { Layout.fillWidth: true } - } Item { @@ -99,7 +97,5 @@ WizardPage { Layout.fillWidth: true } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/QMLWidget.qml b/ScreenPlay/qml/Create/Wizards/QMLWidget.qml index d428382d..43edcd52 100644 --- a/ScreenPlay/qml/Create/Wizards/QMLWidget.qml +++ b/ScreenPlay/qml/Create/Wizards/QMLWidget.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls.Material import QtQuick.Controls import QtQuick.Layouts - import ScreenPlayApp import ScreenPlay import ScreenPlayUtil as Util @@ -52,7 +51,6 @@ WizardPage { anchors.fill: parent fillMode: Image.PreserveAspectCrop } - } Util.ImageSelector { @@ -60,7 +58,6 @@ WizardPage { Layout.fillWidth: true } - } ColumnLayout { @@ -104,11 +101,7 @@ WizardPage { Layout.fillWidth: true } - } - } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/WebsiteWallpaper.qml b/ScreenPlay/qml/Create/Wizards/WebsiteWallpaper.qml index fec21e46..605920aa 100644 --- a/ScreenPlay/qml/Create/Wizards/WebsiteWallpaper.qml +++ b/ScreenPlay/qml/Create/Wizards/WebsiteWallpaper.qml @@ -54,7 +54,6 @@ WizardPage { Layout.fillWidth: true placeholderText: qsTr("Created By") } - } Util.TextField { @@ -99,7 +98,5 @@ WizardPage { Layout.fillWidth: true } - } - } diff --git a/ScreenPlay/qml/Create/Wizards/WizardPage.qml b/ScreenPlay/qml/Create/Wizards/WizardPage.qml index 9a997168..1530c900 100644 --- a/ScreenPlay/qml/Create/Wizards/WizardPage.qml +++ b/ScreenPlay/qml/Create/Wizards/WizardPage.qml @@ -15,11 +15,11 @@ FocusScope { property alias savePopup: savePopup property bool ready: false - signal wizardStarted() - signal wizardExited() - signal saveClicked() - signal saveFinished() - signal cancelClicked() + signal wizardStarted + signal wizardExited + signal saveClicked + signal saveFinished + signal cancelClicked ScrollView { contentWidth: width @@ -45,9 +45,7 @@ FocusScope { top: parent.top horizontalCenter: parent.horizontalCenter } - } - } RowLayout { @@ -80,7 +78,6 @@ FocusScope { savePopup.open(); } } - } Popup { @@ -108,7 +105,6 @@ FocusScope { bottom: parent.bottom bottomMargin: 30 } - } Timer { @@ -120,7 +116,5 @@ FocusScope { root.wizardExited(); } } - } - } diff --git a/ScreenPlay/qml/Create/WizardsFiles/QMLWallpaperMain.qml b/ScreenPlay/qml/Create/WizardsFiles/QMLWallpaperMain.qml index b52940ae..e9d57480 100644 --- a/ScreenPlay/qml/Create/WizardsFiles/QMLWallpaperMain.qml +++ b/ScreenPlay/qml/Create/WizardsFiles/QMLWallpaperMain.qml @@ -10,7 +10,6 @@ Rectangle { implicitWidth: 1366 implicitHeight: 768 - Text { id: name text: qsTr("My ScreenPlay Wallpaper 🚀") diff --git a/ScreenPlay/qml/Create/WizardsFiles/QMLWidgetMain.qml b/ScreenPlay/qml/Create/WizardsFiles/QMLWidgetMain.qml index 1c7c35a9..d754a804 100644 --- a/ScreenPlay/qml/Create/WizardsFiles/QMLWidgetMain.qml +++ b/ScreenPlay/qml/Create/WizardsFiles/QMLWidgetMain.qml @@ -7,7 +7,7 @@ Item { Rectangle { id: background - anchors.fill:parent + anchors.fill: parent opacity: 0.9 color: "#333333" } diff --git a/ScreenPlay/qml/Installed/Installed.qml b/ScreenPlay/qml/Installed/Installed.qml index 6aa332ef..35e689bf 100644 --- a/ScreenPlay/qml/Installed/Installed.qml +++ b/ScreenPlay/qml/Installed/Installed.qml @@ -25,24 +25,24 @@ Item { function checkIsContentInstalled() { if (App.installedListModel.count === 0) { - loaderHelp.active = true - gridView.footerItem.isVisible = true - gridView.visible = false - navWrapper.visible = false + loaderHelp.active = true; + gridView.footerItem.isVisible = true; + gridView.visible = false; + navWrapper.visible = false; } else { - loaderHelp.active = false - gridView.footerItem.isVisible = false - refresh = false - gridView.contentY = -82 - gridView.visible = true - navWrapper.visible = true + loaderHelp.active = false; + gridView.footerItem.isVisible = false; + refresh = false; + gridView.contentY = -82; + gridView.visible = true; + navWrapper.visible = true; } } Component.onCompleted: { - navWrapper.state = "in" - App.installedListFilter.sortBySearchType(SearchType.All) - checkIsContentInstalled() + navWrapper.state = "in"; + App.installedListFilter.sortBySearchType(SearchType.All); + checkIsContentInstalled(); } Action { @@ -52,12 +52,12 @@ Item { Connections { function onInstalledLoadingFinished() { - checkIsContentInstalled() + checkIsContentInstalled(); } function onCountChanged(count) { if (count === 0) - checkIsContentInstalled() + checkIsContentInstalled(); } target: App.installedListModel @@ -72,7 +72,7 @@ Item { Connections { function onSortChanged() { - gridView.positionViewAtBeginning() + gridView.positionViewAtBeginning(); } target: App.installedListFilter @@ -129,12 +129,12 @@ Item { } onContentYChanged: { if (contentY <= -180) - gridView.headerItem.isVisible = true + gridView.headerItem.isVisible = true; else - gridView.headerItem.isVisible = false + gridView.headerItem.isVisible = false; //Pull to refresh if (contentY <= -180 && !refresh && !isDragging) - App.installedListModel.reset() + App.installedListModel.reset(); } anchors { @@ -151,11 +151,11 @@ Item { opacity: 0 onIsVisibleChanged: { if (isVisible) { - txtHeader.color = Material.accent - txtHeader.text = qsTr("Refreshing!") + txtHeader.color = Material.accent; + txtHeader.text = qsTr("Refreshing!"); } else { - txtHeader.color = "gray" - txtHeader.text = qsTr("Pull to refresh!") + txtHeader.color = "gray"; + txtHeader.text = qsTr("Pull to refresh!"); } } @@ -163,7 +163,7 @@ Item { interval: 150 running: true onTriggered: { - animFadeIn.start() + animFadeIn.start(); } } @@ -177,7 +177,7 @@ Item { font.pointSize: 18 } - PropertyAnimation on opacity { + PropertyAnimation on opacity { id: animFadeIn from: 0 @@ -207,11 +207,11 @@ Item { interval: 400 running: true onTriggered: { - animFadeInTxtFooter.start() + animFadeInTxtFooter.start(); } } - PropertyAnimation on opacity { + PropertyAnimation on opacity { id: animFadeInTxtFooter from: 0 @@ -236,16 +236,15 @@ Item { isScrolling: gridView.isScrolling onOpenContextMenu: function (position) { // Set the menu to the current item informations - contextMenu.publishedFileID = delegate.publishedFileID - contextMenu.absoluteStoragePath = delegate.absoluteStoragePath - contextMenu.fileName = delegate.customTitle - const pos = delegate.mapToItem(root, position.x, position.y) + contextMenu.publishedFileID = delegate.publishedFileID; + contextMenu.absoluteStoragePath = delegate.absoluteStoragePath; + contextMenu.fileName = delegate.customTitle; + const pos = delegate.mapToItem(root, position.x, position.y); // Disable duplicate opening. The can happen if we // call popup when we are in the closing animtion. if (contextMenu.visible || contextMenu.opened) - return - - contextMenu.popup(pos.x, pos.y) + return; + contextMenu.popup(pos.x, pos.y); } } @@ -267,7 +266,7 @@ Item { objectName: "openFolder" icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_folder_open.svg" onClicked: { - App.util.openFolderInExplorer(contextMenu.absoluteStoragePath) + App.util.openFolderInExplorer(contextMenu.absoluteStoragePath); } } @@ -276,13 +275,10 @@ Item { objectName: enabled ? "removeItem" : "removeWorkshopItem" icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_import_export_.svg" onClicked: { - exportFileDialog.absoluteStoragePath = contextMenu.absoluteStoragePath - let urlFileName = Labs.StandardPaths.writableLocation( - Labs.StandardPaths.DesktopLocation) + "/" - + contextMenu.fileName + ".screenplay" - - exportFileDialog.currentFile = urlFileName - exportFileDialog.open() + exportFileDialog.absoluteStoragePath = contextMenu.absoluteStoragePath; + let urlFileName = Labs.StandardPaths.writableLocation(Labs.StandardPaths.DesktopLocation) + "/" + contextMenu.fileName + ".screenplay"; + exportFileDialog.currentFile = urlFileName; + exportFileDialog.open(); } } @@ -290,21 +286,18 @@ Item { text: enabled ? qsTr("Remove Item") : qsTr("Remove via Workshop") objectName: enabled ? "removeItem" : "removeWorkshopItem" icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_delete.svg" - enabled: contextMenu.publishedFileID === 0 - || !App.settings.steamVersion + enabled: contextMenu.publishedFileID === 0 || !App.settings.steamVersion onClicked: { - deleteDialog.open() + deleteDialog.open(); } } MenuItem { text: qsTr("Open Workshop Page") - enabled: contextMenu.publishedFileID !== 0 - && App.settings.steamVersion + enabled: contextMenu.publishedFileID !== 0 && App.settings.steamVersion icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg" onClicked: { - Qt.openUrlExternally( - "steam://url/CommunityFilePage/" + contextMenu.publishedFileID) + Qt.openUrlExternally("steam://url/CommunityFilePage/" + contextMenu.publishedFileID); } } } @@ -317,9 +310,8 @@ Item { modalSource: root.modalSource anchors.centerIn: Overlay.overlay onAccepted: { - root.sidebar.clear() - App.installedListModel.deinstallItemAt( - contextMenu.absoluteStoragePath) + root.sidebar.clear(); + App.installedListModel.deinstallItemAt(contextMenu.absoluteStoragePath); } } @@ -328,7 +320,7 @@ Item { fileMode: FileDialog.SaveFile property string absoluteStoragePath onAccepted: { - exportFileProgressDialog.open() + exportFileProgressDialog.open(); } } @@ -341,9 +333,7 @@ Item { modalSource: root.modalSource closePolicy: Popup.NoAutoClose onOpened: { - const success = App.util.exportProject( - exportFileDialog.absoluteStoragePath, - exportFileDialog.currentFile) + const success = App.util.exportProject(exportFileDialog.absoluteStoragePath, exportFileDialog.currentFile); } onClosed: exportProgressBar.value = 0 ColumnLayout { @@ -368,10 +358,10 @@ Item { id: exportConnections target: App.util function onCompressionProgressChanged(file, proc, total, br, bt) { - exportProgressBar.value = (br * 100 / bt) + exportProgressBar.value = (br * 100 / bt); } function onCompressionFinished() { - exportFileProgressDialog.close() + exportFileProgressDialog.close(); } } } @@ -391,31 +381,28 @@ Item { anchors.fill: parent property string filePath onEntered: function (drag) { - dropPopup.open() + dropPopup.open(); } onDropped: function (drop) { - dropPopup.close() - dropArea.enabled = false - + dropPopup.close(); + dropArea.enabled = false; if (drop.urls.length > 1) { - importProjectErrorDialog.title = qsTr( - "We only support adding one item at once.") - importProjectErrorDialog.open() - return + importProjectErrorDialog.title = qsTr("We only support adding one item at once."); + importProjectErrorDialog.open(); + return; } - var file = "" // Convert url to string - file = "" + drop.urls[0] + var file = ""; // Convert url to string + file = "" + drop.urls[0]; if (!file.endsWith('.screenplay')) { - importProjectErrorDialog.title = qsTr( - "File type not supported. We only support '.screenplay' files.") - importProjectErrorDialog.open() - return + importProjectErrorDialog.title = qsTr("File type not supported. We only support '.screenplay' files."); + importProjectErrorDialog.open(); + return; } - importDialog.open() - dropArea.filePath = file + importDialog.open(); + dropArea.filePath = file; } onExited: { - dropPopup.close() + dropPopup.close(); } Util.Dialog { @@ -436,10 +423,9 @@ Item { closePolicy: Popup.NoAutoClose onClosed: importProgressBar.value = 0 onOpened: { - const success = App.util.importProject(dropArea.filePath, - App.globalVariables.localStoragePath) - print("finished", success) - dropArea.filePath = "" + const success = App.util.importProject(dropArea.filePath, App.globalVariables.localStoragePath); + print("finished", success); + dropArea.filePath = ""; } ColumnLayout { width: parent.width @@ -461,10 +447,10 @@ Item { id: importConnections target: App.util function onExtractionProgressChanged(file, proc, total, br, bt) { - importProgressBar.value = (br * 100 / bt) + importProgressBar.value = (br * 100 / bt); } function onExtractionFinished() { - importDialog.close() + importDialog.close(); } } } @@ -480,8 +466,8 @@ Item { modal: true onOpened: fileDropAnimation.state = "fileDrop" onClosed: { - fileDropAnimation.state = "" - dropArea.enabled = true + fileDropAnimation.state = ""; + dropArea.enabled = true; } Util.FileDropAnimation { diff --git a/ScreenPlay/qml/Installed/InstalledNavigation.qml b/ScreenPlay/qml/Installed/InstalledNavigation.qml index 0ca5191a..29658e84 100644 --- a/ScreenPlay/qml/Installed/InstalledNavigation.qml +++ b/ScreenPlay/qml/Installed/InstalledNavigation.qml @@ -33,7 +33,8 @@ Item { } } - Util.MouseHoverBlocker {} + Util.MouseHoverBlocker { + } Item { height: nav.height @@ -47,7 +48,8 @@ Item { TabBar { height: parent.height - background: Item {} + background: Item { + } anchors { top: parent.top topMargin: 5 @@ -56,21 +58,12 @@ Item { bottom: parent.bottom } - component CustomTabButton: TabButton { - icon.height: 16 - icon.width: 16 - height: parent.height - width: implicitWidth - background: Item {} - font.capitalization: Font.MixedCase - } - CustomTabButton { text: qsTr("All") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_installed.svg" onClicked: { - setSidebarActive(false) - App.installedListFilter.sortBySearchType(SearchType.All) + setSidebarActive(false); + App.installedListFilter.sortBySearchType(SearchType.All); } } @@ -78,8 +71,8 @@ Item { text: qsTr("Scenes") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_code.svg" onClicked: { - setSidebarActive(false) - App.installedListFilter.sortBySearchType(SearchType.Scene) + setSidebarActive(false); + App.installedListFilter.sortBySearchType(SearchType.Scene); } } @@ -87,9 +80,8 @@ Item { text: qsTr("Videos") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_movie.svg" onClicked: { - setSidebarActive(false) - App.installedListFilter.sortBySearchType( - SearchType.Wallpaper) + setSidebarActive(false); + App.installedListFilter.sortBySearchType(SearchType.Wallpaper); } } @@ -97,8 +89,8 @@ Item { text: qsTr("Widgets") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_widgets.svg" onClicked: { - setSidebarActive(false) - App.installedListFilter.sortBySearchType(SearchType.Widget) + setSidebarActive(false); + App.installedListFilter.sortBySearchType(SearchType.Widget); } } } @@ -127,10 +119,8 @@ Item { ToolTip.visible: hovered ToolTip.text: (btnSortOrder.sortOrder === Qt.AscendingOrder) ? "Install Date Ascending" : "Install Date Descending" onClicked: { - btnSortOrder.sortOrder - = (btnSortOrder.sortOrder - === Qt.DescendingOrder) ? Qt.AscendingOrder : Qt.DescendingOrder - App.installedListFilter.setSortOrder(btnSortOrder.sortOrder) + btnSortOrder.sortOrder = (btnSortOrder.sortOrder === Qt.DescendingOrder) ? Qt.AscendingOrder : Qt.DescendingOrder; + App.installedListFilter.setSortOrder(btnSortOrder.sortOrder); } anchors { @@ -142,6 +132,16 @@ Item { } } + component CustomTabButton: TabButton { + icon.height: 16 + icon.width: 16 + height: parent.height + width: implicitWidth + background: Item { + } + font.capitalization: Font.MixedCase + } + states: [ State { name: "out" diff --git a/ScreenPlay/qml/Installed/InstalledWelcomeScreen.qml b/ScreenPlay/qml/Installed/InstalledWelcomeScreen.qml index c361622e..c25ab688 100644 --- a/ScreenPlay/qml/Installed/InstalledWelcomeScreen.qml +++ b/ScreenPlay/qml/Installed/InstalledWelcomeScreen.qml @@ -70,8 +70,7 @@ Item { id: txtHeadline y: 80 - text: App.settings.steamVersion ? qsTr("Get free Widgets and Wallpaper via the Steam Workshop") : qsTr( - "Get content via our forum") + text: App.settings.steamVersion ? qsTr("Get free Widgets and Wallpaper via the Steam Workshop") : qsTr("Get content via our forum") font.family: App.settings.font font.capitalization: Font.Capitalize wrapMode: Text.WordWrap @@ -106,9 +105,9 @@ Item { text: { if (App.settings.steamVersion) { - return qsTr("Browse the Steam Workshop") + return qsTr("Browse the Steam Workshop"); } else { - return qsTr("Open the ScreenPlay forum") + return qsTr("Open the ScreenPlay forum"); } } Material.background: Material.color(Material.Orange) @@ -118,18 +117,18 @@ Item { height: implicitHeight + 10 icon.source: { if (App.settings.steamVersion) { - return "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg" + return "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg"; } else { - return "qrc:/qml/ScreenPlayApp/assets/icons/icon_community.svg" + return "qrc:/qml/ScreenPlayApp/assets/icons/icon_community.svg"; } } icon.width: 18 icon.height: 18 onClicked: { if (App.settings.steamVersion) { - App.util.setNavigation("Workshop") + App.util.setNavigation("Workshop"); } else { - Qt.openUrlExternally("https://forum.screen-play.app/") + Qt.openUrlExternally("https://forum.screen-play.app/"); } } @@ -312,7 +311,7 @@ Item { ScriptAction { script: { - animShake.start(2000, 1000, -1) + animShake.start(2000, 1000, -1); } } } diff --git a/ScreenPlay/qml/Installed/ScreenPlayItem.qml b/ScreenPlay/qml/Installed/ScreenPlayItem.qml index 8b9410a8..f2e04297 100644 --- a/ScreenPlay/qml/Installed/ScreenPlayItem.qml +++ b/ScreenPlay/qml/Installed/ScreenPlayItem.qml @@ -25,16 +25,16 @@ Item { height: 180 onTypeChanged: { if (JSUtil.isWidget(type)) { - icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_widgets.svg" - return + icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_widgets.svg"; + return; } if (JSUtil.isScene(type)) { - icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_code.svg" - return + icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_code.svg"; + return; } if (JSUtil.isVideo(type)) { - icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_movie.svg" - return + icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_movie.svg"; + return; } } @@ -42,11 +42,10 @@ Item { running: true onTriggered: showAnim.start() interval: { - var itemIndexMax = itemIndex + var itemIndexMax = itemIndex; if (itemIndex > 30) - itemIndexMax = 3 - - 5 * itemIndexMax * Math.random() + itemIndexMax = 3; + 5 * itemIndexMax * Math.random(); } } @@ -215,20 +214,20 @@ Item { cursorShape: Qt.PointingHandCursor acceptedButtons: Qt.LeftButton | Qt.RightButton onEntered: { - root.state = "hover" - screenPlayItemImage.state = "hover" - screenPlayItemImage.enter() + root.state = "hover"; + screenPlayItemImage.state = "hover"; + screenPlayItemImage.enter(); } onExited: { - root.state = "" - screenPlayItemImage.state = "loaded" - screenPlayItemImage.exit() + root.state = ""; + screenPlayItemImage.state = "loaded"; + screenPlayItemImage.exit(); } onClicked: function (mouse) { if (mouse.button === Qt.LeftButton) - App.util.setSidebarItem(root.screenId, root.type) + App.util.setSidebarItem(root.screenId, root.type); else if (mouse.button === Qt.RightButton) - root.openContextMenu(Qt.point(mouseX, mouseY)) + root.openContextMenu(Qt.point(mouseX, mouseY)); } } } diff --git a/ScreenPlay/qml/Installed/ScreenPlayItemImage.qml b/ScreenPlay/qml/Installed/ScreenPlayItemImage.qml index 7e1c4d4d..a60eedc7 100644 --- a/ScreenPlay/qml/Installed/ScreenPlayItemImage.qml +++ b/ScreenPlay/qml/Installed/ScreenPlayItemImage.qml @@ -11,7 +11,6 @@ Item { function enter() { if (root.sourceImageGIF != "") loader_imgGIFPreview.sourceComponent = component_imgGIFPreview; - } function exit() { @@ -33,7 +32,6 @@ Item { source: { if (root.sourceImage === "") return "qrc:/qml/ScreenPlayApp/assets/images/missingPreview.png"; - return root.screenPreview === "" ? "qrc:/qml/ScreenPlayApp/assets/images/missingPreview.png" : Qt.resolvedUrl(absoluteStoragePath + "/" + root.sourceImage); } onStatusChanged: { @@ -57,7 +55,6 @@ Item { source: root.sourceImageGIF === "" ? "qrc:/qml/ScreenPlayApp/assets/images/missingPreview.png" : Qt.resolvedUrl(absoluteStoragePath + "/" + root.sourceImageGIF) fillMode: Image.PreserveAspectCrop } - } Loader { @@ -79,7 +76,6 @@ Item { to: 1 easing.type: Easing.OutQuart } - }, Transition { from: "hover" @@ -92,7 +88,6 @@ Item { to: 0 easing.type: Easing.OutQuart } - }, Transition { from: "loaded" @@ -106,7 +101,6 @@ Item { to: 1 easing.type: Easing.OutQuart } - } ] } diff --git a/ScreenPlay/qml/Installed/Sidebar.qml b/ScreenPlay/qml/Installed/Sidebar.qml index e0f1519c..f88d8322 100644 --- a/ScreenPlay/qml/Installed/Sidebar.qml +++ b/ScreenPlay/qml/Installed/Sidebar.qml @@ -20,83 +20,70 @@ Item { function indexOfValue(model, value) { for (var i = 0; i < model.length; i++) { - let ourValue = model[i].value + let ourValue = model[i].value; if (value === ourValue) - return i + return i; } - return -1 + return -1; } // This is used for removing wallpaper. We need to clear // the preview image/gif so we can release the file for deletion. function clear() { - imagePreview.source = "" - animatedImagePreview.source = "" - txtHeadline.text = "" - root.state = "inactive" + imagePreview.source = ""; + animatedImagePreview.source = ""; + txtHeadline.text = ""; + root.state = "inactive"; } width: 400 state: "inactive" property bool hasPreviewGif: false onContentFolderNameChanged: { - txtHeadline.text = App.installedListModel.get( - root.contentFolderName).m_title - - const previewGiFilePath = Qt.resolvedUrl( - App.globalVariables.localStoragePath + "/" - + root.contentFolderName + "/" + App.installedListModel.get( - root.contentFolderName).m_previewGIF) - - const previewImageFilePath = Qt.resolvedUrl( - App.globalVariables.localStoragePath + "/" - + root.contentFolderName + "/" + App.installedListModel.get( - root.contentFolderName).m_preview) - - root.hasPreviewGif = App.util.fileExists(previewGiFilePath) - + txtHeadline.text = App.installedListModel.get(root.contentFolderName).m_title; + const previewGiFilePath = Qt.resolvedUrl(App.globalVariables.localStoragePath + "/" + root.contentFolderName + "/" + App.installedListModel.get(root.contentFolderName).m_previewGIF); + const previewImageFilePath = Qt.resolvedUrl(App.globalVariables.localStoragePath + "/" + root.contentFolderName + "/" + App.installedListModel.get(root.contentFolderName).m_preview); + root.hasPreviewGif = App.util.fileExists(previewGiFilePath); if (hasPreviewGif) { - animatedImagePreview.source = previewGiFilePath - animatedImagePreview.playing = true + animatedImagePreview.source = previewGiFilePath; + animatedImagePreview.playing = true; } else { - imagePreview.source = previewImageFilePath + imagePreview.source = previewImageFilePath; } - - if (JSUtil.isWidget(root.type) - || (monitorSelection.activeMonitors.length > 0)) { - btnSetWallpaper.enabled = true - return + if (JSUtil.isWidget(root.type) || (monitorSelection.activeMonitors.length > 0)) { + btnSetWallpaper.enabled = true; + return; } - btnSetWallpaper.enabled = false + btnSetWallpaper.enabled = false; } Connections { function onSetSidebarItem(folderName, type) { // Toggle sidebar if clicked on the same content twice - if (root.contentFolderName === folderName - && root.state !== "inactive") { - root.state = "inactive" - return + if (root.contentFolderName === folderName && root.state !== "inactive") { + root.state = "inactive"; + return; } - root.contentFolderName = folderName - root.type = type + root.contentFolderName = folderName; + root.type = type; if (JSUtil.isWallpaper(root.type)) { if (type === InstalledType.VideoWallpaper) - root.state = "activeWallpaper" + root.state = "activeWallpaper"; else - root.state = "activeScene" - btnSetWallpaper.text = qsTr("Set Wallpaper") + root.state = "activeScene"; + btnSetWallpaper.text = qsTr("Set Wallpaper"); } else { - root.state = "activeWidget" - btnSetWallpaper.text = qsTr("Set Widget") + root.state = "activeWidget"; + btnSetWallpaper.text = qsTr("Set Widget"); } } target: App.util } - Util.MouseHoverBlocker {} + Util.MouseHoverBlocker { + } Rectangle { anchors.fill: parent @@ -350,9 +337,7 @@ Item { "text": qsTr("Scale-Down") }] Component.onCompleted: { - cbVideoFillMode.currentIndex = root.indexOfValue( - cbVideoFillMode.model, - App.settings.videoFillMode) + cbVideoFillMode.currentIndex = root.indexOfValue(cbVideoFillMode.model, App.settings.videoFillMode); } } } @@ -361,47 +346,32 @@ Item { Button { id: btnSetWallpaper objectName: "btnSetWallpaper" - enabled: JSUtil.isWidget( - root.type) ? true : monitorSelection.isSelected + enabled: JSUtil.isWidget(root.type) ? true : monitorSelection.isSelected Material.background: Material.accent Material.foreground: "white" icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_plus.svg" icon.color: "white" font.pointSize: 12 onClicked: { - const absoluteStoragePath = App.globalVariables.localStoragePath - + "/" + root.contentFolderName - const previewImage = App.installedListModel.get( - root.contentFolderName).m_preview + const absoluteStoragePath = App.globalVariables.localStoragePath + "/" + root.contentFolderName; + const previewImage = App.installedListModel.get(root.contentFolderName).m_preview; if (JSUtil.isWallpaper(root.type)) { - let activeMonitors = monitorSelection.getActiveMonitors( - ) + let activeMonitors = monitorSelection.getActiveMonitors(); // TODO Alert user to choose a monitor if (activeMonitors.length === 0) - return + return; // We only have sliderVolume if it is a VideoWallpaper - let volume = 0 + let volume = 0; if (type === InstalledType.VideoWallpaper) - volume = Math.round( - sliderVolume.slider.value * 100) / 100 - - const screenFile = App.installedListModel.get( - root.contentFolderName).m_file - let success = App.screenPlayManager.createWallpaper( - root.type, cbVideoFillMode.currentValue, - absoluteStoragePath, previewImage, screenFile, - activeMonitors, volume, 1, {}, true) + volume = Math.round(sliderVolume.slider.value * 100) / 100; + const screenFile = App.installedListModel.get(root.contentFolderName).m_file; + let success = App.screenPlayManager.createWallpaper(root.type, cbVideoFillMode.currentValue, absoluteStoragePath, previewImage, screenFile, activeMonitors, volume, 1, {}, true); } if (JSUtil.isWidget(root.type)) - App.screenPlayManager.createWidget(type, - Qt.point(0, 0), - absoluteStoragePath, - previewImage, {}, - true) - - root.state = "inactive" - monitorSelection.reset() + App.screenPlayManager.createWidget(type, Qt.point(0, 0), absoluteStoragePath, previewImage, {}, true); + root.state = "inactive"; + monitorSelection.reset(); } anchors { diff --git a/ScreenPlay/qml/Monitors/DefaultVideoControls.qml b/ScreenPlay/qml/Monitors/DefaultVideoControls.qml index 7f926494..e1f51bfb 100644 --- a/ScreenPlay/qml/Monitors/DefaultVideoControls.qml +++ b/ScreenPlay/qml/Monitors/DefaultVideoControls.qml @@ -19,7 +19,6 @@ ColumnLayout { let ourValue = model[i].value; if (value === ourValue) return i; - } return -1; } @@ -44,7 +43,6 @@ ColumnLayout { } } - Util.Slider { id: slCurrentVideoTime @@ -83,23 +81,23 @@ ColumnLayout { valueRole: "value" currentIndex: root.indexOfValue(settingsComboBox.model, App.settings.videoFillMode) model: [{ - "value": FillMode.Stretch, - "text": qsTr("Stretch") - }, { - "value": FillMode.Fill, - "text": qsTr("Fill") - }, { - "value": FillMode.Contain, - "text": qsTr("Contain") - }, { - "value": FillMode.Cover, - "text": qsTr("Cover") - }, { - "value": FillMode.Scale_Down, - "text": qsTr("Scale_Down") - }] + "value": FillMode.Stretch, + "text": qsTr("Stretch") + }, { + "value": FillMode.Fill, + "text": qsTr("Fill") + }, { + "value": FillMode.Contain, + "text": qsTr("Contain") + }, { + "value": FillMode.Cover, + "text": qsTr("Cover") + }, { + "value": FillMode.Scale_Down, + "text": qsTr("Scale_Down") + }] onActivated: { - App.screenPlayManager.setWallpaperFillModeAtMonitorIndex(activeMonitorIndex,settingsComboBox.currentValue); + App.screenPlayManager.setWallpaperFillModeAtMonitorIndex(activeMonitorIndex, settingsComboBox.currentValue); } } @@ -107,7 +105,6 @@ ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true } - } states: [ @@ -119,7 +116,6 @@ ColumnLayout { opacity: 1 anchors.topMargin: 20 } - }, State { name: "hidden" @@ -129,7 +125,6 @@ ColumnLayout { opacity: 0 anchors.topMargin: -50 } - } ] transitions: [ @@ -144,7 +139,6 @@ ColumnLayout { easing.type: Easing.InOutQuart properties: "anchors.topMargin, opacity" } - } ] } diff --git a/ScreenPlay/qml/Monitors/MonitorSelection.qml b/ScreenPlay/qml/Monitors/MonitorSelection.qml index 153c29f8..2dd0b1ac 100644 --- a/ScreenPlay/qml/Monitors/MonitorSelection.qml +++ b/ScreenPlay/qml/Monitors/MonitorSelection.qml @@ -20,9 +20,8 @@ Rectangle { property alias radius: root.radius Component.onCompleted: { - resize() - selectOnly(0) - + resize(); + selectOnly(0); } signal requestProjectSettings(var index, var installedType, var appID) @@ -30,87 +29,84 @@ Rectangle { function selectOnly(index) { for (var i = 0; i < rp.count; i++) { if (i === index) { - rp.itemAt(i).isSelected = true - continue + rp.itemAt(i).isSelected = true; + continue; } - rp.itemAt(i).isSelected = false + rp.itemAt(i).isSelected = false; } - getActiveMonitors() + getActiveMonitors(); } function reset() { for (var i = 0; i < rp.count; i++) { - rp.itemAt(i).isSelected = false + rp.itemAt(i).isSelected = false; } - rp.itemAt(0).isSelected = true - getActiveMonitors() + rp.itemAt(0).isSelected = true; + getActiveMonitors(); } function getActiveMonitors() { - root.activeMonitors = [] + root.activeMonitors = []; for (var i = 0; i < rp.count; i++) { if (rp.itemAt(i).isSelected) - root.activeMonitors.push(rp.itemAt(i).index) + root.activeMonitors.push(rp.itemAt(i).index); } // Must be called manually. When QML properties are getting altered in js the // property binding breaks - root.activeMonitorsChanged() - root.isSelected = root.activeMonitors.length > 0 - return root.activeMonitors + root.activeMonitorsChanged(); + root.isSelected = root.activeMonitors.length > 0; + return root.activeMonitors; } function selectMonitorAt(index) { if (!multipleMonitorsSelectable) - selectOnly(index) + selectOnly(index); else - rp.itemAt(index).isSelected = !rp.itemAt(index).isSelected - getActiveMonitors() + rp.itemAt(index).isSelected = !rp.itemAt(index).isSelected; + getActiveMonitors(); if (rp.itemAt(index).hasContent) - root.requestProjectSettings(index, rp.itemAt(index).installedType, - rp.itemAt(index).appID) + root.requestProjectSettings(index, rp.itemAt(index).installedType, rp.itemAt(index).appID); } function resize() { - var absoluteDesktopSize = App.monitorListModel.absoluteDesktopSize() - var isWidthGreaterThanHeight = false - var windowsDelta = 0 + var absoluteDesktopSize = App.monitorListModel.absoluteDesktopSize(); + var isWidthGreaterThanHeight = false; + var windowsDelta = 0; if (absoluteDesktopSize.width < absoluteDesktopSize.height) { - windowsDelta = absoluteDesktopSize.width / absoluteDesktopSize.height - isWidthGreaterThanHeight = false + windowsDelta = absoluteDesktopSize.width / absoluteDesktopSize.height; + isWidthGreaterThanHeight = false; } else { - windowsDelta = absoluteDesktopSize.height / absoluteDesktopSize.width - isWidthGreaterThanHeight = true + windowsDelta = absoluteDesktopSize.height / absoluteDesktopSize.width; + isWidthGreaterThanHeight = true; } if (rp.count === 1) - availableWidth = availableWidth * 0.66 - - var dynamicHeight = availableWidth * windowsDelta - var dynamicWidth = availableHeight * windowsDelta + availableWidth = availableWidth * 0.66; + var dynamicHeight = availableWidth * windowsDelta; + var dynamicWidth = availableHeight * windowsDelta; // Delta (height/width) - var monitorHeightRationDelta = 0 - var monitorWidthRationDelta = 0 + var monitorHeightRationDelta = 0; + var monitorWidthRationDelta = 0; if (isWidthGreaterThanHeight) { - monitorHeightRationDelta = dynamicHeight / absoluteDesktopSize.height - monitorWidthRationDelta = availableWidth / absoluteDesktopSize.width + monitorHeightRationDelta = dynamicHeight / absoluteDesktopSize.height; + monitorWidthRationDelta = availableWidth / absoluteDesktopSize.width; } else { - monitorHeightRationDelta = availableHeight / absoluteDesktopSize.height - monitorWidthRationDelta = dynamicWidth / absoluteDesktopSize.width + monitorHeightRationDelta = availableHeight / absoluteDesktopSize.height; + monitorWidthRationDelta = dynamicWidth / absoluteDesktopSize.width; } for (var i = 0; i < rp.count; i++) { - rp.itemAt(i).index = i - rp.itemAt(i).height = rp.itemAt(i).height * monitorHeightRationDelta - rp.itemAt(i).width = rp.itemAt(i).width * monitorWidthRationDelta - rp.itemAt(i).x = rp.itemAt(i).x * monitorWidthRationDelta - rp.itemAt(i).y = rp.itemAt(i).y * monitorHeightRationDelta - rp.contentWidth += rp.itemAt(i).width - rp.contentHeight += rp.itemAt(i).height + rp.itemAt(i).index = i; + rp.itemAt(i).height = rp.itemAt(i).height * monitorHeightRationDelta; + rp.itemAt(i).width = rp.itemAt(i).width * monitorWidthRationDelta; + rp.itemAt(i).x = rp.itemAt(i).x * monitorWidthRationDelta; + rp.itemAt(i).y = rp.itemAt(i).y * monitorHeightRationDelta; + rp.contentWidth += rp.itemAt(i).width; + rp.contentHeight += rp.itemAt(i).height; } - rp.contentWidth += 200 - rp.contentHeight += 200 + rp.contentWidth += 200; + rp.contentHeight += 200; } - color: Material.theme === Material.Light ? Material.background : Qt.darker( - Material.background) + color: Material.theme === Material.Light ? Material.background : Qt.darker(Material.background) height: availableHeight width: parent.width clip: true @@ -118,7 +114,7 @@ Rectangle { Connections { function onMonitorReloadCompleted() { - resize() + resize(); } target: App.monitorListModel @@ -150,7 +146,7 @@ Rectangle { installedType: m_installedType monitorWithoutContentSelectable: root.monitorWithoutContentSelectable onMonitorSelected: function (index) { - root.selectMonitorAt(index) + root.selectMonitorAt(index); } } } diff --git a/ScreenPlay/qml/Monitors/MonitorSelectionItem.qml b/ScreenPlay/qml/Monitors/MonitorSelectionItem.qml index 9bf77733..99a6f9cf 100644 --- a/ScreenPlay/qml/Monitors/MonitorSelectionItem.qml +++ b/ScreenPlay/qml/Monitors/MonitorSelectionItem.qml @@ -10,10 +10,10 @@ Item { property rect geometry onGeometryChanged: { - root.width = geometry.width - root.height = geometry.height - root.x = geometry.x - root.y = geometry.y + root.width = geometry.width; + root.height = geometry.height; + root.x = geometry.x; + root.y = geometry.y; } property string previewImage @@ -51,7 +51,6 @@ Item { top: wrapper.bottom topMargin: 5 } - } Rectangle { @@ -83,14 +82,12 @@ Item { onClicked: { if (monitorWithoutContentSelectable) { monitorSelected(index); - return + return; } if (root.hasContent && !root.monitorWithoutContentSelectable) monitorSelected(index); - } } - } states: [ @@ -101,7 +98,6 @@ Item { target: wrapper border.color: "#373737" } - }, State { name: "selected" @@ -110,7 +106,6 @@ Item { target: wrapper border.color: "#F28E0D" } - } ] transitions: [ @@ -125,7 +120,6 @@ Item { easing.type: Easing.InOutQuart property: "border.color" } - } ] } diff --git a/ScreenPlay/qml/Monitors/Monitors.qml b/ScreenPlay/qml/Monitors/Monitors.qml index d6061fd0..50596121 100644 --- a/ScreenPlay/qml/Monitors/Monitors.qml +++ b/ScreenPlay/qml/Monitors/Monitors.qml @@ -18,12 +18,12 @@ Util.Popup { width: 1000 height: 500 onOpened: { - monitorSelection.selectMonitorAt(0) + monitorSelection.selectMonitorAt(0); } Connections { function onRequestToggleWallpaperConfiguration() { - root.open() + root.open(); } target: App.util @@ -81,21 +81,18 @@ Util.Popup { availableHeight: 150 onRequestProjectSettings: function (index, installedType, appID) { if (installedType === InstalledType.VideoWallpaper) { - videoControlWrapper.state = "visible" - customPropertiesGridView.visible = false - const wallpaper = App.screenPlayManager.getWallpaperByAppID( - appID) - videoControlWrapper.wallpaper = wallpaper + videoControlWrapper.state = "visible"; + customPropertiesGridView.visible = false; + const wallpaper = App.screenPlayManager.getWallpaperByAppID(appID); + videoControlWrapper.wallpaper = wallpaper; } else { - videoControlWrapper.state = "hidden" - customPropertiesGridView.visible = true - if (!App.screenPlayManager.requestProjectSettingsAtMonitorIndex( - index)) { - console.warn("Unable to get requested settings from index: ", - index) + videoControlWrapper.state = "hidden"; + customPropertiesGridView.visible = true; + if (!App.screenPlayManager.requestProjectSettingsAtMonitorIndex(index)) { + console.warn("Unable to get requested settings from index: ", index); } } - activeMonitorIndex = index + activeMonitorIndex = index; } anchors { @@ -107,7 +104,7 @@ Util.Popup { Connections { function onProjectSettingsListModelResult(listModel) { - customPropertiesGridView.projectSettingsListmodelRef = listModel + customPropertiesGridView.projectSettingsListmodelRef = listModel; } target: App.screenPlayManager @@ -130,39 +127,32 @@ Util.Popup { highlighted: true text: qsTr("Remove selected") font.family: App.settings.font - enabled: monitorSelection.activeMonitors.length == 1 - && App.screenPlayManager.activeWallpaperCounter > 0 + enabled: monitorSelection.activeMonitors.length == 1 && App.screenPlayManager.activeWallpaperCounter > 0 onClicked: { - if (!App.screenPlayManager.removeWallpaperAt( - monitorSelection.activeMonitors[0])) - print("Unable to close singel wallpaper") + if (!App.screenPlayManager.removeWallpaperAt(monitorSelection.activeMonitors[0])) + print("Unable to close singel wallpaper"); } } Button { id: btnRemoveAllWallpape - text: qsTr("Remove all ") - + App.screenPlayManager.activeWallpaperCounter + " " + qsTr( - "Wallpapers") + text: qsTr("Remove all ") + App.screenPlayManager.activeWallpaperCounter + " " + qsTr("Wallpapers") Material.background: Material.accent highlighted: true font.family: App.settings.font enabled: App.screenPlayManager.activeWallpaperCounter > 0 onClicked: { if (!App.screenPlayManager.removeAllWallpapers()) - print("Unable to close all wallpaper!") - - root.close() + print("Unable to close all wallpaper!"); + root.close(); } } Button { id: btnRemoveAllWidgets - text: qsTr("Remove all ") - + App.screenPlayManager.activeWidgetsCounter + " " + qsTr( - "Widgets") + text: qsTr("Remove all ") + App.screenPlayManager.activeWidgetsCounter + " " + qsTr("Widgets") Material.background: Material.accent Material.foreground: Material.primaryTextColor highlighted: true @@ -170,17 +160,15 @@ Util.Popup { enabled: App.screenPlayManager.activeWidgetsCounter > 0 onClicked: { if (!App.screenPlayManager.removeAllWidgets()) - print("Unable to close all widgets!") - - root.close() + print("Unable to close all widgets!"); + root.close(); } } } } Rectangle { - color: Material.theme === Material.Light ? Material.background : Qt.darker( - Material.background) + color: Material.theme === Material.Light ? Material.background : Qt.darker(Material.background) radius: 3 clip: true @@ -262,7 +250,7 @@ Util.Popup { Connections { function onProfilesSaved() { if (root.opened) - saveNotification.open() + saveNotification.open(); } target: App.screenPlayManager diff --git a/ScreenPlay/qml/Monitors/MonitorsProjectSettingItem.qml b/ScreenPlay/qml/Monitors/MonitorsProjectSettingItem.qml index 12462f6f..88f7f406 100644 --- a/ScreenPlay/qml/Monitors/MonitorsProjectSettingItem.qml +++ b/ScreenPlay/qml/Monitors/MonitorsProjectSettingItem.qml @@ -35,7 +35,6 @@ Item { left: parent.left leftMargin: root.isHeadline ? 0 : 25 } - } Item { @@ -43,8 +42,7 @@ Item { visible: !root.isHeadline Component.onCompleted: { if (root.isHeadline) - return ; - + return; switch (root.value["type"]) { case "slider": loader.sourceComponent = compSlider; @@ -64,7 +62,6 @@ Item { } if (root.value["text"]) txtDescription.text = root.value["text"]; - } anchors { @@ -86,7 +83,6 @@ Item { target: loader.item } - } Component { @@ -119,11 +115,8 @@ Item { right: parent.right verticalCenter: parent.verticalCenter } - } - } - } Component { @@ -148,7 +141,6 @@ Item { right: parent.right verticalCenter: parent.verticalCenter } - } Rectangle { @@ -166,7 +158,6 @@ Item { rightMargin: 20 verticalCenter: parent.verticalCenter } - } ColorDialog { @@ -184,9 +175,7 @@ Item { App.screenPlayManager.setWallpaperValueAtMonitorIndex(selectedMonitor, name, tmpColor); } } - } - } Component { @@ -233,7 +222,6 @@ Item { left: parent.left leftMargin: 20 } - } Text { @@ -247,13 +235,8 @@ Item { right: parent.right verticalCenter: parent.verticalCenter } - } - } - } - } - } diff --git a/ScreenPlay/qml/Monitors/SaveNotification.qml b/ScreenPlay/qml/Monitors/SaveNotification.qml index 5a54ef71..2b1492d8 100644 --- a/ScreenPlay/qml/Monitors/SaveNotification.qml +++ b/ScreenPlay/qml/Monitors/SaveNotification.qml @@ -51,7 +51,6 @@ Rectangle { bottom: parent.bottom bottomMargin: 5 } - } layer.effect: ElevationEffect { @@ -70,7 +69,6 @@ Rectangle { duration: 250 easing.type: Easing.InOutQuart } - } ] states: [ @@ -82,7 +80,6 @@ Rectangle { anchors.bottomMargin: 10 opacity: 1 } - } ] } diff --git a/ScreenPlay/qml/Navigation/ExitPopup.qml b/ScreenPlay/qml/Navigation/ExitPopup.qml index 4e5b9312..3a2ebd3e 100644 --- a/ScreenPlay/qml/Navigation/ExitPopup.qml +++ b/ScreenPlay/qml/Navigation/ExitPopup.qml @@ -9,7 +9,6 @@ import ScreenPlay import ScreenPlayUtil as Util import Qt5Compat.GraphicalEffects - /*! \qmltype exitDialog \brief exitDialog @@ -46,10 +45,10 @@ Util.Popup { Text { text: { if (Qt.platform.os === "windows") { - return qsTr("You can quit ScreenPlay via the bottom right Tray-Icon.") + return qsTr("You can quit ScreenPlay via the bottom right Tray-Icon."); } if (Qt.platform.os === "osx") { - return qsTr("You can quit ScreenPlay via the top right Tray-Icon.") + return qsTr("You can quit ScreenPlay via the top right Tray-Icon."); } } @@ -75,20 +74,20 @@ Util.Popup { Button { text: qsTr("Minimize ScreenPlay") onClicked: { - applicationWindow.hide() - App.showDockIcon(false) - root.close() + applicationWindow.hide(); + App.showDockIcon(false); + root.close(); } } Button { highlighted: true text: qsTr("Always minimize ScreenPlay") onClicked: { - settings.setValue("alwaysMinimize", true) - settings.sync() - App.showDockIcon(false) - applicationWindow.hide() - root.close() + settings.setValue("alwaysMinimize", true); + settings.sync(); + App.showDockIcon(false); + applicationWindow.hide(); + root.close(); } } } diff --git a/ScreenPlay/qml/Navigation/Navigation.qml b/ScreenPlay/qml/Navigation/Navigation.qml index fec57139..16b5c639 100644 --- a/ScreenPlay/qml/Navigation/Navigation.qml +++ b/ScreenPlay/qml/Navigation/Navigation.qml @@ -22,31 +22,30 @@ Rectangle { signal changePage(string name) function setActive(active) { - navActive = active + navActive = active; if (active) - root.state = "enabled" + root.state = "enabled"; else - root.state = "disabled" + root.state = "disabled"; } function setNavigation(name) { - var i = 0 + var i = 0; for (; i < navArray.length; i++) { if (navArray[i].name === name) { - navArray[i].state = "active" - root.currentNavigationName = name + navArray[i].state = "active"; + root.currentNavigationName = name; } else { - navArray[i].state = "inactive" + navArray[i].state = "inactive"; } } } function onPageChanged(name) { if (!navActive) - return - - root.changePage(name) - setNavigation(name) + return; + root.changePage(name); + setNavigation(name); } implicitWidth: 1366 @@ -60,11 +59,11 @@ Rectangle { Connections { function onRequestNavigationActive(isActive) { - setActive(isActive) + setActive(isActive); } function onRequestNavigation(nav) { - onPageChanged(nav) + onPageChanged(nav); } target: App.util @@ -83,16 +82,6 @@ Rectangle { spacing: 0 - component CustomTabButton: TabButton { - icon.height: 16 - icon.width: 16 - font.pointSize: 12 - height: parent.height - width: implicitWidth - background: Item {} - font.capitalization: Font.MixedCase - } - CustomTabButton { id: navCreate icon.height: 22 @@ -100,7 +89,7 @@ Rectangle { text: qsTr("Create") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_plus.svg" onClicked: { - root.onPageChanged("Create") + root.onPageChanged("Create"); } objectName: "createTab" } @@ -111,7 +100,7 @@ Rectangle { text: qsTr("Workshop") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg" onClicked: { - root.onPageChanged("Workshop") + root.onPageChanged("Workshop"); } objectName: "workshopTab" } @@ -121,7 +110,7 @@ Rectangle { text: qsTr("Installed") + " " + App.installedListModel.count icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_installed.svg" onClicked: { - root.onPageChanged("Installed") + root.onPageChanged("Installed"); } objectName: "installedTab" } @@ -131,7 +120,7 @@ Rectangle { text: qsTr("Community") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_community.svg" onClicked: { - root.onPageChanged("Community") + root.onPageChanged("Community"); } objectName: "communityTab" } @@ -141,20 +130,30 @@ Rectangle { text: qsTr("Settings") icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_settings.svg" onClicked: { - root.onPageChanged("Settings") + root.onPageChanged("Settings"); } objectName: "settingsTab" } } + component CustomTabButton: TabButton { + icon.height: 16 + icon.width: 16 + font.pointSize: 12 + height: parent.height + width: implicitWidth + background: Item { + } + font.capitalization: Font.MixedCase + } + Rectangle { id: quickActionRowBackground anchors.centerIn: quickActionRow width: quickActionRow.width + 5 height: quickActionRow.height - 16 color: Material.theme === Material.Light ? Material.background : "#242424" - border.color: Material.theme === Material.Light ? Material.iconDisabledColor : Qt.darker( - Material.background) + border.color: Material.theme === Material.Light ? Material.iconDisabledColor : Qt.darker(Material.background) border.width: 1 radius: 3 } @@ -170,8 +169,7 @@ Rectangle { ToolButton { icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/font-awsome/patreon-brands.svg" text: qsTr("Support me on Patreon!") - onClicked: Qt.openUrlExternally( - "https://www.patreon.com/ScreenPlayApp") + onClicked: Qt.openUrlExternally("https://www.patreon.com/ScreenPlayApp") } } @@ -184,13 +182,12 @@ Rectangle { bottom: parent.bottom } - property bool contentActive: App.screenPlayManager.activeWallpaperCounter > 0 - || App.screenPlayManager.activeWidgetsCounter > 0 + property bool contentActive: App.screenPlayManager.activeWallpaperCounter > 0 || App.screenPlayManager.activeWidgetsCounter > 0 onContentActiveChanged: { if (!contentActive) { - miMuteAll.soundEnabled = true - miStopAll.isPlaying = true + miMuteAll.soundEnabled = true; + miStopAll.isPlaying = true; } } @@ -206,12 +203,11 @@ Rectangle { property bool soundEnabled: true onSoundEnabledChanged: { if (miMuteAll.soundEnabled) { - miMuteAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume.svg" - App.screenPlayManager.setAllWallpaperValue("muted", "false") + miMuteAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume.svg"; + App.screenPlayManager.setAllWallpaperValue("muted", "false"); } else { - miMuteAll.icon.source - = "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume_mute.svg" - App.screenPlayManager.setAllWallpaperValue("muted", "true") + miMuteAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume_mute.svg"; + App.screenPlayManager.setAllWallpaperValue("muted", "true"); } } @@ -230,13 +226,11 @@ Rectangle { property bool isPlaying: true onIsPlayingChanged: { if (miStopAll.isPlaying) { - miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_pause.svg" - App.screenPlayManager.setAllWallpaperValue("isPlaying", - "true") + miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_pause.svg"; + App.screenPlayManager.setAllWallpaperValue("isPlaying", "true"); } else { - miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_play.svg" - App.screenPlayManager.setAllWallpaperValue("isPlaying", - "false") + miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_play.svg"; + App.screenPlayManager.setAllWallpaperValue("isPlaying", "false"); } } hoverEnabled: true @@ -252,10 +246,10 @@ Rectangle { icon.width: root.iconWidth icon.height: root.iconHeight onClicked: { - App.screenPlayManager.removeAllWallpapers() - App.screenPlayManager.removeAllWidgets() - miStopAll.isPlaying = true - miMuteAll.soundEnabled = true + App.screenPlayManager.removeAllWallpapers(); + App.screenPlayManager.removeAllWidgets(); + miStopAll.isPlaying = true; + miMuteAll.soundEnabled = true; } hoverEnabled: true diff --git a/ScreenPlay/qml/Settings/SettingBool.qml b/ScreenPlay/qml/Settings/SettingBool.qml index 14430d29..d2915787 100644 --- a/ScreenPlay/qml/Settings/SettingBool.qml +++ b/ScreenPlay/qml/Settings/SettingBool.qml @@ -19,11 +19,11 @@ Item { width: parent.width onAvailableChanged: { if (!available) { - settingsBool.opacity = 0.5 - radioButton.enabled = false + settingsBool.opacity = 0.5; + radioButton.enabled = false; } else { - settingsButton.opacity = 1 - radioButton.enabled = true + settingsButton.opacity = 1; + radioButton.enabled = true; } } @@ -55,12 +55,10 @@ Item { wrapMode: Text.WordWrap linkColor: Material.color(Material.Orange) onLinkActivated: function (link) { - Qt.openUrlExternally(link) + Qt.openUrlExternally(link); } - color: Material.theme === Material.Light ? Qt.lighter( - Material.foreground) : Qt.darker( - Material.foreground) + color: Material.theme === Material.Light ? Qt.lighter(Material.foreground) : Qt.darker(Material.foreground) font.family: App.settings.font verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft @@ -82,9 +80,9 @@ Item { checked: settingsBool.isChecked onCheckedChanged: { if (radioButton.checkState === Qt.Checked) - checkboxChanged(true) + checkboxChanged(true); else - checkboxChanged(false) + checkboxChanged(false); } anchors { diff --git a/ScreenPlay/qml/Settings/Settings.qml b/ScreenPlay/qml/Settings/Settings.qml index 1dfd225b..a7f90730 100644 --- a/ScreenPlay/qml/Settings/Settings.qml +++ b/ScreenPlay/qml/Settings/Settings.qml @@ -17,11 +17,11 @@ Item { function indexOfValue(model, value) { for (var i = 0; i < model.length; i++) { - let ourValue = model[i].value + let ourValue = model[i].value; if (value === ourValue) - return i + return i; } - return -1 + return -1; } Flickable { @@ -69,11 +69,12 @@ Item { description: qsTr("ScreenPlay will start with Windows and will setup your Desktop every time for you.") isChecked: App.settings.autostart onCheckboxChanged: function (checked) { - App.settings.setAutostart(checked) + App.settings.setAutostart(checked); } } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingBool { headline: qsTr("High priority Autostart") @@ -81,11 +82,12 @@ Item { description: qsTr("This options grants ScreenPlay a higher autostart priority than other apps.") isChecked: App.settings.highPriorityStart onCheckboxChanged: { - App.settings.setHighPriorityStart(checked) + App.settings.setHighPriorityStart(checked); } } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingBool { height: 70 @@ -93,33 +95,33 @@ Item { description: qsTr("Help us make ScreenPlay faster and more stable. All collected data is purely anonymous and only used for development purposes! We use sentry.io to collect and analyze this data. A big thanks to them for providing us with free premium support for open source projects!") isChecked: App.settings.anonymousTelemetry onCheckboxChanged: function (checked) { - App.settings.setAnonymousTelemetry(checked) + App.settings.setAnonymousTelemetry(checked); } } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingsButton { headline: qsTr("Set save location") buttonText: qsTr("Set location") description: { // Remove file:/// so the used does not get confused - let path = App.globalVariables.localStoragePath + "" + let path = App.globalVariables.localStoragePath + ""; if (path.length === 0) - return qsTr("Your storage path is empty!") + return qsTr("Your storage path is empty!"); else - return path.replace('file:///', '') + return path.replace('file:///', ''); } onButtonPressed: { - folderDialogSaveLocation.open() + folderDialogSaveLocation.open(); } FolderDialog { id: folderDialogSaveLocation folder: App.globalVariables.localStoragePath onAccepted: { - App.settings.setLocalStoragePath( - folderDialogSaveLocation.currentFolder) + App.settings.setLocalStoragePath(folderDialogSaveLocation.currentFolder); } } } @@ -142,7 +144,8 @@ Item { } } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingsComboBox { id: settingsLanguage @@ -150,9 +153,7 @@ Item { headline: qsTr("Language") description: qsTr("Set the ScreenPlay UI Language") Component.onCompleted: { - settingsLanguage.comboBox.currentIndex = root.indexOfValue( - settingsLanguage.comboBox.model, - App.settings.language) + settingsLanguage.comboBox.currentIndex = root.indexOfValue(settingsLanguage.comboBox.model, App.settings.language); } comboBox { @@ -197,14 +198,14 @@ Item { "text": "Dutch" }] onActivated: { - App.settings.setLanguage( - settingsLanguage.comboBox.currentValue) - App.settings.retranslateUI() + App.settings.setLanguage(settingsLanguage.comboBox.currentValue); + App.settings.retranslateUI(); } } } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingsComboBox { id: settingsTheme @@ -212,9 +213,7 @@ Item { headline: qsTr("Theme") description: qsTr("Switch dark/light theme") Component.onCompleted: { - settingsTheme.comboBox.currentIndex = root.indexOfValue( - settingsTheme.comboBox.model, - App.settings.theme) + settingsTheme.comboBox.currentIndex = root.indexOfValue(settingsTheme.comboBox.model, App.settings.theme); } comboBox { @@ -229,8 +228,7 @@ Item { "text": qsTr("Light") }] onActivated: { - App.settings.setTheme( - settingsTheme.comboBox.currentValue) + App.settings.setTheme(settingsTheme.comboBox.currentValue); } } } @@ -256,11 +254,12 @@ Item { description: qsTr("We disable the video rendering (not the audio!) for the best performance. If you have problem you can disable this behaviour here. Wallpaper restart required!") isChecked: App.settings.checkWallpaperVisible onCheckboxChanged: function (checked) { - App.settings.setCheckWallpaperVisible(checked) + App.settings.setCheckWallpaperVisible(checked); } } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingsComboBox { id: cbVideoFillMode @@ -268,14 +267,11 @@ Item { headline: qsTr("Default Fill Mode") description: qsTr("Set this property to define how the video is scaled to fit the target area.") Component.onCompleted: { - cbVideoFillMode.comboBox.currentIndex = root.indexOfValue( - cbVideoFillMode.comboBox.model, - App.settings.videoFillMode) + cbVideoFillMode.comboBox.currentIndex = root.indexOfValue(cbVideoFillMode.comboBox.model, App.settings.videoFillMode); } comboBox { - onActivated: App.settings.setVideoFillMode( - cbVideoFillMode.comboBox.currentValue) + onActivated: App.settings.setVideoFillMode(cbVideoFillMode.comboBox.currentValue) model: [{ "value": FillMode.Stretch, "text": qsTr("Stretch") @@ -319,8 +315,7 @@ Item { Item { width: parent.width - height: txtHeadline.paintedHeight + txtDescriptionAbout.paintedHeight - + wrapperLinks.childrenRect.height + 80 + height: txtHeadline.paintedHeight + txtDescriptionAbout.paintedHeight + wrapperLinks.childrenRect.height + 80 Text { id: txtHeadline @@ -443,26 +438,27 @@ Item { } } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingsButton { icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_launch.svg" headline: qsTr("Version") description: App.settings.buildInfos buttonText: qsTr("Open Changelog") - onButtonPressed: Qt.openUrlExternally( - "https://gitlab.com/kelteseth/ScreenPlay/-/releases") + onButtonPressed: Qt.openUrlExternally("https://gitlab.com/kelteseth/ScreenPlay/-/releases") } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingsButton { headline: qsTr("Third Party Software") description: qsTr("ScreenPlay would not be possible without the work of others. A big thank you to: ") buttonText: qsTr("Licenses") onButtonPressed: { - App.util.requestAllLicenses() - expanderCopyright.toggle() + App.util.requestAllLicenses(); + expanderCopyright.toggle(); } } @@ -471,21 +467,22 @@ Item { Connections { function onAllLicenseLoaded(licensesText) { - expanderCopyright.text = licensesText + expanderCopyright.text = licensesText; } target: App.util } } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingsButton { headline: qsTr("Logs") description: qsTr("If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime.") buttonText: qsTr("Show Logs") onButtonPressed: { - expanderDebug.toggle() + expanderDebug.toggle(); } } @@ -495,15 +492,16 @@ Item { text: App.util.debugMessages } - SettingsHorizontalSeperator {} + SettingsHorizontalSeperator { + } SettingsButton { headline: qsTr("Data Protection") description: qsTr("We use you data very carefully to improve ScreenPlay. We do not sell or share this (anonymous) information with others!") buttonText: qsTr("Privacy") onButtonPressed: { - App.util.requestDataProtection() - expanderDataProtection.toggle() + App.util.requestDataProtection(); + expanderDataProtection.toggle(); } } @@ -512,7 +510,7 @@ Item { Connections { function onAllDataProtectionLoaded(dataProtectionText) { - expanderDataProtection.text = dataProtectionText + expanderDataProtection.text = dataProtectionText; } target: App.util diff --git a/ScreenPlay/qml/Settings/SettingsButton.qml b/ScreenPlay/qml/Settings/SettingsButton.qml index d1918ca8..7a4c0b4a 100644 --- a/ScreenPlay/qml/Settings/SettingsButton.qml +++ b/ScreenPlay/qml/Settings/SettingsButton.qml @@ -16,7 +16,7 @@ Item { property bool enabled: true property bool available: true - signal buttonPressed() + signal buttonPressed height: txtHeadline.paintedHeight + txtDescription.paintedHeight + 20 width: parent.width @@ -46,7 +46,6 @@ Item { left: parent.left leftMargin: 20 } - } Text { @@ -68,7 +67,6 @@ Item { right: btnSettings.left rightMargin: 20 } - } Button { @@ -87,7 +85,5 @@ Item { rightMargin: 20 verticalCenter: parent.verticalCenter } - } - } diff --git a/ScreenPlay/qml/Settings/SettingsComboBox.qml b/ScreenPlay/qml/Settings/SettingsComboBox.qml index cc7a77d9..e25fea12 100644 --- a/ScreenPlay/qml/Settings/SettingsComboBox.qml +++ b/ScreenPlay/qml/Settings/SettingsComboBox.qml @@ -32,7 +32,6 @@ Control { left: parent.left leftMargin: 20 } - } Text { @@ -54,7 +53,6 @@ Control { right: comboBox.left rightMargin: 20 } - } ComboBox { @@ -70,7 +68,5 @@ Control { rightMargin: 20 verticalCenter: parent.verticalCenter } - } - } diff --git a/ScreenPlay/qml/Settings/SettingsExpander.qml b/ScreenPlay/qml/Settings/SettingsExpander.qml index e93520b3..d9f8dc73 100644 --- a/ScreenPlay/qml/Settings/SettingsExpander.qml +++ b/ScreenPlay/qml/Settings/SettingsExpander.qml @@ -41,7 +41,6 @@ Item { left: parent.left margins: 20 } - } MouseArea { @@ -55,7 +54,6 @@ Item { snapMode: ScrollBar.SnapOnRelease policy: ScrollBar.AlwaysOn } - } Menu { @@ -67,7 +65,6 @@ Item { App.util.copyToClipboard(txtExpander.text); } } - } states: [ @@ -78,7 +75,6 @@ Item { target: root height: 500 } - }, State { name: "off" @@ -87,7 +83,6 @@ Item { target: root height: 0 } - } ] transitions: [ @@ -101,7 +96,6 @@ Item { property: "height" duration: 250 } - } ] } diff --git a/ScreenPlay/qml/Settings/SettingsHeader.qml b/ScreenPlay/qml/Settings/SettingsHeader.qml index 08ac458c..200f1f93 100644 --- a/ScreenPlay/qml/Settings/SettingsHeader.qml +++ b/ScreenPlay/qml/Settings/SettingsHeader.qml @@ -28,7 +28,6 @@ Item { right: parent.right left: parent.left } - } Rectangle { @@ -63,7 +62,6 @@ Item { left: parent.left leftMargin: 0 } - } ColorOverlay { @@ -89,11 +87,8 @@ Item { left: parent.left leftMargin: 30 } - } - } - } states: [ @@ -111,7 +106,6 @@ Item { anchors.topMargin: 10 opacity: 0 } - }, State { name: "in" @@ -127,7 +121,6 @@ Item { anchors.topMargin: 2 opacity: 1 } - } ] transitions: [ @@ -142,7 +135,6 @@ Item { duration: 400 easing.type: Easing.InOutQuart } - } ] } diff --git a/ScreenPlay/qml/Settings/SettingsHorizontalSeperator.qml b/ScreenPlay/qml/Settings/SettingsHorizontalSeperator.qml index 27fff741..e1dd8f8e 100644 --- a/ScreenPlay/qml/Settings/SettingsHorizontalSeperator.qml +++ b/ScreenPlay/qml/Settings/SettingsHorizontalSeperator.qml @@ -23,7 +23,5 @@ Item { leftMargin: customMargin verticalCenter: parent.verticalCenter } - } - } diff --git a/ScreenPlay/qml/Workshop/Workshop.qml b/ScreenPlay/qml/Workshop/Workshop.qml index 69ef2668..7edb1cc5 100644 --- a/ScreenPlay/qml/Workshop/Workshop.qml +++ b/ScreenPlay/qml/Workshop/Workshop.qml @@ -14,12 +14,11 @@ Item { Component.onCompleted: { if (App.settings.steamVersion) { - workshopLoader.setSource( - "qrc:/qml/ScreenPlayWorkshop/qml/SteamWorkshop.qml", { - "modalSource": modalSource - }) + workshopLoader.setSource("qrc:/qml/ScreenPlayWorkshop/qml/SteamWorkshop.qml", { + "modalSource": modalSource + }); } else { - workshopLoader.setSource("qrc:/qml/ScreenPlayWorkshop/qml/Forum.qml") + workshopLoader.setSource("qrc:/qml/ScreenPlayWorkshop/qml/Forum.qml"); } } diff --git a/ScreenPlay/src/app.cpp b/ScreenPlay/src/app.cpp index b9dbc260..e847a99d 100644 --- a/ScreenPlay/src/app.cpp +++ b/ScreenPlay/src/app.cpp @@ -5,19 +5,19 @@ #include "ScreenPlayUtil/macutils.h" #endif +#include "app.h" #include "steam/steam_qt_enums_generated.h" #include #include #include -#include "app.h" namespace ScreenPlay { -/*! +/*! \module ScreenPlay \title ScreenPlay - + \brief Module for ScreenPlay. */ /*! @@ -367,138 +367,138 @@ void App::setGlobalVariables(GlobalVariables* globalVariables) \property App::screenPlayManager \brief Sets the screen play manager. */ - void App::setScreenPlayManager(ScreenPlayManager* screenPlayManager) - { - if (m_screenPlayManager.get() == screenPlayManager) - return; +void App::setScreenPlayManager(ScreenPlayManager* screenPlayManager) +{ + if (m_screenPlayManager.get() == screenPlayManager) + return; - m_screenPlayManager.reset(screenPlayManager); - emit screenPlayManagerChanged(m_screenPlayManager.get()); - } + m_screenPlayManager.reset(screenPlayManager); + emit screenPlayManagerChanged(m_screenPlayManager.get()); +} /*! \property App::create \brief . . */ - void App::setCreate(Create* create) - { - if (m_create.get() == create) - return; +void App::setCreate(Create* create) +{ + if (m_create.get() == create) + return; - m_create.reset(create); - emit createChanged(m_create.get()); - } + m_create.reset(create); + emit createChanged(m_create.get()); +} /*! \property App::util \brief . . */ - void App::setUtil(Util* util) - { - if (m_util.get() == util) - return; +void App::setUtil(Util* util) +{ + if (m_util.get() == util) + return; - m_util.reset(util); - emit utilChanged(m_util.get()); - } + m_util.reset(util); + emit utilChanged(m_util.get()); +} /*! \property App::settings \brief . . */ - void App::setSettings(Settings* settings) - { - if (m_settings.get() == settings) - return; +void App::setSettings(Settings* settings) +{ + if (m_settings.get() == settings) + return; - m_settings.reset(settings); - emit settingsChanged(m_settings.get()); - } + m_settings.reset(settings); + emit settingsChanged(m_settings.get()); +} /*! \property App::installedListModel \brief . . */ - void App::setInstalledListModel(InstalledListModel* installedListModel) - { - if (m_installedListModel.get() == installedListModel) - return; +void App::setInstalledListModel(InstalledListModel* installedListModel) +{ + if (m_installedListModel.get() == installedListModel) + return; - m_installedListModel.reset(installedListModel); - emit installedListModelChanged(m_installedListModel.get()); - } + m_installedListModel.reset(installedListModel); + emit installedListModelChanged(m_installedListModel.get()); +} /*! \property App::monitorListModel \brief . . */ - void App::setMonitorListModel(MonitorListModel* monitorListModel) - { - if (m_monitorListModel.get() == monitorListModel) - return; +void App::setMonitorListModel(MonitorListModel* monitorListModel) +{ + if (m_monitorListModel.get() == monitorListModel) + return; - m_monitorListModel.reset(monitorListModel); - emit monitorListModelChanged(m_monitorListModel.get()); - } + m_monitorListModel.reset(monitorListModel); + emit monitorListModelChanged(m_monitorListModel.get()); +} /*! \property App::profileListModel \brief . . */ - void App::setProfileListModel(ProfileListModel* profileListModel) - { - if (m_profileListModel.get() == profileListModel) - return; +void App::setProfileListModel(ProfileListModel* profileListModel) +{ + if (m_profileListModel.get() == profileListModel) + return; - m_profileListModel.reset(profileListModel); - emit profileListModelChanged(m_profileListModel.get()); - } + m_profileListModel.reset(profileListModel); + emit profileListModelChanged(m_profileListModel.get()); +} /*! \property App::installedListFilter \brief . . */ - void App::setInstalledListFilter(InstalledListFilter* installedListFilter) - { - if (m_installedListFilter.get() == installedListFilter) - return; +void App::setInstalledListFilter(InstalledListFilter* installedListFilter) +{ + if (m_installedListFilter.get() == installedListFilter) + return; - m_installedListFilter.reset(installedListFilter); - emit installedListFilterChanged(m_installedListFilter.get()); - } + m_installedListFilter.reset(installedListFilter); + emit installedListFilterChanged(m_installedListFilter.get()); +} /*! \property App::mainWindowEngine \brief . . */ - void App::setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine) - { - if (m_mainWindowEngine.get() == mainWindowEngine) - return; +void App::setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine) +{ + if (m_mainWindowEngine.get() == mainWindowEngine) + return; - m_mainWindowEngine.reset(mainWindowEngine); - emit mainWindowEngineChanged(m_mainWindowEngine.get()); - } + m_mainWindowEngine.reset(mainWindowEngine); + emit mainWindowEngineChanged(m_mainWindowEngine.get()); +} /*! \property App::wizards \brief . . */ - void App::setWizards(Wizards* wizards) - { - if (m_wizards.get() == wizards) - return; +void App::setWizards(Wizards* wizards) +{ + if (m_wizards.get() == wizards) + return; - m_wizards.reset(wizards); - emit wizardsChanged(m_wizards.get()); - } + m_wizards.reset(wizards); + emit wizardsChanged(m_wizards.get()); +} } diff --git a/ScreenPlayShader/src/ShadertoyShader.qml b/ScreenPlayShader/src/ShadertoyShader.qml index 2f53c6a1..6c394cb0 100644 --- a/ScreenPlayShader/src/ShadertoyShader.qml +++ b/ScreenPlayShader/src/ShadertoyShader.qml @@ -152,5 +152,4 @@ qt_TexCoord0 = qt_MultiTexCoord0; root.iDate.w = currentDate.getSeconds(); } } - } diff --git a/ScreenPlayShader/src/TestMain.qml b/ScreenPlayShader/src/TestMain.qml index ce9eeadd..7e1f1e4b 100644 --- a/ScreenPlayShader/src/TestMain.qml +++ b/ScreenPlayShader/src/TestMain.qml @@ -22,8 +22,7 @@ Window { property real frequency: 2 property real time: 0 property real framerate: 60 - property real updateInterval: Math.round( - (1000 / framerate) * 10) / 10 + property real updateInterval: Math.round((1000 / framerate) * 10) / 10 Timer { interval: updateInterval @@ -32,9 +31,9 @@ Window { repeat: true onTriggered: { if (parent.time > 600) { - parent.time = 0 + parent.time = 0; } - parent.time += 1 + parent.time += 1; } } diff --git a/ScreenPlaySysInfo/qml/TestMain.qml b/ScreenPlaySysInfo/qml/TestMain.qml index 436557d4..d7cccd17 100644 --- a/ScreenPlaySysInfo/qml/TestMain.qml +++ b/ScreenPlaySysInfo/qml/TestMain.qml @@ -25,11 +25,11 @@ Window { } function stringListToString(list) { - let out = "" + let out = ""; for (var i = 0; i < list.length; i++) { - out += "\n" + list[i] + out += "\n" + list[i]; } - return out + return out; } Rectangle { @@ -45,14 +45,13 @@ Window { } RowLayout { - id:wrapper + id: wrapper spacing: 40 anchors.centerIn: parent ColumnLayout { id: wrapperLeft Layout.preferredWidth: 500 - ColumnLayout { spacing: 10 Item { @@ -67,8 +66,7 @@ Window { } } Text { - text: root.stringListToString( - ipAddress.privateIpV4AddressList) + text: root.stringListToString(ipAddress.privateIpV4AddressList) color: root.accentColor font { pointSize: 16 @@ -76,8 +74,7 @@ Window { } } Text { - text: root.stringListToString( - ipAddress.privateIpV6AddressList) + text: root.stringListToString(ipAddress.privateIpV6AddressList) color: root.accentColor font { pointSize: 16 @@ -236,7 +233,6 @@ Window { horizontalAlignment: Text.AlignHCenter } - ListView { id: storageListView Layout.fillWidth: true diff --git a/ScreenPlayUtil/CMakeLists.txt b/ScreenPlayUtil/CMakeLists.txt index 9e6a6620..5352e8a1 100644 --- a/ScreenPlayUtil/CMakeLists.txt +++ b/ScreenPlayUtil/CMakeLists.txt @@ -40,15 +40,19 @@ set(QML qml/TextField.qml qml/TrayIcon.qml) -set(SOURCES # cmake-format: sort - inc/public/ScreenPlayUtil/httpfileserver.cpp src/contenttypes.cpp src/util.cpp src/projectfile.cpp) +set(SOURCES + # cmake-format: sort + inc/public/ScreenPlayUtil/httpfileserver.cpp + src/contenttypes.cpp + src/projectfile.cpp + src/util.cpp) set(HEADER # cmake-format: sort - inc/public/ScreenPlayUtil/exitcodes.h inc/public/ScreenPlayUtil/AutoPropertyHelpers.h inc/public/ScreenPlayUtil/ConstRefPropertyHelpers.h inc/public/ScreenPlayUtil/contenttypes.h + inc/public/ScreenPlayUtil/exitcodes.h inc/public/ScreenPlayUtil/HelpersCommon.h inc/public/ScreenPlayUtil/httpfileserver.h inc/public/ScreenPlayUtil/ListPropertyHelper.h diff --git a/ScreenPlayUtil/qml/Background.qml b/ScreenPlayUtil/qml/Background.qml index bf1da6e3..6896e2b6 100644 --- a/ScreenPlayUtil/qml/Background.qml +++ b/ScreenPlayUtil/qml/Background.qml @@ -35,7 +35,6 @@ Rectangle { target: bgWorkshop opacity: 0 } - }, State { name: "create" @@ -49,7 +48,6 @@ Rectangle { target: bgWorkshop opacity: 0 } - }, State { name: "community" @@ -63,7 +61,6 @@ Rectangle { target: bgWorkshop opacity: 0 } - }, State { name: "workshop" @@ -77,7 +74,6 @@ Rectangle { target: bgWorkshop opacity: 1 } - } ] transitions: [ @@ -91,7 +87,6 @@ Rectangle { duration: 400 easing.type: Easing.InOutQuart } - } ] } diff --git a/ScreenPlayUtil/qml/CloseIcon.qml b/ScreenPlayUtil/qml/CloseIcon.qml index 129908ef..5e347069 100644 --- a/ScreenPlayUtil/qml/CloseIcon.qml +++ b/ScreenPlayUtil/qml/CloseIcon.qml @@ -64,7 +64,6 @@ MouseArea { target: iconColorOverlay color: Material.color(Material.Orange) } - } ] transitions: [ @@ -78,7 +77,6 @@ MouseArea { duration: 200 easing.type: Easing.InOutQuad } - } ] } diff --git a/ScreenPlayUtil/qml/ColorImage.qml b/ScreenPlayUtil/qml/ColorImage.qml index 127f43f3..ea818ed3 100644 --- a/ScreenPlayUtil/qml/ColorImage.qml +++ b/ScreenPlayUtil/qml/ColorImage.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls.Material import Qt5Compat.GraphicalEffects - /*! \qmltype ColorImage \inqmlmodule Common @@ -14,7 +13,6 @@ import Qt5Compat.GraphicalEffects Image { id: root - /*! \qmlproperty color ColorImage::color diff --git a/ScreenPlayUtil/qml/ColorPicker.qml b/ScreenPlayUtil/qml/ColorPicker.qml index 912aa256..bc8a0024 100644 --- a/ScreenPlayUtil/qml/ColorPicker.qml +++ b/ScreenPlayUtil/qml/ColorPicker.qml @@ -23,7 +23,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - import QtQuick import QtQuick.Layouts import QtQuick.Controls @@ -65,9 +64,9 @@ Pane { function hexToRgb(hex) { // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - hex = hex.replace(shorthandRegex, function(m, r, g, b) { - return r + r + g + g + b + b; - }); + hex = hex.replace(shorthandRegex, function (m, r, g, b) { + return r + r + g + g + b + b; + }); var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { "r": parseInt(result[1], 16), @@ -188,9 +187,7 @@ Pane { position: 1 color: hueColor } - } - } Rectangle { @@ -211,9 +208,7 @@ Pane { position: 0 color: "#00000000" } - } - } Rectangle { @@ -234,7 +229,6 @@ Pane { radius: width / 2 color: "transparent" } - } MouseArea { @@ -250,7 +244,6 @@ Pane { onPositionChanged: handleMouse(mouse) onPressed: handleMouse(mouse) } - } Rectangle { @@ -272,7 +265,6 @@ Pane { PathSvg { path: "M0,0 L30,0" } - } ShapePath { @@ -283,9 +275,7 @@ Pane { PathSvg { path: "M0,-5 L30,-5 L30,4 L0,4z" } - } - } MouseArea { @@ -329,11 +319,8 @@ Pane { position: 0 color: "#FF0000" } - } - } - } ColumnLayout { @@ -356,7 +343,6 @@ Pane { onValueChanged: { if (!updatingControls) setCurrentColor(); - } } @@ -375,7 +361,6 @@ Pane { onValueChanged: { if (!updatingControls) setCurrentColor(); - } } @@ -394,14 +379,12 @@ Pane { onValueChanged: { if (!updatingControls) setCurrentColor(); - } } Item { Layout.fillHeight: true } - } Rectangle { @@ -436,22 +419,16 @@ Pane { var compColor = Qt.rgba(1, 1, 1, 1); if (color.hsvValue > 0.5) compColor = Qt.rgba(0, 0, 0, 1); - border.color = compColor; } onExited: { border.width = 0; } } - } - } - } - } - } Canvas { @@ -480,7 +457,6 @@ Pane { PathSvg { path: "M0,0 L30,0" } - } ShapePath { @@ -491,9 +467,7 @@ Pane { PathSvg { path: "M0,-5 L30,-5 L30,4 L0,4z" } - } - } MouseArea { @@ -513,11 +487,8 @@ Pane { position: 1 color: "#00000000" } - } - } - } ColumnLayout { @@ -555,11 +526,8 @@ Pane { Layout.fillHeight: true color: currentColor } - } - } - } ColumnLayout { @@ -580,7 +548,6 @@ Pane { leftPadding: optRgb.indicator.width + optRgb.spacing verticalAlignment: Text.AlignVCenter } - } RadioButton { @@ -600,9 +567,7 @@ Pane { leftPadding: optHsv.indicator.width + optHsv.spacing verticalAlignment: Text.AlignVCenter } - } - } Item { @@ -623,7 +588,6 @@ Pane { Layout.fillWidth: true color: BppMetrics.textColor } - } RowLayout { @@ -640,7 +604,6 @@ Pane { Layout.fillWidth: true color: BppMetrics.textColor } - } RowLayout { @@ -657,7 +620,6 @@ Pane { Layout.fillWidth: true color: BppMetrics.textColor } - } RowLayout { @@ -674,7 +636,6 @@ Pane { Layout.fillWidth: true color: BppMetrics.textColor } - } RowLayout { @@ -691,7 +652,6 @@ Pane { Layout.fillWidth: true color: BppMetrics.textColor } - } RowLayout { @@ -708,7 +668,6 @@ Pane { Layout.fillWidth: true color: BppMetrics.textColor } - } Item { @@ -729,7 +688,6 @@ Pane { Layout.fillWidth: true color: BppMetrics.textColor } - } RowLayout { @@ -751,23 +709,16 @@ Pane { color: BppMetrics.textColor onTextChanged: { if (!hexColor.focus) - return ; - + return; if (!updatingControls && acceptableInput) { //console.log('updating', rgbColor.r, currentColor.r * 255, rgbColor.g, currentColor.g * 255, rgbColor.b, currentColor.b * 255) - var rgbColor = hexToRgb(text); if (rgbColor && rgbColor.r !== Math.floor(currentColor.r * 255) && rgbColor.g !== Math.floor(currentColor.g * 255) && rgbColor.b !== Math.floor(currentColor.b * 255)) initColorRGB(rgbColor.r, rgbColor.g, rgbColor.b, currentColor.a * 255); - } } } - } - } - } - } diff --git a/ScreenPlayUtil/qml/Dialogs/CriticalError.qml b/ScreenPlayUtil/qml/Dialogs/CriticalError.qml index d7d3c372..71680f9e 100644 --- a/ScreenPlayUtil/qml/Dialogs/CriticalError.qml +++ b/ScreenPlayUtil/qml/Dialogs/CriticalError.qml @@ -15,15 +15,14 @@ Util.Dialog { property string message standardButtons: Dialog.Ok | Dialog.Help onHelpRequested: { - Qt.openUrlExternally( - "https://forum.screen-play.app/category/7/troubleshooting") + Qt.openUrlExternally("https://forum.screen-play.app/category/7/troubleshooting"); } Connections { function onDisplayErrorPopup(msg) { - root.message = msg - root.window.show() - root.open() + root.message = msg; + root.window.show(); + root.open(); } target: App.screenPlayManager diff --git a/ScreenPlayUtil/qml/Dialogs/MonitorConfiguration.qml b/ScreenPlayUtil/qml/Dialogs/MonitorConfiguration.qml index 75492485..aa763aa9 100644 --- a/ScreenPlayUtil/qml/Dialogs/MonitorConfiguration.qml +++ b/ScreenPlayUtil/qml/Dialogs/MonitorConfiguration.qml @@ -14,7 +14,7 @@ Util.Dialog { Connections { function onMonitorConfigurationChanged() { - root.open() + root.open(); } target: App.monitorListModel diff --git a/ScreenPlayUtil/qml/FileSelector.qml b/ScreenPlayUtil/qml/FileSelector.qml index c24c43b0..395a3c0c 100644 --- a/ScreenPlayUtil/qml/FileSelector.qml +++ b/ScreenPlayUtil/qml/FileSelector.qml @@ -73,7 +73,6 @@ Item { bottom: parent.bottom margins: 10 } - } Text { @@ -94,7 +93,6 @@ Item { bottom: parent.bottom margins: 10 } - } Button { @@ -114,7 +112,6 @@ Item { bottom: parent.bottom margins: 5 } - } Button { @@ -133,7 +130,6 @@ Item { bottom: parent.bottom margins: 5 } - } FileDialog { @@ -141,11 +137,10 @@ Item { title: qsTr("Please choose a file") onAccepted: { - root.file = fileDialog.currentFile ; + root.file = fileDialog.currentFile; txtName.text = fileDialog.currentFile.toString(); } } - } states: [ @@ -162,7 +157,6 @@ Item { target: txtPlaceholder opacity: 0 } - }, State { name: "nothingSelected" @@ -172,7 +166,6 @@ Item { opacity: 0 anchors.topMargin: -40 } - } ] transitions: [ @@ -194,7 +187,6 @@ Item { duration: 300 easing.type: Easing.OutQuart } - } ] } diff --git a/ScreenPlayUtil/qml/Grow.qml b/ScreenPlayUtil/qml/Grow.qml index 5413947e..41bf3778 100644 --- a/ScreenPlayUtil/qml/Grow.qml +++ b/ScreenPlayUtil/qml/Grow.qml @@ -43,13 +43,10 @@ Scale { to: 1 duration: 300 } - } PauseAnimation { duration: root.loopOffset } - } - } diff --git a/ScreenPlayUtil/qml/GrowIconLink.qml b/ScreenPlayUtil/qml/GrowIconLink.qml index ffd91b4c..bcd701ca 100644 --- a/ScreenPlayUtil/qml/GrowIconLink.qml +++ b/ScreenPlayUtil/qml/GrowIconLink.qml @@ -51,7 +51,6 @@ Rectangle { height: 34 sourceSize: Qt.size(34, 34) } - } ] transitions: [ @@ -66,7 +65,6 @@ Rectangle { duration: 200 easing.type: Easing.InOutQuart } - } ] } diff --git a/ScreenPlayUtil/qml/Headline.qml b/ScreenPlayUtil/qml/Headline.qml index 411540c0..44965c7d 100644 --- a/ScreenPlayUtil/qml/Headline.qml +++ b/ScreenPlayUtil/qml/Headline.qml @@ -29,7 +29,5 @@ Item { left: parent.left bottom: parent.bottom } - } - } diff --git a/ScreenPlayUtil/qml/ImageSelector.qml b/ScreenPlayUtil/qml/ImageSelector.qml index ee09a857..2d4671b3 100644 --- a/ScreenPlayUtil/qml/ImageSelector.qml +++ b/ScreenPlayUtil/qml/ImageSelector.qml @@ -83,10 +83,8 @@ Item { onClicked: { if (imageSource !== "") popup.open(); - } } - } Popup { @@ -107,7 +105,6 @@ Item { cursorShape: Qt.PointingHandCursor onClicked: popup.close() } - } Text { @@ -130,7 +127,6 @@ Item { bottom: parent.bottom margins: 10 } - } Text { @@ -151,7 +147,6 @@ Item { bottom: parent.bottom margins: 10 } - } Button { @@ -168,7 +163,6 @@ Item { bottom: parent.bottom margins: 5 } - } Button { @@ -187,7 +181,6 @@ Item { bottom: parent.bottom margins: 5 } - } FileDialog { @@ -200,7 +193,6 @@ Item { txtName.text = fileDialog.fileUrl.toString().replace(/^.*[\\\/]/, ''); } } - } states: [ @@ -217,7 +209,6 @@ Item { target: txtPlaceholder opacity: 0 } - }, State { name: "nothingSelected" @@ -227,7 +218,6 @@ Item { opacity: 0 anchors.topMargin: -40 } - } ] transitions: [ @@ -249,7 +239,6 @@ Item { duration: 300 easing.type: Easing.OutQuart } - } ] } diff --git a/ScreenPlayUtil/qml/LicenseSelector.qml b/ScreenPlayUtil/qml/LicenseSelector.qml index fd7f6092..a80e38be 100644 --- a/ScreenPlayUtil/qml/LicenseSelector.qml +++ b/ScreenPlayUtil/qml/LicenseSelector.qml @@ -79,9 +79,7 @@ ColumnLayout { description: qsTr("You do not share any rights and nobody is allowed to use or remix it (Not recommended). Can also used to credit work others.") licenseFile: "License_All_Rights_Reserved_1.0.txt" } - } - } ToolButton { @@ -101,7 +99,5 @@ ColumnLayout { text: licenseModel.get(cb.currentIndex).description } - } - } diff --git a/ScreenPlayUtil/qml/RippleEffect.qml b/ScreenPlayUtil/qml/RippleEffect.qml index aca3ac2c..46fb7f31 100644 --- a/ScreenPlayUtil/qml/RippleEffect.qml +++ b/ScreenPlayUtil/qml/RippleEffect.qml @@ -3,7 +3,6 @@ * https://github.com/rschiang/material * (THE BSD 2-CLAUSE LICENSE) */ - import QtQuick import Qt5Compat.GraphicalEffects import QtQuick.Controls.Material @@ -18,10 +17,10 @@ Item { function trigger() { var wave = ripple.createObject(container, { - "startX": root.width * 0.5, - "startY": root.height * 0.5, - "maxRadius": furthestDistance(root.width * 0.5, root.height * 0.5) - }); + "startX": root.width * 0.5, + "startY": root.height * 0.5, + "maxRadius": furthestDistance(root.width * 0.5, root.height * 0.5) + }); } function distance(x1, y1, x2, y2) { @@ -68,7 +67,6 @@ Item { function fadeIfApplicable() { if (!fadeAnimation.running) fadeAnimation.start(); - } radius: 0 @@ -82,7 +80,6 @@ Item { growAnimation.start(); if (!fadeAnimation.running) fadeAnimation.start(); - } NumberAnimation { @@ -110,11 +107,7 @@ Item { ScriptAction { script: ink.destroy() } - } - } - } - } diff --git a/ScreenPlayUtil/qml/Search.qml b/ScreenPlayUtil/qml/Search.qml index ecff541d..31b85f9f 100644 --- a/ScreenPlayUtil/qml/Search.qml +++ b/ScreenPlayUtil/qml/Search.qml @@ -23,7 +23,6 @@ Item { right: parent.right verticalCenter: parent.verticalCenter } - } TextField { @@ -46,7 +45,5 @@ Item { top: parent.top topMargin: 10 } - } - } diff --git a/ScreenPlayUtil/qml/Shake.qml b/ScreenPlayUtil/qml/Shake.qml index bc1ba60b..bc0d526e 100644 --- a/ScreenPlayUtil/qml/Shake.qml +++ b/ScreenPlayUtil/qml/Shake.qml @@ -75,13 +75,10 @@ Translate { to: 0 duration: 50 } - } PauseAnimation { duration: root.loopOffset } - } - } diff --git a/ScreenPlayUtil/qml/Tag.qml b/ScreenPlayUtil/qml/Tag.qml index bf46f995..3f912c10 100644 --- a/ScreenPlayUtil/qml/Tag.qml +++ b/ScreenPlayUtil/qml/Tag.qml @@ -51,7 +51,6 @@ Item { font.pointSize: 14 font.family: App.settings.font } - } MouseArea { @@ -76,7 +75,6 @@ Item { anchors.fill: parent source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_close.svg" } - } states: [ @@ -93,7 +91,6 @@ Item { opacity: 1 enabled: true } - } ] } diff --git a/ScreenPlayUtil/qml/TagSelector.qml b/ScreenPlayUtil/qml/TagSelector.qml index 3980739c..f9c20783 100644 --- a/ScreenPlayUtil/qml/TagSelector.qml +++ b/ScreenPlayUtil/qml/TagSelector.qml @@ -9,29 +9,28 @@ Item { id: root function getTags() { - var array = [] + var array = []; for (var i = 0; i < listModel.count; i++) { - array.push(listModel.get(i)._name) + array.push(listModel.get(i)._name); } - return array + return array; } height: 70 implicitWidth: 200 onStateChanged: { if (root.state === "add") { - btnAdd.text = qsTr("Save") - textField.focus = true + btnAdd.text = qsTr("Save"); + textField.focus = true; } else { - btnAdd.text = qsTr("Add tag") + btnAdd.text = qsTr("Add tag"); } } Rectangle { id: rectangle - color: Material.theme === Material.Light ? Material.background : Qt.darker( - Material.background) + color: Material.theme === Material.Light ? Material.background : Qt.darker(Material.background) radius: 3 clip: true @@ -61,7 +60,7 @@ Item { Connections { function onRemoveThis() { - listModel.remove(itemIndex) + listModel.remove(itemIndex); } target: delegate @@ -83,9 +82,7 @@ Item { radius: 3 height: parent.height - 20 width: 200 - color: Material.theme - === Material.Light ? Qt.lighter( - Material.background) : Material.background + color: Material.theme === Material.Light ? Qt.lighter(Material.background) : Material.background anchors { top: parent.top @@ -113,7 +110,7 @@ Item { color: Material.primaryTextColor onTextChanged: { if (textField.length >= 10) - textField.text = textField.text + textField.text = textField.text; } anchors { @@ -135,8 +132,8 @@ Item { highlighted: true font.family: App.settings.font onClicked: { - root.state = "" - textField.clear() + root.state = ""; + textField.clear(); } anchors { @@ -157,12 +154,12 @@ Item { onClicked: { if (root.state === "add") { listModel.append({ - "_name": textField.text - }) - textField.clear() - root.state = "" + "_name": textField.text + }); + textField.clear(); + root.state = ""; } else { - root.state = "add" + root.state = "add"; } } diff --git a/ScreenPlayUtil/qml/TextField.qml b/ScreenPlayUtil/qml/TextField.qml index e95a2bb4..086d8b9b 100644 --- a/ScreenPlayUtil/qml/TextField.qml +++ b/ScreenPlayUtil/qml/TextField.qml @@ -15,7 +15,7 @@ Item { property alias text: textField.text property alias placeholderText: txtPlaceholder.text - signal editingFinished() + signal editingFinished height: 55 width: 150 @@ -27,8 +27,7 @@ Item { } onEditingFinished: { if (!root.required) - return ; - + return; } Text { @@ -47,7 +46,6 @@ Item { left: parent.left leftMargin: 10 } - } Timer { @@ -63,7 +61,6 @@ Item { function resetState() { if (textField.text.length === 0) root.state = ""; - textField.focus = false; } @@ -80,7 +77,6 @@ Item { resetState(); if (textField.text.length > 0) root.state = "containsTextEditingFinished"; - } onPressed: { root.state = "containsText"; @@ -91,7 +87,6 @@ Item { right: parent.right bottom: parent.bottom } - } Text { @@ -106,7 +101,6 @@ Item { top: textField.bottom right: textField.right } - } states: [ @@ -120,7 +114,6 @@ Item { anchors.topMargin: 15 anchors.leftMargin: 10 } - }, State { name: "containsText" @@ -133,7 +126,6 @@ Item { anchors.topMargin: 0 anchors.leftMargin: 0 } - }, State { name: "containsTextEditingFinished" @@ -146,7 +138,6 @@ Item { anchors.topMargin: 0 anchors.leftMargin: 0 } - } ] transitions: [ @@ -161,7 +152,6 @@ Item { easing.type: Easing.InOutQuart properties: "font.pointSize,anchors.topMargin,anchors.leftMargin,opacity,color" } - }, Transition { from: "containsText" @@ -174,7 +164,6 @@ Item { easing.type: Easing.OutSine properties: "color,opacity" } - } ] } diff --git a/ScreenPlayUtil/qml/TrayIcon.qml b/ScreenPlayUtil/qml/TrayIcon.qml index 17f693a7..6e946522 100644 --- a/ScreenPlayUtil/qml/TrayIcon.qml +++ b/ScreenPlayUtil/qml/TrayIcon.qml @@ -14,16 +14,16 @@ SystemTrayIcon { onActivated: function (reason) { switch (reason) { case SystemTrayIcon.Unknown: - break + break; case SystemTrayIcon.Context: - break + break; case SystemTrayIcon.DoubleClick: - window.show() - break + window.show(); + break; case SystemTrayIcon.Trigger: - break + break; case SystemTrayIcon.MiddleClick: - break + break; } } @@ -32,7 +32,7 @@ SystemTrayIcon { text: qsTr("Open ScreenPlay") onTriggered: { App.showDockIcon(true); - window.show() + window.show(); } } @@ -44,15 +44,13 @@ SystemTrayIcon { text: qsTr("Mute all") onTriggered: { if (miMuteAll.isMuted) { - isMuted = false - miMuteAll.text = qsTr("Mute all") - App.screenPlayManager.setAllWallpaperValue("muted", - "true") + isMuted = false; + miMuteAll.text = qsTr("Mute all"); + App.screenPlayManager.setAllWallpaperValue("muted", "true"); } else { - isMuted = true - miMuteAll.text = qsTr("Unmute all") - App.screenPlayManager.setAllWallpaperValue("muted", - "false") + isMuted = true; + miMuteAll.text = qsTr("Unmute all"); + App.screenPlayManager.setAllWallpaperValue("muted", "false"); } } } @@ -65,15 +63,13 @@ SystemTrayIcon { text: qsTr("Pause all") onTriggered: { if (miStopAll.isPlaying) { - isPlaying = false - miStopAll.text = qsTr("Pause all") - App.screenPlayManager.setAllWallpaperValue( - "isPlaying", "true") + isPlaying = false; + miStopAll.text = qsTr("Pause all"); + App.screenPlayManager.setAllWallpaperValue("isPlaying", "true"); } else { - isPlaying = true - miStopAll.text = qsTr("Play all") - App.screenPlayManager.setAllWallpaperValue( - "isPlaying", "false") + isPlaying = true; + miStopAll.text = qsTr("Play all"); + App.screenPlayManager.setAllWallpaperValue("isPlaying", "false"); } } } diff --git a/ScreenPlayUtil/src/projectfile.cpp b/ScreenPlayUtil/src/projectfile.cpp index f66b76b4..c3121da6 100644 --- a/ScreenPlayUtil/src/projectfile.cpp +++ b/ScreenPlayUtil/src/projectfile.cpp @@ -87,7 +87,7 @@ bool ProjectFile::init() if (obj.contains("codec")) { if (auto videoCodecOpt = ScreenPlayUtil::getVideoCodecFromString(obj.value("codec").toString())) { videoCodec = videoCodecOpt.value(); - } else{ + } else { qWarning("Invalid videoCodec was specified inside the json object!"); } } else if (type == ScreenPlay::InstalledType::InstalledType::VideoWallpaper) { diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WaitingForScreenplay.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WaitingForScreenplay.qml index deda4063..e4662751 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WaitingForScreenplay.qml +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WaitingForScreenplay.qml @@ -20,27 +20,27 @@ Rectangle { font.pixelSize: 50 } - OpacityAnimator on opacity{ - id: createAnimation - from: 0; - to: 1; - duration: 1000 - onRunningChanged: { - if(!running){ - toBeDeleted.opacity = 1 - toBeCreated.opacity = 0 - destroyAnimation.start() - } - } + OpacityAnimator on opacity { + id: createAnimation + from: 0 + to: 1 + duration: 1000 + onRunningChanged: { + if (!running) { + toBeDeleted.opacity = 1; + toBeCreated.opacity = 0; + destroyAnimation.start(); + } + } } Component.onCompleted: { - createAnimation.start() + createAnimation.start(); } } Rectangle { - opacity: 0 id: toBeDeleted + opacity: 0 anchors.fill: parent color: "black" @@ -54,21 +54,19 @@ Rectangle { font.pixelSize: 50 } - OpacityAnimator on opacity{ - id: destroyAnimation - from: 1; - to: 0; - duration: 1000 - running: false - onRunningChanged: { - if(!running){ - toBeDeleted.opacity = 0 - toBeCreated.opacity = 0 - createAnimation.start() - } - } + OpacityAnimator on opacity { + id: destroyAnimation + from: 1 + to: 0 + duration: 1000 + running: false + onRunningChanged: { + if (!running) { + toBeDeleted.opacity = 0; + toBeCreated.opacity = 0; + createAnimation.start(); + } + } } } } - - diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/Wallpaper.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/Wallpaper.qml index 15d0d782..45d2ed96 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/Wallpaper.qml +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/Wallpaper.qml @@ -5,7 +5,6 @@ import QtWebEngine 1.8 import QtMultimedia 5.12 import Qt.labs.settings 1.1 - Rectangle { id: root color: "black" @@ -18,25 +17,25 @@ Rectangle { property string projectSourceFileAbsolute property bool loops: true - function stop(){ - player1.stop() - player2.stop() - videoOutput1.visible = false - videoOutput2.visible = false - root.enabled = false + function stop() { + player1.stop(); + player2.stop(); + videoOutput1.visible = false; + videoOutput2.visible = false; + root.enabled = false; } - function play(){ - root.enabled = true - videoOutput2.visible = false - videoOutput1.visible = true + function play() { + root.enabled = true; + videoOutput2.visible = false; + videoOutput1.visible = true; //if(wallpaper.configuration.DualPlayback){ - player2.source = root.projectSourceFileAbsolute - player2.play() - player2.pause() + player2.source = root.projectSourceFileAbsolute; + player2.play(); + player2.pause(); //} - player1.play() + player1.play(); } MediaPlayer { @@ -44,17 +43,16 @@ Rectangle { volume: root.volume source: root.projectSourceFileAbsolute onStopped: { - if(!root.enabled) - return - - videoOutput1.visible = false - videoOutput2.visible = true - if(player2.source !== root.projectSourceFileAbsolute){ - player2.source = root.projectSourceFileAbsolute - } - player1.play() - player1.pause() - player2.play() + if (!root.enabled) + return; + videoOutput1.visible = false; + videoOutput2.visible = true; + if (player2.source !== root.projectSourceFileAbsolute) { + player2.source = root.projectSourceFileAbsolute; + } + player1.play(); + player1.pause(); + player2.play(); } } @@ -62,17 +60,16 @@ Rectangle { id: player2 volume: root.volume onStopped: { - if(!root.enabled) - return - videoOutput2.visible = false - videoOutput1.visible = true - player2.play() - player2.pause() - player1.play() + if (!root.enabled) + return; + videoOutput2.visible = false; + videoOutput1.visible = true; + player2.play(); + player2.pause(); + player1.play(); } } - VideoOutput { id: videoOutput1 fillMode: VideoOutput.PreserveAspectCrop @@ -86,7 +83,4 @@ Rectangle { anchors.fill: parent source: player2 } - - - } diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WallpaperContainer.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WallpaperContainer.qml index d7998261..e5781a43 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WallpaperContainer.qml +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/WallpaperContainer.qml @@ -4,7 +4,6 @@ import QtWebSockets 1.1 import QtWebEngine 1.8 import QtMultimedia 5.12 - Rectangle { id: container anchors.fill: parent @@ -16,27 +15,27 @@ Rectangle { property bool connected: false Timer { - id: connectTimer - interval: 1000 - running: true - repeat: true - onTriggered: { - if(!wp.connected){ - console.log("not connected") - wp.source = "" - wp.source = "Wallpaper.qml" - } else { - console.log("connected") - screensaver.visible = false - connectTimer.stop() - } - } + id: connectTimer + interval: 1000 + running: true + repeat: true + onTriggered: { + if (!wp.connected) { + console.log("not connected"); + wp.source = ""; + wp.source = "Wallpaper.qml"; + } else { + console.log("connected"); + screensaver.visible = false; + connectTimer.stop(); + } + } } } Loader { - anchors.fill: parent id: screensaver + anchors.fill: parent source: "WaitingForScreenplay.qml" } } diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml index 48cfdf16..80c2c221 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/config.qml @@ -8,13 +8,11 @@ import org.kde.kcm 1.1 as KCM import org.kde.kirigami 2.4 as Kirigami import org.kde.newstuff 1.1 as NewStuff - Column { id: root property alias cfg_MonitorIndex: monitorIndex.text - anchors.fill: parent spacing: units.largeSpacing @@ -26,8 +24,5 @@ Column { id: monitorIndex text: "0" } - - } - } diff --git a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml index 4f6aa157..cc9b7d3b 100644 --- a/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml +++ b/ScreenPlayWallpaper/kde/ScreenPlay/contents/ui/main.qml @@ -4,55 +4,51 @@ import QtWebSockets 1.1 import QtWebEngine 1.8 import QtMultimedia 5.12 import Qt.labs.settings 1.1 - import org.kde.plasma.core 2.0 as PlasmaCore Rectangle { - id:root - color:"orange" + id: root + color: "orange" property bool connected: false Settings { - id:settings + id: settings } Component.onCompleted: { - wallpaper.projectSourceFileAbsolute = settings.value("SP_projectSourceFileAbsolute","NULL") -// if(root.projectSourceFileAbsolute === "NULL") -// return - - wallpaper.type = settings.value("SP_type") - wallpaper.fillMode = settings.value("SP_fillMode") + wallpaper.projectSourceFileAbsolute = settings.value("SP_projectSourceFileAbsolute", "NULL"); + // if(root.projectSourceFileAbsolute === "NULL") + // return + wallpaper.type = settings.value("SP_type"); + wallpaper.fillMode = settings.value("SP_fillMode"); //wallpaper.volume = settings.value("SP_volume") - wallpaper.play() + wallpaper.play(); } - Wallpaper { - id:wallpaper + id: wallpaper anchors.fill: parent - // visible: root.connected - - onFullContentPathChanged: settings.setValue("SP_fullContentPath",fullContentPath) - onVolumeChanged: settings.setValue("SP_volume",volume) - onFillModeChanged: settings.setValue("SP_fillMode",fillMode) - onTypeChanged: settings.setValue("SP_type",type) - onProjectSourceFileAbsoluteChanged: settings.setValue("SP_projectSourceFileAbsolute",projectSourceFileAbsolute) - onLoopsChanged: settings.setValue("SP_loops",loops) + // visible: root.connected + onFullContentPathChanged: settings.setValue("SP_fullContentPath", fullContentPath) + onVolumeChanged: settings.setValue("SP_volume", volume) + onFillModeChanged: settings.setValue("SP_fillMode", fillMode) + onTypeChanged: settings.setValue("SP_type", type) + onProjectSourceFileAbsoluteChanged: settings.setValue("SP_projectSourceFileAbsolute", projectSourceFileAbsolute) + onLoopsChanged: settings.setValue("SP_loops", loops) } Timer { - id:reconnectTimer + id: reconnectTimer interval: 1000 running: true repeat: true onTriggered: { if (socket.status === WebSocket.Open) - return - socket.active = false - socket.active = true - reconnectTimer.retryCounter += 1 + return; + socket.active = false; + socket.active = true; + reconnectTimer.retryCounter += 1; } property int retryCounter: 0 } @@ -61,35 +57,33 @@ Rectangle { id: socket url: "ws://127.0.0.1:16395" onStatusChanged: { - if (socket.status === WebSocket.Open) - socket.sendTextMessage("Hello World from QML wallpaper") + if (socket.status === WebSocket.Open) + socket.sendTextMessage("Hello World from QML wallpaper"); } - onTextMessageReceived: (message)=> { - - var obj = JSON.parse(message) - root.connected = true - txtCommand.text = obj.command - + onTextMessageReceived: message => { + var obj = JSON.parse(message); + root.connected = true; + txtCommand.text = obj.command; if (obj.command === "replace") { - socket.sendTextMessage("replace") - wallpaper.type = obj.type - wallpaper.fillMode = obj.fillMode - wallpaper.volume = obj.volume - wallpaper.projectSourceFileAbsolute = "file://" + obj.absolutePath + "/" + obj.file - print("got: " + root.projectSourceFileAbsolute) - wallpaper.play() + socket.sendTextMessage("replace"); + wallpaper.type = obj.type; + wallpaper.fillMode = obj.fillMode; + wallpaper.volume = obj.volume; + wallpaper.projectSourceFileAbsolute = "file://" + obj.absolutePath + "/" + obj.file; + print("got: " + root.projectSourceFileAbsolute); + wallpaper.play(); return; - } - if(obj.command === "quit"){ - wallpaper.stop() - } + } + if (obj.command === "quit") { + wallpaper.stop(); + } } } -// WaitingForScreenplay { -// anchors.fill: parent -// visible: !root.connected -// } + // WaitingForScreenplay { + // anchors.fill: parent + // visible: !root.connected + // } Column { anchors { horizontalCenter: parent.horizontalCenter @@ -97,7 +91,7 @@ Rectangle { margins: 60 } Text { - id:txtCommand + id: txtCommand color: "white" } Text { @@ -106,20 +100,15 @@ Rectangle { } Text { color: "white" - text: "projectSourceFileAbsolute " + wallpaper.projectSourceFileAbsolute + text: "projectSourceFileAbsolute " + wallpaper.projectSourceFileAbsolute } Text { color: "white" - text:"reconnectTimer.retryCounter : "+ reconnectTimer.retryCounter + text: "reconnectTimer.retryCounter : " + reconnectTimer.retryCounter } Text { color: "white" text: "MonitorIndex: " + wallpaper.configuration.MonitorIndex } - } - - - } - diff --git a/ScreenPlayWallpaper/qml/MultimediaView.qml b/ScreenPlayWallpaper/qml/MultimediaView.qml index a957d158..5cdfd3e3 100644 --- a/ScreenPlayWallpaper/qml/MultimediaView.qml +++ b/ScreenPlayWallpaper/qml/MultimediaView.qml @@ -10,15 +10,14 @@ Item { property string fillMode: Wallpaper.fillMode onFillModeChanged: { // Convert Web based video modes to the limited Qt fillModes - if (fillMode === "cover" || fillMode === "stretch" - || fillMode === "contain") { - return vo.fillMode = VideoOutput.Stretch + if (fillMode === "cover" || fillMode === "stretch" || fillMode === "contain") { + return vo.fillMode = VideoOutput.Stretch; } if (fillMode === "fill") { - return vo.fillMode = VideoOutput.PreserveAspectFit + return vo.fillMode = VideoOutput.PreserveAspectFit; } if (fillMode === "scale_down") { - return vo.fillMode = VideoOutput.PreserveAspectCrop + return vo.fillMode = VideoOutput.PreserveAspectCrop; } } @@ -29,18 +28,18 @@ Item { property string source: Wallpaper.projectSourceFileAbsolute onSourceChanged: { // Qt 6.3 workaround - mediaPlayer.stop() - mediaPlayer.source = Qt.resolvedUrl(root.source) - mediaPlayer.play() + mediaPlayer.stop(); + mediaPlayer.source = Qt.resolvedUrl(root.source); + mediaPlayer.play(); } MediaPlayer { id: mediaPlayer - onPlaybackStateChanged:{ - if( mediaPlayer.playbackState == MediaPlayer.PlayingState){ - root.ready = true - } - } + onPlaybackStateChanged: { + if (mediaPlayer.playbackState == MediaPlayer.PlayingState) { + root.ready = true; + } + } loops: root.loops ? MediaPlayer.Infinite : 1 videoOutput: vo audioOutput: ao @@ -59,21 +58,20 @@ Item { Connections { function onFillModeChanged(fillMode) { if (fillMode === "stretch") { - vo.fillMode = VideoOutput.Stretch - return + vo.fillMode = VideoOutput.Stretch; + return; } if (fillMode === "fill") { - vo.fillMode = VideoOutput.PreserveAspectFit - return + vo.fillMode = VideoOutput.PreserveAspectFit; + return; } - if (fillMode === "contain" || fillMode === "cover" - || fillMode === "scale-down") { - vo.fillMode = VideoOutput.PreserveAspectCrop + if (fillMode === "contain" || fillMode === "cover" || fillMode === "scale-down") { + vo.fillMode = VideoOutput.PreserveAspectCrop; } } function onCurrentTimeChanged(currentTime) { - mediaPlayer.position = currentTime * mediaPlayer.duration + mediaPlayer.position = currentTime * mediaPlayer.duration; } target: Wallpaper diff --git a/ScreenPlayWallpaper/qml/MultimediaWebView.qml b/ScreenPlayWallpaper/qml/MultimediaWebView.qml index fb1e9b23..c76d067b 100644 --- a/ScreenPlayWallpaper/qml/MultimediaWebView.qml +++ b/ScreenPlayWallpaper/qml/MultimediaWebView.qml @@ -3,7 +3,6 @@ import QtWebEngine import ScreenPlay.Enums.InstalledType import ScreenPlayWallpaper - /*! * The native macOS multimedia stack does not support VP8/VP9. For this we must use the WebEngine. */ @@ -15,44 +14,42 @@ Item { function getSetVideoCommand() { // TODO 30: // Currently wont work. Commit anyways til QtCreator and Qt work with js template literals - var src = "" - src += "var videoPlayer = document.getElementById('videoPlayer');" - src += "var videoSource = document.getElementById('videoSource');" - src += "videoSource.src = '" + Wallpaper.projectSourceFileAbsolute + "';" - src += "videoPlayer.load();" - src += "videoPlayer.volume = " + Wallpaper.volume + ";" - src += "videoPlayer.setAttribute('style', 'object-fit :" + Wallpaper.fillMode + ";');" - src += "videoPlayer.play();" - print(src) - return src + var src = ""; + src += "var videoPlayer = document.getElementById('videoPlayer');"; + src += "var videoSource = document.getElementById('videoSource');"; + src += "videoSource.src = '" + Wallpaper.projectSourceFileAbsolute + "';"; + src += "videoPlayer.load();"; + src += "videoPlayer.volume = " + Wallpaper.volume + ";"; + src += "videoPlayer.setAttribute('style', 'object-fit :" + Wallpaper.fillMode + ";');"; + src += "videoPlayer.play();"; + print(src); + return src; } Component.onCompleted: { - WebEngine.settings.localContentCanAccessFileUrls = true - WebEngine.settings.localContentCanAccessRemoteUrls = true - WebEngine.settings.allowRunningInsecureContent = true - WebEngine.settings.accelerated2dCanvasEnabled = true - WebEngine.settings.javascriptCanOpenWindows = false - WebEngine.settings.showScrollBars = false - WebEngine.settings.playbackRequiresUserGesture = false - WebEngine.settings.focusOnNavigationEnabled = true + WebEngine.settings.localContentCanAccessFileUrls = true; + WebEngine.settings.localContentCanAccessRemoteUrls = true; + WebEngine.settings.allowRunningInsecureContent = true; + WebEngine.settings.accelerated2dCanvasEnabled = true; + WebEngine.settings.javascriptCanOpenWindows = false; + WebEngine.settings.showScrollBars = false; + WebEngine.settings.playbackRequiresUserGesture = false; + WebEngine.settings.focusOnNavigationEnabled = true; } WebEngineView { id: webView anchors.fill: parent - url: Qt.resolvedUrl("file://" + Wallpaper.getApplicationPath( - ) + "/index.html") + url: Qt.resolvedUrl("file://" + Wallpaper.getApplicationPath() + "/index.html") onJavaScriptConsoleMessage: function (lineNumber, message) { - print(lineNumber, message) + print(lineNumber, message); } onLoadProgressChanged: { if (loadProgress === 100) { - webView.runJavaScript(root.getSetVideoCommand(), - function (result) { - requestFadeIn() - }) + webView.runJavaScript(root.getSetVideoCommand(), function (result) { + requestFadeIn(); + }); } } } @@ -75,79 +72,68 @@ Item { interval: 300 onTriggered: { - webView.visible = !Wallpaper.visualsPaused - txtVisualsPaused.visible = Wallpaper.visualsPaused + webView.visible = !Wallpaper.visualsPaused; + txtVisualsPaused.visible = Wallpaper.visualsPaused; } } Connections { function onReloadVideo(oldType) { - webView.runJavaScript(root.getSetVideoCommand()) + webView.runJavaScript(root.getSetVideoCommand()); } function onQmlExit() { - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;"); } function onMutedChanged(muted) { if (muted) - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;"); else - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + Wallpaper.volume + ";") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + Wallpaper.volume + ";"); } function onFillModeChanged(fillMode) { if (webView.loadProgress === 100) - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.setAttribute('style', 'object-fit :" + fillMode + ";');") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.setAttribute('style', 'object-fit :" + fillMode + ";');"); } function onLoopsChanged(loops) { if (webView.loadProgress === 100) - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.loop = " + loops + ";") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.loop = " + loops + ";"); } function onVolumeChanged(volume) { if (webView.loadProgress === 100) - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + volume + ";") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + volume + ";"); } function onCurrentTimeChanged(currentTime) { if (webView.loadProgress === 100) - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.currentTime = " - + currentTime + " * videoPlayer.duration;") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.currentTime = " + currentTime + " * videoPlayer.duration;"); } function onPlaybackRateChanged(playbackRate) { if (webView.loadProgress === 100) - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.playbackRate = " + playbackRate + ";") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.playbackRate = " + playbackRate + ";"); } function onVisualsPausedChanged(visualsPaused) { if (visualsPaused) { // Wait until Wallpaper animation is finsihed - timerCover.restart() + timerCover.restart(); } else { - webView.visible = true - txtVisualsPaused.visible = false + webView.visible = true; + txtVisualsPaused.visible = false; } } function onIsPlayingChanged(isPlaying) { if (webView.loadProgress === 100) { if (isPlaying) - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.play();") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.play();"); else - webView.runJavaScript( - "var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.pause();") + webView.runJavaScript("var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.pause();"); } } diff --git a/ScreenPlayWallpaper/qml/Test.qml b/ScreenPlayWallpaper/qml/Test.qml index 85264b3d..97f4c78f 100644 --- a/ScreenPlayWallpaper/qml/Test.qml +++ b/ScreenPlayWallpaper/qml/Test.qml @@ -33,10 +33,10 @@ Rectangle { id: ma function setPosition() { - attractor.pointX = mouseX - 25 - attractor.pointY = mouseY - 25 - mouseDot.x = mouseX - mouseDot.center - mouseDot.y = mouseY - mouseDot.center + attractor.pointX = mouseX - 25; + attractor.pointY = mouseY - 25; + mouseDot.x = mouseX - mouseDot.center; + mouseDot.y = mouseY - mouseDot.center; } anchors.fill: parent @@ -44,14 +44,13 @@ Rectangle { propagateComposedEvents: true hoverEnabled: true Component.onCompleted: { - attractor.pointX = parent.width * 0.5 - attractor.pointY = parent.height * 0.5 + attractor.pointX = parent.width * 0.5; + attractor.pointY = parent.height * 0.5; } onPositionChanged: { - setPosition() + setPosition(); } onClicked: { - } } @@ -179,10 +178,10 @@ Rectangle { highlighted: true text: qsTr("Click me! - 1") onClicked: { - focus = false - focus = true - print("Button Clicked!") - txtButtonConter.counter = txtButtonConter.counter - 1 + focus = false; + focus = true; + print("Button Clicked!"); + txtButtonConter.counter = txtButtonConter.counter - 1; } } @@ -190,10 +189,10 @@ Rectangle { highlighted: true text: qsTr("Exit Wallpaper") onClicked: { - focus = false - focus = true - print("Exit Wallpaper") - Wallpaper.terminate() + focus = false; + focus = true; + print("Exit Wallpaper"); + Wallpaper.terminate(); } } @@ -202,8 +201,8 @@ Rectangle { focusPolicy: Qt.ClickFocus text: qsTr("Click me! +1") onClicked: { - print("Button Clicked!") - txtButtonConter.counter = txtButtonConter.counter + 1 + print("Button Clicked!"); + txtButtonConter.counter = txtButtonConter.counter + 1; } } } diff --git a/ScreenPlayWallpaper/qml/Wallpaper.qml b/ScreenPlayWallpaper/qml/Wallpaper.qml index d822ae73..039077a0 100644 --- a/ScreenPlayWallpaper/qml/Wallpaper.qml +++ b/ScreenPlayWallpaper/qml/Wallpaper.qml @@ -11,175 +11,159 @@ Rectangle { property bool canFadeByWallpaperFillMode: true function init() { - fadeInImageSetup() + fadeInImageSetup(); switch (Wallpaper.type) { case InstalledType.VideoWallpaper: if (Wallpaper.videoCodec === VideoCodec.Unknown) { - Wallpaper.terminate() + Wallpaper.terminate(); } // macOS only supports h264 via the native Qt MM if (Qt.platform.os === "osx") { - if ((Wallpaper.videoCodec === VideoCodec.VP8 - || Wallpaper.videoCodec === VideoCodec.VP9)) { - loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaWebView.qml" + if ((Wallpaper.videoCodec === VideoCodec.VP8 || Wallpaper.videoCodec === VideoCodec.VP9)) { + loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaWebView.qml"; } else { - loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml" + loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml"; } } - if (Qt.platform.os === "windows") { - loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml" + loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml"; } - - break + break; case InstalledType.HTMLWallpaper: - loader.setSource( - "qrc:/qml/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml", - { - "url": Qt.resolvedUrl( - Wallpaper.projectSourceFileAbsolute) - }) - break + loader.setSource("qrc:/qml/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml", { + "url": Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) + }); + break; case InstalledType.QMLWallpaper: - loader.source = Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) - break + loader.source = Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute); + break; case InstalledType.WebsiteWallpaper: - loader.setSource( - "qrc:/qml/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml", - { - "url": Wallpaper.projectSourceFileAbsolute - }) - break + loader.setSource("qrc:/qml/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml", { + "url": Wallpaper.projectSourceFileAbsolute + }); + break; case InstalledType.GifWallpaper: - loader.setSource( - "qrc:/qml/ScreenPlayWallpaper/qml/GifWallpaper.qml", { - "source": Qt.resolvedUrl( - Wallpaper.projectSourceFileAbsolute) - }) - break + loader.setSource("qrc:/qml/ScreenPlayWallpaper/qml/GifWallpaper.qml", { + "source": Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) + }); + break; } } - function fadeInImageSetup(){ - if (Qt.platform.os !== "windows") { - root.canFadeByWallpaperFillMode = false - return - } - - imgCover.source = Qt.resolvedUrl("file:///" + Wallpaper.windowsDesktopProperties.wallpaperPath) - - switch (Wallpaper.windowsDesktopProperties.wallpaperStyle) { - case 10: - imgCover.fillMode = Image.PreserveAspectCrop - // We only support fade in for one screen - if (Wallpaper.activeScreensList.length !== 1) - return - if (Wallpaper.width === 0) - return - - if (Wallpaper.width > Wallpaper.windowsDesktopProperties.defaultWallpaperSize.width) - return - - // Windows does some weird top margin if the Wallpaper - // is bigger than the monitor. So instead of centering - // it vertically it moves the wallpaper down by 1/3 of - // the remaining height. - // 1. Scale down the wallpaper based on the height. - // The default Windows 11 wallpaper C:\Windows\Web\Wallpaper\Windows\img19.jpg - // has a resoltion of 3841x2400 scaled down to 3440x2150,3 with a given monitor - // resolution of 3440x1440 resulting in a 2150,3 - 1440 = 710,3 - // 710,3 / (1/3) = 236,767 - const monitorWidth = Wallpaper.width - const monitorHeight = Wallpaper.height - const windowsWallpaperWidth = Wallpaper.windowsDesktopProperties.defaultWallpaperSize.width - const windowsWallpapeHeight = Wallpaper.windowsDesktopProperties.defaultWallpaperSize.height - - // 1. Get scale factor: - // -> 3440 / 3840 = 0.8956 - const scaleFactor = monitorWidth / windowsWallpaperWidth - // 2. Scale down the default Windows wallpaper height (width stays the same for correct aspect ratio): - // -> 2400 * 0.8956 = 2149.4 - const scaledDownDefaultWallpaperHeight = windowsWallpapeHeight * scaleFactor - // 3. Calc offste - // -> 2150,3 - 1440 = 710,3 - const offset = scaledDownDefaultWallpaperHeight - monitorHeight - // 4. Calc the one third offset (topMargin) - // -> 710,3 * (1/3) = 236,767 - const topMargin = Math.floor(offset * 0.3333333) - imgCover.anchors.topMargin = -topMargin - - break - case 6: - imgCover.fillMode = Image.PreserveAspectFit - break - case 2: - break - case 0: - if (desktopProperties.isTiled) { - // Tiled - imgCover.fillMode = Image.Tile - } else { - // Center - imgCover.fillMode = Image.PreserveAspectFit - imgCover.anchors.centerIn = parent - imgCover.width = sourceSize.width - imgCover.height = sourceSize.height - } - break - case 22: - root.canFadeByWallpaperFillMode = false - break + function fadeInImageSetup() { + if (Qt.platform.os !== "windows") { + root.canFadeByWallpaperFillMode = false; + return; + } + imgCover.source = Qt.resolvedUrl("file:///" + Wallpaper.windowsDesktopProperties.wallpaperPath); + switch (Wallpaper.windowsDesktopProperties.wallpaperStyle) { + case 10: + imgCover.fillMode = Image.PreserveAspectCrop; + // We only support fade in for one screen + if (Wallpaper.activeScreensList.length !== 1) + return; + if (Wallpaper.width === 0) + return; + if (Wallpaper.width > Wallpaper.windowsDesktopProperties.defaultWallpaperSize.width) + return; + + // Windows does some weird top margin if the Wallpaper + // is bigger than the monitor. So instead of centering + // it vertically it moves the wallpaper down by 1/3 of + // the remaining height. + // 1. Scale down the wallpaper based on the height. + // The default Windows 11 wallpaper C:\Windows\Web\Wallpaper\Windows\img19.jpg + // has a resoltion of 3841x2400 scaled down to 3440x2150,3 with a given monitor + // resolution of 3440x1440 resulting in a 2150,3 - 1440 = 710,3 + // 710,3 / (1/3) = 236,767 + const monitorWidth = Wallpaper.width; + const monitorHeight = Wallpaper.height; + const windowsWallpaperWidth = Wallpaper.windowsDesktopProperties.defaultWallpaperSize.width; + const windowsWallpapeHeight = Wallpaper.windowsDesktopProperties.defaultWallpaperSize.height; + + // 1. Get scale factor: + // -> 3440 / 3840 = 0.8956 + const scaleFactor = monitorWidth / windowsWallpaperWidth; + // 2. Scale down the default Windows wallpaper height (width stays the same for correct aspect ratio): + // -> 2400 * 0.8956 = 2149.4 + const scaledDownDefaultWallpaperHeight = windowsWallpapeHeight * scaleFactor; + // 3. Calc offste + // -> 2150,3 - 1440 = 710,3 + const offset = scaledDownDefaultWallpaperHeight - monitorHeight; + // 4. Calc the one third offset (topMargin) + // -> 710,3 * (1/3) = 236,767 + const topMargin = Math.floor(offset * 0.3333333); + imgCover.anchors.topMargin = -topMargin; + break; + case 6: + imgCover.fillMode = Image.PreserveAspectFit; + break; + case 2: + break; + case 0: + if (desktopProperties.isTiled) { + // Tiled + imgCover.fillMode = Image.Tile; + } else { + // Center + imgCover.fillMode = Image.PreserveAspectFit; + imgCover.anchors.centerIn = parent; + imgCover.width = sourceSize.width; + imgCover.height = sourceSize.height; } + break; + case 22: + root.canFadeByWallpaperFillMode = false; + break; + } } function fadeIn() { - Wallpaper.setVisible(true) - + Wallpaper.setVisible(true); if (canFadeByWallpaperFillMode && Wallpaper.canFade) - imgCover.state = "hideDefaultBackgroundImage" + imgCover.state = "hideDefaultBackgroundImage"; else - imgCover.opacity = 0 + imgCover.opacity = 0; } anchors.fill: parent color: { if (Qt.platform.os !== "windows") - return "black" + return "black"; else - return Wallpaper.windowsDesktopProperties.color + return Wallpaper.windowsDesktopProperties.color; } - + Component.onCompleted: { - init() + init(); } Connections { function onQmlExit() { if (canFadeByWallpaperFillMode && Wallpaper.canFade) - imgCover.state = "exit" + imgCover.state = "exit"; else - Wallpaper.terminate() + Wallpaper.terminate(); } function onQmlSceneValueReceived(key, value) { - var obj2 = 'import QtQuick; Item {Component.onCompleted: loader.item.' - + key + ' = ' + value + '; }' - var newObject = Qt.createQmlObject(obj2.toString(), root, "err") - newObject.destroy(10000) + var obj2 = 'import QtQuick; Item {Component.onCompleted: loader.item.' + key + ' = ' + value + '; }'; + var newObject = Qt.createQmlObject(obj2.toString(), root, "err"); + newObject.destroy(10000); } // Replace wallpaper with QML Scene function onReloadQML(oldType) { - loader.sourceComponent = undefined - loader.source = "" - Wallpaper.clearComponentCache() - loader.source = Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) + loader.sourceComponent = undefined; + loader.source = ""; + Wallpaper.clearComponentCache(); + loader.source = Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute); } // Replace wallpaper with GIF function onReloadGIF(oldType) { - init() + init(); } // This function only gets called here (the same function @@ -189,15 +173,13 @@ Rectangle { // We need to check if the old type // was also Video not get called twice if (oldType === InstalledType.VideoWallpaper) - return - - loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml" + return; + loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml"; } target: Wallpaper } - Loader { id: loader anchors.fill: parent @@ -205,17 +187,15 @@ Rectangle { // an item. QApplication::quit(); waits for the destruction forever. //asynchronous: true onStatusChanged: { - if (loader.status === Loader.Ready ) { - if(loader.item.ready) - root.fadeIn() + if (loader.status === Loader.Ready) { + if (loader.item.ready) + root.fadeIn(); } if (loader.status === Loader.Error) { - loader.source = "" - imgCover.state = "exit" + loader.source = ""; + imgCover.state = "exit"; } } - - } Image { @@ -223,7 +203,7 @@ Rectangle { state: "showDefaultBackgroundImage" sourceSize.width: Wallpaper.width sourceSize.height: Wallpaper.height - + anchors { top: parent.top left: parent.left @@ -324,8 +304,7 @@ Rectangle { } Text { - text: "projectSourceFileAbsolute " + Qt.resolvedUrl( - Wallpaper.projectSourceFileAbsolute) + text: "projectSourceFileAbsolute " + Qt.resolvedUrl(Wallpaper.projectSourceFileAbsolute) font.pointSize: 14 } @@ -362,10 +341,9 @@ Rectangle { Text { text: { if (Qt.platform.os === "windows") - return "imgCover.source " + Qt.resolvedUrl( - "file:///" + Wallpaper.windowsDesktopProperties.wallpaperPath) + return "imgCover.source " + Qt.resolvedUrl("file:///" + Wallpaper.windowsDesktopProperties.wallpaperPath); else - return "" + return ""; } font.pointSize: 14 } diff --git a/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml b/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml index a9aee1cd..d5bd76f4 100644 --- a/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml +++ b/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml @@ -7,7 +7,7 @@ Item { property string url - signal requestFadeIn() + signal requestFadeIn Component.onCompleted: { WebEngine.settings.localContentCanAccessFileUrls = true; @@ -29,8 +29,6 @@ Item { onLoadProgressChanged: { if ((loadProgress === 100)) root.requestFadeIn(); - } } - } diff --git a/ScreenPlayWeather/qml/TestMain.qml b/ScreenPlayWeather/qml/TestMain.qml index d9d7a204..8e9c87aa 100644 --- a/ScreenPlayWeather/qml/TestMain.qml +++ b/ScreenPlayWeather/qml/TestMain.qml @@ -17,55 +17,56 @@ Window { id: weather city: "Friedrichshafen" onReady: { - rp.model = weather.days + rp.model = weather.days; // Qt bug https://bugreports.qt.io/browse/QTBUG-105137 - test() + test(); } } - function test() {} + function test() { + } function mapWeatherCode(code) { - const weather_time = "" // or "-day", "-night" - const weather_prefix = "wi" + weather_time + "-" + const weather_time = ""; // or "-day", "-night" + const weather_prefix = "wi" + weather_time + "-"; // https://open-meteo.com/en/docs // WMO Weather interpretation codes (WW) // to https://erikflowers.github.io/weather-icons/ switch (code) { case 0: - return weather_prefix + "day-sunny" + return weather_prefix + "day-sunny"; case 1: case 2: case 3: - return weather_prefix + "cloud" + return weather_prefix + "cloud"; case 45: case 48: - return weather_prefix + "day-sunny" + return weather_prefix + "day-sunny"; case 51: case 53: case 55: - return weather_prefix + "rain-mix" + return weather_prefix + "rain-mix"; case 61: case 63: case 65: - return weather_prefix + "rain-mix" + return weather_prefix + "rain-mix"; case 71: case 73: case 75: - return weather_prefix + "snow" + return weather_prefix + "snow"; case 77: - return weather_prefix + "snow" + return weather_prefix + "snow"; case 80: case 81: case 82: - return weather_prefix + "snow" + return weather_prefix + "snow"; case 85: case 86: - return weather_prefix + "snow" + return weather_prefix + "snow"; case 95: - return weather_prefix + "thunderstorm" + return weather_prefix + "thunderstorm"; case 96: case 99: - return weather_prefix + "storm-showers" + return weather_prefix + "storm-showers"; } } Rectangle { @@ -100,28 +101,7 @@ Window { Text { Layout.alignment: Qt.AlignCenter horizontalAlignment: Text.AlignHCenter - text: "longtitude: " + weather.longtitude + " - latitude: " - + weather.latitude + " - elevation: " + weather.elevation - + "m - population: " + weather.population - } - - component TextItem: Column { - property alias value: value.text - property alias text: description.text - Layout.preferredWidth: 120 - Text { - id: value - width: 120 - font.pointSize: 16 - horizontalAlignment: Text.AlignHCenter - color: Material.primaryTextColor - } - Text { - id: description - horizontalAlignment: Text.AlignHCenter - color: Material.secondaryTextColor - width: 120 - } + text: "longtitude: " + weather.longtitude + " - latitude: " + weather.latitude + " - elevation: " + weather.elevation + "m - population: " + weather.population } RowLayout { @@ -159,8 +139,7 @@ Window { } Layout.alignment: Qt.AlignCenter horizontalAlignment: Image.AlignHCenter - source: "qrc:/qml/ScreenPlayWeather/assets/icons/" + root.mapWeatherCode( - weatherCode) + ".svg" + source: "qrc:/qml/ScreenPlayWeather/assets/icons/" + root.mapWeatherCode(weatherCode) + ".svg" } TextItem { text: "Weather Code" @@ -188,4 +167,23 @@ Window { } } } + + component TextItem: Column { + property alias value: value.text + property alias text: description.text + Layout.preferredWidth: 120 + Text { + id: value + width: 120 + font.pointSize: 16 + horizontalAlignment: Text.AlignHCenter + color: Material.primaryTextColor + } + Text { + id: description + horizontalAlignment: Text.AlignHCenter + color: Material.secondaryTextColor + width: 120 + } + } } diff --git a/ScreenPlayWidget/qml/Test.qml b/ScreenPlayWidget/qml/Test.qml index 9e9a16b8..8e384e6a 100644 --- a/ScreenPlayWidget/qml/Test.qml +++ b/ScreenPlayWidget/qml/Test.qml @@ -2,11 +2,10 @@ import QtQuick import ScreenPlayWidget Rectangle { - implicitWidth: 500 + implicitWidth: 500 implicitHeight: 300 color: "#80000000" - Text { id: name @@ -18,5 +17,4 @@ Rectangle { anchors.margins: 10 color: "white" } - } diff --git a/ScreenPlayWidget/qml/Widget.qml b/ScreenPlayWidget/qml/Widget.qml index be487cec..f65c972d 100644 --- a/ScreenPlayWidget/qml/Widget.qml +++ b/ScreenPlayWidget/qml/Widget.qml @@ -18,24 +18,23 @@ Item { target: Widget function onQmlExit() { if (Qt.platform.os === "windows") - Widget.setWindowBlur(0) - loader.source = "" - animFadeOut.start() + Widget.setWindowBlur(0); + loader.source = ""; + animFadeOut.start(); } function onQmlSceneValueReceived(key, value) { - var obj2 = 'import QtQuick; Item {Component.onCompleted: loader.item.' - + key + ' = ' + value + '; }' - var newObject = Qt.createQmlObject(obj2.toString(), root, "err") - newObject.destroy(10000) + var obj2 = 'import QtQuick; Item {Component.onCompleted: loader.item.' + key + ' = ' + value + '; }'; + var newObject = Qt.createQmlObject(obj2.toString(), root, "err"); + newObject.destroy(10000); } // Replace wallpaper with QML Scene function onReloadQML(oldType) { - loader.sourceComponent = undefined - loader.source = "" - Widget.clearComponentCache() - loader.source = Qt.resolvedUrl(Widget.projectSourceFileAbsolute) + loader.sourceComponent = undefined; + loader.source = ""; + Widget.clearComponentCache(); + loader.source = Qt.resolvedUrl(Widget.projectSourceFileAbsolute); } } @@ -65,11 +64,11 @@ Item { Component.onCompleted: { switch (Widget.type) { case InstalledType.QMLWidget: - loader.source = Qt.resolvedUrl(Widget.projectSourceFileAbsolute) - break + loader.source = Qt.resolvedUrl(Widget.projectSourceFileAbsolute); + break; case InstalledType.HTMLWidget: - loader.sourceComponent = webViewComponent - break + loader.sourceComponent = webViewComponent; + break; } } onStatusChanged: { @@ -77,10 +76,10 @@ Item { // Resize to loaded widget size // Note: We must use implicit* here to not // break the set values. - root.width = loader.item.implicitWidth - root.height = loader.item.implicitHeight - Widget.show() - root.state = "in" + root.width = loader.item.implicitWidth; + root.height = loader.item.implicitHeight; + Widget.show(); + root.state = "in"; } } } @@ -95,7 +94,7 @@ Item { anchors.fill: parent onJavaScriptConsoleMessage: print(lineNumber, message) Component.onCompleted: { - webView.url = Qt.resolvedUrl(Widget.sourcePath) + webView.url = Qt.resolvedUrl(Widget.sourcePath); } } } @@ -110,20 +109,19 @@ Item { onEntered: imgClose.state = "areaHover" onExited: { if (mouseAreaClose.containsMouse) - return - imgClose.state = "" + return; + imgClose.state = ""; } onPressed: function (mouse) { clickPos = { "x": mouse.x, "y": mouse.y - } + }; } onPositionChanged: { if (mouseArea.pressed) - Widget.setPos(Widget.cursorPos().x - clickPos.x, - Widget.cursorPos().y - clickPos.y) + Widget.setPos(Widget.cursorPos().x - clickPos.x, Widget.cursorPos().y - clickPos.y); } } @@ -137,8 +135,8 @@ Item { onExited: imgClose.state = "" onClicked: { if (Qt.platform.os === "windows") - Widget.setWindowBlur(0) - animFadeOut.start() + Widget.setWindowBlur(0); + animFadeOut.start(); } anchors { diff --git a/ScreenPlayWorkshop/qml/Background.qml b/ScreenPlayWorkshop/qml/Background.qml index ff1ed693..fa30a38f 100644 --- a/ScreenPlayWorkshop/qml/Background.qml +++ b/ScreenPlayWorkshop/qml/Background.qml @@ -7,30 +7,30 @@ Rectangle { property string backgroundImage: "" property int imageOffsetTop: 0 property int stackViewDepth: 0 - onStackViewDepthChanged: { + onStackViewDepthChanged: { if (stackViewDepth > 1) { - root.state = "backgroundBlur" - return true + root.state = "backgroundBlur"; + return true; } - root.state = "backgroundImage" - return false + root.state = "backgroundImage"; + return false; } color: "#161C1D" onImageOffsetTopChanged: { if ((imageOffsetTop * -1) >= 200) { - root.state = "backgroundColor" + root.state = "backgroundColor"; } else { if (root.state !== "backgroundImage") - root.state = "backgroundImage" + root.state = "backgroundImage"; } } onBackgroundImageChanged: { if (backgroundImage === "") - root.state = "" + root.state = ""; else - root.state = "backgroundImage" + root.state = "backgroundImage"; } Image { diff --git a/ScreenPlayWorkshop/qml/Forum.qml b/ScreenPlayWorkshop/qml/Forum.qml index 5dcba368..5cbc8e70 100644 --- a/ScreenPlayWorkshop/qml/Forum.qml +++ b/ScreenPlayWorkshop/qml/Forum.qml @@ -6,7 +6,6 @@ import Qt5Compat.GraphicalEffects import ScreenPlayApp import ScreenPlay - Item { id: root @@ -23,7 +22,7 @@ Item { } RowLayout { - anchors{ + anchors { fill: parent rightMargin: 20 leftMargin: 20 @@ -49,5 +48,4 @@ Item { } } } - } diff --git a/ScreenPlayWorkshop/qml/Navigation.qml b/ScreenPlayWorkshop/qml/Navigation.qml index b3c1bac9..9e961243 100644 --- a/ScreenPlayWorkshop/qml/Navigation.qml +++ b/ScreenPlayWorkshop/qml/Navigation.qml @@ -35,8 +35,7 @@ Rectangle { verticalAlignment: Qt.AlignVCenter wrapMode: Text.WrapAtWordBoundaryOrAnywhere text: { - return steam.steamAccount.username + qsTr( - " Subscribed items: ") + steam.steamAccount.amountSubscribedItems + return steam.steamAccount.username + qsTr(" Subscribed items: ") + steam.steamAccount.amountSubscribedItems; } anchors { @@ -55,7 +54,7 @@ Rectangle { width: 30 height: 30 Component.onCompleted: { - steam.steamAccount.loadAvatar() + steam.steamAccount.loadAvatar(); } anchors { @@ -66,8 +65,8 @@ Rectangle { Connections { function onAvatarChanged(_avatar) { - avatar.setImage(_avatar) - avatarPlaceholder.opacity = 0 + avatar.setImage(_avatar); + avatarPlaceholder.opacity = 0; } target: steam.steamAccount diff --git a/ScreenPlayWorkshop/qml/PopupOffline.qml b/ScreenPlayWorkshop/qml/PopupOffline.qml index 4a52963e..37dffd11 100644 --- a/ScreenPlayWorkshop/qml/PopupOffline.qml +++ b/ScreenPlayWorkshop/qml/PopupOffline.qml @@ -54,8 +54,7 @@ Popup { horizontalAlignment: Text.AlignHCenter Layout.alignment: Qt.AlignHCenter color: Material.secondaryTextColor - text: qsTr("Steam Error Restart: %1\nSteam Error API Init: %2").arg( - steam.steamErrorRestart).arg(root.steam.steamErrorAPIInit) + text: qsTr("Steam Error Restart: %1\nSteam Error API Init: %2").arg(steam.steamErrorRestart).arg(root.steam.steamErrorAPIInit) } Button { @@ -63,8 +62,8 @@ Popup { text: qsTr("Back") Layout.alignment: Qt.AlignHCenter onClicked: { - root.close() - App.util.setNavigation("Installed") + root.close(); + App.util.setNavigation("Installed"); } } Item { diff --git a/ScreenPlayWorkshop/qml/ScreenPlayItem.qml b/ScreenPlayWorkshop/qml/ScreenPlayItem.qml index dcf0f666..9b05eeb6 100644 --- a/ScreenPlayWorkshop/qml/ScreenPlayItem.qml +++ b/ScreenPlayWorkshop/qml/ScreenPlayItem.qml @@ -43,7 +43,6 @@ Item { y: 0 z: 0 } - }, Translate { id: tr @@ -105,7 +104,6 @@ Item { easing.type: Easing.OutQuint properties: "xScale,yScale" } - } RectangularGlow { @@ -124,7 +122,6 @@ Item { top: parent.top topMargin: 3 } - } Item { @@ -170,7 +167,6 @@ Item { left: parent.left margins: 10 } - } Rectangle { @@ -183,9 +179,7 @@ Item { left: parent.left bottom: parent.bottom } - } - } OpacityMask { @@ -201,21 +195,17 @@ Item { onEntered: { if (!hasMenuOpen) screenPlayItem.state = "hover"; - } onExited: { if (!hasMenuOpen) screenPlayItem.state = "visible"; - } onClicked: { checkBox.toggle(); if (mouse.button === Qt.LeftButton) itemClicked(screenId, type, checkBox.checkState === Qt.Checked); - } } - } CheckBox { @@ -233,9 +223,7 @@ Item { right: parent.right margins: 10 } - } - } states: [ @@ -252,7 +240,6 @@ Item { target: effect opacity: 0 } - }, State { name: "visible" @@ -278,7 +265,6 @@ Item { target: icnType opacity: 0 } - }, State { name: "selected" @@ -293,7 +279,6 @@ Item { target: icnType opacity: 0.5 } - } ] transitions: [ @@ -311,7 +296,6 @@ Item { property: "opacity" duration: 80 } - } ] } diff --git a/ScreenPlayWorkshop/qml/ScreenPlayItemImage.qml b/ScreenPlayWorkshop/qml/ScreenPlayItemImage.qml index 7bd3b67b..de92c99d 100644 --- a/ScreenPlayWorkshop/qml/ScreenPlayItemImage.qml +++ b/ScreenPlayWorkshop/qml/ScreenPlayItemImage.qml @@ -34,7 +34,6 @@ Item { target: image opacity: 0 } - }, State { name: "loaded" @@ -43,7 +42,6 @@ Item { target: image opacity: 1 } - } ] transitions: [ @@ -57,7 +55,6 @@ Item { duration: 300 easing.type: Easing.InOutQuad } - } ] } diff --git a/ScreenPlayWorkshop/qml/Sidebar.qml b/ScreenPlayWorkshop/qml/Sidebar.qml index 9ee13594..447d3009 100644 --- a/ScreenPlayWorkshop/qml/Sidebar.qml +++ b/ScreenPlayWorkshop/qml/Sidebar.qml @@ -22,22 +22,21 @@ Drawer { function setWorkshopItem(publishedFileID, imgUrl, videoPreview, subscriptionCount) { if (root.publishedFileID === publishedFileID) { if (!root.visible) - root.open() + root.open(); else - root.close() - return + root.close(); + return; } - root.publishedFileID = publishedFileID - root.imgUrl = imgUrl - root.subscriptionCount = subscriptionCount - root.videoPreview = videoPreview - root.subscribed = false - txtVotesUp.highlighted = false - txtVotesDown.highlighted = false + root.publishedFileID = publishedFileID; + root.imgUrl = imgUrl; + root.subscriptionCount = subscriptionCount; + root.videoPreview = videoPreview; + root.subscribed = false; + txtVotesUp.highlighted = false; + txtVotesDown.highlighted = false; if (!root.visible) - root.open() - - steamWorkshop.requestWorkshopItemDetails(publishedFileID) + root.open(); + steamWorkshop.requestWorkshopItemDetails(publishedFileID); } edge: Qt.RightEdge @@ -49,31 +48,30 @@ Drawer { Connections { function onRequestItemDetailReturned(title, tags, steamIDOwner, description, votesUp, votesDown, url, fileSize, publishedFileId) { - tagListModel.clear() + tagListModel.clear(); // Even if the tags array is empty it still contains // one empty string, resulting in an empty button if (tags.length > 1) { for (var i in tags) { tagListModel.append({ - "name": tags[i] - }) + "name": tags[i] + }); } - rpTagList.model = tagListModel + rpTagList.model = tagListModel; } else { - rpTagList.model = null + rpTagList.model = null; } - txtTitle.text = title - const size = Math.floor((1000 * ((fileSize / 1024) / 1000)) / 1000) - txtFileSize.text = qsTr("Size: ") + size + " MB" - pbVotes.to = votesDown + votesUp - pbVotes.value = votesUp - txtVotesDown.text = votesDown - txtVotesUp.text = votesUp + txtTitle.text = title; + const size = Math.floor((1000 * ((fileSize / 1024) / 1000)) / 1000); + txtFileSize.text = qsTr("Size: ") + size + " MB"; + pbVotes.to = votesDown + votesUp; + pbVotes.value = votesUp; + txtVotesDown.text = votesDown; + txtVotesUp.text = votesUp; if (description === "") - description = qsTr("No description...") - - txtDescription.text = description - pbVotes.hoverText = votesUp + " / " + votesDown + description = qsTr("No description..."); + txtDescription.text = description; + pbVotes.hoverText = votesUp + " / " + votesDown; } target: steamWorkshop @@ -187,9 +185,9 @@ Drawer { ToolTip.visible: hovered ToolTip.text: qsTr("Click here if you like the content") onClicked: { - steamWorkshop.vote(root.publishedFileID, true) - txtVotesUp.highlighted = true - txtVotesDown.highlighted = false + steamWorkshop.vote(root.publishedFileID, true); + txtVotesUp.highlighted = true; + txtVotesDown.highlighted = false; } } @@ -201,9 +199,9 @@ Drawer { ToolTip.visible: hovered ToolTip.text: qsTr("Click here if you do not like the content") onClicked: { - steamWorkshop.vote(root.publishedFileID, false) - txtVotesUp.highlighted = false - txtVotesDown.highlighted = true + steamWorkshop.vote(root.publishedFileID, false); + txtVotesUp.highlighted = false; + txtVotesDown.highlighted = true; } } } @@ -230,8 +228,7 @@ Drawer { ScrollBar.horizontal: ScrollBar { height: 5 } - contentWidth: rpTagList.childrenRect.width + rowTagList.width - + (rpTagList.count * rowTagList.spacing) + contentWidth: rpTagList.childrenRect.width + rowTagList.width + (rpTagList.count * rowTagList.spacing) contentHeight: 40 Row { @@ -259,7 +256,6 @@ Drawer { } } - RowLayout { Layout.fillWidth: true spacing: 20 @@ -331,8 +327,7 @@ Drawer { icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_open_in_new.svg" height: 25 text: qsTr("Open In Steam") - onClicked: Qt.openUrlExternally( - "steam://url/CommunityFilePage/" + root.publishedFileID) + onClicked: Qt.openUrlExternally("steam://url/CommunityFilePage/" + root.publishedFileID) } Button { @@ -343,15 +338,14 @@ Drawer { icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_download.svg" text: root.subscribed ? qsTr("Subscribed!") : qsTr("Subscribe") onClicked: { - root.subscribed = true - root.steamWorkshop.subscribeItem(root.publishedFileID) + root.subscribed = true; + root.steamWorkshop.subscribeItem(root.publishedFileID); } } } background: Rectangle { - color: Material.theme === Material.Light ? "white" : Qt.darker( - Material.background) + color: Material.theme === Material.Light ? "white" : Qt.darker(Material.background) opacity: 0.95 } diff --git a/ScreenPlayWorkshop/qml/SteamProfile.qml b/ScreenPlayWorkshop/qml/SteamProfile.qml index 36da8f75..b3124897 100644 --- a/ScreenPlayWorkshop/qml/SteamProfile.qml +++ b/ScreenPlayWorkshop/qml/SteamProfile.qml @@ -45,13 +45,13 @@ Item { width: 70 height: 70 Component.onCompleted: { - root.steamWorkshop.steamAccount.loadAvatar() + root.steamWorkshop.steamAccount.loadAvatar(); } Connections { function onAvatarChanged(_avatar) { - avatar.setImage(_avatar) - avatarPlaceholder.opacity = 0 + avatar.setImage(_avatar); + avatarPlaceholder.opacity = 0; } target: root.steamWorkshop.steamAccount @@ -133,8 +133,7 @@ Item { text: qsTr("Back") enabled: root.steamWorkshop.workshopProfileListModel.currentPage > 1 onClicked: { - root.steamWorkshop.workshopProfileListModel.setCurrentPage( - root.steamWorkshop.workshopProfileListModel.currentPage - 1) + root.steamWorkshop.workshopProfileListModel.setCurrentPage(root.steamWorkshop.workshopProfileListModel.currentPage - 1); } } @@ -142,8 +141,7 @@ Item { id: txtPage Layout.alignment: Qt.AlignVCenter - text: root.steamWorkshop.workshopProfileListModel.currentPage - + "/" + root.steamWorkshop.workshopProfileListModel.pages + text: root.steamWorkshop.workshopProfileListModel.currentPage + "/" + root.steamWorkshop.workshopProfileListModel.pages color: Material.primaryTextColor } @@ -152,11 +150,9 @@ Item { Layout.alignment: Qt.AlignVCenter text: qsTr("Forward") - enabled: root.steamWorkshop.workshopProfileListModel.currentPage - <= root.steamWorkshop.workshopProfileListModel.pages - 1 + enabled: root.steamWorkshop.workshopProfileListModel.currentPage <= root.steamWorkshop.workshopProfileListModel.pages - 1 onClicked: { - root.steamWorkshop.workshopProfileListModel.setCurrentPage( - root.steamWorkshop.workshopProfileListModel.currentPage + 1) + root.steamWorkshop.workshopProfileListModel.setCurrentPage(root.steamWorkshop.workshopProfileListModel.currentPage + 1); } } diff --git a/ScreenPlayWorkshop/qml/SteamWorkshop.qml b/ScreenPlayWorkshop/qml/SteamWorkshop.qml index 92316ea9..ae1bf12e 100644 --- a/ScreenPlayWorkshop/qml/SteamWorkshop.qml +++ b/ScreenPlayWorkshop/qml/SteamWorkshop.qml @@ -17,26 +17,23 @@ Item { Component.onCompleted: { if (screenPlayWorkshop.init()) { stackView.push("qrc:/qml/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml", { - "stackView": stackView, - "screenPlayWorkshop": screenPlayWorkshop, - "steamWorkshop": screenPlayWorkshop.steamWorkshop, - "background": background, - // "modalSource": root.modalSource - }) + "stackView": stackView, + "screenPlayWorkshop": screenPlayWorkshop, + "steamWorkshop": screenPlayWorkshop.steamWorkshop, + "background": background + }); } else { - popupOffline.open() + popupOffline.open(); } } } - Background { id: background anchors.fill: parent stackViewDepth: stackView.depth } - PopupOffline { id: popupOffline workshop: screenPlayWorkshop @@ -52,7 +49,7 @@ Item { target: stackView.currentItem ignoreUnknownSignals: true function onRequestBack() { - stackView.pop() + stackView.pop(); } } diff --git a/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml b/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml index 9e0567eb..e530ab31 100644 --- a/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml +++ b/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml @@ -16,13 +16,13 @@ Item { property Background background Component.onCompleted: { - root.state = "searching" - root.steamWorkshop.searchWorkshopByText("") + root.state = "searching"; + root.steamWorkshop.searchWorkshopByText(""); } onVisibleChanged: { if (!visible) - sidebar.close() + sidebar.close(); } MouseArea { @@ -40,16 +40,14 @@ Item { id: searchConnection target: root.steamWorkshop function onWorkshopBannerCompleted() { - bannerTxt.text = root.steamWorkshop.workshopListModel.getBannerText( - ) - background.backgroundImage = root.steamWorkshop.workshopListModel.getBannerUrl() - banner.bannerPublishedFileID = root.steamWorkshop.workshopListModel.getBannerID() - bannerTxtUnderline.numberSubscriber - = root.steamWorkshop.workshopListModel.getBannerAmountSubscriber() + bannerTxt.text = root.steamWorkshop.workshopListModel.getBannerText(); + background.backgroundImage = root.steamWorkshop.workshopListModel.getBannerUrl(); + banner.bannerPublishedFileID = root.steamWorkshop.workshopListModel.getBannerID(); + bannerTxtUnderline.numberSubscriber = root.steamWorkshop.workshopListModel.getBannerAmountSubscriber(); } function onWorkshopSearchCompleted(itemCount) { - root.state = "" + root.state = ""; } } @@ -59,7 +57,7 @@ Item { Connections { function onUserNeedsToAcceptWorkshopLegalAgreement() { - popupSteamWorkshopAgreement.open() + popupSteamWorkshopAgreement.open(); } target: root.steamWorkshop.uploadListModel @@ -76,9 +74,9 @@ Item { onContentYChanged: { // Calculate parallax scrolling if (contentY >= 0) - background.imageOffsetTop = (contentY * -0.4) + background.imageOffsetTop = (contentY * -0.4); else - background.imageOffsetTop = 0 + background.imageOffsetTop = 0; } Item { @@ -129,30 +127,6 @@ Item { spacing: 10 - component HeaderLabel: Label { - id: textObj - color: "white" - wrapMode: Text.WrapAnywhere - clip: true - - width: Math.min(100, textWidth) - readonly property alias textWidth: textMetrics.boundingRect.width - - TextMetrics { - id: textMetrics - font: textObj.font - text: textObj.text - elide: textObj.elide - } - - background: Rectangle { - opacity: .9 - color: Material.theme - === Material.Light ? Material.background : "#242424" - } - padding: 10 - } - HeaderLabel { id: bannerTxtUnderline property int numberSubscriber: 0 @@ -161,7 +135,6 @@ Item { } HeaderLabel { - id: bannerTxt font.pointSize: 42 } @@ -175,10 +148,8 @@ Item { highlighted: true icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_download.svg" onClicked: { - text = qsTr("Downloading...") - root.steamWorkshop.subscribeItem( - root.steamWorkshop.workshopListModel.getBannerID( - )) + text = qsTr("Downloading..."); + root.steamWorkshop.subscribeItem(root.steamWorkshop.workshopListModel.getBannerID()); } } @@ -191,16 +162,11 @@ Item { //icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_info.svg" visible: false onClicked: { - sidebar.setWorkshopItem( - publishedFileID, imgUrl, - additionalPreviewUrl, - subscriptionCount) + sidebar.setWorkshopItem(publishedFileID, imgUrl, additionalPreviewUrl, subscriptionCount); } } ToolButton { - onClicked: Qt.openUrlExternally( - "steam://url/CommunityFilePage/" - + banner.bannerPublishedFileID) + onClicked: Qt.openUrlExternally("steam://url/CommunityFilePage/" + banner.bannerPublishedFileID) icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_open_in_new.svg" } } @@ -247,7 +213,7 @@ Item { width: 70 height: 70 Component.onCompleted: { - steamWorkshop.steamAccount.loadAvatar() + steamWorkshop.steamAccount.loadAvatar(); } anchors { @@ -257,8 +223,8 @@ Item { Connections { function onAvatarChanged(_avatar) { - avatar.setImage(_avatar) - avatarPlaceholder.opacity = 0 + avatar.setImage(_avatar); + avatarPlaceholder.opacity = 0; } target: steamWorkshop.steamAccount @@ -283,12 +249,10 @@ Item { text: qsTr("Profile") icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_account_circle.svg" onClicked: { - stackView.push( - "qrc:/qml/ScreenPlayWorkshop/qml/SteamProfile.qml", - { - "screenPlayWorkshop": root.screenPlayWorkshop, - "steamWorkshop": root.steamWorkshop - }) + stackView.push("qrc:/qml/ScreenPlayWorkshop/qml/SteamProfile.qml", { + "screenPlayWorkshop": root.screenPlayWorkshop, + "steamWorkshop": root.steamWorkshop + }); } } @@ -304,12 +268,10 @@ Item { text: qsTr("Upload") icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_file_upload.svg" onClicked: { - stackView.push( - "qrc:/qml/ScreenPlayWorkshop/qml/upload/UploadProject.qml", - { - "screenPlayWorkshop": root.screenPlayWorkshop, - "steamWorkshop": root.steamWorkshop - }) + stackView.push("qrc:/qml/ScreenPlayWorkshop/qml/upload/UploadProject.qml", { + "screenPlayWorkshop": root.screenPlayWorkshop, + "steamWorkshop": root.steamWorkshop + }); } } @@ -328,9 +290,8 @@ Item { ToolButton { icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_search.svg" onClicked: { - root.state = "searching" - root.steamWorkshop.searchWorkshopByText( - tiSearch.text) + root.state = "searching"; + root.steamWorkshop.searchWorkshopByText(tiSearch.text); } icon.width: 20 icon.height: 20 @@ -349,22 +310,17 @@ Item { // WORKAROUND: // onEditingFinished causes internal qml layout crash in Qt 6.4 Keys.onReturnPressed: event => { - event.accepted = true - if (root.state === "searching") { - print("SEARCHING") - return - } - - root.state = "searching" - print("EDITING FINISHED", - root.state) - if (tiSearch.text === "") - return root.steamWorkshop.searchWorkshop( - SteamEnums.K_EUGCQuery_RankedByTrend) - - root.steamWorkshop.searchWorkshopByText( - tiSearch.text) - } + event.accepted = true; + if (root.state === "searching") { + print("SEARCHING"); + return; + } + root.state = "searching"; + print("EDITING FINISHED", root.state); + if (tiSearch.text === "") + return root.steamWorkshop.searchWorkshop(SteamEnums.K_EUGCQuery_RankedByTrend); + root.steamWorkshop.searchWorkshopByText(tiSearch.text); + } leftInset: -20 leftPadding: 20 @@ -379,10 +335,9 @@ Item { ToolButton { icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_close.svg" onClicked: { - root.state = "searching" - tiSearch.text = "" - root.steamWorkshop.searchWorkshop( - SteamEnums.K_EUGCQuery_RankedByTrend) + root.state = "searching"; + tiSearch.text = ""; + root.steamWorkshop.searchWorkshop(SteamEnums.K_EUGCQuery_RankedByTrend); } enabled: tiSearch.text !== "" icon.width: 20 @@ -414,8 +369,7 @@ Item { Button { text: qsTr("Open Workshop in Steam") font.capitalization: Font.Capitalize - onClicked: Qt.openUrlExternally( - "steam://url/SteamWorkshopPage/672870") + onClicked: Qt.openUrlExternally("steam://url/SteamWorkshopPage/672870") icon.source: "qrc:/qml/ScreenPlayWorkshop/assets/icons/icon_steam.svg" icon.width: 18 icon.height: 18 @@ -464,9 +418,8 @@ Item { "text": qsTr("Total Unique Subscriptions") }] onActivated: { - root.state = "searching" - root.steamWorkshop.searchWorkshop( - cbQuerySort.currentValue) + root.state = "searching"; + root.steamWorkshop.searchWorkshop(cbQuerySort.currentValue); } anchors { @@ -487,10 +440,7 @@ Item { itemIndex: index steamWorkshop: root.steamWorkshop onClicked: { - sidebar.setWorkshopItem(m_publishedFileID, - m_workshopPreview, - additionalPreviewUrl, - subscriptionCount) + sidebar.setWorkshopItem(m_publishedFileID, m_workshopPreview, additionalPreviewUrl, subscriptionCount); } } @@ -516,11 +466,9 @@ Item { text: qsTr("Back") enabled: root.steamWorkshop.workshopListModel.currentPage > 1 onClicked: { - root.state = "searching" - root.steamWorkshop.workshopListModel.setCurrentPage( - root.steamWorkshop.workshopListModel.currentPage - 1) - root.steamWorkshop.searchWorkshop( - SteamEnums.K_EUGCQuery_RankedByTrend) + root.state = "searching"; + root.steamWorkshop.workshopListModel.setCurrentPage(root.steamWorkshop.workshopListModel.currentPage - 1); + root.steamWorkshop.searchWorkshop(SteamEnums.K_EUGCQuery_RankedByTrend); } } @@ -528,8 +476,7 @@ Item { id: txtPage Layout.alignment: Qt.AlignVCenter - text: root.steamWorkshop.workshopListModel.currentPage + "/" - + root.steamWorkshop.workshopListModel.pages + text: root.steamWorkshop.workshopListModel.currentPage + "/" + root.steamWorkshop.workshopListModel.pages color: Material.primaryTextColor } @@ -538,14 +485,11 @@ Item { Layout.alignment: Qt.AlignVCenter text: qsTr("Forward") - enabled: root.steamWorkshop.workshopListModel.currentPage - <= root.steamWorkshop.workshopListModel.pages - 1 + enabled: root.steamWorkshop.workshopListModel.currentPage <= root.steamWorkshop.workshopListModel.pages - 1 onClicked: { - root.state = "searching" - root.steamWorkshop.workshopListModel.setCurrentPage( - root.steamWorkshop.workshopListModel.currentPage + 1) - root.steamWorkshop.searchWorkshop( - SteamEnums.K_EUGCQuery_RankedByTrend) + root.state = "searching"; + root.steamWorkshop.workshopListModel.setCurrentPage(root.steamWorkshop.workshopListModel.currentPage + 1); + root.steamWorkshop.searchWorkshop(SteamEnums.K_EUGCQuery_RankedByTrend); } } @@ -555,7 +499,7 @@ Item { } } - Behavior on contentHeight { + Behavior on contentHeight { PropertyAnimation { duration: 400 property: "contentHeight" @@ -568,16 +512,39 @@ Item { } } + component HeaderLabel: Label { + id: textObj + color: "white" + wrapMode: Text.WrapAnywhere + clip: true + + width: Math.min(100, textWidth) + readonly property alias textWidth: textMetrics.boundingRect.width + + TextMetrics { + id: textMetrics + font: textObj.font + text: textObj.text + elide: textObj.elide + } + + background: Rectangle { + opacity: .9 + color: Material.theme === Material.Light ? Material.background : "#242424" + } + padding: 10 + } + Sidebar { id: sidebar topMargin: 60 steamWorkshop: root.steamWorkshop onTagClicked: tag => { - gridView.headerItem.searchField.text = tag - root.steamWorkshop.searchWorkshopByText(tag) - sidebar.close() - } + gridView.headerItem.searchField.text = tag; + root.steamWorkshop.searchWorkshopByText(tag); + sidebar.close(); + } } states: [ diff --git a/ScreenPlayWorkshop/qml/TestMain.qml b/ScreenPlayWorkshop/qml/TestMain.qml index c5566375..d91939b2 100644 --- a/ScreenPlayWorkshop/qml/TestMain.qml +++ b/ScreenPlayWorkshop/qml/TestMain.qml @@ -11,24 +11,22 @@ Window { visible: true title: qsTr("ScreenPlayWorkshop") Component.onCompleted: { - root.Material.theme = Material.Dark + root.Material.theme = Material.Dark; } ScreenPlayWorkshop { id: screenPlayWorkshop Component.onCompleted: { if (screenPlayWorkshop.init()) { - print("init") - stackView.push( - "qrc:/qml/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml", - { - "stackView": stackView, - "screenPlayWorkshop": screenPlayWorkshop, - "steamWorkshop": screenPlayWorkshop.steamWorkshop, - "background": background - }) + print("init"); + stackView.push("qrc:/qml/ScreenPlayWorkshop/qml/SteamWorkshopStartPage.qml", { + "stackView": stackView, + "screenPlayWorkshop": screenPlayWorkshop, + "steamWorkshop": screenPlayWorkshop.steamWorkshop, + "background": background + }); } else { - popupOffline.open() + popupOffline.open(); } } } @@ -91,9 +89,9 @@ Window { } } Rectangle { + id: nav height: 60 color: Material.background - id: nav anchors { right: parent.right left: parent.left diff --git a/ScreenPlayWorkshop/qml/Workshop.qml b/ScreenPlayWorkshop/qml/Workshop.qml index 535bf932..d590c414 100644 --- a/ScreenPlayWorkshop/qml/Workshop.qml +++ b/ScreenPlayWorkshop/qml/Workshop.qml @@ -13,12 +13,11 @@ Item { Component.onCompleted: { if (App.settings.steamVersion) { - workshopLoader.setSource( - "qrc:/qml/ScreenPlayApp/qml/Workshop/SteamWorkshop.qml", { - "modalSource": modalSource - }) + workshopLoader.setSource("qrc:/qml/ScreenPlayApp/qml/Workshop/SteamWorkshop.qml", { + "modalSource": modalSource + }); } else { - workshopLoader.setSource("qrc:/qml/ScreenPlayApp/qml/Workshop/Forum.qml") + workshopLoader.setSource("qrc:/qml/ScreenPlayApp/qml/Workshop/Forum.qml"); } } diff --git a/ScreenPlayWorkshop/qml/WorkshopItem.qml b/ScreenPlayWorkshop/qml/WorkshopItem.qml index c3baf104..8b2f1338 100644 --- a/ScreenPlayWorkshop/qml/WorkshopItem.qml +++ b/ScreenPlayWorkshop/qml/WorkshopItem.qml @@ -33,7 +33,6 @@ Item { y: 0 z: 0 } - }, Translate { id: tr @@ -62,7 +61,6 @@ Item { top: parent.top topMargin: 3 } - } Timer { @@ -114,7 +112,6 @@ Item { easing.type: Easing.OutQuint properties: "xScale,yScale" } - } Item { @@ -177,9 +174,7 @@ Item { position: 1 color: "#00000000" } - } - } Text { @@ -202,7 +197,6 @@ Item { leftMargin: 20 bottomMargin: -50 } - } Item { @@ -224,9 +218,7 @@ Item { sourceSize: Qt.size(parent.width, parent.height) fillMode: Image.PreserveAspectFit } - } - } OpacityMask { @@ -264,9 +256,7 @@ Item { top: parent.top right: parent.right } - } - } FastBlur { @@ -306,11 +296,8 @@ Item { left: parent.left leftMargin: 20 } - } - } - } states: [ @@ -337,7 +324,6 @@ Item { target: effBlur radius: 0 } - }, State { name: "downloading" @@ -367,7 +353,6 @@ Item { opacity: 1 anchors.topMargin: 0 } - }, State { name: "installed" @@ -397,7 +382,6 @@ Item { target: txtDownloading text: qsTr("Download complete!") } - } ] transitions: [ @@ -423,7 +407,6 @@ Item { duration: 100 properties: "opacity" } - }, Transition { from: "*" @@ -454,9 +437,7 @@ Item { duration: 200 properties: "opacity, anchors.topMargin" } - } - } ] } diff --git a/ScreenPlayWorkshop/qml/upload/PopupSteamWorkshopAgreement.qml b/ScreenPlayWorkshop/qml/upload/PopupSteamWorkshopAgreement.qml index a49ba648..0186a220 100644 --- a/ScreenPlayWorkshop/qml/upload/PopupSteamWorkshopAgreement.qml +++ b/ScreenPlayWorkshop/qml/upload/PopupSteamWorkshopAgreement.qml @@ -13,7 +13,6 @@ Popup { closePolicy: Popup.NoAutoClose anchors.centerIn: Overlay.overlay - ColumnLayout { anchors { fill: parent @@ -59,13 +58,10 @@ Popup { root.close(); } } - } - } background: Rectangle { color: Material.theme === Material.Light ? "white" : Material.background } - } diff --git a/ScreenPlayWorkshop/qml/upload/UploadProject.qml b/ScreenPlayWorkshop/qml/upload/UploadProject.qml index 42632cc7..97f37d72 100644 --- a/ScreenPlayWorkshop/qml/upload/UploadProject.qml +++ b/ScreenPlayWorkshop/qml/upload/UploadProject.qml @@ -90,11 +90,11 @@ Item { onItemClicked: { for (let childItem in gridView.contentItem.children) { if (gridView.contentItem.children[childItem].isSelected) { - btnUploadProjects.enabled = true - return + btnUploadProjects.enabled = true; + return; } } - btnUploadProjects.enabled = false + btnUploadProjects.enabled = false; } } @@ -109,7 +109,7 @@ Item { text: qsTr("Abort") onClicked: { - root.requestBack() + root.requestBack(); } anchors { @@ -126,14 +126,13 @@ Item { highlighted: true enabled: false onClicked: { - var uploadListArray = [] + var uploadListArray = []; for (let childItem in gridView.contentItem.children) { if (gridView.contentItem.children[childItem].isSelected) - uploadListArray.push( - gridView.contentItem.children[childItem].absoluteStoragePath) + uploadListArray.push(gridView.contentItem.children[childItem].absoluteStoragePath); } - view.currentIndex = 1 - root.steamWorkshop.bulkUploadToWorkshop(uploadListArray) + view.currentIndex = 1; + root.steamWorkshop.bulkUploadToWorkshop(uploadListArray); } anchors { @@ -185,7 +184,7 @@ Item { highlighted: true enabled: false onClicked: { - root.requestBack() + root.requestBack(); } anchors { @@ -196,7 +195,7 @@ Item { Connections { function onUploadCompleted() { - btnFinish.enabled = true + btnFinish.enabled = true; } target: root.steamWorkshop.uploadListModel @@ -204,5 +203,4 @@ Item { } } } - } diff --git a/ScreenPlayWorkshop/qml/upload/UploadProjectBigItem.qml b/ScreenPlayWorkshop/qml/upload/UploadProjectBigItem.qml index 90d4cbd0..b4f05749 100644 --- a/ScreenPlayWorkshop/qml/upload/UploadProjectBigItem.qml +++ b/ScreenPlayWorkshop/qml/upload/UploadProjectBigItem.qml @@ -44,7 +44,6 @@ Item { layer.effect: ElevationEffect { elevation: 6 } - } Item { @@ -71,7 +70,6 @@ Item { left: parent.left bottom: parent.bottom } - } Image { @@ -86,7 +84,6 @@ Item { left: parent.left margins: 10 } - } ColumnLayout { @@ -111,7 +108,6 @@ Item { text: qsTr("Type: ") + m_type color: Material.foreground } - } Button { @@ -123,7 +119,6 @@ Item { bottom: parent.bottom margins: 20 } - } Text { @@ -135,7 +130,6 @@ Item { font.pointSize: 18 opacity: 0 } - } CheckBox { @@ -154,9 +148,7 @@ Item { right: parent.right margins: 10 } - } - } states: [ @@ -173,7 +165,6 @@ Item { target: icnType opacity: 0.5 } - }, State { name: "invalid" @@ -187,7 +178,6 @@ Item { target: txtInvalidError opacity: 1 } - } ] transitions: [ @@ -200,7 +190,6 @@ Item { target: txtInvalidError duration: 250 } - } ] } diff --git a/ScreenPlayWorkshop/qml/upload/UploadProjectItem.qml b/ScreenPlayWorkshop/qml/upload/UploadProjectItem.qml index f3a79fe2..29d66446 100644 --- a/ScreenPlayWorkshop/qml/upload/UploadProjectItem.qml +++ b/ScreenPlayWorkshop/qml/upload/UploadProjectItem.qml @@ -8,7 +8,6 @@ import ScreenPlayWorkshop import WorkshopEnums Page { - id: root property string previewImagePath @@ -27,10 +26,10 @@ Page { switch (steamStatus) { case SteamEnums.K_EResultNone: root.contentItem.state = "uploadComplete"; - return ; + return; case SteamEnums.K_EResultOK: root.contentItem.state = "uploadComplete"; - return ; + return; case SteamEnums.K_EResultFail: errorText = qsTr("Fail"); break; @@ -387,7 +386,6 @@ Page { layer.effect: ElevationEffect { elevation: 6 } - } contentItem: Item { @@ -429,11 +427,8 @@ Page { position: 1 color: "#00000000" } - } - } - } ColumnLayout { @@ -498,9 +493,7 @@ Page { value: root.progress to: 100 } - } - } states: [ @@ -509,7 +502,6 @@ Page { PropertyChanges { } - }, State { name: "uploadComplete" @@ -533,7 +525,6 @@ Page { target: gradientStop1 color: Material.color(Material.LightGreen) } - }, State { name: "error" @@ -552,7 +543,6 @@ Page { target: gradientStop1 color: Material.color(Material.DeepOrange) } - } ] transitions: [ @@ -564,9 +554,7 @@ Page { targets: [gradient, gradientStop0, gradientStop1] duration: 500 } - } ] } - } From 17347f324e081e964fab1aed2f5219c68ee404c1 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 2 Feb 2023 15:34:09 +0100 Subject: [PATCH 33/56] Remove update translations from CMake to python script --- CMake/CMakeLists.txt | 3 +- CMake/QtUpdateTranslations.cmake | 16 ----------- ScreenPlay/CMakeLists.txt | 8 ------ Tools/update_translations.py | 49 ++++++++++++++++++++++++++++++++ Tools/util.py | 5 ++++ 5 files changed, 55 insertions(+), 26 deletions(-) delete mode 100644 CMake/QtUpdateTranslations.cmake create mode 100644 Tools/update_translations.py diff --git a/CMake/CMakeLists.txt b/CMake/CMakeLists.txt index d36d5594..2e66b8c7 100644 --- a/CMake/CMakeLists.txt +++ b/CMake/CMakeLists.txt @@ -3,8 +3,7 @@ project(CMake) set(FILES CopyRecursive.cmake CreateIFWInstaller.cmake - FetchContentThirdParty.cmake - QtUpdateTranslations.cmake) + FetchContentThirdParty.cmake) add_custom_target( ${PROJECT_NAME} diff --git a/CMake/QtUpdateTranslations.cmake b/CMake/QtUpdateTranslations.cmake deleted file mode 100644 index bb68fc21..00000000 --- a/CMake/QtUpdateTranslations.cmake +++ /dev/null @@ -1,16 +0,0 @@ -find_program(LUPDATE_EXECUTABLE lupdate) -find_program(LRELEASE_EXECUTABLE lrelease) - -# Updates all ts files and generates .qm -# Absolute paths are needed! -# qt_update_translations("${CMAKE_CURRENT_SOURCE_DIR}/qml" "${L10N_LIST}") -# The second argument (list) __must__ be passed as string! -function(qt_update_translations SOURCE_PATH TS_FILES) - - foreach(_ts_file ${TS_FILES}) - message(STATUS "Update Translation: ${_ts_file}") - execute_process(COMMAND ${LUPDATE_EXECUTABLE} -noobsolete -locations none -recursive ${SOURCE_PATH} -ts ${_ts_file} OUTPUT_QUIET) - execute_process(COMMAND ${LRELEASE_EXECUTABLE} ${_ts_file} OUTPUT_QUIET) - endforeach() - -endfunction() diff --git a/ScreenPlay/CMakeLists.txt b/ScreenPlay/CMakeLists.txt index 2fe5969e..ceb62fa2 100644 --- a/ScreenPlay/CMakeLists.txt +++ b/ScreenPlay/CMakeLists.txt @@ -323,14 +323,6 @@ else() set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/translations") endif() -# qt_add_lupdate does not work for some reason. Lets do it manually: -find_program(LUPDATE_EXECUTABLE lupdate) -foreach(_ts_file ${TS_FILES}) - message(STATUS "Update Translation: ${_ts_file}") - execute_process(COMMAND ${LUPDATE_EXECUTABLE} -noobsolete -locations none -recursive ${CMAKE_CURRENT_SOURCE_DIR}/qml -ts - ${CMAKE_CURRENT_SOURCE_DIR}/${_ts_file} OUTPUT_QUIET) -endforeach() - qt_add_lrelease(${PROJECT_NAME} TS_FILES ${TS_FILES}) target_include_directories( diff --git a/Tools/update_translations.py b/Tools/update_translations.py new file mode 100644 index 00000000..9c0b213f --- /dev/null +++ b/Tools/update_translations.py @@ -0,0 +1,49 @@ +import os +import util +import sys +from pathlib import Path +import defines +from execute_util import execute + +sys.stdout.reconfigure(encoding='utf-8') + + +def search_translations(root_dir): + translations_files = [] + for dirpath, dirnames, filenames in os.walk(root_dir): + if "translations" in dirnames: + translations_dir = os.path.join(dirpath, "translations") + for file in os.listdir(translations_dir): + if file.endswith(".ts"): + translations_files.append( + os.path.join(translations_dir, file)) + return translations_files + + +def main(): + + translations = search_translations(os.path.join(util.repo_root_path(), "")) + + if translations: + print("Found translations:") + for translation in translations: + print(translation) + else: + print("No translations found.") + + executable = "lupdate" + if os.name == 'nt': + executable = "lupdate.exe" + qt_bin_path = defines.QT_BIN_PATH + executable = os.path.join(qt_bin_path, executable) + + for translation in translations: + ts = Path(translation) + source_path = ts.parent.parent.resolve() + print(f"LUpdate: {translation}. Using source: {source_path}") + execute( command=f"{executable} -noobsolete -locations none -recursive {source_path} -ts {translation}", + workingDir=ts.parent.resolve(),) + + +if __name__ == '__main__': + main() diff --git a/Tools/util.py b/Tools/util.py index d49f954a..1e1415c3 100644 --- a/Tools/util.py +++ b/Tools/util.py @@ -31,6 +31,11 @@ def run_and_capture_output(cmd, cwd=Path.cwd()) -> str: if result.stdout is not None: return str(result.stdout.decode('utf-8')) return "" + +def repo_root_path() -> str: + # Root dir of the repository + path = os.path.join(os.path.realpath(__file__), "../../") + return os.path.realpath(path) def cd_repo_root_path() -> str: # Make sure the script is always started from the same From 2c12dd4ad4ba1cc6ac72dfb516fd78c1fa81c9a3 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 2 Feb 2023 15:34:18 +0100 Subject: [PATCH 34/56] Update docs --- Docs/DeveloperSetup.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Docs/DeveloperSetup.md b/Docs/DeveloperSetup.md index 9f6db6b8..7ad4b9ca 100644 --- a/Docs/DeveloperSetup.md +++ b/Docs/DeveloperSetup.md @@ -47,7 +47,7 @@ python -m pip install -r requirements.txt python setup.py ``` Now you can either use VSCode or QtCreator: -# Option 1: Setup VSCode and compile ScreenPlay +# Option 1 (Recommended): Setup VSCode and compile ScreenPlay 1. Open VSCode 1. Install these extentions: 1. [C/C++ for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) @@ -55,7 +55,9 @@ Now you can either use VSCode or QtCreator: 2. Press: `CTRL` + `SHIFT` + `P` for every command: 1. `CMake: Select Configure Preset`. Select one of the listed presets like `MSVC SP Qt 6.4.2 Debug` 2. `CMake: Configure` -3. Press `F7` to Compile and `F5` to run! +4. Press `F7` to Compile and `F5` to run! + +⚠️ Do not forget to switch you CMake build target when switching run targets! For example you need to select the `debug` run target when you compile in `debug` mode! # Option 2: Setup QtCreator and compile ScreenPlay 1. Open QtCreator at: 1. Windows: `..\aqt\Tools\QtCreator\bin\qtcreator.exe` From bd4c7e0bcf7c491e640ce4c9f40d8e97c97bb157 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Thu, 2 Feb 2023 15:35:35 +0100 Subject: [PATCH 35/56] Fix argument --- .vscode/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 95f55792..abfbb9a5 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -87,7 +87,7 @@ "args": [ "build.py", "-type=release", - "-deploy_version", + "-deploy-version", "-steam" ] }, From 6f5fabeb0efd9af182760f982e0087e75e9a2469 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 10:16:39 +0100 Subject: [PATCH 36/56] Add qtconnectivity to fix windeploqt and macdeployqt For some reason scene2d.dll need Qt6Bluetooth. What even is scene2d? --- Tools/build.py | 2 +- Tools/setup.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tools/build.py b/Tools/build.py index 2ac9efb4..36dd3b23 100755 --- a/Tools/build.py +++ b/Tools/build.py @@ -157,7 +157,7 @@ def setup(build_config: BuildConfig, build_result: BuildResult) -> Tuple[BuildCo print(f"Using env_dict:\n{env_dict}") os.environ.update(env_dict) # NO f string we fill it later! - build_config.package_command = "windeployqt.exe --{type} --qmldir ../../{app}/qml {app}{executable_file_ending}" + build_config.package_command = "windeployqt6.exe --{type} --qmldir ../../{app}/qml {app}{executable_file_ending}" build_config.aqt_install_qt_packages = f"windows desktop {build_config.qt_version} win64_msvc2019_64 -m all" build_config.aqt_install_tool_packages = "windows desktop tools_ifw" diff --git a/Tools/setup.py b/Tools/setup.py index 54634e26..607f8916 100755 --- a/Tools/setup.py +++ b/Tools/setup.py @@ -50,13 +50,13 @@ def download(aqt_path: Path, qt_platform: Path): elif system() == "Linux": os = "linux" - # aqt list-qt windows desktop --modules 6.3.2 win64_msvc2019_64 - qt_packages = "qt3d qtquick3d qt5compat qtimageformats qtmultimedia qtshadertools qtwebchannel qtwebengine qtwebsockets qtwebview qtpositioning" + # python -m aqt list-qt windows desktop --modules 6.5.0 win64_msvc2019_64 + qt_packages = "qt3d qtquick3d qtconnectivity qt5compat qtimageformats qtmultimedia qtshadertools qtwebchannel qtwebengine qtwebsockets qtwebview qtpositioning" print(f"Downloading: {qt_packages} to {aqt_path}") execute(f"{defines.PYTHON_EXECUTABLE} -m aqt install-qt -O {aqt_path} {os} desktop {defines.QT_VERSION} {qt_platform} -m {qt_packages}") # Tools can only be installed one at the time: - # see: aqt list-tool windows desktop + # see: python -m aqt list-tool windows desktop tools = ["tools_ifw", "tools_qtcreator", "tools_ninja" ,"tools_cmake"] for tool in tools: execute(f"{defines.PYTHON_EXECUTABLE} -m aqt install-tool -O {aqt_path} {os} desktop {tool}") From 829cec6e912dfc3fac98a40f02f614ba3ab85e30 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 10:49:16 +0100 Subject: [PATCH 37/56] Fix windows launch type --- .vscode/launch.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 802d17f9..082461d9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -78,7 +78,6 @@ "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" } ], - "type": "lldb", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug/bin/ScreenPlayWallpaper.exe" }, "osx": { @@ -108,7 +107,6 @@ "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" } ], - "type": "lldb", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_RelWithDebInfo/bin/ScreenPlayWallpaper.exe" }, "osx": { @@ -138,7 +136,6 @@ "value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.5.0\\msvc2019_64\\qml\\;" } ], - "type": "cppvsdbg", "program": "${workspaceFolder}/../build_ScreenPlay_Qt_6.5.0_MSVC_Debug/bin/ScreenPlayWidget.exe" }, "osx": { From 348b06e4cee24451309de1d57d4fc229710e0412 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 10:50:19 +0100 Subject: [PATCH 38/56] Fix .5sec white frame at the beginning --- ScreenPlayWallpaper/qml/Wallpaper.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ScreenPlayWallpaper/qml/Wallpaper.qml b/ScreenPlayWallpaper/qml/Wallpaper.qml index 039077a0..11a7dc1c 100644 --- a/ScreenPlayWallpaper/qml/Wallpaper.qml +++ b/ScreenPlayWallpaper/qml/Wallpaper.qml @@ -117,6 +117,9 @@ Rectangle { root.canFadeByWallpaperFillMode = false; break; } + // NOTE: If we do not set it visible here + // AND in the fadeIn function we get a white frame + Wallpaper.setVisible(true); } function fadeIn() { From d07f3db58e5abd7d9ac83d396bf97b47e795bc92 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 11:45:49 +0100 Subject: [PATCH 39/56] Fix python version for windows and unix --- .vscode/tasks.json | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index abfbb9a5..7a0ae04a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -16,7 +16,8 @@ { "type": "process", "label": "Format Cpp files", - "command": "python", + "command": "python3", + "windows": { "command": "python" }, "group": { "kind": "build", "isDefault": true @@ -31,7 +32,8 @@ { "type": "process", "label": "Format CMake files", - "command": "python", + "command": "python3", + "windows": { "command": "python" }, "group": { "kind": "build", "isDefault": true @@ -46,7 +48,8 @@ { "type": "process", "label": "Format Qml files", - "command": "python", + "command": "python3", + "windows": { "command": "python" }, "group": { "kind": "build", "isDefault": true @@ -61,7 +64,8 @@ { "type": "process", "label": "Run setup.py", - "command": "python", + "command": "python3", + "windows": { "command": "python" }, "group": { "kind": "build", "isDefault": true @@ -76,7 +80,8 @@ { "type": "process", "label": "Export ScreenPlay release, with deploy and steam enabled", - "command": "python", + "command": "python3", + "windows": { "command": "python" }, "group": { "kind": "build", "isDefault": true @@ -94,7 +99,8 @@ { "type": "process", "label": "Update Qt *.ts translations", - "command": "python", + "command": "python3", + "windows": { "command": "python" }, "group": { "kind": "build", "isDefault": true From 0d8d0cef581503ce4514c1fb03c8ea77bb1eb861 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 11:48:26 +0100 Subject: [PATCH 40/56] Fix osx build.py args --- .vscode/tasks.json | 123 ++++++++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 51 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 7a0ae04a..4aa9dc06 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,94 +1,113 @@ { - "version": "2.0.0", - "tasks": [ - { - "type": "cmake", - "label": "CMake: build", - "command": "build", - "targets": [ - "all" - ], - "preset": "${command:cmake.activeBuildPresetName}", - "group": "build", - "problemMatcher": [], - "detail": "CMake template build task" - }, - { - "type": "process", + "version": "2.0.0", + "tasks": [ + { + "type": "cmake", + "label": "CMake: build", + "command": "build", + "targets": [ + "all" + ], + "preset": "${command:cmake.activeBuildPresetName}", + "group": "build", + "problemMatcher": [], + "detail": "CMake template build task" + }, + { + "type": "process", "label": "Format Cpp files", "command": "python3", - "windows": { "command": "python" }, + "windows": { + "command": "python" + }, "group": { "kind": "build", "isDefault": true }, - "options": { - "cwd": "${workspaceFolder}/Tools" - }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, "args": [ "clang_format.py" ] }, - { - "type": "process", + { + "type": "process", "label": "Format CMake files", "command": "python3", - "windows": { "command": "python" }, + "windows": { + "command": "python" + }, "group": { "kind": "build", "isDefault": true }, - "options": { - "cwd": "${workspaceFolder}/Tools" - }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, "args": [ "cmake_format.py" ] }, - { - "type": "process", + { + "type": "process", "label": "Format Qml files", "command": "python3", - "windows": { "command": "python" }, + "windows": { + "command": "python" + }, "group": { "kind": "build", "isDefault": true }, - "options": { - "cwd": "${workspaceFolder}/Tools" - }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, "args": [ "qml_format.py" ] }, - { - "type": "process", + { + "type": "process", "label": "Run setup.py", "command": "python3", - "windows": { "command": "python" }, + "windows": { + "command": "python" + }, "group": { "kind": "build", "isDefault": true }, - "options": { - "cwd": "${workspaceFolder}/Tools" - }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, "args": [ "setup.py" ] }, - { - "type": "process", + { + "type": "process", "label": "Export ScreenPlay release, with deploy and steam enabled", "command": "python3", - "windows": { "command": "python" }, + "windows": { + "command": "python" + }, "group": { "kind": "build", "isDefault": true }, - "options": { - "cwd": "${workspaceFolder}/Tools" - }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, + "osx": { + "args": [ + "build.py", + "-type=release", + "-deploy-version", + "-steam", + "-architecture=arm64" + ] + }, "args": [ "build.py", "-type=release", @@ -96,21 +115,23 @@ "-steam" ] }, - { - "type": "process", + { + "type": "process", "label": "Update Qt *.ts translations", "command": "python3", - "windows": { "command": "python" }, + "windows": { + "command": "python" + }, "group": { "kind": "build", "isDefault": true }, - "options": { - "cwd": "${workspaceFolder}/Tools" - }, + "options": { + "cwd": "${workspaceFolder}/Tools" + }, "args": [ "update_translations.py" ] } - ] + ] } \ No newline at end of file From c4b2bcc67f606adbcf7f3259881336dad13eb2d0 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 12:31:59 +0100 Subject: [PATCH 41/56] Remove deprecated Qt.labs.settings and fix quit --- ScreenPlay/main.qml | 7 ++++--- ScreenPlay/qml/Navigation/ExitPopup.qml | 9 ++++++--- ScreenPlay/src/app.cpp | 2 ++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ScreenPlay/main.qml b/ScreenPlay/main.qml index 141dd9c3..057e0fe5 100644 --- a/ScreenPlay/main.qml +++ b/ScreenPlay/main.qml @@ -1,3 +1,5 @@ +import QtCore as QCore +import QtQml import QtQuick import QtQuick.Window import QtQuick.Controls @@ -8,7 +10,6 @@ import ScreenPlay import Settings import ScreenPlayUtil as Util import Qt5Compat.GraphicalEffects -import Qt.labs.settings 1.0 as Labs import "qml/Monitors" as Monitors import "qml/Installed" as Installed import "qml/Navigation" as Navigation @@ -67,7 +68,7 @@ ApplicationWindow { onClosing: close => { close.accepted = false; if (App.screenPlayManager.activeWallpaperCounter === 0 && App.screenPlayManager.activeWidgetsCounter === 0) { - Qt.quit(); + App.exit(); } const alwaysMinimize = settings.value("alwaysMinimize", null); if (alwaysMinimize === null) { @@ -81,7 +82,7 @@ ApplicationWindow { exitDialog.open(); } - Labs.Settings { + QCore.Settings { id: settings } diff --git a/ScreenPlay/qml/Navigation/ExitPopup.qml b/ScreenPlay/qml/Navigation/ExitPopup.qml index 3a2ebd3e..60683ad2 100644 --- a/ScreenPlay/qml/Navigation/ExitPopup.qml +++ b/ScreenPlay/qml/Navigation/ExitPopup.qml @@ -1,5 +1,6 @@ import QtQuick -import Qt.labs.settings 1.0 as Labs +import QtQml +import QtCore as QCore import QtQuick.Window import QtQuick.Controls import QtQuick.Controls.Material @@ -61,15 +62,16 @@ Util.Popup { color: Material.primaryTextColor } - Labs.Settings { + QCore.Settings { id: settings } + RowLayout { Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true Button { text: qsTr("Quit ScreenPlay now") - onClicked: Qt.quit() + onClicked: App.exit(); } Button { text: qsTr("Minimize ScreenPlay") @@ -85,6 +87,7 @@ Util.Popup { onClicked: { settings.setValue("alwaysMinimize", true); settings.sync(); + print(settings.value("alwaysMinimize")) App.showDockIcon(false); applicationWindow.hide(); root.close(); diff --git a/ScreenPlay/src/app.cpp b/ScreenPlay/src/app.cpp index e847a99d..ccee8a17 100644 --- a/ScreenPlay/src/app.cpp +++ b/ScreenPlay/src/app.cpp @@ -232,6 +232,8 @@ QString App::version() const */ void App::exit() { + m_screenPlayManager->removeAllWallpapers(); + m_screenPlayManager->removeAllWidgets(); QApplication::instance()->quit(); } From 2c2030b437b8e1a9996f253b095caa675f8ce7c1 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 12:45:42 +0100 Subject: [PATCH 42/56] Remove deprecated Qt.labs.platform Remove own ColorPicker in favor if Qt 6.4 --- ScreenPlay/qml/Installed/Installed.qml | 6 +- .../Monitors/MonitorsProjectSettingItem.qml | 8 +- ScreenPlay/qml/Settings/Settings.qml | 1 - ScreenPlayUtil/CMakeLists.txt | 1 - ScreenPlayUtil/qml/ColorPicker.qml | 724 ------------------ 5 files changed, 7 insertions(+), 733 deletions(-) delete mode 100644 ScreenPlayUtil/qml/ColorPicker.qml diff --git a/ScreenPlay/qml/Installed/Installed.qml b/ScreenPlay/qml/Installed/Installed.qml index 35e689bf..8a3aca5e 100644 --- a/ScreenPlay/qml/Installed/Installed.qml +++ b/ScreenPlay/qml/Installed/Installed.qml @@ -5,7 +5,7 @@ import QtQuick.Layouts import QtQuick.Controls.Material import Qt5Compat.GraphicalEffects import QtQuick.Controls.Material.impl -import Qt.labs.platform 1.1 as Labs +import QtCore as QCore import ScreenPlayApp import ScreenPlay import ScreenPlay.Enums.InstalledType @@ -276,7 +276,7 @@ Item { icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_import_export_.svg" onClicked: { exportFileDialog.absoluteStoragePath = contextMenu.absoluteStoragePath; - let urlFileName = Labs.StandardPaths.writableLocation(Labs.StandardPaths.DesktopLocation) + "/" + contextMenu.fileName + ".screenplay"; + let urlFileName = QCore.StandardPaths.writableLocation(QCore.StandardPaths.DesktopLocation) + "/" + contextMenu.fileName + ".screenplay"; exportFileDialog.currentFile = urlFileName; exportFileDialog.open(); } @@ -315,7 +315,7 @@ Item { } } - Labs.FileDialog { + FileDialog { id: exportFileDialog fileMode: FileDialog.SaveFile property string absoluteStoragePath diff --git a/ScreenPlay/qml/Monitors/MonitorsProjectSettingItem.qml b/ScreenPlay/qml/Monitors/MonitorsProjectSettingItem.qml index 88f7f406..4953cfdb 100644 --- a/ScreenPlay/qml/Monitors/MonitorsProjectSettingItem.qml +++ b/ScreenPlay/qml/Monitors/MonitorsProjectSettingItem.qml @@ -1,9 +1,9 @@ import QtQuick import QtQuick.Controls -import Qt5Compat.GraphicalEffects -import Qt.labs.platform 1.1 import QtQuick.Controls.Material import QtQuick.Layouts +import QtQuick.Dialogs +import Qt5Compat.GraphicalEffects import ScreenPlayApp import ScreenPlay @@ -165,8 +165,8 @@ Item { title: qsTr("Please choose a color") onAccepted: { - rctPreviewColor.color = colorDialog.color; - let tmpColor = "'" + colorDialog.color.toString() + "'"; + rctPreviewColor.color = colorDialog.selectedColor; + let tmpColor = "'" + colorDialog.selectedColor.toString() + "'"; let obj = { "value": colorDialog.color, "type": "color" diff --git a/ScreenPlay/qml/Settings/Settings.qml b/ScreenPlay/qml/Settings/Settings.qml index a7f90730..1a004631 100644 --- a/ScreenPlay/qml/Settings/Settings.qml +++ b/ScreenPlay/qml/Settings/Settings.qml @@ -1,6 +1,5 @@ import QtQuick import QtQuick.Controls -import Qt.labs.platform import QtQuick.Controls.Material import QtQuick.Layouts import Qt5Compat.GraphicalEffects diff --git a/ScreenPlayUtil/CMakeLists.txt b/ScreenPlayUtil/CMakeLists.txt index 5352e8a1..e094986a 100644 --- a/ScreenPlayUtil/CMakeLists.txt +++ b/ScreenPlayUtil/CMakeLists.txt @@ -14,7 +14,6 @@ set(QML # cmake-format: sort qml/CloseIcon.qml qml/ColorImage.qml - qml/ColorPicker.qml qml/Dialog.qml qml/Dialogs/CriticalError.qml qml/Dialogs/MonitorConfiguration.qml diff --git a/ScreenPlayUtil/qml/ColorPicker.qml b/ScreenPlayUtil/qml/ColorPicker.qml deleted file mode 100644 index bc8a0024..00000000 --- a/ScreenPlayUtil/qml/ColorPicker.qml +++ /dev/null @@ -1,724 +0,0 @@ -/* - Based on: https://github.com/albertino80/bppgrid - - MIT License - - Copyright (c) 2019 Alberto Bignotti - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ -import QtQuick -import QtQuick.Layouts -import QtQuick.Controls -import QtQuick.Shapes 1.12 - -Pane { - property color hueColor: "blue" - property int colorHandleRadius: 10 - property int marginsValue: 10 - property int chekerSide: 5 - property color currentColor: "black" - property var commonColors: ['#FFFFFF', '#C0C0C0', '#808080', '#000000', '#FF0000', '#800000', '#FFFF00', '#808000', '#00FF00', '#008000', '#00FFFF', '#008080', '#0000FF', '#000080', '#FF00FF', '#800080'] - property bool updatingControls: false - - function initColor(acolor) { - initColorRGB(acolor.r * 255, acolor.g * 255, acolor.b * 255, acolor.a * 255); - } - - function setHueColor(hueValue) { - var v = 1 - hueValue; - if (0 <= v && v < 0.16) { - return Qt.rgba(1, 0, v / 0.16, 1); - } else if (0.16 <= v && v < 0.33) { - return Qt.rgba(1 - (v - 0.16) / 0.17, 0, 1, 1); - } else if (0.33 <= v && v < 0.5) { - return Qt.rgba(0, ((v - 0.33) / 0.17), 1, 1); - } else if (0.5 <= v && v < 0.76) { - return Qt.rgba(0, 1, 1 - (v - 0.5) / 0.26, 1); - } else if (0.76 <= v && v < 0.85) { - return Qt.rgba((v - 0.76) / 0.09, 1, 0, 1); - } else if (0.85 <= v && v <= 1) { - return Qt.rgba(1, 1 - (v - 0.85) / 0.15, 0, 1); - } else { - console.log("Invalid hueValue [0, 1]", hueValue); - return "white"; - } - } - - function hexToRgb(hex) { - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - hex = hex.replace(shorthandRegex, function (m, r, g, b) { - return r + r + g + g + b + b; - }); - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - return result ? { - "r": parseInt(result[1], 16), - "g": parseInt(result[2], 16), - "b": parseInt(result[3], 16) - } : null; - } - - function rgbToHex(r, g, b) { - return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); - } - - function drawChecker(ctx, width, height) { - ctx.lineWidth = 0; - //ctx.strokeStyle = 'blue' - var numRows = Math.ceil(height / chekerSide); - var numCols = Math.ceil(width / chekerSide); - var lastWhite = false; - var lastColWhite = false; - for (var icol = 0; icol < numCols; icol++) { - lastColWhite = lastWhite; - for (var irow = 0; irow < numRows; irow++) { - if (lastWhite) - ctx.fillStyle = 'gray'; - else - ctx.fillStyle = 'white'; - ctx.fillRect(icol * chekerSide, irow * chekerSide, chekerSide, chekerSide); - lastWhite = !lastWhite; - } - lastWhite = !lastColWhite; - } - } - - function handleMouseVertSlider(mouse, ctrlCursor, ctrlHeight) { - if (mouse.buttons & Qt.LeftButton) { - ctrlCursor.y = Math.max(0, Math.min(ctrlHeight, mouse.y)); - setCurrentColor(); - } - } - - function setCurrentColor() { - var alphaFactor = 1 - (shpAlpha.y / shpAlpha.parent.height); - if (optHsv.checked) { - var hueFactor = 1 - (shpHue.y / shpHue.parent.height); - hueColor = setHueColor(hueFactor); - var saturation = (pickerCursor.x + colorHandleRadius) / pickerCursor.parent.width; - var colorValue = 1 - ((pickerCursor.y + colorHandleRadius) / pickerCursor.parent.height); - currentColor = Qt.hsva(hueFactor, saturation, colorValue, alphaFactor); - } else { - currentColor = Qt.rgba(sliderRed.value / 255, sliderGreen.value / 255, sliderBlue.value / 255, alphaFactor); - } - hexColor.text = rgbToHex(currentColor.r * 255, currentColor.g * 255, currentColor.b * 255); - optHsv.focus = true; - } - - function initColorRGB(ared, agreen, ablue, aalpha) { - updatingControls = true; - var acolor = Qt.rgba(ared / 255, agreen / 255, ablue / 255, aalpha / 255); - var valHue = acolor.hsvHue; - if (valHue < 0) - valHue = 0; - - //console.log("toset", acolor.r * 255, acolor.g * 255, acolor.b * 255, acolor.a * 255) - shpHue.y = ((1 - valHue) * shpHue.parent.height); - shpAlpha.y = ((1 - acolor.a) * shpAlpha.parent.height); - pickerCursor.x = (acolor.hsvSaturation * pickerCursor.parent.width) - colorHandleRadius; - pickerCursor.y = ((1 - acolor.hsvValue) * pickerCursor.parent.height) - colorHandleRadius; - sliderRed.value = ared; - sliderGreen.value = agreen; - sliderBlue.value = ablue; - setCurrentColor(); - updatingControls = false; - } - - width: 500 - height: 300 - Component.onCompleted: { - initColorRGB(255, 0, 0, 255); - } - - RowLayout { - anchors.fill: parent - //anchors.margins: marginsValue - anchors.margins: 0 - spacing: marginsValue - - ColumnLayout { - Layout.fillHeight: true - Layout.fillWidth: true - spacing: marginsValue - - RowLayout { - Layout.fillHeight: true - Layout.fillWidth: true - visible: optHsv.checked - spacing: marginsValue - - Item { - Layout.fillHeight: true - Layout.fillWidth: true - - Rectangle { - x: 0 - y: 0 - width: parent.width - height: parent.height - visible: true - - gradient: Gradient { - orientation: Gradient.Horizontal - - GradientStop { - position: 0 - color: "#FFFFFF" - } - - GradientStop { - position: 1 - color: hueColor - } - } - } - - Rectangle { - x: 0 - y: 0 - width: parent.width - height: parent.height - border.color: BppMetrics.accentColor - visible: true - - gradient: Gradient { - GradientStop { - position: 1 - color: "#FF000000" - } - - GradientStop { - position: 0 - color: "#00000000" - } - } - } - - Rectangle { - id: pickerCursor - - width: colorHandleRadius * 2 - height: colorHandleRadius * 2 - radius: colorHandleRadius - border.color: BppMetrics.windowBackground - border.width: 2 - color: "transparent" - - Rectangle { - anchors.fill: parent - anchors.margins: 2 - border.color: BppMetrics.accentColor - border.width: 2 - radius: width / 2 - color: "transparent" - } - } - - MouseArea { - function handleMouse(mouse) { - if (mouse.buttons & Qt.LeftButton) { - pickerCursor.x = Math.max(-colorHandleRadius, Math.min(width, mouse.x) - colorHandleRadius); - pickerCursor.y = Math.max(-colorHandleRadius, Math.min(height, mouse.y) - colorHandleRadius); - setCurrentColor(); - } - } - - anchors.fill: parent - onPositionChanged: handleMouse(mouse) - onPressed: handleMouse(mouse) - } - } - - Rectangle { - Layout.fillHeight: true - Layout.preferredWidth: 30 - border.color: BppMetrics.accentColor - - Shape { - id: shpHue - - anchors.left: parent.left - anchors.margins: 0 - y: 90 - - ShapePath { - strokeWidth: 1 - strokeColor: "black" - - PathSvg { - path: "M0,0 L30,0" - } - } - - ShapePath { - strokeWidth: 2 - strokeColor: BppMetrics.accentColor - fillColor: "transparent" - - PathSvg { - path: "M0,-5 L30,-5 L30,4 L0,4z" - } - } - } - - MouseArea { - anchors.fill: parent - onPositionChanged: handleMouseVertSlider(mouse, shpHue, height) - onPressed: handleMouseVertSlider(mouse, shpHue, height) - } - - gradient: Gradient { - GradientStop { - position: 1 - color: "#FF0000" - } - - GradientStop { - position: 0.85 - color: "#FFFF00" - } - - GradientStop { - position: 0.76 - color: "#00FF00" - } - - GradientStop { - position: 0.5 - color: "#00FFFF" - } - - GradientStop { - position: 0.33 - color: "#0000FF" - } - - GradientStop { - position: 0.16 - color: "#FF00FF" - } - - GradientStop { - position: 0 - color: "#FF0000" - } - } - } - } - - ColumnLayout { - Layout.fillHeight: true - Layout.fillWidth: true - visible: optRgb.checked - - Label { - text: qsTr("Red") - color: BppMetrics.textColor - } - - Slider { - id: sliderRed - - Layout.fillWidth: true - from: 0 - to: 255 - value: 0 - onValueChanged: { - if (!updatingControls) - setCurrentColor(); - } - } - - Label { - text: qsTr("Green") - color: BppMetrics.textColor - } - - Slider { - id: sliderGreen - - Layout.fillWidth: true - from: 0 - to: 255 - value: 0 - onValueChanged: { - if (!updatingControls) - setCurrentColor(); - } - } - - Label { - text: qsTr("Blue") - color: BppMetrics.textColor - } - - Slider { - id: sliderBlue - - Layout.fillWidth: true - from: 0 - to: 255 - value: 0 - onValueChanged: { - if (!updatingControls) - setCurrentColor(); - } - } - - Item { - Layout.fillHeight: true - } - } - - Rectangle { - Layout.fillWidth: true - Layout.minimumHeight: 25 - Layout.maximumHeight: 25 - border.color: BppMetrics.accentColor - - RowLayout { - anchors.fill: parent - anchors.margins: 1 - spacing: 0 - - Repeater { - model: commonColors - - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - color: modelData - border.color: "gray" - border.width: 0 - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onPressed: { - initColorRGB(parent.color.r * 255, parent.color.g * 255, parent.color.b * 255, 255); - } - onEntered: { - border.width = 1; - var compColor = Qt.rgba(1, 1, 1, 1); - if (color.hsvValue > 0.5) - compColor = Qt.rgba(0, 0, 0, 1); - border.color = compColor; - } - onExited: { - border.width = 0; - } - } - } - } - } - } - } - - Canvas { - Layout.fillHeight: true - Layout.preferredWidth: 30 - onPaint: { - var ctx = getContext('2d'); - drawChecker(ctx, width, height); - } - - Rectangle { - anchors.fill: parent - border.color: BppMetrics.accentColor - - Shape { - id: shpAlpha - - anchors.left: parent.left - anchors.margins: 0 - y: 90 - - ShapePath { - strokeWidth: 1 - strokeColor: "black" - - PathSvg { - path: "M0,0 L30,0" - } - } - - ShapePath { - strokeWidth: 2 - strokeColor: BppMetrics.accentColor - fillColor: "transparent" - - PathSvg { - path: "M0,-5 L30,-5 L30,4 L0,4z" - } - } - } - - MouseArea { - anchors.fill: parent - onPositionChanged: handleMouseVertSlider(mouse, shpAlpha, height) - onPressed: handleMouseVertSlider(mouse, shpAlpha, height) - } - - gradient: Gradient { - //GradientStop { position: 0.0; color: "#FF000000" } - GradientStop { - position: 0 - color: Qt.rgba(currentColor.r, currentColor.g, currentColor.b, 1) - } - - GradientStop { - position: 1 - color: "#00000000" - } - } - } - } - - ColumnLayout { - Layout.fillHeight: true - Layout.minimumWidth: 70 - Layout.maximumWidth: 70 - - //spacing: 0 - Canvas { - Layout.fillWidth: true - height: 35 - onPaint: { - var ctx = getContext('2d'); - drawChecker(ctx, width, height); - } - - Rectangle { - border.color: BppMetrics.accentColor - color: "transparent" - anchors.fill: parent - - RowLayout { - anchors.fill: parent - anchors.margins: 1 - spacing: 0 - - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - color: Qt.rgba(currentColor.r, currentColor.g, currentColor.b, 1) - } - - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - color: currentColor - } - } - } - } - - ColumnLayout { - spacing: 0 - - RadioButton { - id: optRgb - - padding: 0 - text: qsTr("RGB") - Layout.alignment: Qt.AlignLeft - onCheckedChanged: initColorRGB(currentColor.r * 255, currentColor.g * 255, currentColor.b * 255, currentColor.a * 255) - - contentItem: Text { - text: optRgb.text - color: BppMetrics.textColor - font.bold: true - leftPadding: optRgb.indicator.width + optRgb.spacing - verticalAlignment: Text.AlignVCenter - } - } - - RadioButton { - id: optHsv - - padding: 0 - text: qsTr("HSV") - Layout.alignment: Qt.AlignLeft - checked: true - focus: true - onCheckedChanged: initColorRGB(currentColor.r * 255, currentColor.g * 255, currentColor.b * 255, currentColor.a * 255) - - contentItem: Text { - text: optHsv.text - color: BppMetrics.textColor - font.bold: true - leftPadding: optHsv.indicator.width + optHsv.spacing - verticalAlignment: Text.AlignVCenter - } - } - } - - Item { - Layout.fillHeight: true - } - - RowLayout { - visible: optRgb.checked - Layout.fillWidth: true - - Label { - text: qsTr("R:") - color: BppMetrics.textColor - } - - Label { - text: Math.floor(currentColor.r * 255) - Layout.fillWidth: true - color: BppMetrics.textColor - } - } - - RowLayout { - visible: optRgb.checked - Layout.fillWidth: true - - Label { - text: qsTr("G:") - color: BppMetrics.textColor - } - - Label { - text: Math.floor(currentColor.g * 255) - Layout.fillWidth: true - color: BppMetrics.textColor - } - } - - RowLayout { - visible: optRgb.checked - Layout.fillWidth: true - - Label { - text: qsTr("B:") - color: BppMetrics.textColor - } - - Label { - text: Math.floor(currentColor.b * 255) - Layout.fillWidth: true - color: BppMetrics.textColor - } - } - - RowLayout { - visible: optHsv.checked - Layout.fillWidth: true - - Label { - text: qsTr("H:") - color: BppMetrics.textColor - } - - Label { - text: Math.floor(currentColor.hsvHue * 360) - Layout.fillWidth: true - color: BppMetrics.textColor - } - } - - RowLayout { - visible: optHsv.checked - Layout.fillWidth: true - - Label { - text: qsTr("S:") - color: BppMetrics.textColor - } - - Label { - text: Math.floor(currentColor.hsvSaturation * 100) - Layout.fillWidth: true - color: BppMetrics.textColor - } - } - - RowLayout { - visible: optHsv.checked - Layout.fillWidth: true - - Label { - text: qsTr("V:") - color: BppMetrics.textColor - } - - Label { - text: Math.floor(currentColor.hsvValue * 100) - Layout.fillWidth: true - color: BppMetrics.textColor - } - } - - Item { - Layout.fillHeight: true - } - - //Label { text: qsTr("Alpha"); color: BppMetrics.textColor; font.bold: true; Layout.alignment: Qt.AlignLeft } - RowLayout { - Layout.fillWidth: true - - Label { - text: qsTr("Alpha:") - color: BppMetrics.textColor - } - - Label { - text: Math.floor(currentColor.a * 255) - Layout.fillWidth: true - color: BppMetrics.textColor - } - } - - RowLayout { - Layout.fillWidth: true - spacing: 0 - - Label { - text: qsTr("#") - color: BppMetrics.textColor - } - - TextInput { - id: hexColor - - Layout.fillWidth: true - text: "FF0099" - inputMask: "HHHHHH" - selectByMouse: true - color: BppMetrics.textColor - onTextChanged: { - if (!hexColor.focus) - return; - if (!updatingControls && acceptableInput) { - //console.log('updating', rgbColor.r, currentColor.r * 255, rgbColor.g, currentColor.g * 255, rgbColor.b, currentColor.b * 255) - var rgbColor = hexToRgb(text); - if (rgbColor && rgbColor.r !== Math.floor(currentColor.r * 255) && rgbColor.g !== Math.floor(currentColor.g * 255) && rgbColor.b !== Math.floor(currentColor.b * 255)) - initColorRGB(rgbColor.r, rgbColor.g, rgbColor.b, currentColor.a * 255); - } - } - } - } - } - } -} From 0a1da4f4a704aebee2cf95f2a9311388bcf11ded Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 15:44:06 +0100 Subject: [PATCH 43/56] Fix all wallpaper except video not showing --- ScreenPlayWallpaper/src/basewindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index b2c0cfab..6f93642b 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -53,7 +53,7 @@ ScreenPlay::WallpaperExitCode BaseWindow::setup() qWarning() << "Invalid project at " << projectPath(); return ScreenPlay::WallpaperExitCode::Invalid_Setup_ProjectParsingError; } - + setType(projectFile.type); setProjectSourceFile(projectFile.file); if (m_type == ScreenPlay::InstalledType::InstalledType::WebsiteWallpaper) { From d2919576d8f31f57ddd620ddeed83f555fdf8141 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 15:44:25 +0100 Subject: [PATCH 44/56] Remove hardcoded string in favor of enum --- ScreenPlay/src/wizards.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ScreenPlay/src/wizards.cpp b/ScreenPlay/src/wizards.cpp index 5862e51a..f9610f45 100644 --- a/ScreenPlay/src/wizards.cpp +++ b/ScreenPlay/src/wizards.cpp @@ -51,7 +51,7 @@ void Wizards::createQMLWidget(const QString& title, obj.insert("title", title); obj.insert("tags", ScreenPlayUtil::fillArray(tags)); obj.insert("createdBy", createdBy); - obj.insert("type", "qmlWidget"); + obj.insert("type", QVariant::fromValue(InstalledType::InstalledType::QMLWidget).toString()); obj.insert("file", "main.qml"); if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) { @@ -117,7 +117,7 @@ void Wizards::createHTMLWidget(const QString& title, obj.insert("createdBy", createdBy); obj.insert("title", title); obj.insert("tags", ScreenPlayUtil::fillArray(tags)); - obj.insert("type", "htmlWidget"); + obj.insert("type", QVariant::fromValue(InstalledType::InstalledType::HTMLWidget).toString()); obj.insert("file", "index.html"); if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) { @@ -185,7 +185,7 @@ void Wizards::createHTMLWallpaper( obj.insert("createdBy", createdBy); obj.insert("title", title); obj.insert("tags", ScreenPlayUtil::fillArray(tags)); - obj.insert("type", "htmlWallpaper"); + obj.insert("type", QVariant::fromValue(InstalledType::InstalledType::HTMLWallpaper).toString()); obj.insert("file", "index.html"); if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) { @@ -252,7 +252,7 @@ void Wizards::createQMLWallpaper( obj.insert("title", title); obj.insert("createdBy", createdBy); obj.insert("tags", ScreenPlayUtil::fillArray(tags)); - obj.insert("type", "qmlWallpaper"); + obj.insert("type", QVariant::fromValue(InstalledType::InstalledType::QMLWallpaper).toString()); obj.insert("file", "main.qml"); if (!previewThumbnail.isEmpty()) { @@ -320,7 +320,7 @@ void Wizards::createGifWallpaper( obj.insert("file", gifFileName); obj.insert("previewGIF", gifFileName); obj.insert("tags", ScreenPlayUtil::fillArray(tags)); - obj.insert("type", "gifWallpaper"); + obj.insert("type", QVariant::fromValue(InstalledType::InstalledType::GifWallpaper).toString()); if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) { qWarning() << "Could not write " << licenseFile; @@ -370,7 +370,7 @@ void Wizards::createWebsiteWallpaper( QJsonObject obj; obj.insert("title", title); obj.insert("tags", ScreenPlayUtil::fillArray(tags)); - obj.insert("type", "websiteWallpaper"); + obj.insert("type", QVariant::fromValue(InstalledType::InstalledType::WebsiteWallpaper).toString()); obj.insert("url", url.toString()); if (!previewThumbnail.isEmpty()) { From 4bce0a2cab6558410b2f73f841bc104b1d767884 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 16:17:47 +0100 Subject: [PATCH 45/56] Remove QApplication in favor of QGuiApplication --- .../inc/public/ScreenPlay/createimportvideo.h | 2 +- .../inc/public/ScreenPlay/monitorlistmodel.h | 2 +- .../inc/public/ScreenPlay/screenplaymanager.h | 2 +- .../inc/public/ScreenPlay/sdkconnection.h | 2 +- ScreenPlay/inc/public/ScreenPlay/settings.h | 2 +- ScreenPlay/inc/public/ScreenPlay/util.h | 2 +- ScreenPlay/src/app.cpp | 18 +++++----- ScreenPlay/src/createimportvideo.cpp | 7 ++-- ScreenPlay/src/monitorlistmodel.cpp | 20 +++++------ ScreenPlay/src/screenplaymanager.cpp | 5 ++- ScreenPlay/src/settings.cpp | 8 ++--- ScreenPlay/src/util.cpp | 7 ++-- ScreenPlay/tests/tst_main.cpp | 2 +- ScreenPlayWallpaper/main.cpp | 13 ++++---- ScreenPlayWallpaper/src/MacBridge.mm | 2 +- ScreenPlayWallpaper/src/basewindow.cpp | 7 ++-- ScreenPlayWallpaper/src/basewindow.h | 2 +- ScreenPlayWallpaper/src/linuxx11window.cpp | 2 ++ ScreenPlayWallpaper/src/linuxx11window.h | 2 +- ScreenPlayWallpaper/src/macbridge.h | 2 +- ScreenPlayWallpaper/src/macintegration.h | 2 +- ScreenPlayWallpaper/src/macwindow.cpp | 2 ++ ScreenPlayWallpaper/src/macwindow.h | 2 +- ScreenPlayWallpaper/src/winwindow.cpp | 33 ++++++++++--------- ScreenPlayWallpaper/src/winwindow.h | 2 +- ScreenPlayWidget/main.cpp | 7 ++-- ScreenPlayWidget/src/widgetwindow.cpp | 6 ++-- ScreenPlayWidget/src/widgetwindow.h | 2 +- 28 files changed, 90 insertions(+), 75 deletions(-) diff --git a/ScreenPlay/inc/public/ScreenPlay/createimportvideo.h b/ScreenPlay/inc/public/ScreenPlay/createimportvideo.h index 6a22cd5b..da7cf06e 100644 --- a/ScreenPlay/inc/public/ScreenPlay/createimportvideo.h +++ b/ScreenPlay/inc/public/ScreenPlay/createimportvideo.h @@ -2,7 +2,7 @@ #pragma once -#include + #include #include #include diff --git a/ScreenPlay/inc/public/ScreenPlay/monitorlistmodel.h b/ScreenPlay/inc/public/ScreenPlay/monitorlistmodel.h index 58af0ccf..ed80ce6e 100644 --- a/ScreenPlay/inc/public/ScreenPlay/monitorlistmodel.h +++ b/ScreenPlay/inc/public/ScreenPlay/monitorlistmodel.h @@ -3,7 +3,7 @@ #pragma once #include -#include + #include #include #include diff --git a/ScreenPlay/inc/public/ScreenPlay/screenplaymanager.h b/ScreenPlay/inc/public/ScreenPlay/screenplaymanager.h index 04df4be3..90c698ec 100644 --- a/ScreenPlay/inc/public/ScreenPlay/screenplaymanager.h +++ b/ScreenPlay/inc/public/ScreenPlay/screenplaymanager.h @@ -2,7 +2,7 @@ #pragma once -#include + #include #include #include diff --git a/ScreenPlay/inc/public/ScreenPlay/sdkconnection.h b/ScreenPlay/inc/public/ScreenPlay/sdkconnection.h index f898ab7a..da04a12f 100644 --- a/ScreenPlay/inc/public/ScreenPlay/sdkconnection.h +++ b/ScreenPlay/inc/public/ScreenPlay/sdkconnection.h @@ -2,7 +2,7 @@ #pragma once -#include + #include #include #include diff --git a/ScreenPlay/inc/public/ScreenPlay/settings.h b/ScreenPlay/inc/public/ScreenPlay/settings.h index b73a9506..4d0388ac 100644 --- a/ScreenPlay/inc/public/ScreenPlay/settings.h +++ b/ScreenPlay/inc/public/ScreenPlay/settings.h @@ -2,7 +2,7 @@ #pragma once -#include +#include #include #include #include diff --git a/ScreenPlay/inc/public/ScreenPlay/util.h b/ScreenPlay/inc/public/ScreenPlay/util.h index 15cf3e78..654070b0 100644 --- a/ScreenPlay/inc/public/ScreenPlay/util.h +++ b/ScreenPlay/inc/public/ScreenPlay/util.h @@ -2,7 +2,7 @@ #pragma once -#include + #include #include #include diff --git a/ScreenPlay/src/app.cpp b/ScreenPlay/src/app.cpp index ccee8a17..8fd01055 100644 --- a/ScreenPlay/src/app.cpp +++ b/ScreenPlay/src/app.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace ScreenPlay { @@ -132,7 +133,7 @@ App::App() /*! \brief Used for initialization after the constructor. The sole purpose is to check if another ScreenPlay instance is running and then quit early. This is also because we cannot - call QApplication::quit(); in the SDKConnector before the app.exec(); ( the Qt main event + call QGuiApplication::quit(); in the SDKConnector before the app.exec(); ( the Qt main event loop ) has started. */ void App::init() @@ -189,25 +190,25 @@ void App::init() // Init after we have the paths from settings m_installedListModel->init(); - auto* guiApplication = QGuiApplication::instance(); + auto* guiAppInst = dynamic_cast(QGuiApplication::instance()); // Set visible if the -silent parameter was not set - if (guiApplication->arguments().contains("-silent")) { + if (guiAppInst->arguments().contains("-silent")) { qInfo() << "Starting in silent mode."; settings()->setSilentStart(true); } qmlRegisterSingletonInstance("ScreenPlay", 1, 0, "App", this); - m_mainWindowEngine->addImportPath(guiApplication->applicationDirPath() + "/qml"); + m_mainWindowEngine->addImportPath(guiAppInst->applicationDirPath() + "/qml"); #if defined(Q_OS_OSX) - QDir workingDir(guiApplication->applicationDirPath()); + QDir workingDir(guiAppInst->applicationDirPath()); workingDir.cdUp(); workingDir.cdUp(); workingDir.cdUp(); // OSX Development workaround: m_mainWindowEngine->addImportPath(workingDir.path() + "/qml"); #endif - guiApplication->addLibraryPath(guiApplication->applicationDirPath() + "/qml"); + guiAppInst->addLibraryPath(guiAppInst->applicationDirPath() + "/qml"); if (m_settings->desktopEnvironment() == Settings::DesktopEnvironment::KDE) { setupKDE(); @@ -227,14 +228,15 @@ QString App::version() const } /*! - \brief Calls QApplication quit() and can be used to do additional + \brief Calls QGuiApplication quit() and can be used to do additional tasks before exiting. */ void App::exit() { m_screenPlayManager->removeAllWallpapers(); m_screenPlayManager->removeAllWidgets(); - QApplication::instance()->quit(); + auto* guiAppInst = dynamic_cast(QGuiApplication::instance()); + guiAppInst->quit(); } bool App::isKDEInstalled() diff --git a/ScreenPlay/src/createimportvideo.cpp b/ScreenPlay/src/createimportvideo.cpp index 1447bf28..f6ff3492 100644 --- a/ScreenPlay/src/createimportvideo.cpp +++ b/ScreenPlay/src/createimportvideo.cpp @@ -2,6 +2,7 @@ #include "ScreenPlay/createimportvideo.h" #include "ScreenPlayUtil/util.h" +#include namespace ScreenPlay { @@ -61,8 +62,8 @@ void CreateImportVideo::setupFFMPEG() m_ffprobeExecutable = "ffprobe"; m_ffmpegExecutable = "ffmpeg"; #else - m_ffprobeExecutable = QApplication::applicationDirPath() + "/ffprobe" + ScreenPlayUtil::executableBinEnding(); - m_ffmpegExecutable = QApplication::applicationDirPath() + "/ffmpeg" + ScreenPlayUtil::executableBinEnding(); + m_ffprobeExecutable = QGuiApplication::applicationDirPath() + "/ffprobe" + ScreenPlayUtil::executableBinEnding(); + m_ffmpegExecutable = QGuiApplication::applicationDirPath() + "/ffmpeg" + ScreenPlayUtil::executableBinEnding(); #endif if (!QFileInfo::exists(m_ffprobeExecutable)) { @@ -732,7 +733,7 @@ QString CreateImportVideo::waitForFinished( m_process->setProcessChannelMode(processChannelMode); m_process->setArguments(args); - m_process->setWorkingDirectory(QApplication::applicationDirPath()); + m_process->setWorkingDirectory(QGuiApplication::applicationDirPath()); m_process->start(); qInfo() << m_process->workingDirectory() << m_process->program() << m_process->arguments(); diff --git a/ScreenPlay/src/monitorlistmodel.cpp b/ScreenPlay/src/monitorlistmodel.cpp index d1c2e58c..7a01d428 100644 --- a/ScreenPlay/src/monitorlistmodel.cpp +++ b/ScreenPlay/src/monitorlistmodel.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "ScreenPlay/monitorlistmodel.h" - +#include namespace ScreenPlay { /*! @@ -27,9 +27,9 @@ MonitorListModel::MonitorListModel(QObject* parent) { loadMonitors(); - auto* guiAppInst = dynamic_cast(QApplication::instance()); - connect(guiAppInst, &QApplication::screenAdded, this, &MonitorListModel::screenAdded); - connect(guiAppInst, &QApplication::screenRemoved, this, &MonitorListModel::screenRemoved); + auto* guiAppInst = dynamic_cast(QGuiApplication::instance()); + connect(guiAppInst, &QGuiApplication::screenAdded, this, &MonitorListModel::screenAdded); + connect(guiAppInst, &QGuiApplication::screenRemoved, this, &MonitorListModel::screenRemoved); } /*! @@ -148,8 +148,8 @@ void MonitorListModel::loadMonitors() int offsetX = 0; int offsetY = 0; - for (int i = 0; i < QApplication::screens().count(); i++) { - QScreen* screen = QApplication::screens().at(i); + for (int i = 0; i < QGuiApplication::screens().count(); i++) { + QScreen* screen = QGuiApplication::screens().at(i); if (screen->availableGeometry().x() < 0) { offsetX += (screen->availableGeometry().x() * -1); } @@ -158,8 +158,8 @@ void MonitorListModel::loadMonitors() } } - for (int i = 0; i < QApplication::screens().count(); i++) { - QScreen* screen = QApplication::screens().at(i); + for (int i = 0; i < QGuiApplication::screens().count(); i++) { + QScreen* screen = QGuiApplication::screens().at(i); // Sometimes we get invalid monitors on Windows. I don't know why... if (screen->geometry().width() == 0 || screen->geometry().height() == 0) @@ -222,8 +222,8 @@ void MonitorListModel::closeWallpaper(const QString& appID) */ QRect MonitorListModel::absoluteDesktopSize() const { - auto* app = static_cast(QGuiApplication::instance()); - return app->screens().at(0)->availableVirtualGeometry(); + auto* guiAppInst = dynamic_cast(QGuiApplication::instance()); + return guiAppInst->screens().at(0)->availableVirtualGeometry(); } /*! diff --git a/ScreenPlay/src/screenplaymanager.cpp b/ScreenPlay/src/screenplaymanager.cpp index 7b52ab28..78b5165b 100644 --- a/ScreenPlay/src/screenplaymanager.cpp +++ b/ScreenPlay/src/screenplaymanager.cpp @@ -1,10 +1,9 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "ScreenPlay/screenplaymanager.h" +#include "ScreenPlay/util.h" + #include - -#include "util.h" - namespace ScreenPlay { /*! diff --git a/ScreenPlay/src/settings.cpp b/ScreenPlay/src/settings.cpp index 21096788..4f617bcf 100644 --- a/ScreenPlay/src/settings.cpp +++ b/ScreenPlay/src/settings.cpp @@ -241,7 +241,7 @@ void Settings::initInstalledPath() */ void Settings::initSteamInstalledPath() { - QString appBasePath = QApplication::instance()->applicationDirPath(); + QString appBasePath = QGuiApplication::instance()->applicationDirPath(); if (desktopEnvironment() == DesktopEnvironment::OSX) { appBasePath += "/../../.."; } @@ -293,14 +293,14 @@ bool Settings::retranslateUI() QString langCode = fixLanguageCode(QVariant::fromValue(language()).toString()); QFile tsFile; - const QString qmPath = QApplication::applicationDirPath() + "/translations/ScreenPlay_" + langCode + ".qm"; + const QString qmPath = QGuiApplication::applicationDirPath() + "/translations/ScreenPlay_" + langCode + ".qm"; if (tsFile.exists(qmPath)) { if (!m_translator.load(qmPath)) { qWarning() << "Unable to load translation file: " << qmPath; return false; } - auto* app = static_cast(QApplication::instance()); - app->installTranslator(&m_translator); + auto* guiAppInst = dynamic_cast(QGuiApplication::instance()); + guiAppInst->installTranslator(&m_translator); emit requestRetranslation(); if (language() == Settings::Language::Ko_KR) { diff --git a/ScreenPlay/src/util.cpp b/ScreenPlay/src/util.cpp index a435b0b6..f264c94c 100644 --- a/ScreenPlay/src/util.cpp +++ b/ScreenPlay/src/util.cpp @@ -4,7 +4,9 @@ #include "qarchive_enums.hpp" #include "qarchivediskcompressor.hpp" #include "qarchivediskextractor.hpp" + #include +#include #if defined(Q_OS_WIN) #include @@ -26,7 +28,8 @@ Util::Util() { // Fix log access vilation on quit utilPointer = this; - QObject::connect(QGuiApplication::instance(), &QGuiApplication::aboutToQuit, this, []() { utilPointer = nullptr; }); + auto* guiAppInst = dynamic_cast(QGuiApplication::instance()); + QObject::connect(guiAppInst, &QGuiApplication::aboutToQuit, this, []() { utilPointer = nullptr; }); m_extractor = std::make_unique(); m_compressor = std::make_unique(); @@ -58,7 +61,7 @@ Util::~Util() { } */ void Util::copyToClipboard(const QString& text) const { - auto* clipboard = QApplication::clipboard(); + auto* clipboard = QGuiApplication::clipboard(); clipboard->setText(text); } diff --git a/ScreenPlay/tests/tst_main.cpp b/ScreenPlay/tests/tst_main.cpp index 5fb4e6ad..e60d9def 100644 --- a/ScreenPlay/tests/tst_main.cpp +++ b/ScreenPlay/tests/tst_main.cpp @@ -2,7 +2,7 @@ #include "ScreenPlay/app.h" #include "ScreenPlay/create.h" -#include + #include #include #include diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index 4f70cada..3515a322 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -1,9 +1,10 @@ -#include + #include #include #include #include #include +#include #include "ScreenPlayUtil/exitcodes.h" #include "ScreenPlayUtil/util.h" @@ -23,13 +24,13 @@ int main(int argc, char* argv[]) { #if !defined(Q_OS_LINUX) - qputenv("QT_MEDIA_BACKEND", "ffmpeg"); + qputenv("QT_MEDIA_BACKEND", "windows"); #endif - QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + QGuiApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QtWebEngineQuick::initialize(); - QApplication app(argc, argv); + QGuiApplication app(argc, argv); #if defined(Q_OS_WIN) WinWindow window; @@ -46,8 +47,8 @@ int main(int argc, char* argv[]) // For testing purposes when starting the ScreenPlayWallpaper directly. if (argumentList.length() == 1) { window.setActiveScreensList({ 0 }); - window.setProjectPath("test"); - // window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/19112022140605-Horde 1980"); + //window.setProjectPath("test"); + window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/particles"); window.setAppID("test"); window.setVolume(1); window.setFillMode("fill"); diff --git a/ScreenPlayWallpaper/src/MacBridge.mm b/ScreenPlayWallpaper/src/MacBridge.mm index 11187e03..89f259e6 100644 --- a/ScreenPlayWallpaper/src/MacBridge.mm +++ b/ScreenPlayWallpaper/src/MacBridge.mm @@ -2,7 +2,7 @@ #include "macbridge.h" #import -#include + #include #import diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index 6f93642b..7295ff65 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -4,6 +4,9 @@ #include "ScreenPlayUtil/projectfile.h" #include "ScreenPlayUtil/util.h" +#include + + /*! \module ScreenPlayWallpaper \title ScreenPlayWallpaper @@ -18,7 +21,7 @@ BaseWindow::BaseWindow() { - QApplication::instance()->installEventFilter(this); + QGuiApplication::instance()->installEventFilter(this); qRegisterMetaType(); qmlRegisterUncreatableMetaObject(ScreenPlay::InstalledType::staticMetaObject, @@ -196,7 +199,7 @@ QString BaseWindow::loadFromFile(const QString& filename) */ QString BaseWindow::getApplicationPath() { - return QApplication::applicationDirPath(); + return QGuiApplication::applicationDirPath(); } /*! diff --git a/ScreenPlayWallpaper/src/basewindow.h b/ScreenPlayWallpaper/src/basewindow.h index 5d7fa842..e701f76e 100644 --- a/ScreenPlayWallpaper/src/basewindow.h +++ b/ScreenPlayWallpaper/src/basewindow.h @@ -2,7 +2,7 @@ #pragma once -#include + #include #include #include diff --git a/ScreenPlayWallpaper/src/linuxx11window.cpp b/ScreenPlayWallpaper/src/linuxx11window.cpp index 7005db69..a7c586ad 100644 --- a/ScreenPlayWallpaper/src/linuxx11window.cpp +++ b/ScreenPlayWallpaper/src/linuxx11window.cpp @@ -16,6 +16,8 @@ #include #include +#include + #define WIDTH 512 #define HEIGHT 384 #define OPAQUE 0xffffffff diff --git a/ScreenPlayWallpaper/src/linuxx11window.h b/ScreenPlayWallpaper/src/linuxx11window.h index 7f6e0860..25261e51 100644 --- a/ScreenPlayWallpaper/src/linuxx11window.h +++ b/ScreenPlayWallpaper/src/linuxx11window.h @@ -2,7 +2,7 @@ #pragma once -#include + #include #include #include diff --git a/ScreenPlayWallpaper/src/macbridge.h b/ScreenPlayWallpaper/src/macbridge.h index 39514db7..c2b3d03b 100644 --- a/ScreenPlayWallpaper/src/macbridge.h +++ b/ScreenPlayWallpaper/src/macbridge.h @@ -2,7 +2,7 @@ #pragma once -#include + class MacBridge : public QObject { Q_OBJECT diff --git a/ScreenPlayWallpaper/src/macintegration.h b/ScreenPlayWallpaper/src/macintegration.h index 8775630b..44e1fc56 100644 --- a/ScreenPlayWallpaper/src/macintegration.h +++ b/ScreenPlayWallpaper/src/macintegration.h @@ -2,7 +2,7 @@ #pragma once -#include + class MacIntegration : public QObject { Q_OBJECT diff --git a/ScreenPlayWallpaper/src/macwindow.cpp b/ScreenPlayWallpaper/src/macwindow.cpp index 9b1ed75c..8c8ff0b3 100644 --- a/ScreenPlayWallpaper/src/macwindow.cpp +++ b/ScreenPlayWallpaper/src/macwindow.cpp @@ -1,6 +1,8 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "macwindow.h" +#include + ScreenPlay::WallpaperExitCode MacWindow::start() { auto* screen = QGuiApplication::screens().at(activeScreensList().at(0)); diff --git a/ScreenPlayWallpaper/src/macwindow.h b/ScreenPlayWallpaper/src/macwindow.h index 0000a556..05b9f073 100644 --- a/ScreenPlayWallpaper/src/macwindow.h +++ b/ScreenPlayWallpaper/src/macwindow.h @@ -2,7 +2,7 @@ #pragma once -#include + #include #include #include diff --git a/ScreenPlayWallpaper/src/winwindow.cpp b/ScreenPlayWallpaper/src/winwindow.cpp index b203ce64..2a9bce8f 100644 --- a/ScreenPlayWallpaper/src/winwindow.cpp +++ b/ScreenPlayWallpaper/src/winwindow.cpp @@ -1,7 +1,8 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only -#include "winwindow.h" #include "ScreenPlayUtil/projectfile.h" -#include "qqml.h" +#include "winwindow.h" +#include +#include #include #include #include @@ -77,15 +78,15 @@ LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam) auto event = QMouseEvent(type, g_LastMousePosition, mouseButton, mouseButtons, keyboardModifier); - QApplication::sendEvent(g_winGlobalHook, &event); + QGuiApplication::sendEvent(g_winGlobalHook, &event); if (type == QMouseEvent::Type::MouseButtonPress) { } QTimer::singleShot(100, [&]() { // auto eventPress = QMouseEvent(QMouseEvent::Type::MouseButtonPress, g_LastMousePosition, mouseButton, mouseButtons, {}); - // qInfo() << mouseButton << QApplication::sendEvent(g_winGlobalHook, &eventPress) << g_globalOffset.x() << g_globalOffset.y(); + // qInfo() << mouseButton << QGuiApplication::sendEvent(g_winGlobalHook, &eventPress) << g_globalOffset.x() << g_globalOffset.y(); auto eventRelease = QMouseEvent(QMouseEvent::Type::MouseButtonRelease, g_LastMousePosition, mouseButton, mouseButtons, {}); - QApplication::sendEvent(g_winGlobalHook, &eventRelease); + QGuiApplication::sendEvent(g_winGlobalHook, &eventRelease); }); return CallNextHookEx(g_mouseHook, nCode, wParam, lParam); @@ -120,17 +121,17 @@ ScreenPlay::WallpaperExitCode WinWindow::start() } }, Qt::QueuedConnection); - auto* guiAppInst = dynamic_cast(QApplication::instance()); + auto* guiAppInst = dynamic_cast(QGuiApplication::instance()); if (!debugMode()) { connect(m_sdk.get(), &ScreenPlaySDK::sdkDisconnected, this, &WinWindow::destroyThis); } - connect(guiAppInst, &QApplication::screenAdded, this, &WinWindow::configureWindowGeometry); - connect(guiAppInst, &QApplication::screenRemoved, this, &WinWindow::configureWindowGeometry); - connect(guiAppInst, &QApplication::primaryScreenChanged, this, &WinWindow::configureWindowGeometry); + connect(guiAppInst, &QGuiApplication::screenAdded, this, &WinWindow::configureWindowGeometry); + connect(guiAppInst, &QGuiApplication::screenRemoved, this, &WinWindow::configureWindowGeometry); + connect(guiAppInst, &QGuiApplication::primaryScreenChanged, this, &WinWindow::configureWindowGeometry); connect(this, &BaseWindow::reloadQML, this, &WinWindow::clearComponentCache); connect(&m_checkForFullScreenWindowTimer, &QTimer::timeout, this, &WinWindow::checkForFullScreenWindow); - const auto screens = QApplication::screens(); + const auto screens = QGuiApplication::screens(); for (const auto& screen : screens) { connect(screen, &QScreen::geometryChanged, this, &WinWindow::configureWindowGeometry); } @@ -209,7 +210,7 @@ BOOL CALLBACK GetMonitorByIndex(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMo void WinWindow::setupWallpaperForOneScreen(int activeScreen) { - const QRect screenRect = QApplication::screens().at(activeScreen)->geometry(); + const QRect screenRect = QGuiApplication::screens().at(activeScreen)->geometry(); const int boderWidth = 2; const float scaling = getScaling(activeScreen); const int borderOffset = -1; @@ -291,7 +292,7 @@ void WinWindow::setupWallpaperForMultipleScreens(const QVector& activeScree QScreen* upperLeftScreen { nullptr }; // Check for the upper left screen first so we get x and y positions for (const int screen : activeScreensList) { - QScreen* screenTmp = QApplication::screens().at(screen); + QScreen* screenTmp = QGuiApplication::screens().at(screen); if (upperLeftScreen != nullptr) { if (screenTmp->geometry().x() < upperLeftScreen->geometry().x() || screenTmp->geometry().y() < upperLeftScreen->geometry().y()) { upperLeftScreen = screenTmp; @@ -338,7 +339,7 @@ bool WinWindow::searchWorkerWindowToParentTo() */ float WinWindow::getScaling(const int monitorIndex) { - QScreen* screen = QApplication::screens().at(monitorIndex); + QScreen* screen = QGuiApplication::screens().at(monitorIndex); const int factor = screen->physicalDotsPerInch(); switch (factor) { case 72: @@ -359,7 +360,7 @@ float WinWindow::getScaling(const int monitorIndex) */ bool WinWindow::hasWindowScaling() { - const auto screens = QApplication::screens(); + const auto screens = QGuiApplication::screens(); for (int i = 0; i < screens.count(); i++) { if (getScaling(i) != 1) { return true; @@ -394,7 +395,7 @@ void WinWindow::configureWindowGeometry() SetWindowLongPtr(m_windowHandle, GWL_STYLE, WS_POPUPWINDOW); // Ether for one Screen or for all - if ((QApplication::screens().length() == activeScreensList().length()) && (activeScreensList().length() != 1)) { + if ((QGuiApplication::screens().length() == activeScreensList().length()) && (activeScreensList().length() != 1)) { setupWallpaperForAllScreens(); } else if (activeScreensList().length() == 1) { setupWallpaperForOneScreen(activeScreensList().at(0)); @@ -494,7 +495,7 @@ void WinWindow::terminate() ShowWindow(m_windowHandleWorker, SW_HIDE); ShowWindow(m_windowHandleWorker, SW_SHOW); - QApplication::quit(); + QGuiApplication::quit(); } /*! diff --git a/ScreenPlayWallpaper/src/winwindow.h b/ScreenPlayWallpaper/src/winwindow.h index 01e577b6..e5035a77 100644 --- a/ScreenPlayWallpaper/src/winwindow.h +++ b/ScreenPlayWallpaper/src/winwindow.h @@ -2,7 +2,7 @@ #pragma once -#include + #include #include #include diff --git a/ScreenPlayWidget/main.cpp b/ScreenPlayWidget/main.cpp index 05dd8f96..8469bc14 100644 --- a/ScreenPlayWidget/main.cpp +++ b/ScreenPlayWidget/main.cpp @@ -1,8 +1,9 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only -#include + #include #include #include +#include #include "src/widgetwindow.h" @@ -20,9 +21,9 @@ int main(int argc, char* argv[]) #endif QtWebEngineQuick::initialize(); - QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + QGuiApplication::setAttribute(Qt::AA_ShareOpenGLContexts); - QApplication app(argc, argv); + QGuiApplication app(argc, argv); const QStringList argumentList = app.arguments(); diff --git a/ScreenPlayWidget/src/widgetwindow.cpp b/ScreenPlayWidget/src/widgetwindow.cpp index bf7b9bb6..0b3ec2fb 100644 --- a/ScreenPlayWidget/src/widgetwindow.cpp +++ b/ScreenPlayWidget/src/widgetwindow.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #include "widgetwindow.h" -#include +#include #include #include "ScreenPlayUtil/contenttypes.h" @@ -76,8 +76,8 @@ WidgetWindow::WidgetWindow( qWarning() << "Cannot parse Wallpaper type from value" << m_project.value("type"); } } - - m_window.engine()->addImportPath(qGuiApp->applicationDirPath() + "/qml"); + auto* guiAppInst = dynamic_cast(QGuiApplication::instance()); + m_window.engine()->addImportPath(guiAppInst->applicationDirPath() + "/qml"); m_window.setTextRenderType(QQuickWindow::TextRenderType::NativeTextRendering); m_window.setResizeMode(QQuickView::ResizeMode::SizeViewToRootObject); m_window.setSource(QUrl("qrc:/qml/ScreenPlayWidget/qml/Widget.qml")); diff --git a/ScreenPlayWidget/src/widgetwindow.h b/ScreenPlayWidget/src/widgetwindow.h index 39c0ff78..fd6385c6 100644 --- a/ScreenPlayWidget/src/widgetwindow.h +++ b/ScreenPlayWidget/src/widgetwindow.h @@ -2,7 +2,7 @@ #pragma once -#include + #include #include #include From 10eabc0a56a6e6811dd74f81df7ec5834c982f89 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 16:18:13 +0100 Subject: [PATCH 46/56] Formatting --- ScreenPlay/inc/public/ScreenPlay/createimportvideo.h | 1 - ScreenPlay/inc/public/ScreenPlay/screenplaymanager.h | 1 - ScreenPlay/inc/public/ScreenPlay/sdkconnection.h | 1 - ScreenPlay/inc/public/ScreenPlay/settings.h | 2 +- ScreenPlay/inc/public/ScreenPlay/util.h | 1 - ScreenPlay/src/app.cpp | 2 +- ScreenPlayWallpaper/src/macintegration.h | 2 -- 7 files changed, 2 insertions(+), 8 deletions(-) diff --git a/ScreenPlay/inc/public/ScreenPlay/createimportvideo.h b/ScreenPlay/inc/public/ScreenPlay/createimportvideo.h index da7cf06e..e2671914 100644 --- a/ScreenPlay/inc/public/ScreenPlay/createimportvideo.h +++ b/ScreenPlay/inc/public/ScreenPlay/createimportvideo.h @@ -2,7 +2,6 @@ #pragma once - #include #include #include diff --git a/ScreenPlay/inc/public/ScreenPlay/screenplaymanager.h b/ScreenPlay/inc/public/ScreenPlay/screenplaymanager.h index 90c698ec..ba183f50 100644 --- a/ScreenPlay/inc/public/ScreenPlay/screenplaymanager.h +++ b/ScreenPlay/inc/public/ScreenPlay/screenplaymanager.h @@ -2,7 +2,6 @@ #pragma once - #include #include #include diff --git a/ScreenPlay/inc/public/ScreenPlay/sdkconnection.h b/ScreenPlay/inc/public/ScreenPlay/sdkconnection.h index da04a12f..6dbf336c 100644 --- a/ScreenPlay/inc/public/ScreenPlay/sdkconnection.h +++ b/ScreenPlay/inc/public/ScreenPlay/sdkconnection.h @@ -2,7 +2,6 @@ #pragma once - #include #include #include diff --git a/ScreenPlay/inc/public/ScreenPlay/settings.h b/ScreenPlay/inc/public/ScreenPlay/settings.h index 4d0388ac..517803f4 100644 --- a/ScreenPlay/inc/public/ScreenPlay/settings.h +++ b/ScreenPlay/inc/public/ScreenPlay/settings.h @@ -2,11 +2,11 @@ #pragma once -#include #include #include #include #include +#include #include #include #include diff --git a/ScreenPlay/inc/public/ScreenPlay/util.h b/ScreenPlay/inc/public/ScreenPlay/util.h index 654070b0..40387ed8 100644 --- a/ScreenPlay/inc/public/ScreenPlay/util.h +++ b/ScreenPlay/inc/public/ScreenPlay/util.h @@ -2,7 +2,6 @@ #pragma once - #include #include #include diff --git a/ScreenPlay/src/app.cpp b/ScreenPlay/src/app.cpp index 8fd01055..1e3ed6eb 100644 --- a/ScreenPlay/src/app.cpp +++ b/ScreenPlay/src/app.cpp @@ -7,10 +7,10 @@ #include "app.h" #include "steam/steam_qt_enums_generated.h" +#include #include #include #include -#include namespace ScreenPlay { diff --git a/ScreenPlayWallpaper/src/macintegration.h b/ScreenPlayWallpaper/src/macintegration.h index 44e1fc56..416507fd 100644 --- a/ScreenPlayWallpaper/src/macintegration.h +++ b/ScreenPlayWallpaper/src/macintegration.h @@ -2,8 +2,6 @@ #pragma once - - class MacIntegration : public QObject { Q_OBJECT public: From d129bf5cf4ca268089aefefbd95ffb0de3201708 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 17:03:10 +0100 Subject: [PATCH 47/56] Fix long standing qml error internal crash We now wait until the event loop is done until we call terminate. Before ScreenPlayWallpaper would crash internally and stay alive as a zombie process for some reason... --- ScreenPlayWallpaper/main.cpp | 3 +- ScreenPlayWallpaper/qml/GifWallpaper.qml | 3 + ScreenPlayWallpaper/qml/MultimediaView.qml | 3 +- ScreenPlayWallpaper/qml/MultimediaWebView.qml | 4 +- ScreenPlayWallpaper/qml/Test.qml | 4 +- ScreenPlayWallpaper/qml/Wallpaper.qml | 56 ++++++++----------- ScreenPlayWallpaper/qml/WebsiteWallpaper.qml | 6 +- ScreenPlayWallpaper/src/basewindow.cpp | 12 +++- ScreenPlayWallpaper/src/basewindow.h | 7 ++- ScreenPlayWallpaper/src/linuxx11window.cpp | 5 ++ ScreenPlayWallpaper/src/linuxx11window.h | 2 +- ScreenPlayWallpaper/src/macbridge.h | 2 - ScreenPlayWallpaper/src/macwindow.h | 3 +- ScreenPlayWallpaper/src/winwindow.h | 3 +- ScreenPlayWidget/main.cpp | 2 +- ScreenPlayWidget/src/widgetwindow.h | 1 - 16 files changed, 57 insertions(+), 59 deletions(-) diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index 3515a322..749f5479 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -1,10 +1,10 @@ +#include #include #include #include #include #include -#include #include "ScreenPlayUtil/exitcodes.h" #include "ScreenPlayUtil/util.h" @@ -114,5 +114,6 @@ int main(int argc, char* argv[]) if (startStatus != ScreenPlay::WallpaperExitCode::Ok) { return static_cast(startStatus); } + emit window.qmlStart(); return app.exec(); } diff --git a/ScreenPlayWallpaper/qml/GifWallpaper.qml b/ScreenPlayWallpaper/qml/GifWallpaper.qml index 13c3786a..71d8a2dc 100644 --- a/ScreenPlayWallpaper/qml/GifWallpaper.qml +++ b/ScreenPlayWallpaper/qml/GifWallpaper.qml @@ -1,4 +1,7 @@ import QtQuick +import ScreenPlayWallpaper + AnimatedImage { + Component.onCompleted: Wallpaper.requestFadeIn(); } diff --git a/ScreenPlayWallpaper/qml/MultimediaView.qml b/ScreenPlayWallpaper/qml/MultimediaView.qml index 5cdfd3e3..4ec82d1a 100644 --- a/ScreenPlayWallpaper/qml/MultimediaView.qml +++ b/ScreenPlayWallpaper/qml/MultimediaView.qml @@ -23,7 +23,6 @@ Item { onIsPlayingChanged: isPlaying ? mediaPlayer.play() : mediaPlayer.pause() property bool isWindows: Qt.platform.os === "windows" - property bool ready: false property string source: Wallpaper.projectSourceFileAbsolute onSourceChanged: { @@ -37,7 +36,7 @@ Item { id: mediaPlayer onPlaybackStateChanged: { if (mediaPlayer.playbackState == MediaPlayer.PlayingState) { - root.ready = true; + Wallpaper.requestFadeIn(); } } loops: root.loops ? MediaPlayer.Infinite : 1 diff --git a/ScreenPlayWallpaper/qml/MultimediaWebView.qml b/ScreenPlayWallpaper/qml/MultimediaWebView.qml index c76d067b..2f37fed5 100644 --- a/ScreenPlayWallpaper/qml/MultimediaWebView.qml +++ b/ScreenPlayWallpaper/qml/MultimediaWebView.qml @@ -9,8 +9,6 @@ import ScreenPlayWallpaper Item { id: root - signal requestFadeIn - function getSetVideoCommand() { // TODO 30: // Currently wont work. Commit anyways til QtCreator and Qt work with js template literals @@ -48,7 +46,7 @@ Item { onLoadProgressChanged: { if (loadProgress === 100) { webView.runJavaScript(root.getSetVideoCommand(), function (result) { - requestFadeIn(); + Wallpaper.requestFadeIn(); }); } } diff --git a/ScreenPlayWallpaper/qml/Test.qml b/ScreenPlayWallpaper/qml/Test.qml index 97f4c78f..548e3d56 100644 --- a/ScreenPlayWallpaper/qml/Test.qml +++ b/ScreenPlayWallpaper/qml/Test.qml @@ -19,13 +19,11 @@ Rectangle { //Image property real imgOpacity: 0.75 - signal requestFadeIn - anchors.fill: parent color: Material.color(Material.Grey, Material.Shade800) border.width: 10 border.color: "orange" - Component.onCompleted: root.requestFadeIn() + Component.onCompleted: Wallpaper.requestFadeIn(); MouseArea { diff --git a/ScreenPlayWallpaper/qml/Wallpaper.qml b/ScreenPlayWallpaper/qml/Wallpaper.qml index 11a7dc1c..cb39d6c3 100644 --- a/ScreenPlayWallpaper/qml/Wallpaper.qml +++ b/ScreenPlayWallpaper/qml/Wallpaper.qml @@ -9,8 +9,9 @@ Rectangle { id: root property bool canFadeByWallpaperFillMode: true + anchors.fill: parent - function init() { + function start() { fadeInImageSetup(); switch (Wallpaper.type) { case InstalledType.VideoWallpaper: @@ -130,19 +131,15 @@ Rectangle { imgCover.opacity = 0; } - anchors.fill: parent - color: { - if (Qt.platform.os !== "windows") - return "black"; - else - return Wallpaper.windowsDesktopProperties.color; - } - - Component.onCompleted: { - init(); - } Connections { + target: Wallpaper + function onQmlStart(){ + root.start() + } + function onFadeIn(){ + root.fadeIn() + } function onQmlExit() { if (canFadeByWallpaperFillMode && Wallpaper.canFade) imgCover.state = "exit"; @@ -180,23 +177,31 @@ Rectangle { loader.source = "qrc:/qml/ScreenPlayWallpaper/qml/MultimediaView.qml"; } - target: Wallpaper } - Loader { id: loader anchors.fill: parent // QML Engine deadlocks in 5.15.2 when a loader cannot load - // an item. QApplication::quit(); waits for the destruction forever. + // an item. QGuiApplication::quit(); waits for the destruction forever. //asynchronous: true onStatusChanged: { if (loader.status === Loader.Ready) { - if (loader.item.ready) + if(Wallpaper.type === InstalledType.QMLWallpaper) { root.fadeIn(); + } } if (loader.status === Loader.Error) { - loader.source = ""; - imgCover.state = "exit"; + print("ScreenPlayWallpaper encountered an error and will be terminated.") + // Must be callLater so we do not kill on startup + // See emit window.qmlStart(); + Qt.callLater(function(){ + loader.source = "" + Qt.callLater(function(){ + Wallpaper.terminate() + }) + }) + + } } } @@ -316,21 +321,6 @@ Rectangle { font.pointSize: 14 } - Text { - text: "sdk.type " + Wallpaper.sdk.type - font.pointSize: 14 - } - - Text { - text: "sdk.isConnected " + Wallpaper.sdk.isConnected - font.pointSize: 14 - } - - Text { - text: "sdk.appID " + Wallpaper.sdk.appID - font.pointSize: 14 - } - Text { text: "canFadeByWallpaperFillMode " + canFadeByWallpaperFillMode font.pointSize: 14 diff --git a/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml b/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml index d5bd76f4..41ab1be0 100644 --- a/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml +++ b/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml @@ -7,8 +7,6 @@ Item { property string url - signal requestFadeIn - Component.onCompleted: { WebEngine.settings.localContentCanAccessFileUrls = true; WebEngine.settings.localContentCanAccessRemoteUrls = true; @@ -27,8 +25,8 @@ Item { url: Qt.resolvedUrl(root.url) onJavaScriptConsoleMessage: print(lineNumber, message) onLoadProgressChanged: { - if ((loadProgress === 100)) - root.requestFadeIn(); + if (loadProgress === 100) + Wallpaper.requestFadeIn(); } } } diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index 7295ff65..455a6c38 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -6,7 +6,6 @@ #include - /*! \module ScreenPlayWallpaper \title ScreenPlayWallpaper @@ -178,6 +177,15 @@ void BaseWindow::replaceWallpaper( emit reloadGIF(oldType); } + +/*! + \brief QML Convenience function for global fade in + */ +void BaseWindow::requestFadeIn() +{ + emit fadeIn(); +} + /*! \brief Used for loading shader. Loading shader relative to the qml file will be available in Qt 6 */ @@ -233,5 +241,5 @@ void BaseWindow::setVideoCodec(ScreenPlay::VideoCodec::VideoCodec newVideoCodec) if (m_videoCodec == newVideoCodec) return; m_videoCodec = newVideoCodec; - emit videoCodecChanged(); + emit videoCodecChanged(newVideoCodec); } diff --git a/ScreenPlayWallpaper/src/basewindow.h b/ScreenPlayWallpaper/src/basewindow.h index e701f76e..97ad3c3f 100644 --- a/ScreenPlayWallpaper/src/basewindow.h +++ b/ScreenPlayWallpaper/src/basewindow.h @@ -2,7 +2,6 @@ #pragma once - #include #include #include @@ -87,7 +86,9 @@ public: void setVideoCodec(ScreenPlay::VideoCodec::VideoCodec newVideoCodec); signals: + void qmlStart(); void qmlExit(); + void fadeIn(); void reloadQML(const ScreenPlay::InstalledType::InstalledType oldType); void reloadVideo(const ScreenPlay::InstalledType::InstalledType oldType); void reloadGIF(const ScreenPlay::InstalledType::InstalledType oldType); @@ -114,10 +115,12 @@ signals: void projectPathChanged(const QString& rojectPath); void projectSourceFileChanged(const QString& projectSourceFile); void projectSourceFileAbsoluteChanged(const QUrl& rojectSourceFileAbsolute); - void videoCodecChanged(); + void videoCodecChanged(ScreenPlay::VideoCodec::VideoCodec codec); public slots: + void requestFadeIn(); virtual void destroyThis() { } + virtual void terminate() { } virtual void setVisible(bool show) { Q_UNUSED(show) } virtual void messageReceived(QString key, QString value) final; virtual void clearComponentCache() { } diff --git a/ScreenPlayWallpaper/src/linuxx11window.cpp b/ScreenPlayWallpaper/src/linuxx11window.cpp index a7c586ad..a72917c7 100644 --- a/ScreenPlayWallpaper/src/linuxx11window.cpp +++ b/ScreenPlayWallpaper/src/linuxx11window.cpp @@ -136,3 +136,8 @@ void LinuxX11Window::destroyThis() { QCoreApplication::quit(); } + +void LinuxX11Window::terminate() +{ + QCoreApplication::quit(); +} diff --git a/ScreenPlayWallpaper/src/linuxx11window.h b/ScreenPlayWallpaper/src/linuxx11window.h index 25261e51..26e151dc 100644 --- a/ScreenPlayWallpaper/src/linuxx11window.h +++ b/ScreenPlayWallpaper/src/linuxx11window.h @@ -2,7 +2,6 @@ #pragma once - #include #include #include @@ -26,6 +25,7 @@ signals: public slots: void setVisible(bool show) override; void destroyThis() override; + void terminate() override; private: QQuickView m_window; diff --git a/ScreenPlayWallpaper/src/macbridge.h b/ScreenPlayWallpaper/src/macbridge.h index c2b3d03b..43623938 100644 --- a/ScreenPlayWallpaper/src/macbridge.h +++ b/ScreenPlayWallpaper/src/macbridge.h @@ -2,8 +2,6 @@ #pragma once - - class MacBridge : public QObject { Q_OBJECT diff --git a/ScreenPlayWallpaper/src/macwindow.h b/ScreenPlayWallpaper/src/macwindow.h index 05b9f073..796fd01a 100644 --- a/ScreenPlayWallpaper/src/macwindow.h +++ b/ScreenPlayWallpaper/src/macwindow.h @@ -2,7 +2,6 @@ #pragma once - #include #include #include @@ -26,7 +25,7 @@ signals: public slots: void setVisible(bool show) override; void destroyThis() override; - void terminate(); + void terminate() override; void clearComponentCache() override; private: diff --git a/ScreenPlayWallpaper/src/winwindow.h b/ScreenPlayWallpaper/src/winwindow.h index e5035a77..522ffcb0 100644 --- a/ScreenPlayWallpaper/src/winwindow.h +++ b/ScreenPlayWallpaper/src/winwindow.h @@ -2,7 +2,6 @@ #pragma once - #include #include #include @@ -33,7 +32,7 @@ public: public slots: void setVisible(bool show) override; void destroyThis() override; - void terminate(); + void terminate() override; void clearComponentCache() override; void setWindowsDesktopProperties(WindowsDesktopProperties* windowsDesktopProperties) diff --git a/ScreenPlayWidget/main.cpp b/ScreenPlayWidget/main.cpp index 8469bc14..49f9590a 100644 --- a/ScreenPlayWidget/main.cpp +++ b/ScreenPlayWidget/main.cpp @@ -1,9 +1,9 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only +#include #include #include #include -#include #include "src/widgetwindow.h" diff --git a/ScreenPlayWidget/src/widgetwindow.h b/ScreenPlayWidget/src/widgetwindow.h index fd6385c6..48b13d85 100644 --- a/ScreenPlayWidget/src/widgetwindow.h +++ b/ScreenPlayWidget/src/widgetwindow.h @@ -2,7 +2,6 @@ #pragma once - #include #include #include From 13959b39cf8e81b9532c47826af1e048109a125d Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 17:07:44 +0100 Subject: [PATCH 48/56] Fix still using old FolderDialog labs api --- ScreenPlay/qml/Settings/Settings.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ScreenPlay/qml/Settings/Settings.qml b/ScreenPlay/qml/Settings/Settings.qml index 1a004631..2fbf8e91 100644 --- a/ScreenPlay/qml/Settings/Settings.qml +++ b/ScreenPlay/qml/Settings/Settings.qml @@ -1,4 +1,5 @@ import QtQuick +import QtQuick.Dialogs import QtQuick.Controls import QtQuick.Controls.Material import QtQuick.Layouts @@ -118,7 +119,7 @@ Item { FolderDialog { id: folderDialogSaveLocation - folder: App.globalVariables.localStoragePath + currentFolder : App.globalVariables.localStoragePath onAccepted: { App.settings.setLocalStoragePath(folderDialogSaveLocation.currentFolder); } From 46391d1e5d3e3adbb8eb5179406c67029293178c Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Fri, 3 Feb 2023 17:55:22 +0100 Subject: [PATCH 49/56] Fix osx compilation --- ScreenPlayWallpaper/src/macbridge.h | 2 ++ ScreenPlayWallpaper/src/macintegration.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ScreenPlayWallpaper/src/macbridge.h b/ScreenPlayWallpaper/src/macbridge.h index 43623938..206249dc 100644 --- a/ScreenPlayWallpaper/src/macbridge.h +++ b/ScreenPlayWallpaper/src/macbridge.h @@ -1,6 +1,8 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only #pragma once +#include +#include class MacBridge : public QObject { Q_OBJECT diff --git a/ScreenPlayWallpaper/src/macintegration.h b/ScreenPlayWallpaper/src/macintegration.h index 416507fd..2cdba419 100644 --- a/ScreenPlayWallpaper/src/macintegration.h +++ b/ScreenPlayWallpaper/src/macintegration.h @@ -2,6 +2,8 @@ #pragma once +#include +#include class MacIntegration : public QObject { Q_OBJECT public: From df33695e7d1b28620a53acf36c2b3ccb75877751 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 4 Feb 2023 10:51:16 +0100 Subject: [PATCH 50/56] Add osx close icon and remove hardcoded size --- ScreenPlay/CMakeLists.txt | 1 + ScreenPlay/assets/images/trayIcon_osx.png | Bin 0 -> 17404 bytes ScreenPlay/qml/Navigation/ExitPopup.qml | 19 +++++++++++++------ 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 ScreenPlay/assets/images/trayIcon_osx.png diff --git a/ScreenPlay/CMakeLists.txt b/ScreenPlay/CMakeLists.txt index ceb62fa2..c0ba4911 100644 --- a/ScreenPlay/CMakeLists.txt +++ b/ScreenPlay/CMakeLists.txt @@ -191,6 +191,7 @@ set(RESOURCES assets/images/scale_window_indicator.png assets/images/steam_offline.png assets/images/trayIcon_windows.png + assets/images/trayIcon_osx.png assets/images/Window.svg assets/licenses/Apache2.txt assets/licenses/OFL.txt diff --git a/ScreenPlay/assets/images/trayIcon_osx.png b/ScreenPlay/assets/images/trayIcon_osx.png new file mode 100644 index 0000000000000000000000000000000000000000..9cace2e070e0e10d64e473d2f127da6a470782d0 GIT binary patch literal 17404 zcmafa1AL^-((i;DYh&BCZQIGlwr$(lcw^g6Hny#e?QF8~o%cQGJLl8AcYeQT=IQ=d zS65eeRaavo73C%1VX$EU006v{q^L6R_YwF+LV*Im6Tp?D0RZq8OI1x5O*vU^V|!bA zLlb)=Q+f|u2Otgr@CtZ17#drfx)2(fnp@iO5np%q5))dQ@DXdU$uY_~h?rVfN_sh& zs(8t(8hcqAbD0ne@Wb$Wa040Gnz|Sgdf3|7IdgmP5&zAX8~FZLHUlx?-y|;9e8ie^ zii9HePNsxx^lbEu#QZRXyiO)&+{&Wj|11nl@ey0NxHxb#Fu1$B)4Q|K+dG*vFmZ8l zF)%VSFf-EuDd?O%?OY5!=Kgb;{>|N}gE$kis)qwv}#lPVH zQ4pxU|GkKZp~L@1EGPH>CbzZyFU@dv5px47;-5RZo|BdkxbFnip{TtHyU!lL0&8=wZVQQl(YH4d~=M3cf@9O@IYW*klKcxH{6|uLm zcTxckZBwB5f7kY}zTo~Fle0GgLM;Cck`fV7bh0LQ~zx2*W?BHZ? z;%aPa@^|GxcK<+~?af@=4V_Gd%z>TEM=WG!W(n*ePeP#iSeo0JIuSC{Gt&P<75^&Z zZejYD#{aLaWB8|R41d|(e+b9R@IS=o{hQ!F87i>cKk|SM0O&~={^d%5iGMjGQ#+ss zass-V{AG;+001P=64){SqeB1y%0$=1b{P>Nr0`x`6a``nLqlXy6*3eOa9dhp{U7L3 z;DzjCEa3_JxB5X5)do0WFDlV?%y!iPwzMF`ukYM-0E%MIDHXmzYG z@st(nNV%xF`gCRF_OR~Mr>hM&<#iIturNEBUR^&K$V;i;OdHUlV}qLYR#Pi>J>Y39 z>1b#fN;$HqsC%E7zRhQjPKA;^Mz|M#H3}l6FTpfU0f50x;Pyr5`DrOp>^vn4$mlzv zWvDIBY7&WMg5oPhEAtUCQF#fAhp{z&`oC6Ce0fhjs}{2GV2)|!cd!v^H^Iyc4^!d? z-5}9DsCa$`!}P-FR$cOX>Td@zPgkSs0Xxo`{rzLOX*J&DYb$y3jTfk`(n(v`(UA0v z-xF6)_-KdE657R8pw2W;dJl-LgZZh*T}LHw&VY81)N%#@5C;ExKvHQCZ~y>8fRw0^ zsz>%^x4VnUm@9$Lc_>0H*er-3$?+K1%#}@cM(k!ES$j+g>G-@fG1)?kjZ~WDr|~PU z&Yk(%$Hh#6fQl}?MgeBJwq0DZGbH3!5IDwQT<-9d>+U-O2AA&HSi2t}4{*os4rVXi z8oTOC)jF+qTNT0t_YEo#&nNhS@Ndmuo$_e{0iMRsPmaJKkm?l%h?wgQ@)lDap zUjT*HG zX0hpLz;GHML@4RuA|$fF03fJ_zmnEWgL584JAtAE{Q>9$@aEy+XK}ioTCwIPIE#%^ z#v(yhF?N%=gi4boM~cd#f>RtjIne_QG}9=xnTA%%*!;;F2Piolh~zwsV<{IngBHmZ z$%2VMMF$#d-)DM#-qzBW?Kb5%G-(aFAcav0i(0DcN3ogGOpebhlSqxARairjQYq?+ zX#tAG9!&e8o40TsQ4mVcVKNh-n&YH0NmT=*%p0O5SE0HY9k-gPvS&zFzuRziW6gAUy6!lB3Wp zSLrm{8ME?kEVmb|6a1j0&bwJa+hGQaDWw=TH!mTTYKVvi0T6*BP-yJT4>QwJwYij6 z5V(-AjCVglSUvK;&i6mfUuGab{vD4dZ;&6LdZeXsI9(_OH5KhR#5N=@rafU&CG)47}er= z%9;c<|K*d3ySI$568yfOmplWl7MYITyp0PgEA&sxvJXXLhX6? zD_p~Snm7bAZR(D9q^r(>5u43w`jHq9tLRdegz?`U! zvuyLD; z^3PlO{@jg?#MAh3?@e>sBSKoUAuU8u^W5k~q5?ms``v1VYZlNFg%@J-*%r^}Ravz7 z_Z>K?GVQMQhs@{kXw>UzJ3Wts!wd$3-+jn)3YUJAl`$kv9^dJx$&8sbCf>L(BbQ<= zn>E(1)uk4c-BTbap>~_DkW@|4L#@e@N2H*fy;!HQpEc_EDtF3 zw4EnXP-P~mk@(j=zH@wBofWgdPhI9(^-A4nF*1OWTbwnbFBmBk3mA(vk{XiXB0o=j zxA}0IMq905A!dwYM^7gk6=O56#wq;klbrmCO*5DI1zoC#Cmuy~= z-`&mUA%YY_hsY~Emnj_2r`EGvqsC_*N4CeL&`dB|F~im_k7o{a%T1i50td8~CYn{u z?TNR?znqv!HNlt1YgyD$EtI0GMvLlqJ13Jgt0A8$K>G;q5@Lf$z_-yf&%gl*9!Sc4 zGk}$lb~8b^GCmP?w}@<{gr(TU!Ld1f5CflktDQtJ0#>$G{+koO&|aZ>ebrac-*QtL z-V8BY?Q~FD1vON&t%=!H>wF2?^rXqd%vCc4Z5~Glt2sn~I-czF){6)ASFf48n#V7N zyBWjF2w`e!CZg!!HW}G!qMukQsCt)(MsTbHgN2EjtTALvi>pD%*#dr0N~%wp@ThX$ z-Tb}1>Pe(avL+U$0GjE!2uZSJ+5v9dY@y9HJb9@kQYqG^YAeurswY4n(tRE7b#m7a zHQI40Vm2w$j?$JIb+UFvaoc&pH2%6f`BY4(7*oPR9V;r)U}RraNWxhgHOXo4zyf1~ z7$(3F;S9CxM&J>k-sleuVbom{(Q+^r$1DQZ585)dNcb=}<(}~g!#ftsFi=(|er|5w z6scmyG(jeQnr~E5Fw2Wvdi13eu>td%a;M~j9#kuQkfF8E;$Lh%$}8=g*6;!XOtlo$ z*u<1}Gs>;g864@|Rdg_vU)aP0WEZ}mJ|^rk_(Vr@@)6DD;q?n} z0Zgq>*>EPz2Io1bkKy$P*;4NBRau(RhIFG-)bOBvB~NF9W>~9l(~7iH_}{JVU^`)j z&m@?ous4D+Nwei5+_#4`K4}!?9fvs9hPxx2D1S#V87xspJXBI+Rp_i(`w=rZBQ>BTgbdn3;LO zu9g()lJfqhMT`@6b~d-LRbX=vz~T&zP*r6G07xPgC*F18?r&&WI&U?QdO4ZOV}xt; zdS@R$8T~OT$daBc4F*s|eZS-QIO+7i&FTG!_J8j)R`B)>Ow12tkr2Sg!-rc8L%GGY zZX^kT;s7a}CJ83eKXWGeIaWy8av&@l0d}sR3Ts0dOnf)l4pycXK+CBk^A#D{c|BFQ zzN(bCIa0O1CJSf0aut)57HFA7eMUBl7yhvw?<$!DgMEY{-xt|-hd)u68)Zi{5-PEX zq{q=>C;J%(508pSEur=^J7&Y^HYi3$rtt-&iC#j}d#MexrOEAeyM0aypU8*BJJoCK zPEV44Yp4y7AAV&LFV9F6VG<^UAEo z8}8$3sHf&al~)dn-&_s)T5sXurTh~U1Vzm9G7S&&7tmef4SP%tU!saRajAz!E7@dx zIWy3E=lERme><5X@V_~V7bBWz=gXm4c@B0xR=_QwJiDFo$zT5_a)Z!v-~?$2R!)Vg zp68sDc|oVm`qQMOo|H+7qvESJ)`O32i4aa|bii;+R6GnQzy#A`X%3Hwl)n&;wSe;xRVyNhag~UT)B!F9aI`d~A-l zlVjVk=B-!T_qROu@-eZZKO0%)IGS4oJ|L;XP>`>u-zTn%s)>C zE(IJx_=q-Ct;0EiQhSg3s^~W-??e`mLV?OHr1-;ntk;vCoQk6k1x$q_qks$PW3GT_ zQ1iO3L#Y?H6*+P#5mSutJ%!eSTZE48%*ElS=(61TJocrp9}Yx&G9@C;^tTCZvu+IWG}Rxlzl?H(oa< zP~{Y2w$ntRHR&o`gGMi8t*03%8XwS#$EkuXF=hKBvFS3|36%r!Vesk2)7A_{9MWoO3X^DnS`jk6+PEUzf1w$-x*F6Mq9 z;E`t@@{>==%5iaBNneu@W&K`RT;yQq(X%V?r!fvHl7O-ivNj_;CG`KCCnSZGh)T-5$lv`zU{bd@zW@Sd_PR9h=v(t{i;eu<4$1+`dV zoDz!-orBzD6b|R0eIDWEt}<5fyL&Z0-MFGIg9Paewo^I;;*2>(X^H4h3MvY(rOcKM z8`u6btJ>0XBL`8MEAtpBK$QQ6F?M!ad z;8{zjOrmnk^HrHcWU*%=nK<}Bri3|HsqviHw;DuQS#VXzSxqgrpTtYqlY^t$cJWj2#KsGL8<$^~vpo9(@ZHRBA2qo^wzf;14Weni0 zB#A+PakAR1sKzb-CV0uhb?;k4b9g4VBM z3@g_OPH1xV_m~z)@|0mjm{U<=YRXy71N_M@h{~i>c70gR-41fx0s?7WtqFGI`=c{Y??O?#jQ?BnvyMxko;R z(OHOn($G@Apw7l^{B_OUH**HKcbHSn^_i%C5A-dZg z??!0ShKfP6x?E`a1yHj(f?F8?!<_k`Srcey}7SwPjzBP33|g{GOXhn>Qva8-vGtbDAF<4o*~QAqQ)r z5)yTjPtPVdy*qEA4M){;K^q6+EPs_ag71G+|iYsC9e%aXhXBJq#$K-PmBus5IkQFtwSX2@>RAE6IA0+_>ZD27l(y#k7Ahuuzx((G9|7<4d4U)|{sHu$tp`#4+Wb2;D) z05{J*JZ@L>EiY(+WTst*1`l_~QVX))5-XW()@crJROs$l(Z-a9xGCvvT~Eo{1>mpwNf+CgzMI%TEY zy81AjkMOLeq+>x(-XtrJ@~n2CqrPf5HDjW5e^*zu-WuUGaEu$@LQtKg67dXR%FV_l zz{cM5>;ZnNtGh2m%*m76eZ4)5d^WEUU0htg#~laXRfuEmk44`0_Y3(GjyA;X5IA)5 zLFEU2;IxK^6L=jkIj1zBt~S9MtvS@zx1BwJVW*=Cm?DAi-sFQx#N$>xK3}-K^4NE; zEp_ije|w1<*rmkqY;0t)e?Oa=OXTS{aIo>&ymWd$;`pc^*=K{G#Yu+^a=6_KB?(7R z)6g(y&X6U)A2p7@-fZ@^vN{`%JvT%D2GFQ@sTn&p^~`Vh!^eh=1EX@W8?8~Jdv)2~ z=KqxuR&>eEbL^yq3ISNNVNaAaY3!Of zbmGiL6)RSz0w4|9P^UV!bCxEPj0E;fq&I4PSbzJhetCHTN)deRUwgbaw1s$uEXI@} zd$UG6(I8)%Y^a%g3?bBqS*lWQm4^tRKpCUWt6#gsJx+?h-)G4XWhR0Nnz(f1%!bOB zC8q<%l2NBF>$?u)%gUK%%QfGgo*8_!l8R)~>2U?znyRb$GS z6e(4Ax}DG_8UTtqI#07C@wvQ?J|ok5=JI(L*S%woHRa`0r31GIDl<(j%`! z$J0asf{cHD<%VZvW$pYKQh*SWEmev12x_ip@V}j4V{6u?XO&}tOO_q{8X2->_qi_c z0xy^_Wmc=(?sIUH??P?bxYla7(c-v}_LU;;_oJ>8CobU6GsZXUcIVfV#DQ|v`O^b@ zuRn8WG#b#tkHJqn?Vj(DVk-Ta>myHBwbj+{e+Hf;BqWf9>n%`~P7WD-hprK=+Eq}O z7FTVI*G!nppHUa#{X{c7O1P2cfUSDsI}u< z|G86_kDD*G`dtow*F6+X;2Rqo;bC@o+#ZCQDk=mOwUxECwf5h0bGe;g7SEQf+3hx2 z8D|ApSr=1f4d5CZ8}t01qvhnL5+(m^uCY|ASL=7$y*~qM$mPd^S=woHyc}*m&+~qc zrnTnr`ZF78ERpB;$OT6T_4BI&|KxgrEE5$Fw<O~h^Sh1zZzXE2Lm-R7VxN>xzW$qUjQ2~-ktV~RPdw-OK zkVxhnyd}~FkT7v@Ql(%ZgMi9zg@oL%*Cfu6G-q~obzS2B{3YnGS60*7YQFJ^*PyO0 zszdnhd<)kZp`!8|SGsUtpGrCPfP&=+A6*)oQ&z`o0z7N#%Bj7yv=n75WXdl6+{oa^ z&TgIeCO$w^DQaIpY(X;#5KI|`DtzjK4XE(#IZ8v1a|Q{RG7|wh9#%Qnf&>!0{nJyb zDBzaadY9#W+ReoU!_J@QjD^yc>&;MrQUoXrWa{bdx4+}jlGM9&0!v~a9bYzqssIN0$!XV{w${DXZH@!dJ z)=EmuJSlL03NB2Jr&iMIbMCCKqeqIXSLtf$qG4y%qZYyphb?%}3Tyh3`R?AEh*{o} z!6{F}foQrN(d^mROf#Cp6bq772?jg|nywuk9RUSC+|CsxrZ;Kiu+!!7zuJsKqsft{ zfaK){ZYR0WpvUTW&mZ4EW2RYJS{q}QG&VZF#^uOO(YbXF3}?~>aKj-W06m_Gjg2ZQ z#9A+KL#cH_Zs8#oXJ!9(HTHZ(9#;T6{@6r7c=XckOK`uU??4M)CwFJZ7CyrOBi$5T zQpie`POIG`8vR;!Dfo1<6h1aPn;gzxwBA-cP|vcx!r z*qCd$6C(@w92l6Jr>FK)2pmzkGxn21aE=c$X!>gXSj%vt+<`S~7yAxkA%8fe;pr`* z!HL`BRb2ad1fN+_Sa0F1GV!R_2|^TA;E^lfdM8SqAziwF$p3&eu@3z3aCdI|KG}9| z1tL{xH)oo`WZ)qQ!^6k6LVnryJ_hFJ?y^ATf`4I%_iwhb{? zO-6Y;y-rJKu*Wm{SC@&T_083IL{XayQOYf7C+B^c=S}W8 zIXU47_#XQh0>+r)_m6I!TXb~Q=F{09u{&?#bH6pn58@;kdo(^MGK#;$gTX3=MCy*u zDU5%y<*7FO=4$AG+iH5=lD6EkmVu>&+NGw(#>S>^ug07K9&mJ&MyJzCw&xh`u4`i-`VSaF`2DT#D;EVt)~egpdaP^ukPxNn=c@6mnOVvHZQI0Q zMMVt)q%~#KdYz#$rD~ou#ig4BqvrlWTWl74wRX35+@S*}huymF&g^&j;tMx#Am-wP zd+Y^_3xS3Ou5{zo4dS0rl9AJi|ASJy1?01KUZcIRxEX|` z-EQUT+RTt6?~E&<)HHDk2?$Bp+AXWD)WQE;{n@2RT*~;AB7{3>OO z3jm;sB_=C`4-nB*9mvG5oIiR5IAl~+E+7nq2@;yuB?~E~2q4`&zbBCH+lE-YwPWh0-)*PLAd%?#^0a(T&BTl_Uz-ISP?|x`-^NC=MIm-BbM=yf+qIXc07O6N{#}Gm{yOH<^UM}i9=1dHKS7lPS zw9QYqL2vV5R*^DvyyA{nv4iFkmnls&^TG1r*`aOsL8IcPZHEUxYQ?yzV=gV&cmtggRrBt6 z)v0B;fYX`y{`ERG4KERi6b;=$R3;yZ3yVNQX8c@+B;1Sf9wS(kMR}@|k zj}LDT6av_I?bY3h?#?~0k2-UbgUo9*jP-p00G`TUcL9LG-|YxNOxz|_br*HbgC2gn zbNKOdfB#2fVxsct%zZ1=7fg)MS7o0$Ln<+trOv=PPkt6Ae!s>~GxFrLouY;EMss-z z6lkf2o-cyHsj}uO{H5}0oJANc9GpqMcaji$Unl}Bd$J^@MK&e8`tF$^^74V$Y*qR zG9_q|5dG(Odv-RC?uT}U3;(_H^OYLi)AOy)>qz_exz-$nV;=j@s7WI;FKMI@hOW0_ z4ZrKGF_XKyL;X`bPP1ElK(U>4+D6S_u^e1+Xsf)DpZ^e8;PDhvQI_gN=+&pAbMV8`moV+gQtMw#Fr0u#_nzT`l zB9O$Bx7k;Nj!@y=2T-Y)&@Va3{-??$Nh; zo0y3D#xoArd%ziAR99G8*lfP{?H^ds>6%*FdMxxna4i&&S^cz)9~5Xn$m+&RDx8CLecoUu5`=<$7YlFP-3 zQs)+WtXMD`n{+OkviTFeMHqd&5*a}>1Iqca6nd7(^IITr$kChmG_BbL8q{@Ete;m` z+^JXVwQgTNDxzLi-z_hP^5Wa8siDcSWKS%08;QxtSnE-WDy7UE?{jLns=1077tS1; zV}_Y#04JH|^JQzDJ!E0})`|05X1K3#%P#J<7It>!HII(C8sBz)-FgAn-YqT5myaoh zc4=Rr^85P(WiS{{b~3qdiN{{v(hZ3^V|kOEh{kVuHM=I)w6=_*f%EX^fx>6ks1ET_ zcAj*SNsmrU+difttzpc4PPH-C`!+yK=?nk+$?p}vAKunRjst#|4MhIM+cIvBl*z}+ zM4ET>TAffzX9)X7g*!B5im-Fts{7CC95jtb*Ll4s?(Hf+Y#eKQ~#SHU$-y-kD zLeaC8!!TknJhYzpnhAFKkAlZh_xcRhnqYra9ZUw#I8QL5J2L%*(y0`|jFDJGOV2rr z4jPjvgUc~lgVq#RwOGU2BbPCy^2aY9)%i^e!SxgB_;TBM^CpLbrkI=Qgk4$90_}7C zhwzkW%&^JR74cxVc8#=1Xw-M_u>zy^nO%OrEk}m>KW{mf*T#v8&=viBEf0-^Ap^S( z9%-gnnTEXh@jizG%0^aB%-GS(D=Q<$x2LCLsWcjeotEWglnMjIBi)00u+3$gZGM** zYYXh*cpy+(hC>ypi2Q$Ul<8aIAdb*nw?#pn}YxZ5d!+M z!)>DrB7kwc?DPuqz74yKQi`cA-1nIq_AIA%1$LUE1uUtg1}&mgdAgZP&nH~Wc5EfA zIO6dg!XdKGU&!zvlISTZ%9Io%V;mxji;KDZt_`1N{A3u?l?e8G?+X_ir=)kNf?B zAn6m$)=$AYt+o`tsxS0UJ~tn)<*Lk@D)*y>@vg4bnwq!Q1K24}IJ2M-!+ex>4x}i% zoX5ZV1c?*>+-dYa{@L~gE{h28J3^U&{0j&HfWNjG&6rQ?>+5@Zw()q}KDMtv1CyQg zI^D!jLtFiRPiWFU0vF#Sh*zE`dqej?w{BT}?{l;OmUpq<{o3k(oZ8VbJ4X`k$=~P` zN{6UuI>`X9*rFHMC7$emTACnTu_?eRP~9w8Bz%fY!+)d*mFQc8S}`mxA)m`R%y=Q_ zFCc8O^#X6#T3T4ilOw&ZnMEmGt~x%C2&p8AT6}wZJ6v*9n)e*DW%nf@S0){QrsKip`RR;mPxKw}=) z@5WCt1(E5pzPZlTO*0S~n|qZN(Z~E~JUyek%H@lblQ9FkC;D^Ue(&V18_w_ROYs69 ziYQ`H1?FZYY+h_igs`ECWqvDHTcz^3e{Od^t2Zt^FK&HZn_V+xk0#4iG+tjwrBKA` z8yjVM_Pzj=%MY?XZ-!4!A{NFX3nbGmjmH}bDAf#3^$s(#waoiFqKZRDJ2opyyX@?n z3^4_dY%N18M~oDl5>4lYfhU~&ccX>t&lJ2fPY=2k)z!X_EDW-8@?B5cJOIH3VC=hl zBP(KT%$yh@PVAbmn0DNqTXCHGX+xgu_gc*{lLs6%#{%c~ulTEt=KI5PL4@Lk$kSt% z9e*x2T3_j(-aj~c)$}g^iuN;DN~4LJ3Y7A3_@JnIZk{_2U6skmWYkf_AzRalS@WMS z`Y3vFo*qaJ?w{@85wdx_&D`9~+{_>WnpxGw#lJV(8&6%xadTruNdSyExqO~`-v@Rd zUf)s0mXFqcR4Jv_j6SX<3Q{azLE!n1y+7y3_Ehng zU{rT|mnR0+NxIVLfFTsiTx;h3zMTYfYqP*|Qq$B6-xQ3epf^GTI>xKV9&Z9z5NAYN z$;uEtfhQ$L1HhH?@aQo|G{%XIGlA(~1I-?w?_gQ6&TvjNJQUa7c-PjHZ)>qvv;?Dr zX1yvKVNtFuv^uQO@^OIY!&-?xv$z4%^!AQpU<(vGpqLaR7Dq4R9e$yDJEf*ywhYQ# z+qM#pe0gx{yD?S+VHGdZ@sUI2Z<(C6&1?%Mgjf}-$KM}{{+soZrOaC!NFbt-(lU&A zM=$$vJ9>_#TUp8i>K38O*c-Gvcua>P$Om~@k1?dSPtV@F5wMHl?w}KLLz_RYyjsYW z!1v|NHT65fqq?fvlA9Pfpq+!2oDn zAB6i`>gLKChqw1y8(A|WVEI~;$Etqo*`fyRc-58o6Tgo&YxXQ&uxjrNE_r+x74P86 zz=FPy)|;B**YRzJ2av{)K;JIQhG96SCi}H*INS32y7KC6U%;{a9#6q_FQ2P}icjWE zxFgU#Xi#CWx$||4-Z3s@9EOu2=)iu@%ZpPOf^aqfzrpDYCipFmuoGi%dDI~?-O3PV zp46TopZ4%yEaW-T7yR?B=SQ6#av@ zxbNZadM^)`o*Ozw{q!%j?ZF8Ma(C^l25*(M6SGCVBU{#{81YHRX6NcC2>NHZYGM(A z&CBQI?b$xj7yrEPQN_jK9lX7-ntI|1A9vkM@i|G1ab~1|8y-ucpSLj&I|8_!Y&o~< z<=vGP_}YivOqm@H60*?Jc03z;{%ryeXZd3awPHG8j|`VkyuD-Yw!CN)lDN^C6}DJH z*f8cykUX(n2;4MA1QH4qL%>rM2bY}m9Jz=>ro&}37@+`TPLwr$fOz9@V`m`cIkfh9&1)qlxWs2M* z(wM3?7(d#S2_QpKn#Xi<8YK;xpFL7B?Y`8vTf!msa~?DbNlV@W>UvJPs7T6K6lT>*HW)cE^Dl9%D>E}o_PBrx8`)PXQGhN zMtHd9>~AP6*IFNl#(3LPd~RjAt1okX46($XR*8bVErlDiLe%nVZydCiHqJjG%J+Er zjEfg`S9a}e;@ov+WVGFA5X9iOp}!6XvmsVL5W|F4tVUWqzJ`2m~Qpsod#N8!FMG8c7LVVCBzN*d=E1(3p_D=aTr;?}tZdZZ4>HIF9 zS8Y$~=}Sx}i3u=E`uWOd*c*L{z{PEaH|00vHH+ue1b%@U6icUD7RASg>3{roF;&0# z$;Ie*>!vJovuMDZg!DOpq4RNfPZwYNppTaRO^YGqZ z=qkj~S-pj(5WVy6qKi~ye+eHL@-eYNvLdeR{~^4vY*tgbd^?k86G1xkdE2iUh4J}k z?8U6Nn$BRSwWhV=n2bGmq4Nq;->fvm|9#m`hQ>U5E$EKk`HzZaa1yH5VI!%il+ahiks zKl7QA)Z(Bg^a_g~ROG$H2If>>WZ)Id=ht*$3Jr4$5+-t2wBW&HheHF$WHq`Q-C6l^ zMo;(NRWdL>&r^52o329XK57M27X)%Y6zt<46in4QxO?3#-Xu!RnL)2QlYe4j`?O>w zXMFlP?2S(SfyJrZ2zp$JmnUod)15nd>;_42a;KXo$?>uVra>~7vdWR<=c(~yc#05w zf$3wXmuH+1N^On5aqZZh1yI+%_WM|Y!vwOE{_m>bq8(t_~z@#98tA z3hbPra#za1PzQC^g!~kFUinuRXJkJ@X|;(;`sW8lL*v$a=?weF zz}niW=A$zY*jUWN%r}DU2-x@iQ;gO>pKBkAeN!$gTr-=}LDVgx&@<$r;(3>cmw|r_ zZ%f8?R!W&a3l{DLdglFZw2R0L{EhT}zw#v}gWb~E)-YTnwBfQs+%$g){(OJ0&(FZ+ z(eKE?{Vx4^+6YhZAS#T1lrhy~|9M$`{`GWB@=?cI-6UL$@L|Cx0^|WJEc z+;t}b8AF_W;z1@Xj~;X}RSSOZJQF#lH^0x^aQr#$xi!ltk99LFSJtF%wp8ej3_4r8 zu#&J+7JiKT_km=Mk%dO+`r&~Z%RLkvb%OgzR_>xei=WK7DRovFu>p}TH{R#;#=Hzib z5T{K-A)#`#h_b)iU~h7ur?_8F9LvkifG-{V7?X9c79sytE0Dv{x~cMEp+4b6gXXPpz7y_zIXWaA;QgBysv2~>b_c~yj`RE@ufm+jKT2AF=_^WzS@)qA7lD)Prf&dT8qs+jM~twinT zjhbF%s>k(FmzFMz2nNemSLf68WIObdxM2w6fxF7CSQTB{+e99m^%v_%Op4GhDj7`D zN*_<;cul!qMiA*5qHw!0jsk29M*Irtl=zs0LT#jk0Xeo;RUy6Z4h5>f%_|DI6yo?< zEjLCerHYFIt1o4WIDT5c8ll-?N(YJ29;9s=nL&;JeAH7R?u3=jh$XDP7tS zkmO+sA*8+fvW-H`L@XG0wPI{tEd2t~Awv5Lv3rKmS`Z`yn1Fo7kqFw|&wg{}NKrEU z8gE402&)jG^Qa-CmD+C`4X)wrx^qz8n#hECqwO<$_x%@>57mJncXDJFQ~<$#+zmgZ z@z2tBCAF}5(^v;ipSP1aP1c6Zkj;r-&$8ck4!5_rH!GudzZ}$Yr6x-poD)AVS8;CZ z)#+_AE7hs0!l9zK?GUHaS{t|8@BDSPum0)-H=ta0lbH8Z>`~u`8C{SdP0o-l@N}Q| zL5d#_rYteXTh;jB=6F!Yqn1T9TvGh?J*a}q**2$aUUTz1xmf;DTAJ;K8!H<6-H#U6JC35zAm zbodyYo#Ah)Nec;&qsr3v|>FFYi?g~V&x^ON(?;D1V05GU& zVwi?S*y6AbNYBvyUAp_Ko@%R+4EB|DWv+M1mGzv;!}zWo#fNg-2Q;=&8f3Tg+_07A zorkY*{e)h$?_utu9}M4AB)XR9 zFv{o2^Tu#b?L%2aXCRii5t*d{CNMIPEBN(CE0If}TIdo_Un@gb##H%0?)bdb6$jPk zsKJDgg4*{|Ju#=MlQosW2?;i|4*mqdAZ9+B&8q**K`IN4#d(fQG)}HbG*I$4BM&VI z!x4S6_Os8C+*UojVmwBRUXG_G%dAM`U{q3Pt6OtZgzGN;=^-R1q`CD)tjKuHAXIq) zCL=u-YvAH5j6#K67*v%%>q3Hg*8(=lwTmax zn+GYQkQIe!rhHWBC|qduB@vm3FffURWOSNq)6)k%e*`E=l5}2lp3+()f+!wT4NKWPtp7s6s@ygJW*v ztRqkTB}TXTKKFr2u{p(b79(*Nd8+(_{P)4lIl)Yst|QhblMfsyha9VbHR1dSL)&R?aZg%N-Kq z@qR5VrjyHXfQ-r*ylV_yOGK*0#5d)X=sMw!ATAQ$Vxp~=)<@;$ij%^09Yk7PkfDPx zS&@-0rk$TtsVw*2fpgEpO>Z8e{B&2i*H ze+uD}EQljsf|9E5&cpIyA$KwKlJ|+!EO+=cy7{Bmi^}z9v%a(pSKQH2M#*AcD=(g% z&RZjV@ep;KY4D)pw^~e5Qino~3>YuctMu1}xSHQl(@7KFMU`rPrzx6tdH3|75MA&kUv{KIt$Qad4^X>>6blr;S%TDVk?hWmJTnLlWz-U d+~N}k_`eoQ9ftQ&4G{nU002ovPDHLkV1lMF*tq}z literal 0 HcmV?d00001 diff --git a/ScreenPlay/qml/Navigation/ExitPopup.qml b/ScreenPlay/qml/Navigation/ExitPopup.qml index 60683ad2..a8444180 100644 --- a/ScreenPlay/qml/Navigation/ExitPopup.qml +++ b/ScreenPlay/qml/Navigation/ExitPopup.qml @@ -18,12 +18,11 @@ import Qt5Compat.GraphicalEffects Util.Popup { id: root property ApplicationWindow applicationWindow - contentHeight: 400 - contentWidth: 600 - contentItem: Item { + contentItem: Pane { + background: Item{} + padding:20 + bottomPadding: 10 ColumnLayout { - anchors.margins: 20 - anchors.fill: parent spacing: 20 Text { @@ -39,7 +38,15 @@ Util.Popup { Image { Layout.alignment: Qt.AlignHCenter - source: "qrc:/qml/ScreenPlayApp/assets/images/trayIcon_windows.png" + source: { + if (Qt.platform.os === "windows") { + return "qrc:/qml/ScreenPlayApp/assets/images/trayIcon_windows.png" + } + if (Qt.platform.os === "osx") { + return "qrc:/qml/ScreenPlayApp/assets/images/trayIcon_osx.png" + } + } + fillMode: Image.PreserveAspectFit } From 6501a4c79fa579e0c4dea88492d7bf25e5713d6e Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 4 Feb 2023 11:42:32 +0100 Subject: [PATCH 51/56] Add automatic moc include for faster compile times --- ScreenPlay/src/app.cpp | 2 + ScreenPlay/src/create.cpp | 2 + ScreenPlay/src/createimportvideo.cpp | 2 + ScreenPlay/src/globalvariables.cpp | 2 + ScreenPlay/src/installedlistfilter.cpp | 2 + ScreenPlay/src/installedlistmodel.cpp | 2 + ScreenPlay/src/monitorlistmodel.cpp | 2 + ScreenPlay/src/profilelistmodel.cpp | 2 + ScreenPlay/src/projectsettingslistmodel.cpp | 2 + ScreenPlay/src/screenplaymanager.cpp | 2 + ScreenPlay/src/screenplaywallpaper.cpp | 2 + ScreenPlay/src/screenplaywidget.cpp | 2 + ScreenPlay/src/sdkconnection.cpp | 2 + ScreenPlay/src/settings.cpp | 2 + ScreenPlay/src/util.cpp | 2 + ScreenPlay/src/wizards.cpp | 2 + ScreenPlayShader/src/shaderlibrary.cpp | 2 + ScreenPlaySysInfo/src/cpu.cpp | 2 + ScreenPlaySysInfo/src/gpu.cpp | 2 + ScreenPlaySysInfo/src/ipaddress.cpp | 2 + ScreenPlaySysInfo/src/ram.cpp | 2 + ScreenPlaySysInfo/src/storage.cpp | 2 + ScreenPlaySysInfo/src/sysinfo.cpp | 2 + ScreenPlaySysInfo/src/uptime.cpp | 2 + .../public/ScreenPlayUtil/httpfileserver.cpp | 2 + ScreenPlayWallpaper/main.cpp | 4 +- ScreenPlayWallpaper/src/basewindow.cpp | 2 + ScreenPlayWallpaper/src/linuxx11window.cpp | 2 + ScreenPlayWallpaper/src/macintegration.cpp | 2 + ScreenPlayWallpaper/src/macwindow.cpp | 2 + .../src/windowsdesktopproperties.cpp | 2 + ScreenPlayWallpaper/src/winwindow.cpp | 2 + ScreenPlayWeather/src/screenplayweather.cpp | 2 + ScreenPlayWidget/src/widgetwindow.cpp | 2 + ScreenPlayWorkshop/src/installedlistmodel.cpp | 2 + ScreenPlayWorkshop/src/screenplayworkshop.cpp | 2 + ScreenPlayWorkshop/src/steamaccount.cpp | 2 + .../src/steamqmlimageprovider.cpp | 2 + ScreenPlayWorkshop/src/steamworkshop.cpp | 2 + ScreenPlayWorkshop/src/steamworkshopitem.cpp | 2 + .../src/steamworkshoplistmodel.cpp | 2 + Tools/check_moc_includes.py | 63 +++++++++++++++++++ 42 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 Tools/check_moc_includes.py diff --git a/ScreenPlay/src/app.cpp b/ScreenPlay/src/app.cpp index 1e3ed6eb..79ff86ca 100644 --- a/ScreenPlay/src/app.cpp +++ b/ScreenPlay/src/app.cpp @@ -506,3 +506,5 @@ void App::setWizards(Wizards* wizards) emit wizardsChanged(m_wizards.get()); } } + +#include "moc_app.cpp" diff --git a/ScreenPlay/src/create.cpp b/ScreenPlay/src/create.cpp index 8a39e33b..32fd381b 100644 --- a/ScreenPlay/src/create.cpp +++ b/ScreenPlay/src/create.cpp @@ -360,3 +360,5 @@ void Create::abortAndCleanup() } } + +#include "moc_create.cpp" diff --git a/ScreenPlay/src/createimportvideo.cpp b/ScreenPlay/src/createimportvideo.cpp index f6ff3492..8142474b 100644 --- a/ScreenPlay/src/createimportvideo.cpp +++ b/ScreenPlay/src/createimportvideo.cpp @@ -766,3 +766,5 @@ QString CreateImportVideo::waitForFinished( } } + +#include "moc_createimportvideo.cpp" diff --git a/ScreenPlay/src/globalvariables.cpp b/ScreenPlay/src/globalvariables.cpp index c3effc5a..5e3cb75c 100644 --- a/ScreenPlay/src/globalvariables.cpp +++ b/ScreenPlay/src/globalvariables.cpp @@ -20,3 +20,5 @@ ScreenPlay::GlobalVariables::GlobalVariables(QObject* parent) } } + +#include "moc_globalvariables.cpp" diff --git a/ScreenPlay/src/installedlistfilter.cpp b/ScreenPlay/src/installedlistfilter.cpp index ac8c714a..abdb15e2 100644 --- a/ScreenPlay/src/installedlistfilter.cpp +++ b/ScreenPlay/src/installedlistfilter.cpp @@ -83,3 +83,5 @@ void InstalledListFilter::resetFilter() } } + +#include "moc_installedlistfilter.cpp" diff --git a/ScreenPlay/src/installedlistmodel.cpp b/ScreenPlay/src/installedlistmodel.cpp index 6ce6014c..1e1276b8 100644 --- a/ScreenPlay/src/installedlistmodel.cpp +++ b/ScreenPlay/src/installedlistmodel.cpp @@ -280,3 +280,5 @@ void InstalledListModel::reset() } } + +#include "moc_installedlistmodel.cpp" diff --git a/ScreenPlay/src/monitorlistmodel.cpp b/ScreenPlay/src/monitorlistmodel.cpp index 7a01d428..3b17e431 100644 --- a/ScreenPlay/src/monitorlistmodel.cpp +++ b/ScreenPlay/src/monitorlistmodel.cpp @@ -272,3 +272,5 @@ void MonitorListModel::reset() } } + +#include "moc_monitorlistmodel.cpp" diff --git a/ScreenPlay/src/profilelistmodel.cpp b/ScreenPlay/src/profilelistmodel.cpp index ab5ba536..c92c6a1d 100644 --- a/ScreenPlay/src/profilelistmodel.cpp +++ b/ScreenPlay/src/profilelistmodel.cpp @@ -95,3 +95,5 @@ void ProfileListModel::append(const Profile& profile) { } } + +#include "moc_profilelistmodel.cpp" diff --git a/ScreenPlay/src/projectsettingslistmodel.cpp b/ScreenPlay/src/projectsettingslistmodel.cpp index 9f900797..eb0aa2ce 100644 --- a/ScreenPlay/src/projectsettingslistmodel.cpp +++ b/ScreenPlay/src/projectsettingslistmodel.cpp @@ -204,3 +204,5 @@ QHash ProjectSettingsListModel::roleNames() const } } + +#include "moc_projectsettingslistmodel.cpp" diff --git a/ScreenPlay/src/screenplaymanager.cpp b/ScreenPlay/src/screenplaymanager.cpp index 78b5165b..fcba65ba 100644 --- a/ScreenPlay/src/screenplaymanager.cpp +++ b/ScreenPlay/src/screenplaymanager.cpp @@ -737,3 +737,5 @@ void ScreenPlayManager::setIsKDEConnected(bool isKDEConnected) } } + +#include "moc_screenplaymanager.cpp" diff --git a/ScreenPlay/src/screenplaywallpaper.cpp b/ScreenPlay/src/screenplaywallpaper.cpp index fbe3e8e8..8717a001 100644 --- a/ScreenPlay/src/screenplaywallpaper.cpp +++ b/ScreenPlay/src/screenplaywallpaper.cpp @@ -282,3 +282,5 @@ bool ScreenPlayWallpaper::replace( } } + +#include "moc_screenplaywallpaper.cpp" diff --git a/ScreenPlay/src/screenplaywidget.cpp b/ScreenPlay/src/screenplaywidget.cpp index 38007d6f..41e91ff8 100644 --- a/ScreenPlay/src/screenplaywidget.cpp +++ b/ScreenPlay/src/screenplaywidget.cpp @@ -133,3 +133,5 @@ QJsonObject ScreenPlayWidget::getActiveSettingsJson() return obj; } } + +#include "moc_screenplaywidget.cpp" diff --git a/ScreenPlay/src/sdkconnection.cpp b/ScreenPlay/src/sdkconnection.cpp index 5652b401..99fa4812 100644 --- a/ScreenPlay/src/sdkconnection.cpp +++ b/ScreenPlay/src/sdkconnection.cpp @@ -125,3 +125,5 @@ bool ScreenPlay::SDKConnection::close() return m_socket->state() == QLocalSocket::UnconnectedState; } } + +#include "moc_sdkconnection.cpp" diff --git a/ScreenPlay/src/settings.cpp b/ScreenPlay/src/settings.cpp index 4f617bcf..36c37689 100644 --- a/ScreenPlay/src/settings.cpp +++ b/ScreenPlay/src/settings.cpp @@ -329,3 +329,5 @@ QString Settings::fixLanguageCode(const QString& languageCode) } } + +#include "moc_settings.cpp" diff --git a/ScreenPlay/src/util.cpp b/ScreenPlay/src/util.cpp index f264c94c..c1dba609 100644 --- a/ScreenPlay/src/util.cpp +++ b/ScreenPlay/src/util.cpp @@ -439,3 +439,5 @@ bool Util::copyPreviewThumbnail(QJsonObject& obj, const QString& previewThumbnai } } + +#include "moc_util.cpp" diff --git a/ScreenPlay/src/wizards.cpp b/ScreenPlay/src/wizards.cpp index f9610f45..5fd438b1 100644 --- a/ScreenPlay/src/wizards.cpp +++ b/ScreenPlay/src/wizards.cpp @@ -409,3 +409,5 @@ const std::optional Wizards::createTemporaryFolder() const return folderName; } } + +#include "moc_wizards.cpp" diff --git a/ScreenPlayShader/src/shaderlibrary.cpp b/ScreenPlayShader/src/shaderlibrary.cpp index 50c9d06e..bbcc9927 100644 --- a/ScreenPlayShader/src/shaderlibrary.cpp +++ b/ScreenPlayShader/src/shaderlibrary.cpp @@ -38,3 +38,5 @@ ShaderLibrary::ShaderLibrary(QQuickItem* parent) ShaderLibrary::~ShaderLibrary() { } + +#include "moc_shaderlibrary.cpp" diff --git a/ScreenPlaySysInfo/src/cpu.cpp b/ScreenPlaySysInfo/src/cpu.cpp index e428cc2c..d5a197cc 100644 --- a/ScreenPlaySysInfo/src/cpu.cpp +++ b/ScreenPlaySysInfo/src/cpu.cpp @@ -58,3 +58,5 @@ void CPU::update() // publish result setUsage(currentUsage); } + +#include "moc_cpu.cpp" diff --git a/ScreenPlaySysInfo/src/gpu.cpp b/ScreenPlaySysInfo/src/gpu.cpp index 24af2230..a6f9cd87 100644 --- a/ScreenPlaySysInfo/src/gpu.cpp +++ b/ScreenPlaySysInfo/src/gpu.cpp @@ -57,3 +57,5 @@ GPU::GPU(QObject* parent) setMaxFrequency(properties_of_device.max_frequency); } } + +#include "moc_gpu.cpp" diff --git a/ScreenPlaySysInfo/src/ipaddress.cpp b/ScreenPlaySysInfo/src/ipaddress.cpp index de09db28..e9962367 100644 --- a/ScreenPlaySysInfo/src/ipaddress.cpp +++ b/ScreenPlaySysInfo/src/ipaddress.cpp @@ -48,3 +48,5 @@ IpAddress::IpAddress(QObject* parent) }); } } + +#include "moc_ipaddress.cpp" diff --git a/ScreenPlaySysInfo/src/ram.cpp b/ScreenPlaySysInfo/src/ram.cpp index a5b2a516..3722a564 100644 --- a/ScreenPlaySysInfo/src/ram.cpp +++ b/ScreenPlaySysInfo/src/ram.cpp @@ -42,3 +42,5 @@ void RAM::update() // set overall usage setUsage(memoryStatus.dwMemoryLoad); } + +#include "moc_ram.cpp" diff --git a/ScreenPlaySysInfo/src/storage.cpp b/ScreenPlaySysInfo/src/storage.cpp index 4747d314..57b4308e 100644 --- a/ScreenPlaySysInfo/src/storage.cpp +++ b/ScreenPlaySysInfo/src/storage.cpp @@ -100,3 +100,5 @@ void Storage::loadStorageDevices() } endInsertRows(); } + +#include "moc_storage.cpp" diff --git a/ScreenPlaySysInfo/src/sysinfo.cpp b/ScreenPlaySysInfo/src/sysinfo.cpp index cdd870b3..3f5721c4 100644 --- a/ScreenPlaySysInfo/src/sysinfo.cpp +++ b/ScreenPlaySysInfo/src/sysinfo.cpp @@ -26,3 +26,5 @@ SysInfo::SysInfo(QQuickItem* parent) , m_uptime(std::make_unique()) { } + +#include "moc_sysinfo.cpp" diff --git a/ScreenPlaySysInfo/src/uptime.cpp b/ScreenPlaySysInfo/src/uptime.cpp index 72fd5f1e..581425c6 100644 --- a/ScreenPlaySysInfo/src/uptime.cpp +++ b/ScreenPlaySysInfo/src/uptime.cpp @@ -43,3 +43,5 @@ void Uptime::update() setYears(years); #endif } + +#include "moc_uptime.cpp" diff --git a/ScreenPlayUtil/inc/public/ScreenPlayUtil/httpfileserver.cpp b/ScreenPlayUtil/inc/public/ScreenPlayUtil/httpfileserver.cpp index 0d674d67..48ffa4ab 100644 --- a/ScreenPlayUtil/inc/public/ScreenPlayUtil/httpfileserver.cpp +++ b/ScreenPlayUtil/inc/public/ScreenPlayUtil/httpfileserver.cpp @@ -27,3 +27,5 @@ void HttpFileServer::stopServer() m_thread.join(); } } + +#include "moc_httpfileserver.cpp" diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index 749f5479..ed2d0a0d 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -47,8 +47,8 @@ int main(int argc, char* argv[]) // For testing purposes when starting the ScreenPlayWallpaper directly. if (argumentList.length() == 1) { window.setActiveScreensList({ 0 }); - //window.setProjectPath("test"); - window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/particles"); + // window.setProjectPath("test"); + window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/2023_01_05_141855"); window.setAppID("test"); window.setVolume(1); window.setFillMode("fill"); diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index 455a6c38..24bbe761 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -243,3 +243,5 @@ void BaseWindow::setVideoCodec(ScreenPlay::VideoCodec::VideoCodec newVideoCodec) m_videoCodec = newVideoCodec; emit videoCodecChanged(newVideoCodec); } + +#include "moc_basewindow.cpp" diff --git a/ScreenPlayWallpaper/src/linuxx11window.cpp b/ScreenPlayWallpaper/src/linuxx11window.cpp index a72917c7..24d1b175 100644 --- a/ScreenPlayWallpaper/src/linuxx11window.cpp +++ b/ScreenPlayWallpaper/src/linuxx11window.cpp @@ -141,3 +141,5 @@ void LinuxX11Window::terminate() { QCoreApplication::quit(); } + +#include "moc_linuxx11window.cpp" diff --git a/ScreenPlayWallpaper/src/macintegration.cpp b/ScreenPlayWallpaper/src/macintegration.cpp index 09268b93..43ef2c0c 100644 --- a/ScreenPlayWallpaper/src/macintegration.cpp +++ b/ScreenPlayWallpaper/src/macintegration.cpp @@ -12,3 +12,5 @@ void MacIntegration::SetBackgroundLevel(QWindow* window) { MacBridge::SetBackgroundLevel(window); } + +#include "moc_macintegration.cpp" diff --git a/ScreenPlayWallpaper/src/macwindow.cpp b/ScreenPlayWallpaper/src/macwindow.cpp index 8c8ff0b3..570d9657 100644 --- a/ScreenPlayWallpaper/src/macwindow.cpp +++ b/ScreenPlayWallpaper/src/macwindow.cpp @@ -55,3 +55,5 @@ void MacWindow::clearComponentCache() { m_window.engine()->clearComponentCache(); } + +#include "moc_macwindow.cpp" diff --git a/ScreenPlayWallpaper/src/windowsdesktopproperties.cpp b/ScreenPlayWallpaper/src/windowsdesktopproperties.cpp index ed07b3c0..0aed1d9b 100644 --- a/ScreenPlayWallpaper/src/windowsdesktopproperties.cpp +++ b/ScreenPlayWallpaper/src/windowsdesktopproperties.cpp @@ -58,3 +58,5 @@ WindowsDesktopProperties::WindowsDesktopProperties(QObject* parent) if (canParse) setWindowsVersion(value); } + +#include "moc_windowsdesktopproperties.cpp" diff --git a/ScreenPlayWallpaper/src/winwindow.cpp b/ScreenPlayWallpaper/src/winwindow.cpp index 2a9bce8f..24b21161 100644 --- a/ScreenPlayWallpaper/src/winwindow.cpp +++ b/ScreenPlayWallpaper/src/winwindow.cpp @@ -507,3 +507,5 @@ void WinWindow::clearComponentCache() { m_window.engine()->clearComponentCache(); } + +#include "moc_winwindow.cpp" diff --git a/ScreenPlayWeather/src/screenplayweather.cpp b/ScreenPlayWeather/src/screenplayweather.cpp index 5d5c152e..b9d485e3 100644 --- a/ScreenPlayWeather/src/screenplayweather.cpp +++ b/ScreenPlayWeather/src/screenplayweather.cpp @@ -144,3 +144,5 @@ QNetworkRequest ScreenPlayWeather::defaultRequest() const request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json"); return request; } + +#include "moc_screenplayweather.cpp" diff --git a/ScreenPlayWidget/src/widgetwindow.cpp b/ScreenPlayWidget/src/widgetwindow.cpp index 0b3ec2fb..f238dcc8 100644 --- a/ScreenPlayWidget/src/widgetwindow.cpp +++ b/ScreenPlayWidget/src/widgetwindow.cpp @@ -220,3 +220,5 @@ void WidgetWindow::setupLiveReloading() QObject::connect(&m_liveReloadLimiter, &QTimer::timeout, this, reloadQMLLambda); m_fileSystemWatcher.addPaths({ projectPath() }); } + +#include "moc_widgetwindow.cpp" diff --git a/ScreenPlayWorkshop/src/installedlistmodel.cpp b/ScreenPlayWorkshop/src/installedlistmodel.cpp index 31110257..0c75086f 100644 --- a/ScreenPlayWorkshop/src/installedlistmodel.cpp +++ b/ScreenPlayWorkshop/src/installedlistmodel.cpp @@ -155,3 +155,5 @@ void InstalledListModel::reset() loadInstalledContent(); } } + +#include "moc_installedlistmodel.cpp" diff --git a/ScreenPlayWorkshop/src/screenplayworkshop.cpp b/ScreenPlayWorkshop/src/screenplayworkshop.cpp index d0bad357..150f6883 100644 --- a/ScreenPlayWorkshop/src/screenplayworkshop.cpp +++ b/ScreenPlayWorkshop/src/screenplayworkshop.cpp @@ -12,3 +12,5 @@ ScreenPlayWorkshop::ScreenPlayWorkshop() } } + +#include "moc_screenplayworkshop.cpp" diff --git a/ScreenPlayWorkshop/src/steamaccount.cpp b/ScreenPlayWorkshop/src/steamaccount.cpp index 7e2cd6b7..2f625512 100644 --- a/ScreenPlayWorkshop/src/steamaccount.cpp +++ b/ScreenPlayWorkshop/src/steamaccount.cpp @@ -81,3 +81,5 @@ void SteamAccount::onAvatarImageLoaded(AvatarImageLoaded_t* avatarImage) m_avatarLoaded = true; } } + +#include "moc_steamaccount.cpp" diff --git a/ScreenPlayWorkshop/src/steamqmlimageprovider.cpp b/ScreenPlayWorkshop/src/steamqmlimageprovider.cpp index f0389b22..f5b288f8 100644 --- a/ScreenPlayWorkshop/src/steamqmlimageprovider.cpp +++ b/ScreenPlayWorkshop/src/steamqmlimageprovider.cpp @@ -8,3 +8,5 @@ SteamQMLImageProvider::SteamQMLImageProvider(QQuickItem* parent) setFlag(QQuickItem::ItemHasContents); } } + +#include "moc_steamqmlimageprovider.cpp" diff --git a/ScreenPlayWorkshop/src/steamworkshop.cpp b/ScreenPlayWorkshop/src/steamworkshop.cpp index eca42f1f..59db47ab 100644 --- a/ScreenPlayWorkshop/src/steamworkshop.cpp +++ b/ScreenPlayWorkshop/src/steamworkshop.cpp @@ -396,3 +396,5 @@ void SteamWorkshop::onRequestUserItemsReturned(SteamUGCQueryCompleted_t* pCallba // } } } + +#include "moc_steamworkshop.cpp" diff --git a/ScreenPlayWorkshop/src/steamworkshopitem.cpp b/ScreenPlayWorkshop/src/steamworkshopitem.cpp index 7f26678c..0df69dd4 100644 --- a/ScreenPlayWorkshop/src/steamworkshopitem.cpp +++ b/ScreenPlayWorkshop/src/steamworkshopitem.cpp @@ -221,3 +221,5 @@ void SteamWorkshopItem::saveWorkshopID() } } + +#include "moc_steamworkshopitem.cpp" diff --git a/ScreenPlayWorkshop/src/steamworkshoplistmodel.cpp b/ScreenPlayWorkshop/src/steamworkshoplistmodel.cpp index d28fb6ce..43134931 100644 --- a/ScreenPlayWorkshop/src/steamworkshoplistmodel.cpp +++ b/ScreenPlayWorkshop/src/steamworkshoplistmodel.cpp @@ -76,3 +76,5 @@ void SteamWorkshopListModel::clear() } } + +#include "moc_steamworkshoplistmodel.cpp" diff --git a/Tools/check_moc_includes.py b/Tools/check_moc_includes.py new file mode 100644 index 00000000..5f2ea3f9 --- /dev/null +++ b/Tools/check_moc_includes.py @@ -0,0 +1,63 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only +import os +from pathlib import Path +import util +import argparse + +def find_files(path, pattern, file_extensions): + files = [] + for root, dirnames, filenames in os.walk(path): + for filename in filenames: + if any(filename.endswith(ext) for ext in file_extensions): + file_path = os.path.join(root, filename) + with open(file_path) as f: + contents = f.read() + if any(substring in contents for substring in pattern): + files.append(file_path) + print(f"Found file {file_path}") + return files + + +def check_moc_include(filename, add_include=False): + cppfile = Path(filename) + # replace cppfile ending with .cpp + cppfile = cppfile.with_suffix(".cpp").resolve() + # check if cpp file exists + if not cppfile.exists(): + # check if cpp file exists but 3 directories up and then in src + cppfile = cppfile.joinpath( + "../../../../src/{}".format(cppfile.name)).resolve() + if not cppfile.exists(): + print(f"FAIL: {cppfile} does not exist") + return + print(f"Check {cppfile}") + + with open(cppfile) as f: + if '#include "moc_{}"'.format(os.path.basename(cppfile)) in f.read(): + print("OK: {} HAS moc include".format(cppfile)) + else: + print("FAIL: {} MISSES moc include".format(cppfile)) + if add_include: + with open(cppfile, 'a') as f: + f.write("\n#include \"moc_{}\"\n".format( + os.path.basename(cppfile))) + print("Adding include...") + else: + print("Add this line to the end of the file:") + print("#include \"moc_{}\"".format(os.path.basename(cppfile))) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="Check if moc includes are present and add them if requested.") + parser.add_argument('-a', '--addinclude', action='store_true', + help='Automatically add missing moc includes') + args = parser.parse_args() + repo_root = util.repo_root_path() + filenames = find_files(repo_root, ['Q_OBJECT', 'Q_GADGET', 'Q_NAMESPACE'], [ + '.cpp', '.h', "main.cpp"]) + for filename in filenames: + check_moc_include(filename, args.addinclude) + if not args.addinclude: + print("Run this script with the '-a' or '--addinclude' flag to automatically add the moc includes") From 2b5d990c7cf920e9b35aa375dfe699e3d70b88a3 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 4 Feb 2023 11:54:44 +0100 Subject: [PATCH 52/56] Fix save autostart changes ever time This fixes issue 163 --- ScreenPlay/inc/public/ScreenPlay/settings.h | 74 +++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/ScreenPlay/inc/public/ScreenPlay/settings.h b/ScreenPlay/inc/public/ScreenPlay/settings.h index 517803f4..7d97e04c 100644 --- a/ScreenPlay/inc/public/ScreenPlay/settings.h +++ b/ScreenPlay/inc/public/ScreenPlay/settings.h @@ -28,6 +28,9 @@ #include #include #include +#include +#include +#include #include "ScreenPlay/globalvariables.h" #include "ScreenPlay/util.h" @@ -184,6 +187,77 @@ public slots: const QString homePath = QDir::homePath(); QFile settingsPlist(homePath + "/Library/LaunchAgents/" + plistFileName); if (settingsPlist.exists()) { + QDomDocument doc; + if (!doc.setContent(&settingsPlist)){ + settingsPlist.close(); + return ; + } + settingsPlist.close(); + + QDomElement root = doc.firstChildElement(); + QDomNodeList dictList = root.elementsByTagName("dict"); + if(dictList.size() > 1 && dictList.size() < 1 ){ + return; + } + + + // Check if autostart and corresponding path is set and abort if so. This is needed since osx 13.0 Ventura + // because it displays an annoying message every time we change the file. + bool isCorrectPath = false; + bool isAutostartEnabled = false; + QDomNode dictNode = dictList.at(0); + if (dictNode.isElement()){ + QDomElement dictElement = dictNode.toElement(); + QDomNodeList keyList = dictElement.elementsByTagName("key"); + for (int j = 0; j < keyList.size(); j++){ + QDomNode keyNode = keyList.at(j); + if (keyNode.isElement()){ + QDomElement keyElement = keyNode.toElement(); + if (keyElement.text() == "ProgramArguments"){ + QDomNode valueNode = keyNode.nextSibling(); + if (valueNode.isElement()){ + QDomElement valueElement = valueNode.toElement(); + QDomNodeList stringList = valueElement.elementsByTagName("string"); + if (!stringList.isEmpty()){ + QDomNode stringNode = stringList.at(0); + if (stringNode.isElement()){ + QDomElement stringElement = stringNode.toElement(); + const QString path = stringElement.text(); + if(path == screenPlayPath){ + isCorrectPath = true; + } + } + } + } + } + } + } + } + + if (dictNode.isElement()){ + QDomElement dictElement = dictNode.toElement(); + QDomNodeList keyList = dictElement.elementsByTagName("key"); + for (int j = 0; j < keyList.size(); j++){ + QDomNode keyNode = keyList.at(j); + if (keyNode.isElement()){ + QDomElement keyElement = keyNode.toElement(); + if (keyElement.text() == "RunAtLoad"){ + QDomNode valueNode = keyNode.nextSibling(); + if (valueNode.isElement()){ + QDomElement valueElement = valueNode.toElement(); + if (valueElement.tagName() == "true"){ + isAutostartEnabled = true; + } + } + } + } + } + } + + // Nothing to do. Autostart has the same value and the path is also correct. + if(isAutostartEnabled == autostart && isCorrectPath) + return; + if (!settingsPlist.remove()) { qCritical() << "Unable to remove: " << settingsPlist.fileName(); } From cbf8978c68d0c23b4efcac6b7f4e27dc39770b79 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 4 Feb 2023 11:56:23 +0100 Subject: [PATCH 53/56] Add SPDX license --- Tools/update_translations.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tools/update_translations.py b/Tools/update_translations.py index 9c0b213f..b57582f6 100644 --- a/Tools/update_translations.py +++ b/Tools/update_translations.py @@ -1,3 +1,5 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only import os import util import sys From dbd92317ee52129e8ed6645aedf50c7fe89c9834 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 4 Feb 2023 12:01:07 +0100 Subject: [PATCH 54/56] Add missing xml dependency --- ScreenPlay/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ScreenPlay/CMakeLists.txt b/ScreenPlay/CMakeLists.txt index c0ba4911..fbed1fe5 100644 --- a/ScreenPlay/CMakeLists.txt +++ b/ScreenPlay/CMakeLists.txt @@ -261,6 +261,7 @@ find_package( Widgets WebSockets Svg + Xml LinguistTools Test) @@ -284,6 +285,7 @@ qt_add_qml_module( ${HEADER} RESOURCES ${RESOURCES}) + target_link_libraries( ScreenPlayApp PUBLIC ScreenPlaySDK @@ -295,6 +297,7 @@ target_link_libraries( Qt6::WebSockets Qt6::Svg Qt6::QuickControls2 + Qt6::Xml ScreenPlayUtil ScreenPlayUtilplugin QArchive From e96f80c68c8cfbc88c83eebbd4cf3882e402ba1d Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 4 Feb 2023 12:15:41 +0100 Subject: [PATCH 55/56] Fix linux compilation --- ScreenPlayWallpaper/src/linuxx11window.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ScreenPlayWallpaper/src/linuxx11window.cpp b/ScreenPlayWallpaper/src/linuxx11window.cpp index 24d1b175..b92ce5af 100644 --- a/ScreenPlayWallpaper/src/linuxx11window.cpp +++ b/ScreenPlayWallpaper/src/linuxx11window.cpp @@ -140,6 +140,4 @@ void LinuxX11Window::destroyThis() void LinuxX11Window::terminate() { QCoreApplication::quit(); -} - -#include "moc_linuxx11window.cpp" +} \ No newline at end of file From 924819bb0bbe2ff845fc67b2b2a41b88df253fa1 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 4 Feb 2023 12:16:24 +0100 Subject: [PATCH 56/56] Formatting --- ScreenPlay/inc/public/ScreenPlay/settings.h | 51 ++++++++++----------- ScreenPlayWallpaper/main.cpp | 3 +- ScreenPlayWallpaper/src/basewindow.cpp | 1 - ScreenPlayWallpaper/src/winwindow.cpp | 4 +- 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/ScreenPlay/inc/public/ScreenPlay/settings.h b/ScreenPlay/inc/public/ScreenPlay/settings.h index 7d97e04c..a7457457 100644 --- a/ScreenPlay/inc/public/ScreenPlay/settings.h +++ b/ScreenPlay/inc/public/ScreenPlay/settings.h @@ -4,6 +4,9 @@ #include #include +#include +#include +#include #include #include #include @@ -28,9 +31,6 @@ #include #include #include -#include -#include -#include #include "ScreenPlay/globalvariables.h" #include "ScreenPlay/util.h" @@ -188,42 +188,41 @@ public slots: QFile settingsPlist(homePath + "/Library/LaunchAgents/" + plistFileName); if (settingsPlist.exists()) { QDomDocument doc; - if (!doc.setContent(&settingsPlist)){ + if (!doc.setContent(&settingsPlist)) { settingsPlist.close(); - return ; - } - settingsPlist.close(); - - QDomElement root = doc.firstChildElement(); - QDomNodeList dictList = root.elementsByTagName("dict"); - if(dictList.size() > 1 && dictList.size() < 1 ){ return; } + settingsPlist.close(); + QDomElement root = doc.firstChildElement(); + QDomNodeList dictList = root.elementsByTagName("dict"); + if (dictList.size() > 1 && dictList.size() < 1) { + return; + } // Check if autostart and corresponding path is set and abort if so. This is needed since osx 13.0 Ventura // because it displays an annoying message every time we change the file. bool isCorrectPath = false; bool isAutostartEnabled = false; QDomNode dictNode = dictList.at(0); - if (dictNode.isElement()){ + if (dictNode.isElement()) { QDomElement dictElement = dictNode.toElement(); QDomNodeList keyList = dictElement.elementsByTagName("key"); - for (int j = 0; j < keyList.size(); j++){ + for (int j = 0; j < keyList.size(); j++) { QDomNode keyNode = keyList.at(j); - if (keyNode.isElement()){ + if (keyNode.isElement()) { QDomElement keyElement = keyNode.toElement(); - if (keyElement.text() == "ProgramArguments"){ + if (keyElement.text() == "ProgramArguments") { QDomNode valueNode = keyNode.nextSibling(); - if (valueNode.isElement()){ + if (valueNode.isElement()) { QDomElement valueElement = valueNode.toElement(); QDomNodeList stringList = valueElement.elementsByTagName("string"); - if (!stringList.isEmpty()){ + if (!stringList.isEmpty()) { QDomNode stringNode = stringList.at(0); - if (stringNode.isElement()){ + if (stringNode.isElement()) { QDomElement stringElement = stringNode.toElement(); const QString path = stringElement.text(); - if(path == screenPlayPath){ + if (path == screenPlayPath) { isCorrectPath = true; } } @@ -234,18 +233,18 @@ public slots: } } - if (dictNode.isElement()){ + if (dictNode.isElement()) { QDomElement dictElement = dictNode.toElement(); QDomNodeList keyList = dictElement.elementsByTagName("key"); - for (int j = 0; j < keyList.size(); j++){ + for (int j = 0; j < keyList.size(); j++) { QDomNode keyNode = keyList.at(j); - if (keyNode.isElement()){ + if (keyNode.isElement()) { QDomElement keyElement = keyNode.toElement(); - if (keyElement.text() == "RunAtLoad"){ + if (keyElement.text() == "RunAtLoad") { QDomNode valueNode = keyNode.nextSibling(); - if (valueNode.isElement()){ + if (valueNode.isElement()) { QDomElement valueElement = valueNode.toElement(); - if (valueElement.tagName() == "true"){ + if (valueElement.tagName() == "true") { isAutostartEnabled = true; } } @@ -255,7 +254,7 @@ public slots: } // Nothing to do. Autostart has the same value and the path is also correct. - if(isAutostartEnabled == autostart && isCorrectPath) + if (isAutostartEnabled == autostart && isCorrectPath) return; if (!settingsPlist.remove()) { diff --git a/ScreenPlayWallpaper/main.cpp b/ScreenPlayWallpaper/main.cpp index ed2d0a0d..5e22ae6e 100644 --- a/ScreenPlayWallpaper/main.cpp +++ b/ScreenPlayWallpaper/main.cpp @@ -47,8 +47,7 @@ int main(int argc, char* argv[]) // For testing purposes when starting the ScreenPlayWallpaper directly. if (argumentList.length() == 1) { window.setActiveScreensList({ 0 }); - // window.setProjectPath("test"); - window.setProjectPath("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/2023_01_05_141855"); + window.setProjectPath("test"); window.setAppID("test"); window.setVolume(1); window.setFillMode("fill"); diff --git a/ScreenPlayWallpaper/src/basewindow.cpp b/ScreenPlayWallpaper/src/basewindow.cpp index 24bbe761..4928fe33 100644 --- a/ScreenPlayWallpaper/src/basewindow.cpp +++ b/ScreenPlayWallpaper/src/basewindow.cpp @@ -177,7 +177,6 @@ void BaseWindow::replaceWallpaper( emit reloadGIF(oldType); } - /*! \brief QML Convenience function for global fade in */ diff --git a/ScreenPlayWallpaper/src/winwindow.cpp b/ScreenPlayWallpaper/src/winwindow.cpp index 24b21161..7bebf619 100644 --- a/ScreenPlayWallpaper/src/winwindow.cpp +++ b/ScreenPlayWallpaper/src/winwindow.cpp @@ -1,8 +1,8 @@ // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only -#include "ScreenPlayUtil/projectfile.h" #include "winwindow.h" -#include +#include "ScreenPlayUtil/projectfile.h" #include +#include #include #include #include