diff --git a/.github/workflows/xmake.yml b/.github/workflows/xmake.yml index 2f09d7ee..ba5b7b5b 100644 --- a/.github/workflows/xmake.yml +++ b/.github/workflows/xmake.yml @@ -9,6 +9,10 @@ on: release: types: [created] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: windows-2025 @@ -41,6 +45,7 @@ jobs: xmake b --yes --verbose inject xmake b --yes --verbose shell + - name: Upload Artifacts uses: actions/upload-artifact@v4.6.0 with: diff --git a/resources/locales/en-US.json b/resources/locales/en-US.json new file mode 100644 index 00000000..aaf7014b --- /dev/null +++ b/resources/locales/en-US.json @@ -0,0 +1,78 @@ +{ + "$metadata": { + "language": "en-US", + "name": "English (US)", + "direction": "ltr" + }, + "settings.title": "Breeze Settings", + "settings.theme": "Theme", + "settings.animation": "Animation", + "settings.misc": "Miscellaneous", + "settings.debug_console": "Debug Console", + "settings.vsync": "VSync", + "settings.ignore_owner_draw": "Ignore Owner Draw Menus", + "settings.reverse_if_open_to_up": "Reverse When Opening Upward", + "settings.use_dwm_round_corners": "Try to Use Windows 11 Rounded Corners", + "settings.acrylic_background": "Acrylic Background Effect", + "settings.keyboard_hotkeys": "Keyboard Hotkeys", + "settings.show_settings_button": "Show Settings Button in Top Left", + "settings.priority_load_plugins": "Priority Load Plugins", + "menu.manage_breeze": "Manage Breeze Shell", + "menu.plugin_store": "Plugin Market / Update Shell", + "menu.breeze_settings": "Breeze Settings", + "menu.delete": "Delete", + "menu.new": "New", + "menu.folder": "Folder", + "menu.file": "File", + "menu.rename": "Rename", + "explorer.empty_recycle_bin": "Empty Recycle Bin", + "menu.set_priority": "Set as Priority Load", + "menu.cancel_priority": "Cancel Priority Load", + "sidebar.main_config": "Main Config", + "sidebar.update": "Update", + "sidebar.plugin_store": "Plugin Store", + "sidebar.plugin_config": "Plugin Config", + "sidebar.source": "Update Source", + "plugins.loading": "Loading...", + "plugins.updating": "Updating...", + "plugins.installing": "Installing...", + "plugins.installed": "Installed", + "plugins.not_installed": "Not Installed", + "plugins.installed_plugins": "Installed Plugins", + "plugins.priority_load": "Priority Load Plugins", + "plugins.install": "Install", + "plugins.update": "Update ({from} -> {to})", + "plugins.install_success": "Plugin installed successfully: {name}", + "plugins.install_failed": "Plugin install failed: {name}", + "plugins.update_downloaded": "New version downloaded, will take effect next time the file manager is restarted", + "plugins.update_failed": "Update failed: {error}", + "plugins.version": "Version: {version}", + "plugins.author": "Author: {author}", + "plugins.current_source": "Current source: {source}", + "plugins.store": "Plugin Store", + "plugins.config": "Plugin Config", + "update.title": "Update", + "update.current_version": "Current version: {version}", + "update.latest_version": "Latest version: {version}", + "update.changelog": "Changelog:", + "update.cannot_move_file": "Cannot move current file", + "error.config_parse_failed": "Config parse failed: {error}", + "status.config_changed": "Config changed: {path} {type}", + "theme.default": "Default", + "theme.compact": "Compact", + "theme.relaxed": "Relaxed", + "theme.rounded": "Rounded", + "theme.square": "Square", + "theme.custom": "Custom", + "animation.default": "Default", + "animation.fast": "Fast", + "animation.none": "None", + "source.switch": "Switch Source", + "source.switching": "Switching source...", + "source.switch_success": "Source switched successfully", + "common.loading": "Loading...", + "common.please_wait": "Please wait", + "common.load_failed": "Load failed", + "common.network_error": "Network error", + "common.latest": "(latest)" +} \ No newline at end of file diff --git a/resources/locales/zh-CN.json b/resources/locales/zh-CN.json new file mode 100644 index 00000000..20b9b9ed --- /dev/null +++ b/resources/locales/zh-CN.json @@ -0,0 +1,78 @@ +{ + "$metadata": { + "language": "zh-CN", + "name": "简体中文", + "direction": "ltr" + }, + "settings.title": "Breeze 设置", + "settings.theme": "主题", + "settings.animation": "动画", + "settings.misc": "杂项", + "settings.debug_console": "调试控制台", + "settings.vsync": "垂直同步", + "settings.ignore_owner_draw": "忽略自绘菜单", + "settings.reverse_if_open_to_up": "向上展开时反向排列", + "settings.use_dwm_round_corners": "尝试使用 Windows 11 圆角", + "settings.acrylic_background": "亚克力背景效果", + "settings.keyboard_hotkeys": "键盘热键", + "settings.show_settings_button": "在左上角显示设置按钮", + "settings.priority_load_plugins": "优先加载插件", + "menu.manage_breeze": "管理 Breeze Shell", + "menu.plugin_store": "插件市场 / 更新本体", + "menu.breeze_settings": "Breeze 设置", + "menu.delete": "删除", + "menu.new": "新建", + "menu.folder": "文件夹", + "menu.file": "文件", + "menu.rename": "重命名", + "explorer.empty_recycle_bin": "清空回收站", + "menu.set_priority": "设为优先加载", + "menu.cancel_priority": "取消优先加载", + "sidebar.main_config": "主配置", + "sidebar.update": "更新", + "sidebar.plugin_store": "插件商店", + "sidebar.plugin_config": "插件配置", + "sidebar.source": "更新源", + "plugins.loading": "加载中...", + "plugins.updating": "更新中...", + "plugins.installing": "安装中...", + "plugins.installed": "已安装", + "plugins.not_installed": "未安装", + "plugins.installed_plugins": "已安装插件", + "plugins.priority_load": "优先加载插件", + "plugins.install": "安装", + "plugins.update": "更新 ({from} -> {to})", + "plugins.install_success": "插件安装成功: {name}", + "plugins.install_failed": "插件安装失败: {name}", + "plugins.update_downloaded": "新版本已下载,将于下次重启资源管理器生效", + "plugins.update_failed": "更新失败: {error}", + "plugins.version": "版本: {version}", + "plugins.author": "作者: {author}", + "plugins.current_source": "当前源: {source}", + "plugins.store": "插件市场", + "plugins.config": "插件配置", + "update.title": "更新", + "update.current_version": "当前版本: {version}", + "update.latest_version": "最新版本: {version}", + "update.changelog": "更新日志:", + "update.cannot_move_file": "无法移动当前文件", + "error.config_parse_failed": "配置文件解析失败: {error}", + "status.config_changed": "配置文件变更: {path} {type}", + "theme.default": "默认", + "theme.compact": "紧凑", + "theme.relaxed": "宽松", + "theme.rounded": "圆角", + "theme.square": "方角", + "theme.custom": "自定义", + "animation.default": "默认", + "animation.fast": "快速", + "animation.none": "无", + "source.switch": "换源", + "source.switching": "切换源中...", + "source.switch_success": "切换源成功", + "common.loading": "加载中...", + "common.please_wait": "请稍候", + "common.load_failed": "加载失败", + "common.network_error": "网络错误", + "common.latest": "(最新)" +} \ No newline at end of file diff --git a/src/shell/config.cc b/src/shell/config.cc index a227e5d9..f6ed7108 100644 --- a/src/shell/config.cc +++ b/src/shell/config.cc @@ -11,6 +11,7 @@ #include "rfl/json.hpp" #include "utils.h" +#include "i18n_manager.h" #include "windows.h" namespace rfl { @@ -102,6 +103,14 @@ void config::read_config() { } else { ShowWindow(GetConsoleWindow(), SW_HIDE); } + + // Initialize/update i18n manager with config language preference + auto& i18n = i18n_manager::instance(); + if (config::current->language) { + i18n.set_language(*config::current->language); + } else { + i18n.reload(); + } } std::filesystem::path config::data_directory() { diff --git a/src/shell/config.h b/src/shell/config.h index 243f89c0..74da9f12 100644 --- a/src/shell/config.h +++ b/src/shell/config.h @@ -122,6 +122,9 @@ struct config { bool res_string_loader_use_hook = false; bool avoid_resize_ui = false; std::vector plugin_load_order = {}; + + // Language preference override (uses system language if nullopt) + std::optional language; std::string $schema; static std::unique_ptr current; diff --git a/src/shell/i18n_manager.cc b/src/shell/i18n_manager.cc new file mode 100644 index 00000000..771b9272 --- /dev/null +++ b/src/shell/i18n_manager.cc @@ -0,0 +1,434 @@ +#include "i18n_manager.h" +#include "config.h" +#include "utils.h" +#include "logger.h" + +#include +#include +#include +#include +#include + +#include "rfl.hpp" +#include "rfl/json.hpp" +#include + +#include "windows.h" + +namespace mb_shell { + + +namespace { +const unsigned char g_en_US_json[] = { +#include "en-US.json.h" +}; +const unsigned char g_zh_CN_json[] = { +#include "zh-CN.json.h" +}; + +void ensure_file(const std::filesystem::path& path, const unsigned char* data, size_t size) { + // Check for and strip trailing null terminator if present + size_t write_size = size; + if (write_size > 0 && data[write_size - 1] == '\0') { + write_size--; + } + + // Always overwrite embedded locale files to ensure updates propagate correctly + try { + std::filesystem::create_directories(path.parent_path()); + std::ofstream f(path, std::ios::binary | std::ios::trunc); + if (f) { + f.write(reinterpret_cast(data), write_size); + dbgout("Extracted/updated locale: {} (size: {})", path.string(), write_size); + } + } catch (const std::exception& e) { + std::cerr << "Failed to extract locale " << path << ": " << e.what() << std::endl; + } +} + +struct LocaleMetadata { + std::optional direction; +}; + +struct LocaleFile { + rfl::Rename<"$metadata", std::optional> metadata; + rfl::ExtraFields translations; +}; + +} + +i18n_manager& i18n_manager::instance() { + static i18n_manager instance; + return instance; +} + +i18n_manager::i18n_manager() : current_lang_("en-US"), is_rtl_(false) { + auto locales_dir = config::data_directory() / "locales"; + ensure_file(locales_dir / "en-US.json", g_en_US_json, sizeof(g_en_US_json)); + ensure_file(locales_dir / "zh-CN.json", g_zh_CN_json, sizeof(g_zh_CN_json)); + reload(); +} + +std::string i18n_manager::get(const std::string& key) { + std::shared_lock lock(mutex_); + + // Try current language first + auto lang_it = translations_.find(current_lang_); + if (lang_it != translations_.end()) { + auto key_it = lang_it->second.find(key); + if (key_it != lang_it->second.end()) { + return key_it->second; + } + } + + // Try plugin translations + auto plugin_lang_it = plugin_translations_.find(current_lang_); + if (plugin_lang_it != plugin_translations_.end()) { + auto key_it = plugin_lang_it->second.find(key); + if (key_it != plugin_lang_it->second.end()) { + return key_it->second; + } + } + + // Fallback to en-US if not current language + if (current_lang_ != "en-US") { + auto fallback_it = translations_.find("en-US"); + if (fallback_it != translations_.end()) { + auto key_it = fallback_it->second.find(key); + if (key_it != fallback_it->second.end()) { + return key_it->second; + } + } + } + + // Return key itself as last resort + return key; +} + +std::string i18n_manager::get(const std::string& key, + const std::map& params) { + std::string result = get(key); + return interpolate(result, params); +} + +void i18n_manager::set_language(const std::string& lang) { + std::unique_lock lock(mutex_); + + if (lang == current_lang_) { + return; + } + + // Check if locale is loaded, if not try to load it + bool loaded = true; + if (translations_.find(lang) == translations_.end()) { + loaded = load_locale(lang); + } + + if (loaded) { + current_lang_ = lang; + + // Update RTL status from metadata + is_rtl_ = false; // Default to LTR + auto lang_it = translations_.find(current_lang_); + if (lang_it != translations_.end()) { + auto meta_it = lang_it->second.find("$metadata.direction"); + if (meta_it != lang_it->second.end() && meta_it->second == "rtl") { + is_rtl_ = true; + } + } + } else { + std::cerr << "Failed to load locale " << lang << ", keeping " << current_lang_ << std::endl; + } +} + +std::string i18n_manager::current_language() const { + std::shared_lock lock(mutex_); + return current_lang_; +} + +bool i18n_manager::is_rtl() const { + std::shared_lock lock(mutex_); + return is_rtl_; +} + +void i18n_manager::register_translations(const std::string& lang, + const std::map& translations) { + std::unique_lock lock(mutex_); + + for (const auto& [key, value] : translations) { + // Check if this is a core key - warn but don't override + if (core_keys_.find(key) != core_keys_.end()) { + std::cerr << "Warning: Plugin attempted to override core translation key: " + << key << std::endl; + continue; + } + + plugin_translations_[lang][key] = value; + } +} + +void i18n_manager::reload() { + std::unique_lock lock(mutex_); + + translations_.clear(); + plugin_translations_.clear(); + core_keys_.clear(); + + // Determine language priority: config > system > en-US + std::string target_lang; + + // Check if config has language override + if (config::current && config::current->language) { + target_lang = *config::current->language; + } else { + target_lang = get_system_language(); + } + + // Always load en-US as fallback + load_locale("en-US"); + + // Load target language if different + if (target_lang != "en-US") { + if (!load_locale(target_lang)) { + // Fallback to en-US if target language fails + target_lang = "en-US"; + } + } + + current_lang_ = target_lang; + dbgout("Current language set to: {}", current_lang_); + + // Load plugin locales + load_plugin_locales(); + + // Update RTL status + is_rtl_ = false; + auto lang_it = translations_.find(current_lang_); + if (lang_it != translations_.end()) { + auto meta_it = lang_it->second.find("$metadata.direction"); + if (meta_it != lang_it->second.end() && meta_it->second == "rtl") { + is_rtl_ = true; + } + } +} + +bool i18n_manager::load_locale(const std::string& lang) { + // Security validation: Validate language code format + static const std::regex kLangRegex("^[A-Za-z]{2,3}(-[A-Za-z]{2,4})?$"); + if (!std::regex_match(lang, kLangRegex) || + lang.find("..") != std::string::npos || + lang.find('/') != std::string::npos || + lang.find('\\') != std::string::npos) { + std::cerr << "Invalid language code or path traversal attempt: " << lang << std::endl; + return false; + } + + auto locales_dir = config::data_directory() / "locales"; + auto locale_path = locales_dir / (lang + ".json"); + + if (!std::filesystem::exists(locale_path)) { + dbgout("Locale file not found: {}", locale_path.string()); + return false; + } + + // Path Traversal Protection: Verify resolved path is inside locales directory + std::error_code ec; + auto canonical_path = std::filesystem::canonical(locale_path, ec); + if (ec) { + std::cerr << "Failed to canonicalize path: " << locale_path << " - " << ec.message() << std::endl; + return false; + } + + auto canonical_base = std::filesystem::canonical(locales_dir, ec); + if (ec) { + std::cerr << "Failed to canonicalize base directory: " << locales_dir << std::endl; + return false; + } + + // Check if the file path starts with the base directory path + if (canonical_path.string().find(canonical_base.string()) != 0) { + std::cerr << "Security violation: Attempted to load locale outside allowed directory: " + << canonical_path << std::endl; + return false; + } + + std::ifstream file(locale_path); + if (!file) { + std::cerr << "Failed to open locale file: " << locale_path << std::endl; + return false; + } + + std::string json_str((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + + // Use reflect-cpp for JSON parsing + auto result = rfl::json::read(json_str); + if (!result) { + std::cerr << "Failed to parse locale file: " << locale_path << " Error: " << result.error().what() << std::endl; + return false; + } + + const auto& locale_data = result.value(); + auto& lang_translations = translations_[lang]; + + // Copy translations + for (const auto& [key, val] : locale_data.translations) { + // Skip metadata keys just in case, though they should be handled by 'metadata' field + if (key.starts_with("$metadata")) continue; + + lang_translations[key] = val; + core_keys_.insert(key); + } + + // Handle metadata + if (locale_data.metadata.value()) { + if (locale_data.metadata.value()->direction) { + lang_translations["$metadata.direction"] = *locale_data.metadata.value()->direction; + } + } + + dbgout("Loaded locale: {} ({} translations)", lang, lang_translations.size()); + return true; +} + +void i18n_manager::load_plugin_locales() { + auto plugins_locale_dir = config::data_directory() / "locales" / "plugins"; + + if (!std::filesystem::exists(plugins_locale_dir)) { + return; + } + + try { + for (const auto& plugin_entry : std::filesystem::directory_iterator(plugins_locale_dir)) { + if (!plugin_entry.is_directory()) { + continue; + } + + std::string plugin_name = plugin_entry.path().filename().string(); + + // Load all language files for this plugin + for (const auto& lang_file : std::filesystem::directory_iterator(plugin_entry.path())) { + if (!lang_file.is_regular_file() || + lang_file.path().extension() != ".json") { + continue; + } + + std::string lang = lang_file.path().stem().string(); + + std::ifstream file(lang_file.path()); + if (!file) { + continue; + } + + std::string json_str((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + + // Use reflect-cpp to parse into LocaleFile + // We reuse LocaleFile struct as it handles the structure we expect + auto result = rfl::json::read(json_str); + if (!result) { + std::cerr << "Failed to parse plugin locale file: " << lang_file.path() << " Error: " << result.error().what() << std::endl; + continue; + } + + const auto& locale_data = result.value(); + + for (const auto& [key, val] : locale_data.translations) { + // Skip metadata keys + if (key.starts_with("$metadata")) { + continue; + } + + // Warn if attempting to override core key + if (core_keys_.find(key) != core_keys_.end()) { + std::cerr << "Warning: Plugin " << plugin_name + << " attempted to override core key: " << key << std::endl; + continue; + } + + plugin_translations_[lang][key] = val; + } + } + } + } catch (const std::exception& e) { + std::cerr << "Error loading plugin locales: " << e.what() << std::endl; + } +} + +std::string i18n_manager::get_system_language() { + ULONG num_langs = 0; + ULONG buffer_size = 0; + + // First call to determine required buffer size + if (GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num_langs, nullptr, &buffer_size)) { + std::vector buffer(buffer_size); + // Second call to retrieve languages + if (GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num_langs, buffer.data(), &buffer_size)) { + // buffer contains null-separated strings; take the first one if available + if (num_langs > 0 && buffer_size > 0) { + return wstring_to_utf8(buffer.data()); + } + } + } + + return "en-US"; +} + +std::string i18n_manager::interpolate(const std::string& str, + const std::map& params) { + if (params.empty()) { + return str; + } + + std::string result = str; + // Support alphanumeric, dots, and hyphens in placeholders (e.g., {user.name}, {my-key}) + std::regex placeholder_regex(R"(\{([\w.-]+)\})"); + + std::smatch match; + std::string::const_iterator search_start(result.cbegin()); + std::string output; + + while (std::regex_search(search_start, result.cend(), match, placeholder_regex)) { + // Append text before the match + output.append(search_start, match[0].first); + + std::string placeholder_name = match[1].str(); + auto param_it = params.find(placeholder_name); + + if (param_it != params.end()) { + // Replace with parameter value + output.append(param_it->second); + } else { + // Keep placeholder intact if not found + output.append(match[0].str()); + } + + search_start = match.suffix().first; + } + + // Append remaining text + output.append(search_start, result.cend()); + + return output; +} + +std::vector i18n_manager::available_languages() const { + std::shared_lock lock(mutex_); + + std::vector languages; + + auto locales_dir = config::data_directory() / "locales"; + if (!std::filesystem::exists(locales_dir)) { + return languages; + } + + for (const auto& entry : std::filesystem::directory_iterator(locales_dir)) { + if (entry.is_regular_file() && entry.path().extension() == ".json") { + languages.push_back(entry.path().stem().string()); + } + } + + return languages; +} + +} // namespace mb_shell diff --git a/src/shell/i18n_manager.h b/src/shell/i18n_manager.h new file mode 100644 index 00000000..883d60e1 --- /dev/null +++ b/src/shell/i18n_manager.h @@ -0,0 +1,139 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace mb_shell { + +/** + * @brief Internationalization manager for loading and querying translations. + * + * This class provides a singleton interface for managing locale files and + * retrieving translated strings. It supports: + * - Loading JSON locale files from /locales/ + * - Language selection priority: user config > system language > en-US + * - String interpolation with {placeholder} syntax + * - Plugin namespace protection for custom translations + * - RTL direction detection for right-to-left languages + */ +class i18n_manager { +public: + /** + * @brief Get the singleton instance. + */ + static i18n_manager& instance(); + + /** + * @brief Get a translated string for the given key. + * @param key The translation key (e.g., "settings.title") + * @return The translated string, or the key itself if not found + */ + std::string get(const std::string& key); + + /** + * @brief Get a translated string with placeholder substitution. + * @param key The translation key + * @param params Map of placeholder names to values (e.g., {"name": "MyPlugin"}) + * @return The translated string with placeholders replaced + */ + std::string get(const std::string& key, const std::map& params); + + /** + * @brief Set the current language. + * @param lang Language code (e.g., "en-US", "zh-CN") + */ + void set_language(const std::string& lang); + + /** + * @brief Get the current language code. + * @return Current language code (e.g., "en-US") + */ + std::string current_language() const; + + /** + * @brief Check if the current language is RTL (right-to-left). + * @return true if RTL, false otherwise + */ + bool is_rtl() const; + + /** + * @brief Register translations from a plugin. + * @param lang Language code + * @param translations Map of keys to translated strings + * @note Plugin keys should be prefixed with the plugin name (e.g., "myplugin.hello") + * @note Core keys cannot be overridden by plugins + */ + void register_translations(const std::string& lang, + const std::map& translations); + + /** + * @brief Reload locale files from disk. + */ + void reload(); + + /** + * @brief Get all available language codes. + * @return Vector of language codes found in locales directory + */ + std::vector available_languages() const; + +private: + i18n_manager(); + ~i18n_manager() = default; + + // Non-copyable + i18n_manager(const i18n_manager&) = delete; + i18n_manager& operator=(const i18n_manager&) = delete; + i18n_manager(i18n_manager&&) = delete; + i18n_manager& operator=(i18n_manager&&) = delete; + + /** + * @brief Load a locale file from disk. + * @param lang Language code + * @return true if successful + */ + bool load_locale(const std::string& lang); + + /** + * @brief Load plugin locale files from plugins directory. + */ + void load_plugin_locales(); + + /** + * @brief Get the system's preferred UI language. + * @return System language code or "en-US" as fallback + */ + static std::string get_system_language(); + + /** + * @brief Perform placeholder substitution on a string. + * @param str The string containing {placeholder} patterns + * @param params Map of placeholder names to values + * @return String with placeholders replaced + * @note Supported placeholder characters: alphanumeric, dots, and hyphens (e.g., {user.name}, {my-key}). + * Regex pattern: \{([\w.-]+)\}. + */ + static std::string interpolate(const std::string& str, + const std::map& params); + + std::string current_lang_; + bool is_rtl_; + + // Core translations: lang -> (key -> value) + std::map> translations_; + + // Plugin translations: lang -> (key -> value), stored separately for namespace protection + std::map> plugin_translations_; + + // Set of core keys (cannot be overridden by plugins) + std::set core_keys_; + + mutable std::shared_mutex mutex_; +}; + +} // namespace mb_shell diff --git a/src/shell/script/binding_qjs.h b/src/shell/script/binding_qjs.h index 8c586ec2..ebd6478d 100644 --- a/src/shell/script/binding_qjs.h +++ b/src/shell/script/binding_qjs.h @@ -1143,6 +1143,12 @@ template<> struct js_bind { .static_fun<&mb_shell::js::breeze::should_show_settings_button>("should_show_settings_button") .static_fun<&mb_shell::js::breeze::current_process_name>("current_process_name") .static_fun<&mb_shell::js::breeze::current_process_path>("current_process_path") + .static_fun<&mb_shell::js::breeze::get_translation>("get_translation") + .static_fun<&mb_shell::js::breeze::get_translation_with_params>("get_translation_with_params") + .static_fun<&mb_shell::js::breeze::is_rtl>("is_rtl") + .static_fun<&mb_shell::js::breeze::register_translations>("register_translations") + .static_fun<&mb_shell::js::breeze::available_languages>("available_languages") + .static_fun<&mb_shell::js::breeze::set_language>("set_language") ; } }; diff --git a/src/shell/script/binding_types.cc b/src/shell/script/binding_types.cc index 00440b00..ed93a00a 100644 --- a/src/shell/script/binding_types.cc +++ b/src/shell/script/binding_types.cc @@ -25,6 +25,7 @@ #include "script.h" #include "shell/utils.h" +#include "shell/i18n_manager.h" #include "winhttp.h" #include @@ -649,7 +650,6 @@ void network::download_async(std::string url, std::string path, fs::write_binary(path, std::vector(data.begin(), data.end())); ctx.enqueueJob([=]() { callback(); }); - callback(); } catch (std::exception &e) { error_callback(e.what()); } @@ -663,24 +663,7 @@ size_t win32::load_library(std::string path) { LoadLibraryW(utf8_to_wstring(path).c_str())); } std::string breeze::user_language() { - wchar_t buffer[256]; - - /* - BOOL GetUserPreferredUILanguages( - [in] DWORD dwFlags, - [out] PULONG pulNumLanguages, - [out, optional] PZZWSTR pwszLanguagesBuffer, - [in, out] PULONG pcchLanguagesBuffer - ); - */ - - ULONG num_langs = 256; - if (GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num_langs, buffer, - &num_langs)) { - return wstring_to_utf8(buffer); - } - - return "en-US"; + return mb_shell::i18n_manager::instance().current_language(); } std::optional win32::env(std::string name) { return mb_shell::env(name); @@ -689,6 +672,35 @@ std::optional win32::env(std::string name) { std::string breeze::hash() { return BREEZE_GIT_COMMIT_HASH; } std::string breeze::branch() { return BREEZE_GIT_BRANCH_NAME; } std::string breeze::build_date() { return BREEZE_BUILD_DATE_TIME; } + +// i18n API implementations +std::string breeze::get_translation(const std::string& key) { + return mb_shell::i18n_manager::instance().get(key); +} + +std::string breeze::get_translation_with_params( + const std::string& key, + const std::map& params) { + return mb_shell::i18n_manager::instance().get(key, params); +} + +bool breeze::is_rtl() { + return mb_shell::i18n_manager::instance().is_rtl(); +} + +void breeze::register_translations( + const std::string& lang, + const std::map& translations) { + mb_shell::i18n_manager::instance().register_translations(lang, translations); +} + +std::vector breeze::available_languages() { + return mb_shell::i18n_manager::instance().available_languages(); +} + +void breeze::set_language(const std::string& lang) { + mb_shell::i18n_manager::instance().set_language(lang); +} std::vector> menu_item_parent_item_controller::children() { if (!valid()) diff --git a/src/shell/script/binding_types.d.ts b/src/shell/script/binding_types.d.ts index e23ad61a..8dd2bbf6 100644 --- a/src/shell/script/binding_types.d.ts +++ b/src/shell/script/binding_types.d.ts @@ -1078,6 +1078,49 @@ export class breeze { static should_show_settings_button(): boolean static current_process_name(): string static current_process_path(): string + /** + * i18n API + * Get a translated string by key + * 获取翻译字符串 + * @param key: string + * @returns string + */ + static get_translation(key: string): string + /** + * Get a translated string with placeholder substitution + * 获取带占位符替换的翻译字符串 + * @param key: string + * @param params: std.map + * @returns string + */ + static get_translation_with_params(key: string, params: std.map): string + /** + * Check if current language is RTL + * 检查当前语言是否为从右到左 + @returns boolean + */ + static is_rtl(): boolean + /** + * Register plugin translations + * 注册插件翻译 + * @param lang: string + * @param translations: std.map + * @returns void + */ + static register_translations(lang: string, translations: std.map): void + /** + * Get available languages + * 获取可用语言列表 + @returns Array + */ + static available_languages(): Array + /** + * Set language + * 设置语言 + * @param lang: string + * @returns void + */ + static set_language(lang: string): void } export class win32 { /** diff --git a/src/shell/script/binding_types.hpp b/src/shell/script/binding_types.hpp index 1989bf07..337e6e67 100644 --- a/src/shell/script/binding_types.hpp +++ b/src/shell/script/binding_types.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "binding_types_breeze_ui.h" @@ -635,6 +636,35 @@ struct breeze { static bool should_show_settings_button(); static std::string current_process_name(); static std::string current_process_path(); + + // i18n API + // Get a translated string by key + // 获取翻译字符串 + static std::string get_translation(const std::string& key); + + // Get a translated string with placeholder substitution + // 获取带占位符替换的翻译字符串 + static std::string get_translation_with_params( + const std::string& key, + const std::map& params); + + // Check if current language is RTL + // 检查当前语言是否为从右到左 + static bool is_rtl(); + + // Register plugin translations + // 注册插件翻译 + static void register_translations( + const std::string& lang, + const std::map& translations); + + // Get available languages + // 获取可用语言列表 + static std::vector available_languages(); + + // Set language + // 设置语言 + static void set_language(const std::string& lang); }; struct win32 { diff --git a/src/shell/script/quickjspp.hpp b/src/shell/script/quickjspp.hpp index afd7110b..7d484703 100644 --- a/src/shell/script/quickjspp.hpp +++ b/src/shell/script/quickjspp.hpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -2098,6 +2099,136 @@ template struct js_traits> { } }; +/** Convert from std::unordered_map to Object and vice-versa. + * Maps string keys to JS object properties with typed values. + */ +template struct js_traits> { + static JSValue wrap(JSContext *ctx, const std::unordered_map &map) noexcept { + try { + auto jsobj = Value{weakFromContext(ctx), JS_NewObject(ctx)}; + for (const auto &[key, value] : map) + jsobj[key.c_str()] = value; + return jsobj.release(); + } catch (exception) { + return JS_EXCEPTION; + } catch (std::exception const &err) { + JS_ThrowInternalError(ctx, "%s", err.what()); + return JS_EXCEPTION; + } catch (...) { + JS_ThrowInternalError(ctx, "Unknown error"); + return JS_EXCEPTION; + } + } + + static std::unordered_map unwrap(JSContext *ctx, JSValueConst jsobj) { + if (!JS_IsObject(jsobj) || JS_IsArray(jsobj)) { + JS_ThrowTypeError(ctx, "Expected object for unordered_map conversion"); + throw exception{ctx}; + } + std::unordered_map map; + Value obj{ctx, JS_DupValue(ctx, jsobj)}; + + JSPropertyEnum *props = nullptr; + uint32_t prop_count = 0; + if (JS_GetOwnPropertyNames(ctx, &props, &prop_count, jsobj, JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY) < 0) + throw exception{ctx}; + + // RAII guard to ensure cleanup on exception + struct PropsGuard { + JSContext *ctx; + JSPropertyEnum *props; + uint32_t count; + uint32_t freed_until = 0; + ~PropsGuard() { + for (uint32_t i = freed_until; i < count; i++) { + JS_FreeAtom(ctx, props[i].atom); + } + js_free(ctx, props); + } + } guard{ctx, props, prop_count}; + + for (uint32_t i = 0; i < prop_count; i++) { + const char *key = JS_AtomToCString(ctx, props[i].atom); + if (key) { + struct KeyGuard { + JSContext *ctx; + const char *key; + ~KeyGuard() { JS_FreeCString(ctx, key); } + } key_guard{ctx, key}; + map[key] = static_cast(obj[key]); + } + JS_FreeAtom(ctx, props[i].atom); + guard.freed_until = i + 1; + } + return map; + } +}; + +/** Convert from std::map to Object and vice-versa. + * Maps string keys to JS object properties with typed values. + */ +template struct js_traits> { + static JSValue wrap(JSContext *ctx, const std::map &map) noexcept { + try { + auto jsobj = Value{weakFromContext(ctx), JS_NewObject(ctx)}; + for (const auto &[key, value] : map) + jsobj[key.c_str()] = value; + return jsobj.release(); + } catch (exception) { + return JS_EXCEPTION; + } catch (std::exception const &err) { + JS_ThrowInternalError(ctx, "%s", err.what()); + return JS_EXCEPTION; + } catch (...) { + JS_ThrowInternalError(ctx, "Unknown error"); + return JS_EXCEPTION; + } + } + + static std::map unwrap(JSContext *ctx, JSValueConst jsobj) { + if (!JS_IsObject(jsobj) || JS_IsArray(jsobj)) { + JS_ThrowTypeError(ctx, "Expected object for map conversion"); + throw exception{ctx}; + } + std::map map; + Value obj{ctx, JS_DupValue(ctx, jsobj)}; + + JSPropertyEnum *props = nullptr; + uint32_t prop_count = 0; + if (JS_GetOwnPropertyNames(ctx, &props, &prop_count, jsobj, JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY) < 0) + throw exception{ctx}; + + // RAII guard to ensure cleanup on exception + struct PropsGuard { + JSContext *ctx; + JSPropertyEnum *props; + uint32_t count; + uint32_t freed_until = 0; + ~PropsGuard() { + for (uint32_t i = freed_until; i < count; i++) { + JS_FreeAtom(ctx, props[i].atom); + } + js_free(ctx, props); + } + } guard{ctx, props, prop_count}; + + for (uint32_t i = 0; i < prop_count; i++) { + const char *key = JS_AtomToCString(ctx, props[i].atom); + if (key) { + struct KeyGuard { + JSContext *ctx; + const char *key; + ~KeyGuard() { JS_FreeCString(ctx, key); } + } key_guard{ctx, key}; + map[key] = static_cast(obj[key]); + } + JS_FreeAtom(ctx, props[i].atom); + guard.freed_until = i + 1; + } + return map; + } +}; + template struct js_traits> { static JSValue wrap(JSContext *ctx, std::pair obj) noexcept { try { diff --git a/src/shell/script/script.js b/src/shell/script/script.js index 777e0e76..d4c64272 100644 --- a/src/shell/script/script.js +++ b/src/shell/script/script.js @@ -5,18 +5,18 @@ import * as __mshell from "mshell"; const setTimeout = __mshell.infra.setTimeout; const clearTimeout = __mshell.infra.clearTimeout; -var lf=Object.create;var Ss=Object.defineProperty;var of=Object.getOwnPropertyDescriptor;var uf=Object.getOwnPropertyNames;var sf=Object.getPrototypeOf,af=Object.prototype.hasOwnProperty;var Pn=(i,u)=>()=>(u||i((u={exports:{}}).exports,u),u.exports);var cf=(i,u,a,p)=>{if(u&&typeof u=="object"||typeof u=="function")for(let g of uf(u))!af.call(i,g)&&g!==a&&Ss(i,g,{get:()=>u[g],enumerable:!(p=of(u,g))||p.enumerable});return i};var lt=(i,u,a)=>(a=i!=null?lf(sf(i)):{},cf(u||!i||!i.__esModule?Ss(a,"default",{value:i,enumerable:!0}):a,i));var Ls=Pn(O=>{"use strict";var tr=Symbol.for("react.element"),ff=Symbol.for("react.portal"),df=Symbol.for("react.fragment"),pf=Symbol.for("react.strict_mode"),hf=Symbol.for("react.profiler"),mf=Symbol.for("react.provider"),gf=Symbol.for("react.context"),vf=Symbol.for("react.forward_ref"),yf=Symbol.for("react.suspense"),_f=Symbol.for("react.memo"),xf=Symbol.for("react.lazy"),ws=Symbol.iterator;function Sf(i){return i===null||typeof i!="object"?null:(i=ws&&i[ws]||i["@@iterator"],typeof i=="function"?i:null)}var ks={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Ps=Object.assign,Es={};function En(i,u,a){this.props=i,this.context=u,this.refs=Es,this.updater=a||ks}En.prototype.isReactComponent={};En.prototype.setState=function(i,u){if(typeof i!="object"&&typeof i!="function"&&i!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,i,u,"setState")};En.prototype.forceUpdate=function(i){this.updater.enqueueForceUpdate(this,i,"forceUpdate")};function Is(){}Is.prototype=En.prototype;function Qo(i,u,a){this.props=i,this.context=u,this.refs=Es,this.updater=a||ks}var qo=Qo.prototype=new Is;qo.constructor=Qo;Ps(qo,En.prototype);qo.isPureReactComponent=!0;var Cs=Array.isArray,Ns=Object.prototype.hasOwnProperty,Go={current:null},Ts={key:!0,ref:!0,__self:!0,__source:!0};function Ms(i,u,a){var p,g={},C=null,d=null;if(u!=null)for(p in u.ref!==void 0&&(d=u.ref),u.key!==void 0&&(C=""+u.key),u)Ns.call(u,p)&&!Ts.hasOwnProperty(p)&&(g[p]=u[p]);var _=arguments.length-2;if(_===1)g.children=a;else if(1<_){for(var P=Array(_),N=0;N<_;N++)P[N]=arguments[N+2];g.children=P}if(i&&i.defaultProps)for(p in _=i.defaultProps,_)g[p]===void 0&&(g[p]=_[p]);return{$$typeof:tr,type:i,key:C,ref:d,props:g,_owner:Go.current}}function wf(i,u){return{$$typeof:tr,type:i.type,key:u,ref:i.ref,props:i.props,_owner:i._owner}}function Jo(i){return typeof i=="object"&&i!==null&&i.$$typeof===tr}function Cf(i){var u={"=":"=0",":":"=2"};return"$"+i.replace(/[=:]/g,function(a){return u[a]})}var zs=/\/+/g;function Vo(i,u){return typeof i=="object"&&i!==null&&i.key!=null?Cf(""+i.key):u.toString(36)}function cl(i,u,a,p,g){var C=typeof i;(C==="undefined"||C==="boolean")&&(i=null);var d=!1;if(i===null)d=!0;else switch(C){case"string":case"number":d=!0;break;case"object":switch(i.$$typeof){case tr:case ff:d=!0}}if(d)return d=i,g=g(d),i=p===""?"."+Vo(d,0):p,Cs(g)?(a="",i!=null&&(a=i.replace(zs,"$&/")+"/"),cl(g,u,a,"",function(N){return N})):g!=null&&(Jo(g)&&(g=wf(g,a+(!g.key||d&&d.key===g.key?"":(""+g.key).replace(zs,"$&/")+"/")+i)),u.push(g)),1;if(d=0,p=p===""?".":p+":",Cs(i))for(var _=0;_{"use strict";Fs.exports=Ls()});var Js=Pn(J=>{"use strict";function $o(i,u){var a=i.length;i.push(u);e:for(;0>>1,g=i[p];if(0>>1;ppl(_,a))Ppl(N,_)?(i[p]=N,i[P]=a,p=P):(i[p]=_,i[d]=a,p=d);else if(Ppl(N,a))i[p]=N,i[P]=a,p=P;else break e}}return u}function pl(i,u){var a=i.sortIndex-u.sortIndex;return a!==0?a:i.id-u.id}typeof performance=="object"&&typeof performance.now=="function"?(js=performance,J.unstable_now=function(){return js.now()}):(Ko=Date,Hs=Ko.now(),J.unstable_now=function(){return Ko.now()-Hs});var js,Ko,Hs,vt=[],Vt=[],Pf=1,Xe=null,Se=3,gl=!1,un=!1,rr=!1,Bs=typeof setTimeout=="function"?setTimeout:null,Vs=typeof clearTimeout=="function"?clearTimeout:null,As=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function bo(i){for(var u=ot(Vt);u!==null;){if(u.callback===null)ml(Vt);else if(u.startTime<=i)ml(Vt),u.sortIndex=u.expirationTime,$o(vt,u);else break;u=ot(Vt)}}function ei(i){if(rr=!1,bo(i),!un)if(ot(vt)!==null)un=!0,ni(ti);else{var u=ot(Vt);u!==null&&ri(ei,u.startTime-i)}}function ti(i,u){un=!1,rr&&(rr=!1,Vs(lr),lr=-1),gl=!0;var a=Se;try{for(bo(u),Xe=ot(vt);Xe!==null&&(!(Xe.expirationTime>u)||i&&!Gs());){var p=Xe.callback;if(typeof p=="function"){Xe.callback=null,Se=Xe.priorityLevel;var g=p(Xe.expirationTime<=u);u=J.unstable_now(),typeof g=="function"?Xe.callback=g:Xe===ot(vt)&&ml(vt),bo(u)}else ml(vt);Xe=ot(vt)}if(Xe!==null)var C=!0;else{var d=ot(Vt);d!==null&&ri(ei,d.startTime-u),C=!1}return C}finally{Xe=null,Se=a,gl=!1}}var vl=!1,hl=null,lr=-1,Qs=5,qs=-1;function Gs(){return!(J.unstable_now()-qsi||125p?(i.sortIndex=a,$o(Vt,i),ot(vt)===null&&i===ot(Vt)&&(rr?(Vs(lr),lr=-1):rr=!0,ri(ei,a-p))):(i.sortIndex=g,$o(vt,i),un||gl||(un=!0,ni(ti))),i};J.unstable_shouldYield=Gs;J.unstable_wrapCallback=function(i){var u=Se;return function(){var a=Se;Se=u;try{return i.apply(this,arguments)}finally{Se=a}}}});var Ks=Pn((Yf,Zs)=>{"use strict";Zs.exports=Js()});var Ys=Pn(($f,Xs)=>{Xs.exports=function(u){var a={},p=Ke(),g=Ks(),C=Object.assign;function d(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n()=>(u||i((u={exports:{}}).exports,u),u.exports);var mf=(i,u,a,p)=>{if(u&&typeof u=="object"||typeof u=="function")for(let v of df(u))!gf.call(i,v)&&v!==a&&ks(i,v,{get:()=>u[v],enumerable:!(p=ff(u,v))||p.enumerable});return i};var at=(i,u,a)=>(a=i!=null?cf(pf(i)):{},mf(u||!i||!i.__esModule?ks(a,"default",{value:i,enumerable:!0}):a,i));var Os=Rn(A=>{"use strict";var sr=Symbol.for("react.element"),hf=Symbol.for("react.portal"),vf=Symbol.for("react.fragment"),yf=Symbol.for("react.strict_mode"),_f=Symbol.for("react.profiler"),xf=Symbol.for("react.provider"),Sf=Symbol.for("react.context"),wf=Symbol.for("react.forward_ref"),Cf=Symbol.for("react.suspense"),zf=Symbol.for("react.memo"),kf=Symbol.for("react.lazy"),Ps=Symbol.iterator;function Pf(i){return i===null||typeof i!="object"?null:(i=Ps&&i[Ps]||i["@@iterator"],typeof i=="function"?i:null)}var Ns={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Ts=Object.assign,Ms={};function Ln(i,u,a){this.props=i,this.context=u,this.refs=Ms,this.updater=a||Ns}Ln.prototype.isReactComponent={};Ln.prototype.setState=function(i,u){if(typeof i!="object"&&typeof i!="function"&&i!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,i,u,"setState")};Ln.prototype.forceUpdate=function(i){this.updater.enqueueForceUpdate(this,i,"forceUpdate")};function Rs(){}Rs.prototype=Ln.prototype;function Xo(i,u,a){this.props=i,this.context=u,this.refs=Ms,this.updater=a||Ns}var Yo=Xo.prototype=new Rs;Yo.constructor=Xo;Ts(Yo,Ln.prototype);Yo.isPureReactComponent=!0;var Es=Array.isArray,Ls=Object.prototype.hasOwnProperty,$o={current:null},Fs={key:!0,ref:!0,__self:!0,__source:!0};function Us(i,u,a){var p,v={},S=null,c=null;if(u!=null)for(p in u.ref!==void 0&&(c=u.ref),u.key!==void 0&&(S=""+u.key),u)Ls.call(u,p)&&!Fs.hasOwnProperty(p)&&(v[p]=u[p]);var _=arguments.length-2;if(_===1)v.children=a;else if(1<_){for(var z=Array(_),N=0;N<_;N++)z[N]=arguments[N+2];v.children=z}if(i&&i.defaultProps)for(p in _=i.defaultProps,_)v[p]===void 0&&(v[p]=_[p]);return{$$typeof:sr,type:i,key:S,ref:c,props:v,_owner:$o.current}}function Ef(i,u){return{$$typeof:sr,type:i.type,key:u,ref:i.ref,props:i.props,_owner:i._owner}}function bo(i){return typeof i=="object"&&i!==null&&i.$$typeof===sr}function If(i){var u={"=":"=0",":":"=2"};return"$"+i.replace(/[=:]/g,function(a){return u[a]})}var Is=/\/+/g;function Ko(i,u){return typeof i=="object"&&i!==null&&i.key!=null?If(""+i.key):u.toString(36)}function gl(i,u,a,p,v){var S=typeof i;(S==="undefined"||S==="boolean")&&(i=null);var c=!1;if(i===null)c=!0;else switch(S){case"string":case"number":c=!0;break;case"object":switch(i.$$typeof){case sr:case hf:c=!0}}if(c)return c=i,v=v(c),i=p===""?"."+Ko(c,0):p,Es(v)?(a="",i!=null&&(a=i.replace(Is,"$&/")+"/"),gl(v,u,a,"",function(N){return N})):v!=null&&(bo(v)&&(v=Ef(v,a+(!v.key||c&&c.key===v.key?"":(""+v.key).replace(Is,"$&/")+"/")+i)),u.push(v)),1;if(c=0,p=p===""?".":p+":",Es(i))for(var _=0;_{"use strict";js.exports=Os()});var $s=Rn(Z=>{"use strict";function li(i,u){var a=i.length;i.push(u);e:for(;0>>1,v=i[p];if(0>>1;pyl(_,a))zyl(N,_)?(i[p]=N,i[z]=a,p=z):(i[p]=_,i[c]=a,p=c);else if(zyl(N,a))i[p]=N,i[z]=a,p=z;else break e}}return u}function yl(i,u){var a=i.sortIndex-u.sortIndex;return a!==0?a:i.id-u.id}typeof performance=="object"&&typeof performance.now=="function"?(Vs=performance,Z.unstable_now=function(){return Vs.now()}):(ti=Date,Qs=ti.now(),Z.unstable_now=function(){return ti.now()-Qs});var Vs,ti,Qs,St=[],Zt=[],Mf=1,be=null,Ce=3,Sl=!1,pn=!1,fr=!1,Js=typeof setTimeout=="function"?setTimeout:null,Zs=typeof clearTimeout=="function"?clearTimeout:null,qs=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function oi(i){for(var u=ct(Zt);u!==null;){if(u.callback===null)xl(Zt);else if(u.startTime<=i)xl(Zt),u.sortIndex=u.expirationTime,li(St,u);else break;u=ct(Zt)}}function ii(i){if(fr=!1,oi(i),!pn)if(ct(St)!==null)pn=!0,si(ui);else{var u=ct(Zt);u!==null&&ai(ii,u.startTime-i)}}function ui(i,u){pn=!1,fr&&(fr=!1,Zs(dr),dr=-1),Sl=!0;var a=Ce;try{for(oi(u),be=ct(St);be!==null&&(!(be.expirationTime>u)||i&&!Ys());){var p=be.callback;if(typeof p=="function"){be.callback=null,Ce=be.priorityLevel;var v=p(be.expirationTime<=u);u=Z.unstable_now(),typeof v=="function"?be.callback=v:be===ct(St)&&xl(St),oi(u)}else xl(St);be=ct(St)}if(be!==null)var S=!0;else{var c=ct(Zt);c!==null&&ai(ii,c.startTime-u),S=!1}return S}finally{be=null,Ce=a,Sl=!1}}var wl=!1,_l=null,dr=-1,Ks=5,Xs=-1;function Ys(){return!(Z.unstable_now()-Xsi||125p?(i.sortIndex=a,li(Zt,i),ct(St)===null&&i===ct(Zt)&&(fr?(Zs(dr),dr=-1):fr=!0,ai(ii,a-p))):(i.sortIndex=v,li(St,i),pn||Sl||(pn=!0,si(ui))),i};Z.unstable_shouldYield=Ys;Z.unstable_wrapCallback=function(i){var u=Ce;return function(){var a=Ce;Ce=u;try{return i.apply(this,arguments)}finally{Ce=a}}}});var ea=Rn((od,bs)=>{"use strict";bs.exports=$s()});var na=Rn((id,ta)=>{ta.exports=function(u){var a={},p=$e(),v=ea(),S=Object.assign;function c(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;nc||l[s]!==o[c]){var v=` -`+l[s].replace(" at new "," at ");return e.displayName&&v.includes("")&&(v=v.replace("",e.displayName)),v}while(1<=s&&0<=c);break}}}finally{Ml=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?Dn(e):""}var dc=Object.prototype.hasOwnProperty,Ll=[],dn=-1;function Lt(e){return{current:e}}function Z(e){0>dn||(e.current=Ll[dn],Ll[dn]=null,dn--)}function G(e,t){dn++,Ll[dn]=e.current,e.current=t}var Ft={},ge=Lt(Ft),ke=Lt(!1),Xt=Ft;function pn(e,t){var n=e.type.contextTypes;if(!n)return Ft;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var l={},o;for(o in n)l[o]=t[o];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=l),l}function Pe(e){return e=e.childContextTypes,e!=null}function yr(){Z(ke),Z(ge)}function Ai(e,t,n){if(ge.current!==Ft)throw Error(d(168));G(ge,t),G(ke,n)}function Wi(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var l in r)if(!(l in t))throw Error(d(108,He(e)||"Unknown",l));return C({},n,r)}function _r(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Ft,Xt=ge.current,G(ge,e),G(ke,ke.current),!0}function Bi(e,t,n){var r=e.stateNode;if(!r)throw Error(d(169));n?(e=Wi(e,t,Xt),r.__reactInternalMemoizedMergedChildContext=e,Z(ke),Z(ge),G(ge,e)):Z(ke),G(ke,n)}var $e=Math.clz32?Math.clz32:mc,pc=Math.log,hc=Math.LN2;function mc(e){return e>>>=0,e===0?32:31-(pc(e)/hc|0)|0}var xr=64,Sr=4194304;function On(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function wr(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,l=e.suspendedLanes,o=e.pingedLanes,s=n&268435455;if(s!==0){var c=s&~l;c!==0?r=On(c):(o&=s,o!==0&&(r=On(o)))}else s=n&~l,s!==0?r=On(s):o!==0&&(r=On(o));if(r===0)return 0;if(t!==0&&t!==r&&(t&l)===0&&(l=r&-r,o=t&-t,l>=o||l===16&&(o&4194240)!==0))return t;if((r&4)!==0&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function jn(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-$e(t),e[t]=n}function yc(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0>=s,l-=s,wt=1<<32-$e(t)+l|n<B?(ae=F,F=null):ae=F.sibling;var V=z(m,F,y[B],k);if(V===null){F===null&&(F=ae);break}e&&F&&V.alternate===null&&t(m,F),f=o(V,f,B),U===null?M=V:U.sibling=V,U=V,F=ae}if(B===y.length)return n(m,F),X&&$t(m,B),M;if(F===null){for(;BB?(ae=F,F=null):ae=F.sibling;var Bt=z(m,F,V.value,k);if(Bt===null){F===null&&(F=ae);break}e&&F&&Bt.alternate===null&&t(m,F),f=o(Bt,f,B),U===null?M=Bt:U.sibling=Bt,U=Bt,F=ae}if(V.done)return n(m,F),X&&$t(m,B),M;if(F===null){for(;!V.done;B++,V=y.next())V=L(m,V.value,k),V!==null&&(f=o(V,f,B),U===null?M=V:U.sibling=V,U=V);return X&&$t(m,B),M}for(F=r(m,F);!V.done;B++,V=y.next())V=K(F,m,B,V.value,k),V!==null&&(e&&V.alternate!==null&&F.delete(V.key===null?B:V.key),f=o(V,f,B),U===null?M=V:U.sibling=V,U=V);return e&&F.forEach(function(rf){return t(m,rf)}),X&&$t(m,B),M}function Et(m,f,y,k){if(typeof y=="object"&&y!==null&&y.type===R&&y.key===null&&(y=y.props.children),typeof y=="object"&&y!==null){switch(y.$$typeof){case P:e:{for(var M=y.key,U=f;U!==null;){if(U.key===M){if(M=y.type,M===R){if(U.tag===7){n(m,U.sibling),f=l(U,y.props.children),f.return=m,m=f;break e}}else if(U.elementType===M||typeof M=="object"&&M!==null&&M.$$typeof===st&&$i(M)===U.type){n(m,U.sibling),f=l(U,y.props),f.ref=An(m,U,y),f.return=m,m=f;break e}n(m,U);break}else t(m,U);U=U.sibling}y.type===R?(f=on(y.props.children,m.mode,k,y.key),f.return=m,m=f):(k=il(y.type,y.key,y.props,null,m.mode,k),k.ref=An(m,f,y),k.return=m,m=k)}return s(m);case N:e:{for(U=y.key;f!==null;){if(f.key===U)if(f.tag===4&&f.stateNode.containerInfo===y.containerInfo&&f.stateNode.implementation===y.implementation){n(m,f.sibling),f=l(f,y.children||[]),f.return=m,m=f;break e}else{n(m,f);break}else t(m,f);f=f.sibling}f=Bo(y,m.mode,k),f.return=m,m=f}return s(m);case st:return U=y._init,Et(m,f,U(y._payload),k)}if(hr(y))return q(m,f,y,k);if(Kt(y))return Te(m,f,y,k);Nr(m,y)}return typeof y=="string"&&y!==""||typeof y=="number"?(y=""+y,f!==null&&f.tag===6?(n(m,f.sibling),f=l(f,y),f.return=m,m=f):(n(m,f),f=Wo(y,m.mode,k),f.return=m,m=f),s(m)):n(m,f)}return Et}var vn=bi(!0),eu=bi(!1),Tr=Lt(null),Mr=null,yn=null,Gl=null;function Jl(){Gl=yn=Mr=null}function tu(e,t,n){mr?(G(Tr,t._currentValue),t._currentValue=n):(G(Tr,t._currentValue2),t._currentValue2=n)}function Zl(e){var t=Tr.current;Z(Tr),mr?e._currentValue=t:e._currentValue2=t}function Kl(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,r!==null&&(r.childLanes|=t)):r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function _n(e,t){Mr=e,Gl=yn=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(Ee=!0),e.firstContext=null)}function Qe(e){var t=mr?e._currentValue:e._currentValue2;if(Gl!==e)if(e={context:e,memoizedValue:t,next:null},yn===null){if(Mr===null)throw Error(d(308));yn=e,Mr.dependencies={lanes:0,firstContext:e}}else yn=yn.next=e;return t}var bt=null;function Xl(e){bt===null?bt=[e]:bt.push(e)}function nu(e,t,n,r){var l=t.interleaved;return l===null?(n.next=n,Xl(t)):(n.next=l.next,l.next=n),t.interleaved=n,ft(e,r)}function ft(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var Ut=!1;function Yl(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function ru(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function zt(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Dt(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,(D&2)!==0){var l=r.pending;return l===null?t.next=t:(t.next=l.next,l.next=t),r.pending=t,ft(e,n)}return l=r.interleaved,l===null?(t.next=t,Xl(r)):(t.next=l.next,l.next=t),r.interleaved=t,ft(e,n)}function Rr(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194240)!==0)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Dl(e,n)}}function lu(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var l=null,o=null;if(n=n.firstBaseUpdate,n!==null){do{var s={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};o===null?l=o=s:o=o.next=s,n=n.next}while(n!==null);o===null?l=o=t:o=o.next=t}else l=o=t;n={baseState:r.baseState,firstBaseUpdate:l,lastBaseUpdate:o,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Lr(e,t,n,r){var l=e.updateQueue;Ut=!1;var o=l.firstBaseUpdate,s=l.lastBaseUpdate,c=l.shared.pending;if(c!==null){l.shared.pending=null;var v=c,x=v.next;v.next=null,s===null?o=x:s.next=x,s=v;var I=e.alternate;I!==null&&(I=I.updateQueue,c=I.lastBaseUpdate,c!==s&&(c===null?I.firstBaseUpdate=x:c.next=x,I.lastBaseUpdate=v))}if(o!==null){var L=l.baseState;s=0,I=x=v=null,c=o;do{var z=c.lane,K=c.eventTime;if((r&z)===z){I!==null&&(I=I.next={eventTime:K,lane:0,tag:c.tag,payload:c.payload,callback:c.callback,next:null});e:{var q=e,Te=c;switch(z=t,K=n,Te.tag){case 1:if(q=Te.payload,typeof q=="function"){L=q.call(K,L,z);break e}L=q;break e;case 3:q.flags=q.flags&-65537|128;case 0:if(q=Te.payload,z=typeof q=="function"?q.call(K,L,z):q,z==null)break e;L=C({},L,z);break e;case 2:Ut=!0}}c.callback!==null&&c.lane!==0&&(e.flags|=64,z=l.effects,z===null?l.effects=[c]:z.push(c))}else K={eventTime:K,lane:z,tag:c.tag,payload:c.payload,callback:c.callback,next:null},I===null?(x=I=K,v=L):I=I.next=K,s|=z;if(c=c.next,c===null){if(c=l.shared.pending,c===null)break;z=c,c=z.next,z.next=null,l.lastBaseUpdate=z,l.shared.pending=null}}while(!0);if(I===null&&(v=L),l.baseState=v,l.firstBaseUpdate=x,l.lastBaseUpdate=I,t=l.shared.interleaved,t!==null){l=t;do s|=l.lane,l=l.next;while(l!==t)}else o===null&&(l.shared.lanes=0);tn|=s,e.lanes=s,e.memoizedState=L}}function ou(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;tn?n:4,e(!0);var r=no.transition;no.transition={};try{e(!1),t()}finally{W=n,no.transition=r}}function zu(){return Ge().memoizedState}function Tc(e,t,n){var r=Ht(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},ku(e))Pu(t,n);else if(n=nu(e,t,n,r),n!==null){var l=xe();Je(n,e,r,l),Eu(n,t,r)}}function Mc(e,t,n){var r=Ht(e),l={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(ku(e))Pu(t,l);else{var o=e.alternate;if(e.lanes===0&&(o===null||o.lanes===0)&&(o=t.lastRenderedReducer,o!==null))try{var s=t.lastRenderedState,c=o(s,n);if(l.hasEagerState=!0,l.eagerState=c,be(c,s)){var v=t.interleaved;v===null?(l.next=l,Xl(t)):(l.next=v.next,v.next=l),t.interleaved=l;return}}catch{}finally{}n=nu(e,t,l,r),n!==null&&(l=xe(),Je(n,e,r,l),Eu(n,t,r))}}function ku(e){var t=e.alternate;return e===ee||t!==null&&t===ee}function Pu(e,t){Vn=Dr=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Eu(e,t,n){if((n&4194240)!==0){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Dl(e,n)}}var Hr={readContext:Qe,useCallback:ve,useContext:ve,useEffect:ve,useImperativeHandle:ve,useInsertionEffect:ve,useLayoutEffect:ve,useMemo:ve,useReducer:ve,useRef:ve,useState:ve,useDebugValue:ve,useDeferredValue:ve,useTransition:ve,useMutableSource:ve,useSyncExternalStore:ve,useId:ve,unstable_isNewReconciler:!1},Rc={readContext:Qe,useCallback:function(e,t){return pt().memoizedState=[e,t===void 0?null:t],e},useContext:Qe,useEffect:gu,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,Or(4194308,4,_u.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Or(4194308,4,e,t)},useInsertionEffect:function(e,t){return Or(4,2,e,t)},useMemo:function(e,t){var n=pt();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=pt();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=Tc.bind(null,ee,e),[r.memoizedState,e]},useRef:function(e){var t=pt();return e={current:e},t.memoizedState=e},useState:hu,useDebugValue:ao,useDeferredValue:function(e){return pt().memoizedState=e},useTransition:function(){var e=hu(!1),t=e[0];return e=Nc.bind(null,e[1]),pt().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=ee,l=pt();if(X){if(n===void 0)throw Error(d(407));n=n()}else{if(n=t(),se===null)throw Error(d(349));(en&30)!==0||au(r,t,n)}l.memoizedState=n;var o={value:n,getSnapshot:t};return l.queue=o,gu(fu.bind(null,r,o,e),[e]),r.flags|=2048,Gn(9,cu.bind(null,r,o,n,t),void 0,null),n},useId:function(){var e=pt(),t=se.identifierPrefix;if(X){var n=Ct,r=wt;n=(r&~(1<<32-$e(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=Qn++,0f||l[s]!==o[f]){var m=` +`+l[s].replace(" at new "," at ");return e.displayName&&m.includes("")&&(m=m.replace("",e.displayName)),m}while(1<=s&&0<=f);break}}}finally{Ol=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?Vn(e):""}var vc=Object.prototype.hasOwnProperty,Hl=[],yn=-1;function jt(e){return{current:e}}function K(e){0>yn||(e.current=Hl[yn],Hl[yn]=null,yn--)}function J(e,t){yn++,Hl[yn]=e.current,e.current=t}var Ht={},ye=jt(Ht),Ne=jt(!1),nn=Ht;function _n(e,t){var n=e.type.contextTypes;if(!n)return Ht;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var l={},o;for(o in n)l[o]=t[o];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=l),l}function Te(e){return e=e.childContextTypes,e!=null}function wr(){K(Ne),K(ye)}function Qi(e,t,n){if(ye.current!==Ht)throw Error(c(168));J(ye,t),J(Ne,n)}function qi(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var l in r)if(!(l in t))throw Error(c(108,Ti(e)||"Unknown",l));return S({},n,r)}function Cr(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Ht,nn=ye.current,J(ye,e),J(Ne,Ne.current),!0}function Gi(e,t,n){var r=e.stateNode;if(!r)throw Error(c(169));n?(e=qi(e,t,nn),r.__reactInternalMemoizedMergedChildContext=e,K(Ne),K(ye),J(ye,e)):K(Ne),J(Ne,n)}var rt=Math.clz32?Math.clz32:xc,yc=Math.log,_c=Math.LN2;function xc(e){return e>>>=0,e===0?32:31-(yc(e)/_c|0)|0}var zr=64,kr=4194304;function Qn(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Pr(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,l=e.suspendedLanes,o=e.pingedLanes,s=n&268435455;if(s!==0){var f=s&~l;f!==0?r=Qn(f):(o&=s,o!==0&&(r=Qn(o)))}else s=n&~l,s!==0?r=Qn(s):o!==0&&(r=Qn(o));if(r===0)return 0;if(t!==0&&t!==r&&(t&l)===0&&(l=r&-r,o=t&-t,l>=o||l===16&&(o&4194240)!==0))return t;if((r&4)!==0&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function qn(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-rt(t),e[t]=n}function Cc(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0>=s,l-=s,Et=1<<32-rt(t)+l|n<V?(de=U,U=null):de=U.sibling;var Q=w(g,U,y[V],C);if(Q===null){U===null&&(U=de);break}e&&U&&Q.alternate===null&&t(g,U),d=o(Q,d,V),D===null?T=Q:D.sibling=Q,D=Q,U=de}if(V===y.length)return n(g,U),b&&ln(g,V),T;if(U===null){for(;VV?(de=U,U=null):de=U.sibling;var Jt=w(g,U,Q.value,C);if(Jt===null){U===null&&(U=de);break}e&&U&&Jt.alternate===null&&t(g,U),d=o(Jt,d,V),D===null?T=Jt:D.sibling=Jt,D=Jt,U=de}if(Q.done)return n(g,U),b&&ln(g,V),T;if(U===null){for(;!Q.done;V++,Q=y.next())Q=F(g,Q.value,C),Q!==null&&(d=o(Q,d,V),D===null?T=Q:D.sibling=Q,D=Q);return b&&ln(g,V),T}for(U=r(g,U);!Q.done;V++,Q=y.next())Q=X(U,g,V,Q.value,C),Q!==null&&(e&&Q.alternate!==null&&U.delete(Q.key===null?V:Q.key),d=o(Q,d,V),D===null?T=Q:D.sibling=Q,D=Q);return e&&U.forEach(function(af){return t(g,af)}),b&&ln(g,V),T}function Rt(g,d,y,C){if(typeof y=="object"&&y!==null&&y.type===L&&y.key===null&&(y=y.props.children),typeof y=="object"&&y!==null){switch(y.$$typeof){case z:e:{for(var T=y.key,D=d;D!==null;){if(D.key===T){if(T=y.type,T===L){if(D.tag===7){n(g,D.sibling),d=l(D,y.props.children),d.return=g,g=d;break e}}else if(D.elementType===T||typeof T=="object"&&T!==null&&T.$$typeof===E&&nu(T)===D.type){n(g,D.sibling),d=l(D,y.props),d.ref=Jn(g,D,y),d.return=g,g=d;break e}n(g,D);break}else t(g,D);D=D.sibling}y.type===L?(d=dn(y.props.children,g.mode,C,y.key),d.return=g,g=d):(C=cl(y.type,y.key,y.props,null,g.mode,C),C.ref=Jn(g,d,y),C.return=g,g=C)}return s(g);case N:e:{for(D=y.key;d!==null;){if(d.key===D)if(d.tag===4&&d.stateNode.containerInfo===y.containerInfo&&d.stateNode.implementation===y.implementation){n(g,d.sibling),d=l(d,y.children||[]),d.return=g,g=d;break e}else{n(g,d);break}else t(g,d);d=d.sibling}d=Zo(y,g.mode,C),d.return=g,g=d}return s(g);case E:return D=y._init,Rt(g,d,D(y._payload),C)}if(yr(y))return G(g,d,y,C);if(zt(y))return Fe(g,d,y,C);Lr(g,y)}return typeof y=="string"&&y!==""||typeof y=="number"?(y=""+y,d!==null&&d.tag===6?(n(g,d.sibling),d=l(d,y),d.return=g,g=d):(n(g,d),d=Jo(y,g.mode,C),d.return=g,g=d),s(g)):n(g,d)}return Rt}var Cn=ru(!0),lu=ru(!1),Fr=jt(null),Ur=null,zn=null,$l=null;function bl(){$l=zn=Ur=null}function ou(e,t,n){_r?(J(Fr,t._currentValue),t._currentValue=n):(J(Fr,t._currentValue2),t._currentValue2=n)}function eo(e){var t=Fr.current;K(Fr),_r?e._currentValue=t:e._currentValue2=t}function to(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,r!==null&&(r.childLanes|=t)):r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function kn(e,t){Ur=e,$l=zn=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(Me=!0),e.firstContext=null)}function Je(e){var t=_r?e._currentValue:e._currentValue2;if($l!==e)if(e={context:e,memoizedValue:t,next:null},zn===null){if(Ur===null)throw Error(c(308));zn=e,Ur.dependencies={lanes:0,firstContext:e}}else zn=zn.next=e;return t}var on=null;function no(e){on===null?on=[e]:on.push(e)}function iu(e,t,n,r){var l=t.interleaved;return l===null?(n.next=n,no(t)):(n.next=l.next,l.next=n),t.interleaved=n,mt(e,r)}function mt(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var At=!1;function ro(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function uu(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Nt(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Wt(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,(H&2)!==0){var l=r.pending;return l===null?t.next=t:(t.next=l.next,l.next=t),r.pending=t,mt(e,n)}return l=r.interleaved,l===null?(t.next=t,no(r)):(t.next=l.next,l.next=t),r.interleaved=t,mt(e,n)}function Dr(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194240)!==0)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Bl(e,n)}}function su(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var l=null,o=null;if(n=n.firstBaseUpdate,n!==null){do{var s={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};o===null?l=o=s:o=o.next=s,n=n.next}while(n!==null);o===null?l=o=t:o=o.next=t}else l=o=t;n={baseState:r.baseState,firstBaseUpdate:l,lastBaseUpdate:o,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Or(e,t,n,r){var l=e.updateQueue;At=!1;var o=l.firstBaseUpdate,s=l.lastBaseUpdate,f=l.shared.pending;if(f!==null){l.shared.pending=null;var m=f,x=m.next;m.next=null,s===null?o=x:s.next=x,s=m;var P=e.alternate;P!==null&&(P=P.updateQueue,f=P.lastBaseUpdate,f!==s&&(f===null?P.firstBaseUpdate=x:f.next=x,P.lastBaseUpdate=m))}if(o!==null){var F=l.baseState;s=0,P=x=m=null,f=o;do{var w=f.lane,X=f.eventTime;if((r&w)===w){P!==null&&(P=P.next={eventTime:X,lane:0,tag:f.tag,payload:f.payload,callback:f.callback,next:null});e:{var G=e,Fe=f;switch(w=t,X=n,Fe.tag){case 1:if(G=Fe.payload,typeof G=="function"){F=G.call(X,F,w);break e}F=G;break e;case 3:G.flags=G.flags&-65537|128;case 0:if(G=Fe.payload,w=typeof G=="function"?G.call(X,F,w):G,w==null)break e;F=S({},F,w);break e;case 2:At=!0}}f.callback!==null&&f.lane!==0&&(e.flags|=64,w=l.effects,w===null?l.effects=[f]:w.push(f))}else X={eventTime:X,lane:w,tag:f.tag,payload:f.payload,callback:f.callback,next:null},P===null?(x=P=X,m=F):P=P.next=X,s|=w;if(f=f.next,f===null){if(f=l.shared.pending,f===null)break;w=f,f=w.next,w.next=null,l.lastBaseUpdate=w,l.shared.pending=null}}while(!0);if(P===null&&(m=F),l.baseState=m,l.firstBaseUpdate=x,l.lastBaseUpdate=P,t=l.shared.interleaved,t!==null){l=t;do s|=l.lane,l=l.next;while(l!==t)}else o===null&&(l.shared.lanes=0);sn|=s,e.lanes=s,e.memoizedState=F}}function au(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;tn?n:4,e(!0);var r=so.transition;so.transition={};try{e(!1),t()}finally{B=n,so.transition=r}}function Iu(){return Ke().memoizedState}function Uc(e,t,n){var r=Qt(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},Nu(e))Tu(t,n);else if(n=iu(e,t,n,r),n!==null){var l=we();Xe(n,e,r,l),Mu(n,t,r)}}function Dc(e,t,n){var r=Qt(e),l={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(Nu(e))Tu(t,l);else{var o=e.alternate;if(e.lanes===0&&(o===null||o.lanes===0)&&(o=t.lastRenderedReducer,o!==null))try{var s=t.lastRenderedState,f=o(s,n);if(l.hasEagerState=!0,l.eagerState=f,lt(f,s)){var m=t.interleaved;m===null?(l.next=l,no(t)):(l.next=m.next,m.next=l),t.interleaved=l;return}}catch{}finally{}n=iu(e,t,l,r),n!==null&&(l=we(),Xe(n,e,r,l),Mu(n,t,r))}}function Nu(e){var t=e.alternate;return e===re||t!==null&&t===re}function Tu(e,t){Xn=Ar=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Mu(e,t,n){if((n&4194240)!==0){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Bl(e,n)}}var Vr={readContext:Je,useCallback:_e,useContext:_e,useEffect:_e,useImperativeHandle:_e,useInsertionEffect:_e,useLayoutEffect:_e,useMemo:_e,useReducer:_e,useRef:_e,useState:_e,useDebugValue:_e,useDeferredValue:_e,useTransition:_e,useMutableSource:_e,useSyncExternalStore:_e,useId:_e,unstable_isNewReconciler:!1},Oc={readContext:Je,useCallback:function(e,t){return vt().memoizedState=[e,t===void 0?null:t],e},useContext:Je,useEffect:xu,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,Wr(4194308,4,Cu.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Wr(4194308,4,e,t)},useInsertionEffect:function(e,t){return Wr(4,2,e,t)},useMemo:function(e,t){var n=vt();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=vt();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=Uc.bind(null,re,e),[r.memoizedState,e]},useRef:function(e){var t=vt();return e={current:e},t.memoizedState=e},useState:yu,useDebugValue:ho,useDeferredValue:function(e){return vt().memoizedState=e},useTransition:function(){var e=yu(!1),t=e[0];return e=Fc.bind(null,e[1]),vt().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=re,l=vt();if(b){if(n===void 0)throw Error(c(407));n=n()}else{if(n=t(),fe===null)throw Error(c(349));(un&30)!==0||pu(r,t,n)}l.memoizedState=n;var o={value:n,getSnapshot:t};return l.queue=o,xu(mu.bind(null,r,o,e),[e]),r.flags|=2048,bn(9,gu.bind(null,r,o,n,t),void 0,null),n},useId:function(){var e=vt(),t=fe.identifierPrefix;if(b){var n=It,r=Et;n=(r&~(1<<32-rt(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=Yn++,0Lo&&(t.flags|=128,r=!0,Kn(l,!1),t.lanes=4194304)}else{if(!r)if(e=Fr(o),e!==null){if(t.flags|=128,r=!0,e=e.updateQueue,e!==null&&(t.updateQueue=e,t.flags|=4),Kn(l,!0),l.tail===null&&l.tailMode==="hidden"&&!o.alternate&&!X)return ye(t),null}else 2*ie()-l.renderingStartTime>Lo&&n!==1073741824&&(t.flags|=128,r=!0,Kn(l,!1),t.lanes=4194304);l.isBackwards?(o.sibling=t.child,t.child=o):(e=l.last,e!==null?e.sibling=o:t.child=o,l.last=o)}return l.tail!==null?(t=l.tail,l.rendering=t,l.tail=t.sibling,l.renderingStartTime=ie(),t.sibling=null,e=b.current,G(b,r?e&1|2:e&1),t):(ye(t),null);case 22:case 23:return jo(),n=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==n&&(t.flags|=8192),n&&(t.mode&1)!==0?(Fe&1073741824)!==0&&(ye(t),Re&&t.subtreeFlags&6&&(t.flags|=8192)):ye(t),null;case 24:return null;case 25:return null}throw Error(d(156,t.tag))}function Ac(e,t){switch(Bl(t),t.tag){case 1:return Pe(t.type)&&yr(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Sn(),Z(ke),Z(ge),to(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return bl(t),null;case 13:if(Z(b),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(d(340));gn()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Z(b),null;case 4:return Sn(),null;case 10:return Zl(t.type._context),null;case 22:case 23:return jo(),null;case 24:return null;default:return null}}var qr=!1,_e=!1,Wc=typeof WeakSet=="function"?WeakSet:Set,E=null;function Cn(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){Y(e,t,r)}else n.current=null}function So(e,t,n){try{n()}catch(r){Y(e,t,r)}}var Ku=!1;function Bc(e,t){for(ma(e.containerInfo),E=t;E!==null;)if(e=E,t=e.child,(e.subtreeFlags&1028)!==0&&t!==null)t.return=e,E=t;else for(;E!==null;){e=E;try{var n=e.alternate;if((e.flags&1024)!==0)switch(e.tag){case 0:case 11:case 15:break;case 1:if(n!==null){var r=n.memoizedProps,l=n.memoizedState,o=e.stateNode,s=o.getSnapshotBeforeUpdate(e.elementType===e.type?r:tt(e.type,r),l);o.__reactInternalSnapshotBeforeUpdate=s}break;case 3:Re&&Qa(e.stateNode.containerInfo);break;case 5:case 6:case 4:case 17:break;default:throw Error(d(163))}}catch(c){Y(e,e.return,c)}if(t=e.sibling,t!==null){t.return=e.return,E=t;break}E=e.return}return n=Ku,Ku=!1,n}function Xn(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var l=r=r.next;do{if((l.tag&e)===e){var o=l.destroy;l.destroy=void 0,o!==void 0&&So(t,n,o)}l=l.next}while(l!==r)}}function Gr(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function wo(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=zl(n);break;default:e=n}typeof t=="function"?t(e):t.current=e}}function Xu(e){var t=e.alternate;t!==null&&(e.alternate=null,Xu(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&wa(t)),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Yu(e){return e.tag===5||e.tag===3||e.tag===4}function $u(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Yu(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Co(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?Oa(n,e,t):Ra(n,e);else if(r!==4&&(e=e.child,e!==null))for(Co(e,t,n),e=e.sibling;e!==null;)Co(e,t,n),e=e.sibling}function zo(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?Da(n,e,t):Ma(n,e);else if(r!==4&&(e=e.child,e!==null))for(zo(e,t,n),e=e.sibling;e!==null;)zo(e,t,n),e=e.sibling}var fe=null,nt=!1;function mt(e,t,n){for(n=n.child;n!==null;)ko(e,t,n),n=n.sibling}function ko(e,t,n){if(at&&typeof at.onCommitFiberUnmount=="function")try{at.onCommitFiberUnmount(Cr,n)}catch{}switch(n.tag){case 5:_e||Cn(n,t);case 6:if(Re){var r=fe,l=nt;fe=null,mt(e,t,n),fe=r,nt=l,fe!==null&&(nt?Ha(fe,n.stateNode):ja(fe,n.stateNode))}else mt(e,t,n);break;case 18:Re&&fe!==null&&(nt?sc(fe,n.stateNode):uc(fe,n.stateNode));break;case 4:Re?(r=fe,l=nt,fe=n.stateNode.containerInfo,nt=!0,mt(e,t,n),fe=r,nt=l):(gr&&(r=n.stateNode.containerInfo,l=Ui(r),Il(r,l)),mt(e,t,n));break;case 0:case 11:case 14:case 15:if(!_e&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){l=r=r.next;do{var o=l,s=o.destroy;o=o.tag,s!==void 0&&((o&2)!==0||(o&4)!==0)&&So(n,t,s),l=l.next}while(l!==r)}mt(e,t,n);break;case 1:if(!_e&&(Cn(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(c){Y(n,t,c)}mt(e,t,n);break;case 21:mt(e,t,n);break;case 22:n.mode&1?(_e=(r=_e)||n.memoizedState!==null,mt(e,t,n),_e=r):mt(e,t,n);break;default:mt(e,t,n)}}function bu(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new Wc),t.forEach(function(r){var l=Yc.bind(null,e,r);n.has(r)||(n.add(r),r.then(l,l))})}}function rt(e,t){var n=t.deletions;if(n!==null)for(var r=0;r";case Zr:return":has("+(Io(e)||"")+")";case Kr:return'[role="'+e.value+'"]';case Yr:return'"'+e.value+'"';case Xr:return'[data-testname="'+e.value+'"]';default:throw Error(d(365))}}function os(e,t){var n=[];e=[e,0];for(var r=0;rl&&(l=s),r&=~o}if(r=l,r=ie()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Qc(r/1960))-r,10e?16:e,jt===null)var r=!1;else{if(e=jt,jt=null,nl=0,(D&6)!==0)throw Error(d(331));var l=D;for(D|=4,E=e.current;E!==null;){var o=E,s=o.child;if((E.flags&16)!==0){var c=o.deletions;if(c!==null){for(var v=0;vie()-Ro?nn(e,0):Mo|=n),Ne(e,t)}function hs(e,t){t===0&&((e.mode&1)===0?t=1:(t=Sr,Sr<<=1,(Sr&130023424)===0&&(Sr=4194304)));var n=xe();e=ft(e,t),e!==null&&(jn(e,t,n),Ne(e,n))}function Xc(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),hs(e,n)}function Yc(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,l=e.memoizedState;l!==null&&(n=l.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(d(314))}r!==null&&r.delete(t),hs(e,n)}var ms;ms=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||ke.current)Ee=!0;else{if((e.lanes&n)===0&&(t.flags&128)===0)return Ee=!1,jc(e,t,n);Ee=(e.flags&131072)!==0}else Ee=!1,X&&(t.flags&1048576)!==0&&Ji(t,Pr,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;Br(e,t),e=t.pendingProps;var l=pn(t,ge.current);_n(t,n),l=lo(null,t,r,e,l,n);var o=oo();return t.flags|=1,typeof l=="object"&&l!==null&&typeof l.render=="function"&&l.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Pe(r)?(o=!0,_r(t)):o=!1,t.memoizedState=l.state!==null&&l.state!==void 0?l.state:null,Yl(t),l.updater=Ar,t.stateNode=l,l._reactInternals=t,fo(t,r,e,n),t=go(null,t,r,!0,o,n)):(t.tag=0,X&&o&&Wl(t),Ce(null,t,l,n),t=t.child),t;case 16:r=t.elementType;e:{switch(Br(e,t),e=t.pendingProps,l=r._init,r=l(r._payload),t.type=r,l=t.tag=bc(r),e=tt(r,e),l){case 0:t=mo(null,t,r,e,n);break e;case 1:t=Wu(null,t,r,e,n);break e;case 11:t=Du(null,t,r,e,n);break e;case 14:t=Ou(null,t,r,tt(r.type,e),n);break e}throw Error(d(306,r,""))}return t;case 0:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:tt(r,l),mo(e,t,r,l,n);case 1:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:tt(r,l),Wu(e,t,r,l,n);case 3:e:{if(Bu(t),e===null)throw Error(d(387));r=t.pendingProps,o=t.memoizedState,l=o.element,ru(e,t),Lr(t,r,null,n);var s=t.memoizedState;if(r=s.element,Ae&&o.isDehydrated)if(o={element:r,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=o,t.memoizedState=o,t.flags&256){l=wn(Error(d(423)),t),t=Vu(e,t,r,n,l);break e}else if(r!==l){l=wn(Error(d(424)),t),t=Vu(e,t,r,n,l);break e}else for(Ae&&(Ve=ba(t.stateNode.containerInfo),Le=t,X=!0,et=null,Hn=!1),n=eu(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(gn(),r===l){t=kt(e,t,n);break e}Ce(e,t,r,n)}t=t.child}return t;case 5:return iu(t),e===null&&Ql(t),r=t.type,l=t.pendingProps,o=e!==null?e.memoizedProps:null,s=l.children,Pl(r,l)?s=null:o!==null&&Pl(r,o)&&(t.flags|=32),Au(e,t),Ce(e,t,s,n),t.child;case 6:return e===null&&Ql(t),null;case 13:return Qu(e,t,n);case 4:return $l(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=vn(t,null,r,n):Ce(e,t,r,n),t.child;case 11:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:tt(r,l),Du(e,t,r,l,n);case 7:return Ce(e,t,t.pendingProps,n),t.child;case 8:return Ce(e,t,t.pendingProps.children,n),t.child;case 12:return Ce(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,l=t.pendingProps,o=t.memoizedProps,s=l.value,tu(t,r,s),o!==null)if(be(o.value,s)){if(o.children===l.children&&!ke.current){t=kt(e,t,n);break e}}else for(o=t.child,o!==null&&(o.return=t);o!==null;){var c=o.dependencies;if(c!==null){s=o.child;for(var v=c.firstContext;v!==null;){if(v.context===r){if(o.tag===1){v=zt(-1,n&-n),v.tag=2;var x=o.updateQueue;if(x!==null){x=x.shared;var I=x.pending;I===null?v.next=v:(v.next=I.next,I.next=v),x.pending=v}}o.lanes|=n,v=o.alternate,v!==null&&(v.lanes|=n),Kl(o.return,n,t),c.lanes|=n;break}v=v.next}}else if(o.tag===10)s=o.type===t.type?null:o.child;else if(o.tag===18){if(s=o.return,s===null)throw Error(d(341));s.lanes|=n,c=s.alternate,c!==null&&(c.lanes|=n),Kl(s,n,t),s=o.sibling}else s=o.child;if(s!==null)s.return=o;else for(s=o;s!==null;){if(s===t){s=null;break}if(o=s.sibling,o!==null){o.return=s.return,s=o;break}s=s.return}o=s}Ce(e,t,l.children,n),t=t.child}return t;case 9:return l=t.type,r=t.pendingProps.children,_n(t,n),l=Qe(l),r=r(l),t.flags|=1,Ce(e,t,r,n),t.child;case 14:return r=t.type,l=tt(r,t.pendingProps),l=tt(r.type,l),Ou(e,t,r,l,n);case 15:return ju(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:tt(r,l),Br(e,t),t.tag=1,Pe(r)?(e=!0,_r(t)):e=!1,_n(t,n),Nu(t,r,l),fo(t,r,l,n),go(null,t,r,!0,e,n);case 19:return Gu(e,t,n);case 22:return Hu(e,t,n)}throw Error(d(156,t.tag))};function gs(e,t){return Ol(e,t)}function $c(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Ze(e,t,n,r){return new $c(e,t,n,r)}function Ao(e){return e=e.prototype,!(!e||!e.isReactComponent)}function bc(e){if(typeof e=="function")return Ao(e)?1:0;if(e!=null){if(e=e.$$typeof,e===H)return 11;if(e===_t)return 14}return 2}function Wt(e,t){var n=e.alternate;return n===null?(n=Ze(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function il(e,t,n,r,l,o){var s=2;if(r=e,typeof e=="function")Ao(e)&&(s=1);else if(typeof e=="string")s=5;else e:switch(e){case R:return on(n.children,l,o,t);case T:s=8,l|=8;break;case $:return e=Ze(12,n,t,l|2),e.elementType=$,e.lanes=o,e;case Q:return e=Ze(13,n,t,l),e.elementType=Q,e.lanes=o,e;case ce:return e=Ze(19,n,t,l),e.elementType=ce,e.lanes=o,e;case dr:return ul(n,l,o,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case S:s=10;break e;case w:s=9;break e;case H:s=11;break e;case _t:s=14;break e;case st:s=16,r=null;break e}throw Error(d(130,e==null?e:typeof e,""))}return t=Ze(s,n,t,l),t.elementType=e,t.type=r,t.lanes=o,t}function on(e,t,n,r){return e=Ze(7,e,r,t),e.lanes=n,e}function ul(e,t,n,r){return e=Ze(22,e,r,t),e.elementType=dr,e.lanes=n,e.stateNode={isHidden:!1},e}function Wo(e,t,n){return e=Ze(6,e,null,t),e.lanes=n,e}function Bo(e,t,n){return t=Ze(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function ef(e,t,n,r,l){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=El,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Ul(0),this.expirationTimes=Ul(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ul(0),this.identifierPrefix=r,this.onRecoverableError=l,Ae&&(this.mutableSourceEagerHydrationData=null)}function vs(e,t,n,r,l,o,s,c,v){return e=new ef(e,t,n,c,v),t===1?(t=1,o===!0&&(t|=8)):t=0,o=Ze(3,null,null,t),e.current=o,o.stateNode=e,o.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Yl(o),e}function ys(e){if(!e)return Ft;e=e._reactInternals;e:{if(xt(e)!==e||e.tag!==1)throw Error(d(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(Pe(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(t!==null);throw Error(d(171))}if(e.tag===1){var n=e.type;if(Pe(n))return Wi(e,n,t)}return t}function _s(e){var t=e._reactInternals;if(t===void 0)throw typeof e.render=="function"?Error(d(188)):(e=Object.keys(e).join(","),Error(d(268,e)));return e=Ei(t),e===null?null:e.stateNode}function xs(e,t){if(e=e.memoizedState,e!==null&&e.dehydrated!==null){var n=e.retryLane;e.retryLane=n!==0&&n=x&&o>=L&&l<=I&&s<=z){e.splice(t,1);break}else if(r!==x||n.width!==v.width||zs){if(!(o!==L||n.height!==v.height||Il)){x>r&&(v.width+=x-r,v.x=r),Io&&(v.height+=L-o,v.y=o),zn&&(n=s)),sHo&&(t.flags|=128,r=!0,nr(l,!1),t.lanes=4194304)}else{if(!r)if(e=jr(o),e!==null){if(t.flags|=128,r=!0,e=e.updateQueue,e!==null&&(t.updateQueue=e,t.flags|=4),nr(l,!0),l.tail===null&&l.tailMode==="hidden"&&!o.alternate&&!b)return xe(t),null}else 2*ae()-l.renderingStartTime>Ho&&n!==1073741824&&(t.flags|=128,r=!0,nr(l,!1),t.lanes=4194304);l.isBackwards?(o.sibling=t.child,t.child=o):(e=l.last,e!==null?e.sibling=o:t.child=o,l.last=o)}return l.tail!==null?(t=l.tail,l.rendering=t,l.tail=t.sibling,l.renderingStartTime=ae(),t.sibling=null,e=ne.current,J(ne,r?e&1|2:e&1),t):(xe(t),null);case 22:case 23:return Qo(),n=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==n&&(t.flags|=8192),n&&(t.mode&1)!==0?(He&1073741824)!==0&&(xe(t),Oe&&t.subtreeFlags&6&&(t.flags|=8192)):xe(t),null;case 24:return null;case 25:return null}throw Error(c(156,t.tag))}function qc(e,t){switch(Zl(t),t.tag){case 1:return Te(t.type)&&wr(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return En(),K(Ne),K(ye),uo(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return oo(t),null;case 13:if(K(ne),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(c(340));wn()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return K(ne),null;case 4:return En(),null;case 10:return eo(t.type._context),null;case 22:case 23:return Qo(),null;case 24:return null;default:return null}}var Kr=!1,Se=!1,Gc=typeof WeakSet=="function"?WeakSet:Set,k=null;function Nn(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){ee(e,t,r)}else n.current=null}function Eo(e,t,n){try{n()}catch(r){ee(e,t,r)}}var bu=!1;function Jc(e,t){for(xa(e.containerInfo),k=t;k!==null;)if(e=k,t=e.child,(e.subtreeFlags&1028)!==0&&t!==null)t.return=e,k=t;else for(;k!==null;){e=k;try{var n=e.alternate;if((e.flags&1024)!==0)switch(e.tag){case 0:case 11:case 15:break;case 1:if(n!==null){var r=n.memoizedProps,l=n.memoizedState,o=e.stateNode,s=o.getSnapshotBeforeUpdate(e.elementType===e.type?r:it(e.type,r),l);o.__reactInternalSnapshotBeforeUpdate=s}break;case 3:Oe&&Ka(e.stateNode.containerInfo);break;case 5:case 6:case 4:case 17:break;default:throw Error(c(163))}}catch(f){ee(e,e.return,f)}if(t=e.sibling,t!==null){t.return=e.return,k=t;break}k=e.return}return n=bu,bu=!1,n}function rr(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var l=r=r.next;do{if((l.tag&e)===e){var o=l.destroy;l.destroy=void 0,o!==void 0&&Eo(t,n,o)}l=l.next}while(l!==r)}}function Xr(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function Io(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=Tl(n);break;default:e=n}typeof t=="function"?t(e):t.current=e}}function es(e){var t=e.alternate;t!==null&&(e.alternate=null,es(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&Ea(t)),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function ts(e){return e.tag===5||e.tag===3||e.tag===4}function ns(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||ts(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function No(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?Ba(n,e,t):Oa(n,e);else if(r!==4&&(e=e.child,e!==null))for(No(e,t,n),e=e.sibling;e!==null;)No(e,t,n),e=e.sibling}function To(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?Wa(n,e,t):Da(n,e);else if(r!==4&&(e=e.child,e!==null))for(To(e,t,n),e=e.sibling;e!==null;)To(e,t,n),e=e.sibling}var pe=null,ut=!1;function _t(e,t,n){for(n=n.child;n!==null;)Mo(e,t,n),n=n.sibling}function Mo(e,t,n){if(pt&&typeof pt.onCommitFiberUnmount=="function")try{pt.onCommitFiberUnmount(Er,n)}catch{}switch(n.tag){case 5:Se||Nn(n,t);case 6:if(Oe){var r=pe,l=ut;pe=null,_t(e,t,n),pe=r,ut=l,pe!==null&&(ut?Qa(pe,n.stateNode):Va(pe,n.stateNode))}else _t(e,t,n);break;case 18:Oe&&pe!==null&&(ut?pc(pe,n.stateNode):dc(pe,n.stateNode));break;case 4:Oe?(r=pe,l=ut,pe=n.stateNode.containerInfo,ut=!0,_t(e,t,n),pe=r,ut=l):(xr&&(r=n.stateNode.containerInfo,l=Hi(r),Fl(r,l)),_t(e,t,n));break;case 0:case 11:case 14:case 15:if(!Se&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){l=r=r.next;do{var o=l,s=o.destroy;o=o.tag,s!==void 0&&((o&2)!==0||(o&4)!==0)&&Eo(n,t,s),l=l.next}while(l!==r)}_t(e,t,n);break;case 1:if(!Se&&(Nn(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(f){ee(n,t,f)}_t(e,t,n);break;case 21:_t(e,t,n);break;case 22:n.mode&1?(Se=(r=Se)||n.memoizedState!==null,_t(e,t,n),Se=r):_t(e,t,n);break;default:_t(e,t,n)}}function rs(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new Gc),t.forEach(function(r){var l=nf.bind(null,e,r);n.has(r)||(n.add(r),r.then(l,l))})}}function st(e,t){var n=t.deletions;if(n!==null)for(var r=0;r";case $r:return":has("+(Fo(e)||"")+")";case br:return'[role="'+e.value+'"]';case tl:return'"'+e.value+'"';case el:return'[data-testname="'+e.value+'"]';default:throw Error(c(365))}}function as(e,t){var n=[];e=[e,0];for(var r=0;rl&&(l=s),r&=~o}if(r=l,r=ae()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Kc(r/1960))-r,10e?16:e,Vt===null)var r=!1;else{if(e=Vt,Vt=null,il=0,(H&6)!==0)throw Error(c(331));var l=H;for(H|=4,k=e.current;k!==null;){var o=k,s=o.child;if((k.flags&16)!==0){var f=o.deletions;if(f!==null){for(var m=0;mae()-jo?an(e,0):Oo|=n),Le(e,t)}function ys(e,t){t===0&&((e.mode&1)===0?t=1:(t=kr,kr<<=1,(kr&130023424)===0&&(kr=4194304)));var n=we();e=mt(e,t),e!==null&&(qn(e,t,n),Le(e,n))}function tf(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),ys(e,n)}function nf(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,l=e.memoizedState;l!==null&&(n=l.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(c(314))}r!==null&&r.delete(t),ys(e,n)}var _s;_s=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||Ne.current)Me=!0;else{if((e.lanes&n)===0&&(t.flags&128)===0)return Me=!1,Vc(e,t,n);Me=(e.flags&131072)!==0}else Me=!1,b&&(t.flags&1048576)!==0&&Yi(t,Tr,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;Gr(e,t),e=t.pendingProps;var l=_n(t,ye.current);kn(t,n),l=co(null,t,r,e,l,n);var o=fo();return t.flags|=1,typeof l=="object"&&l!==null&&typeof l.render=="function"&&l.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Te(r)?(o=!0,Cr(t)):o=!1,t.memoizedState=l.state!==null&&l.state!==void 0?l.state:null,ro(t),l.updater=Qr,t.stateNode=l,l._reactInternals=t,yo(t,r,e,n),t=wo(null,t,r,!0,o,n)):(t.tag=0,b&&o&&Jl(t),Pe(null,t,l,n),t=t.child),t;case 16:r=t.elementType;e:{switch(Gr(e,t),e=t.pendingProps,l=r._init,r=l(r._payload),t.type=r,l=t.tag=lf(r),e=it(r,e),l){case 0:t=So(null,t,r,e,n);break e;case 1:t=qu(null,t,r,e,n);break e;case 11:t=Au(null,t,r,e,n);break e;case 14:t=Wu(null,t,r,it(r.type,e),n);break e}throw Error(c(306,r,""))}return t;case 0:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:it(r,l),So(e,t,r,l,n);case 1:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:it(r,l),qu(e,t,r,l,n);case 3:e:{if(Gu(t),e===null)throw Error(c(387));r=t.pendingProps,o=t.memoizedState,l=o.element,uu(e,t),Or(t,r,null,n);var s=t.memoizedState;if(r=s.element,Ve&&o.isDehydrated)if(o={element:r,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=o,t.memoizedState=o,t.flags&256){l=In(Error(c(423)),t),t=Ju(e,t,r,n,l);break e}else if(r!==l){l=In(Error(c(424)),t),t=Ju(e,t,r,n,l);break e}else for(Ve&&(Ge=lc(t.stateNode.containerInfo),je=t,b=!0,ot=null,Gn=!1),n=lu(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(wn(),r===l){t=Tt(e,t,n);break e}Pe(e,t,r,n)}t=t.child}return t;case 5:return cu(t),e===null&&Xl(t),r=t.type,l=t.pendingProps,o=e!==null?e.memoizedProps:null,s=l.children,Rl(r,l)?s=null:o!==null&&Rl(r,o)&&(t.flags|=32),Qu(e,t),Pe(e,t,s,n),t.child;case 6:return e===null&&Xl(t),null;case 13:return Zu(e,t,n);case 4:return lo(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=Cn(t,null,r,n):Pe(e,t,r,n),t.child;case 11:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:it(r,l),Au(e,t,r,l,n);case 7:return Pe(e,t,t.pendingProps,n),t.child;case 8:return Pe(e,t,t.pendingProps.children,n),t.child;case 12:return Pe(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,l=t.pendingProps,o=t.memoizedProps,s=l.value,ou(t,r,s),o!==null)if(lt(o.value,s)){if(o.children===l.children&&!Ne.current){t=Tt(e,t,n);break e}}else for(o=t.child,o!==null&&(o.return=t);o!==null;){var f=o.dependencies;if(f!==null){s=o.child;for(var m=f.firstContext;m!==null;){if(m.context===r){if(o.tag===1){m=Nt(-1,n&-n),m.tag=2;var x=o.updateQueue;if(x!==null){x=x.shared;var P=x.pending;P===null?m.next=m:(m.next=P.next,P.next=m),x.pending=m}}o.lanes|=n,m=o.alternate,m!==null&&(m.lanes|=n),to(o.return,n,t),f.lanes|=n;break}m=m.next}}else if(o.tag===10)s=o.type===t.type?null:o.child;else if(o.tag===18){if(s=o.return,s===null)throw Error(c(341));s.lanes|=n,f=s.alternate,f!==null&&(f.lanes|=n),to(s,n,t),s=o.sibling}else s=o.child;if(s!==null)s.return=o;else for(s=o;s!==null;){if(s===t){s=null;break}if(o=s.sibling,o!==null){o.return=s.return,s=o;break}s=s.return}o=s}Pe(e,t,l.children,n),t=t.child}return t;case 9:return l=t.type,r=t.pendingProps.children,kn(t,n),l=Je(l),r=r(l),t.flags|=1,Pe(e,t,r,n),t.child;case 14:return r=t.type,l=it(r,t.pendingProps),l=it(r.type,l),Wu(e,t,r,l,n);case 15:return Bu(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:it(r,l),Gr(e,t),t.tag=1,Te(r)?(e=!0,Cr(t)):e=!1,kn(t,n),Lu(t,r,l),yo(t,r,l,n),wo(null,t,r,!0,e,n);case 19:return Xu(e,t,n);case 22:return Vu(e,t,n)}throw Error(c(156,t.tag))};function xs(e,t){return Vl(e,t)}function rf(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Ye(e,t,n,r){return new rf(e,t,n,r)}function Go(e){return e=e.prototype,!(!e||!e.isReactComponent)}function lf(e){if(typeof e=="function")return Go(e)?1:0;if(e!=null){if(e=e.$$typeof,e===q)return 11;if(e===R)return 14}return 2}function Gt(e,t){var n=e.alternate;return n===null?(n=Ye(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function cl(e,t,n,r,l,o){var s=2;if(r=e,typeof e=="function")Go(e)&&(s=1);else if(typeof e=="string")s=5;else e:switch(e){case L:return dn(n.children,l,o,t);case I:s=8,l|=8;break;case Y:return e=Ye(12,n,t,l|2),e.elementType=Y,e.lanes=o,e;case $:return e=Ye(13,n,t,l),e.elementType=$,e.lanes=o,e;case ke:return e=Ye(19,n,t,l),e.elementType=ke,e.lanes=o,e;case De:return fl(n,l,o,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case M:s=10;break e;case j:s=9;break e;case q:s=11;break e;case R:s=14;break e;case E:s=16,r=null;break e}throw Error(c(130,e==null?e:typeof e,""))}return t=Ye(s,n,t,l),t.elementType=e,t.type=r,t.lanes=o,t}function dn(e,t,n,r){return e=Ye(7,e,r,t),e.lanes=n,e}function fl(e,t,n,r){return e=Ye(22,e,r,t),e.elementType=De,e.lanes=n,e.stateNode={isHidden:!1},e}function Jo(e,t,n){return e=Ye(6,e,null,t),e.lanes=n,e}function Zo(e,t,n){return t=Ye(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function of(e,t,n,r,l){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=Ll,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Wl(0),this.expirationTimes=Wl(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Wl(0),this.identifierPrefix=r,this.onRecoverableError=l,Ve&&(this.mutableSourceEagerHydrationData=null)}function Ss(e,t,n,r,l,o,s,f,m){return e=new of(e,t,n,f,m),t===1?(t=1,o===!0&&(t|=8)):t=0,o=Ye(3,null,null,t),e.current=o,o.stateNode=e,o.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},ro(o),e}function ws(e){if(!e)return Ht;e=e._reactInternals;e:{if(te(e)!==e||e.tag!==1)throw Error(c(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(Te(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(t!==null);throw Error(c(171))}if(e.tag===1){var n=e.type;if(Te(n))return qi(e,n,t)}return t}function Cs(e){var t=e._reactInternals;if(t===void 0)throw typeof e.render=="function"?Error(c(188)):(e=Object.keys(e).join(","),Error(c(268,e)));return e=Mi(t),e===null?null:e.stateNode}function zs(e,t){if(e=e.memoizedState,e!==null&&e.dehydrated!==null){var n=e.retryLane;e.retryLane=n!==0&&n=x&&o>=F&&l<=P&&s<=w){e.splice(t,1);break}else if(r!==x||n.width!==m.width||ws){if(!(o!==F||n.height!==m.height||Pl)){x>r&&(m.width+=x-r,m.x=r),Po&&(m.height+=F-o,m.y=o),wn&&(n=s)),s ")+` No matching component was found for: - `)+e.join(" > ")}return null},a.getPublicRootInstance=function(e){if(e=e.current,!e.child)return null;switch(e.child.tag){case 5:return zl(e.child.stateNode);default:return e.child.stateNode}},a.injectIntoDevTools=function(e){if(e={bundleType:e.bundleType,version:e.version,rendererPackageName:e.rendererPackageName,rendererConfig:e.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:_.ReactCurrentDispatcher,findHostInstanceByFiber:tf,findFiberByHostInstance:e.findFiberByHostInstance||nf,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1"},typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u")e=!1;else{var t=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(t.isDisabled||!t.supportsFiber)e=!0;else{try{Cr=t.inject(e),at=t}catch{}e=!!t.checkDCE}}return e},a.isAlreadyRendering=function(){return!1},a.observeVisibleRects=function(e,t,n,r){if(!Fn)throw Error(d(363));e=No(e,t);var l=Ta(e,n,r).disconnect;return{disconnect:function(){l()}}},a.registerMutableSourceForHydration=function(e,t){var n=t._getVersion;n=n(t._source),e.mutableSourceEagerHydrationData==null?e.mutableSourceEagerHydrationData=[t,n]:e.mutableSourceEagerHydrationData.push(t,n)},a.runWithPriority=function(e,t){var n=W;try{return W=e,t()}finally{W=n}},a.shouldError=function(){return null},a.shouldSuspend=function(){return!1},a.updateContainer=function(e,t,n,r){var l=t.current,o=xe(),s=Ht(l);return n=ys(n),t.context===null?t.context=n:t.pendingContext=n,t=zt(o,s),t.payload={element:e},r=r===void 0?null:r,r!==null&&(t.callback=r),e=Dt(l,t,s),e!==null&&(Je(e,l,s,o),Rr(e,l,s)),s},a}});var bs=Pn((bf,$s)=>{"use strict";$s.exports=Ys()});var fr=lt(Ke());import*as je from"mshell";import*as Me from"mshell";var Zo=(i,u)=>{let a=u.split("."),p=i;for(let g of a){if(p==null)return;p=p[g]}return p},Us=(i,u,a)=>{let p=u.split("."),g=i;for(let C=0;C{for(let a of Ds)a(i,u)});globalThis.on_plugin_menu={};var Os=(i,u={})=>{let a="config.json",{name:p,url:g}=i,C={},d=p.endsWith(".js")?p.slice(0,-3):p,_=u,P=new Set,N={i18n:{define:(R,T)=>{C[R]=T},t:R=>C[Me.breeze.user_language()][R]||R},set_on_menu:R=>{globalThis.on_plugin_menu[d]=R},config_directory:dl+d+"/",config:{read_config(){if(Me.fs.exists(N.config_directory+a))try{_=JSON.parse(Me.fs.read(N.config_directory+a))}catch(R){Me.println(`[${p}] \u914D\u7F6E\u6587\u4EF6\u89E3\u6790\u5931\u8D25: ${R}`)}},write_config(){Me.fs.write(N.config_directory+a,JSON.stringify(_,null,4))},get(R){return Zo(_,R)||Zo(u,R)||null},set(R,T){Us(_,R,T),N.config.write_config()},all(){return _},on_reload(R){let T=()=>{P.delete(R)};return P.add(R),T}},log(...R){Me.println(`[${p}]`,...R)}};return Me.fs.mkdir(N.config_directory),N.config.read_config(),Ds.add((R,T)=>{if(R.replace(dl,"")===`${d}\\${a}`){Me.println(`[${p}] \u914D\u7F6E\u6587\u4EF6\u53D8\u66F4: ${R} ${T}`),N.config.read_config();for(let S of P)S(_)}}),N};var ta=lt(bs());import*as In from"mshell";var A=i=>({set:(u,a)=>{let p=Array.isArray(a)?a:[a];u.downcast()["set_"+i](...p)},get:u=>u.downcast()["get_"+i]()}),Ef=(i,u=4)=>({set:(a,p)=>{let g=Array.isArray(p)?p:[p];for(;g.lengtha.downcast()["get_"+i]()}),li=i=>({set:(u,a)=>{u["set_"+i](If(a))},get:u=>Nf(u["get_"+i]())}),If=i=>{if(i.startsWith("#")){let u=i.slice(1);if(u.length===6)return[parseInt(u.slice(0,2),16)/255,parseInt(u.slice(2,4),16)/255,parseInt(u.slice(4,6),16)/255,1];if(u.length===8)return[parseInt(u.slice(0,2),16)/255,parseInt(u.slice(2,4),16)/255,parseInt(u.slice(4,6),16)/255,parseInt(u.slice(6,8),16)/255]}},Nf=i=>{let u=Math.round(i[0]*255).toString(16).padStart(2,"0"),a=Math.round(i[1]*255).toString(16).padStart(2,"0"),p=Math.round(i[2]*255).toString(16).padStart(2,"0"),g=Math.round(i[3]*255).toString(16).padStart(2,"0");return`#${u}${a}${p}${g}`},Tf={set:(i,u)=>{for(let a of u)i.set_animation(a,!0);i._last_animated_vars=u},get:i=>i._last_animated_vars},oi={animatedVars:Tf,x:A("x"),y:A("y"),width:A("width"),height:A("height")},yl={text:{creator:In.breeze_ui.widgets_factory.create_text_widget,props:{text:{set:(i,u)=>{i.text=Array.isArray(u)?u.join(""):u},get:i=>i.text},fontSize:A("font_size"),color:li("color"),maxWidth:A("max_width"),...oi}},flex:{creator:In.breeze_ui.widgets_factory.create_flex_layout_widget,props:{padding:Ef("padding"),paddingTop:A("padding_top"),paddingRight:A("padding_right"),paddingBottom:A("padding_bottom"),paddingLeft:A("padding_left"),onClick:A("on_click"),onMouseEnter:A("on_mouse_enter"),onMouseLeave:A("on_mouse_leave"),onMouseDown:A("on_mouse_down"),onMouseUp:A("on_mouse_up"),onMouseMove:A("on_mouse_move"),backgroundColor:li("background_color"),borderColor:li("border_color"),borderRadius:A("border_radius"),borderWidth:A("border_width"),backgroundPaint:A("background_paint"),borderPaint:A("border_paint"),horizontal:A("horizontal"),autoSize:A("auto_size"),justifyContent:A("justify_content"),alignItems:A("align_items"),gap:A("gap"),flexGrow:A("flex_grow"),flexShrink:A("flex_shrink"),maxHeight:A("max_height"),enableScrolling:A("enable_scrolling"),enableChildClipping:A("enable_child_clipping"),cropOverflow:A("crop_overflow"),...oi}},img:{creator:In.breeze_ui.widgets_factory.create_image_widget,props:{svg:A("svg"),...oi}},spacer:{creator:In.breeze_ui.widgets_factory.create_spacer_widget,props:{size:A("size")}}},na={getPublicInstance(i){return i},getRootHostContext(i){return null},getChildHostContext(i,u,a){return i},prepareForCommit(i){return null},resetAfterCommit(i){},createInstance(i,u,a,p,g){try{if(!yl[i])throw new Error(`Unknown component type: ${i}`);let C=yl[i].creator();for(let d in u){if(d==="children")continue;let _=yl[i]?.props?.[d];if(_)_.set(C,u[d]);else throw new Error(`Unknown property: ${d} for component type: ${i}`)}return C}catch(C){throw console.error(`Error creating instance of type ${i}:`,C,C.stack),C}},appendInitialChild(i,u){i.append_child(u)},finalizeInitialChildren(i,u,a,p,g){return!1},prepareUpdate(i,u,a,p,g,C){let d={};for(let _ in p)p[_]!==a[_]&&(d[_]=p[_]);return Object.keys(d).length>0?d:null},shouldSetTextContent(i,u){return!1},createTextInstance(i,u,a,p){let g=In.breeze_ui.widgets_factory.create_text_widget();return g.text=i,g},scheduleTimeout:setTimeout,cancelTimeout:clearTimeout,noTimeout:-1,isPrimaryRenderer:!0,warnsIfNotActing:!0,supportsMutation:!0,supportsPersistence:!1,supportsHydration:!1,getInstanceFromNode(i){throw new Error("getInstanceFromNode not implemented")},beforeActiveInstanceBlur(){},afterActiveInstanceBlur(){},preparePortalMount(i){throw new Error("preparePortalMount not implemented")},prepareScopeUpdate(i,u){throw new Error("prepareScopeUpdate not implemented")},getInstanceFromScope(i){throw new Error("getInstanceFromScope not implemented")},getCurrentEventPriority(){return 16},detachDeletedInstance(i){},commitMount(i,u,a,p){},commitUpdate(i,u,a,p,g,C){for(let d in g){if(d==="children")continue;let _=yl[a].props[d];_&&g[d]!==p[d]&&_.set(i,g[d])}},clearContainer(i){for(let u of i.children())i.remove_child(u)},appendChild(i,u){i.append_child(u)},appendChildToContainer(i,u){i.append_child(u)},removeChild(i,u){i.remove_child(u)},removeChildFromContainer(i,u){i.remove_child(u)},commitTextUpdate(i,u,a){i.text=a},insertBefore(i,u,a){a?i.append_child_after(u,i.children().indexOf(a)-1):i.append_child(u)},resetTextContent(i){let u=i.downcast();"set_text"in u&&u.set_text("")}},ea=(0,ta.default)(na),ra=i=>({render:u=>{let a=ea.createContainer(i,0,null,!1,null,"",p=>console.error(p),null);ea.updateContainer(u,a,null,null)}});import*as wl from"mshell";var Qt={"Github Raw":"https://raw.githubusercontent.com/breeze-shell/plugins-packed/refs/heads/main/",Enlysure:"https://breeze.enlysure.com/","Enlysure Shanghai":"https://breeze-c.enlysure.com/"},ii='',ui='',si='',ai='',ci='',fi='',di=800,_l=600,pi=170,sn={\u9ED8\u8BA4:null,\u7D27\u51D1:{radius:4,item_height:20,item_gap:2,item_radius:3,margin:4,padding:4,text_padding:6,icon_padding:3,right_icon_padding:16,multibutton_line_gap:-4},\u5BBD\u677E:{radius:6,item_height:24,item_gap:4,item_radius:8,margin:6,padding:6,text_padding:8,icon_padding:4,right_icon_padding:20,multibutton_line_gap:-6},\u5706\u89D2:{radius:12,item_radius:12},\u65B9\u89D2:{radius:0,item_radius:0}},pe={easing:"mutation"},Nn={\u9ED8\u8BA4:null,\u5FEB\u901F:{item:{opacity:{delay_scale:0},width:pe,x:pe},submenu_bg:{opacity:{delay_scale:0,duration:100}},main_bg:{opacity:pe}},\u65E0:{item:{opacity:pe,width:pe,x:pe,y:pe},submenu_bg:{opacity:pe,x:pe,y:pe,w:pe,h:pe},main_bg:{opacity:pe,x:pe,y:pe,w:pe,h:pe}}};var hi=lt(Ke());import*as he from"mshell";import{menu_controller as Mf}from"mshell";var Tn=()=>{let[i,u]=(0,hi.useState)(!1),[a,p]=(0,hi.useState)(!1);return{isHovered:i,isActive:a,onMouseEnter:()=>u(!0),onMouseLeave:()=>u(!1),onMouseDown:()=>p(!0),onMouseUp:()=>p(!1)}},xl=i=>{let u=Mf.create_detached();i(u),u.show_at_cursor()},It=(i,u)=>u.split(".").reduce((a,p)=>a?.[p],i),Nt=(i,u,a)=>{let p=u.split("."),g=p.pop(),C=p.reduce((d,_)=>d[_]=d[_]||{},i);C[g]=a},it=()=>{let i=he.breeze.user_language()==="zh-CN"?"zh-CN":"en-US";return{t:a=>({"zh-CN":{"\u7BA1\u7406 Breeze Shell":"\u7BA1\u7406 Breeze Shell",\u63D2\u4EF6\u5E02\u573A:"\u63D2\u4EF6\u5E02\u573A","\u52A0\u8F7D\u4E2D...":"\u52A0\u8F7D\u4E2D...","\u66F4\u65B0\u4E2D...":"\u66F4\u65B0\u4E2D...","\u5B89\u88C5\u4E2D...":"\u5B89\u88C5\u4E2D...","\u65B0\u7248\u672C\u5DF2\u4E0B\u8F7D\uFF0C\u5C06\u4E8E\u4E0B\u6B21\u91CD\u542F\u8D44\u6E90\u7BA1\u7406\u5668\u751F\u6548":"\u65B0\u7248\u672C\u5DF2\u4E0B\u8F7D\uFF0C\u5C06\u4E8E\u4E0B\u6B21\u91CD\u542F\u8D44\u6E90\u7BA1\u7406\u5668\u751F\u6548","\u66F4\u65B0\u5931\u8D25: ":"\u66F4\u65B0\u5931\u8D25: ","\u63D2\u4EF6\u5B89\u88C5\u6210\u529F: ":"\u63D2\u4EF6\u5B89\u88C5\u6210\u529F: ","\u7248\u672C: ":"\u7248\u672C: ","\u4F5C\u8005: ":"\u4F5C\u8005: ",\u5220\u9664:"\u5220\u9664","Breeze \u8BBE\u7F6E":"Breeze \u8BBE\u7F6E",\u4F18\u5148\u52A0\u8F7D\u63D2\u4EF6:"\u4F18\u5148\u52A0\u8F7D\u63D2\u4EF6",\u8C03\u8BD5\u63A7\u5236\u53F0:"\u8C03\u8BD5\u63A7\u5236\u53F0",\u5782\u76F4\u540C\u6B65:"\u5782\u76F4\u540C\u6B65",\u5FFD\u7565\u81EA\u7ED8\u83DC\u5355:"\u5FFD\u7565\u81EA\u7ED8\u83DC\u5355",\u5411\u4E0A\u5C55\u5F00\u65F6\u53CD\u5411\u6392\u5217:"\u5411\u4E0A\u5C55\u5F00\u65F6\u53CD\u5411\u6392\u5217","\u5C1D\u8BD5\u4F7F\u7528 Windows 11 \u5706\u89D2":"\u5C1D\u8BD5\u4F7F\u7528 Windows 11 \u5706\u89D2",\u4E9A\u514B\u529B\u80CC\u666F\u6548\u679C:"\u4E9A\u514B\u529B\u80CC\u666F\u6548\u679C",\u4E3B\u9898:"\u4E3B\u9898",\u52A8\u753B:"\u52A8\u753B","\u5F53\u524D\u6E90: ":"\u5F53\u524D\u6E90: ",\u63D2\u4EF6:"\u63D2\u4EF6",\u63D2\u4EF6\u6E90:"\u63D2\u4EF6\u6E90",\u6362\u6E90:"\u6362\u6E90",\u8BF7\u7A0D\u5019:"\u8BF7\u7A0D\u5019","\u5207\u6362\u6E90\u4E2D...":"\u5207\u6362\u6E90\u4E2D...",\u52A0\u8F7D\u5931\u8D25:"\u52A0\u8F7D\u5931\u8D25",\u7F51\u7EDC\u9519\u8BEF:"\u7F51\u7EDC\u9519\u8BEF",\u5207\u6362\u6E90\u6210\u529F:"\u5207\u6362\u6E90\u6210\u529F"},"en-US":{}})[i][a]||a,currentLang:i}};var or=i=>{he.fs.write(he.breeze.data_directory()+"/config.json",JSON.stringify(i,null,4))},mi=()=>he.fs.readdir(he.breeze.data_directory()+"/scripts").map(i=>i.split("/").pop()).filter(i=>i.endsWith(".js")||i.endsWith(".disabled")).map(i=>i.replace(".js","").replace(".disabled","")),gi=i=>{let u=he.breeze.data_directory()+"/scripts/"+i;he.fs.exists(u+".js")?he.fs.rename(u+".js",u+".js.disabled"):he.fs.exists(u+".js.disabled")&&he.fs.rename(u+".js.disabled",u+".js")},vi=i=>{let u=he.breeze.data_directory()+"/scripts/"+i;he.fs.exists(u+".js")&&he.fs.remove(u+".js"),he.fs.exists(u+".js.disabled")&&he.fs.remove(u+".js.disabled")};var an=lt(Ke()),ir=(0,an.createContext)(null),ur=(0,an.createContext)(null),sr=(0,an.createContext)(null),Tt=(0,an.createContext)(null),Mt=(0,an.createContext)(null),qt=(0,an.createContext)(null);import*as cn from"mshell";var Rt=lt(Ke());import{breeze as Gt}from"mshell";var Jt=lt(Ke()),Mn=(i,u=14)=>h("img",{svg:i.replace("h(Fragment,null,i.split(` -`).map((a,p)=>a.trim().startsWith("# ")?h(j,{key:p,fontSize:22,maxWidth:u},a.trim().substring(2).trim()):a.trim().startsWith("## ")?h(j,{key:p,fontSize:20,maxWidth:u},a.trim().substring(3).trim()):a.trim().startsWith("### ")?h(j,{key:p,fontSize:18,maxWidth:u},a.trim().substring(4).trim()):a.trim().startsWith("#### ")?h(j,{key:p,fontSize:16,maxWidth:u},a.trim().substring(5).trim()):h(j,{key:p,fontSize:14,maxWidth:u},a))),ut=(0,Jt.memo)(({onClick:i,children:u,selected:a})=>{let p=Gt.is_light_theme(),{isHovered:g,isActive:C,onMouseEnter:d,onMouseLeave:_,onMouseDown:P,onMouseUp:N}=Tn();return h("flex",{onClick:i,backgroundColor:C?p?"#c0c0c0cc":"#505050cc":g?p?"#e0e0e0cc":"#606060cc":p?"#f0f0f0cc":"#404040cc",borderRadius:8,paddingLeft:12,paddingRight:12,paddingTop:8,paddingBottom:8,autoSize:!0,justifyContent:"center",alignItems:"center",horizontal:!0,gap:6,borderWidth:a?2:0,borderColor:"#2979FF",onMouseEnter:d,onMouseLeave:_,onMouseDown:P,onMouseUp:N,animatedVars:[".r",".g",".b",".a"]},u)}),j=(0,Jt.memo)(({children:i,fontSize:u=14,maxWidth:a=-1})=>{let p=Gt.is_light_theme();return h("text",{text:i,fontSize:u,maxWidth:a,color:p?"#000000ff":"#ffffffff"})}),Rf=(0,Jt.memo)(({onClick:i,children:u,icon:a})=>h(ut,{onClick:i},a?Mn(a,14):null,h(j,{fontSize:14},u))),yt=({label:i,value:u,onChange:a})=>{let p=Gt.is_light_theme(),{isHovered:g,isActive:C,onMouseEnter:d,onMouseLeave:_,onMouseDown:P,onMouseUp:N}=Tn();return h("flex",{horizontal:!0,alignItems:"center",gap:10,justifyContent:"space-between"},h(j,null,i),h("flex",{width:40,height:20,borderRadius:10,backgroundColor:u?"#0078D4":g?p?"#CCCCCCAA":"#555555AA":p?"#CCCCCC77":"#55555577",justifyContent:u?"end":"start",horizontal:!0,alignItems:"center",onClick:()=>a(!u),autoSize:!1,onMouseEnter:d,padding:g||C?2:3,onMouseLeave:_,onMouseDown:P,onMouseUp:N,animatedVars:[".r",".g",".b",".a"],borderWidth:.5,borderColor:u?"#00000000":p?"#5A5A5A5":"#CECDD0"},h("flex",{width:C?19:g?16:14,height:g||C?16:14,borderRadius:8,backgroundColor:u?p?"#FFFFFF":"#000000":p?"#5A5A5A":"#CECDD0",animatedVars:["x","width","height"],autoSize:!1})))},Rn=(0,Jt.memo)(({onClick:i,icon:u,isActive:a,children:p})=>{let g=Gt.is_light_theme(),{isHovered:C,isActive:d,onMouseEnter:_,onMouseLeave:P,onMouseDown:N,onMouseUp:R}=Tn();return h("flex",{onClick:i,backgroundColor:a?g?"#c0c0c077":"#50505077":d?g?"#c0c0c0cc":"#505050cc":C?g?"#e0e0e0cc":"#606060cc":g?"#e0e0e000":"#60606000",paddingLeft:0,paddingRight:12,paddingTop:8,paddingBottom:8,autoSize:!1,height:32,justifyContent:"start",alignItems:"center",horizontal:!0,gap:6,borderRadius:6,onMouseEnter:_,onMouseLeave:P,onMouseDown:N,onMouseUp:R,animatedVars:[".r",".g",".b",".a"]},h("flex",{width:3,height:a?15:0,backgroundColor:a?"#2979FF":"#00000000",borderRadius:3,autoSize:!1,animatedVars:[".a","height"]}),Mn(u,14),h(j,{fontSize:14},p))}),la=(0,Jt.memo)(({isEnabled:i,onToggle:u})=>{let a=Gt.is_light_theme(),{isHovered:p,isActive:g,onMouseEnter:C,onMouseLeave:d,onMouseDown:_,onMouseUp:P}=Tn();return h("flex",{width:20,height:20,borderRadius:4,borderWidth:1,borderColor:a?"#CCCCCC":"#555555",backgroundColor:i?g?"#1E5F99":p?"#3F7FBF":"#2979FF":g?a?"#c0c0c0cc":"#505050cc":p?a?"#e0e0e0cc":"#606060cc":a?"#e0e0e066":"#60606066",justifyContent:"center",alignItems:"center",onClick:u,onMouseEnter:C,onMouseLeave:d,onMouseDown:_,onMouseUp:P,animatedVars:[".r",".g",".b",".a"]},i?h("img",{svg:``,width:14,height:14}):h("flex",{width:14,height:14,autoSize:!1}))}),oa=(0,Jt.memo)(({onClick:i})=>{let u=Gt.is_light_theme(),{isHovered:a,isActive:p,onMouseEnter:g,onMouseLeave:C,onMouseDown:d,onMouseUp:_}=Tn();return h("flex",{width:32,height:32,borderRadius:16,justifyContent:"center",alignItems:"center",backgroundColor:p?u?"#c0c0c0cc":"#505050cc":a?u?"#e0e0e0cc":"#606060cc":"#00000000",onClick:i,onMouseEnter:g,onMouseLeave:C,onMouseDown:d,onMouseUp:_,animatedVars:[".r",".g",".b",".a"]},Mn(ci,16))}),Sl=(0,Jt.memo)(({name:i,isEnabled:u,isPrioritized:a,onToggle:p,onMoreClick:g})=>{let C=Gt.is_light_theme();return h("flex",{horizontal:!0,alignItems:"center",gap:12,padding:12,borderRadius:8},h("flex",{width:8,height:8,borderRadius:4,backgroundColor:u?"#4CAF50":"#9E9E9E",autoSize:!1}),h("flex",{flexGrow:1},h(j,{fontSize:14},i),a&&h("flex",{padding:4},h(j,{fontSize:10},"\u4F18\u5148\u52A0\u8F7D"))),h("spacer",null),h(la,{isEnabled:u,onToggle:p}),h(oa,{onClick:()=>g(i)}))});var Lf=(0,Rt.memo)(({activePage:i,setActivePage:u,sidebarWidth:a,windowHeight:p})=>{let{t:g}=it(),{updateData:C,setUpdateData:d}=(0,Rt.useContext)(Tt),{errorMessage:_,setErrorMessage:P,loadingMessage:N,setLoadingMessage:R}=(0,Rt.useContext)(Mt),{currentPluginSource:T,setCurrentPluginSource:$,cachedPluginIndex:S,setCachedPluginIndex:w}=(0,Rt.useContext)(qt);(0,Rt.useEffect)(()=>{if(_){let Q=setTimeout(()=>{P(null)},3e3);return()=>clearTimeout(Q)}},[_,P]);let H=Q=>{$(Q),w(null),R(g("\u5207\u6362\u6E90\u4E2D...")),cn.network.get_async(Qt[Q]+"plugins-index.json",ce=>{w(ce),d(JSON.parse(ce)),R(null)},ce=>{cn.println("Failed to fetch update data:",ce),P(g("\u52A0\u8F7D\u5931\u8D25")),R(null)})};return(0,Rt.useEffect)(()=>{H(T)},[T]),h("flex",{width:a,height:p,backgroundColor:cn.breeze.is_light_theme()?"#f0f0f077":"#40404077",padding:10,gap:10,alignItems:"stretch",autoSize:!1},h("flex",{horizontal:!0,alignItems:"center",gap:3,padding:10},Mn(fi,24),h(j,{fontSize:18},"Breeze")),h(Rn,{onClick:()=>u("context-menu"),icon:ii,isActive:i==="context-menu"},"\u4E3B\u914D\u7F6E"),h(Rn,{onClick:()=>u("update"),icon:ui,isActive:i==="update"},"\u66F4\u65B0"),h(Rn,{onClick:()=>u("plugin-store"),icon:si,isActive:i==="plugin-store"},"\u63D2\u4EF6\u5546\u5E97"),h(Rn,{onClick:()=>u("plugin-config"),icon:ai,isActive:i==="plugin-config"},"\u63D2\u4EF6\u914D\u7F6E"),h("spacer",null),_&&h("flex",{backgroundColor:"#FF4444AA",padding:8,borderRadius:6,paddingBottom:5},h("text",{text:_,fontSize:12,color:"#FFFFFFFF"})),N&&h("flex",{backgroundColor:"#0078D4AA",padding:8,borderRadius:6,paddingBottom:5},h("text",{text:N,fontSize:12,color:"#FFFFFFFF"})),h(ut,{onClick:()=>{xl(Q=>{Object.keys(Qt).forEach(ce=>{Q.append_menu({name:ce,action(){H(ce),Q.close()},icon_svg:ce===T?``:void 0})})})}},h(j,{fontSize:12},`${g("\u66F4\u65B0\u6E90")} - ${T}`)))}),_i=Lf;import*as xi from"mshell";var ar=lt(Ke()),Ff=(0,ar.memo)(()=>{let{config:i,update:u}=(0,ar.useContext)(ir),{value:a,update:p}=(0,ar.useContext)(ur),{t:g}=it(),C=i?.theme,d=i?.theme?.animation,_=S=>{if(!S)return[];let w=new Set;for(let H of Object.values(S))if(H)for(let Q of Object.keys(H))w.add(Q);return[...w]},P=(S,w,H)=>{let Q=_(H),ce=S?{...S}:{};for(let _t in w)Q.includes(_t)||(ce[_t]=w[_t]);return ce},N=(S,w)=>!S||!w?!1:Object.keys(w).every(H=>JSON.stringify(S[H])===JSON.stringify(w[H])),R=(S,w)=>{if(!S)return"\u9ED8\u8BA4";for(let[H,Q]of Object.entries(w))if(Q&&N(S,Q))return H;return"\u81EA\u5B9A\u4E49"},T=R(C,sn),$=R(d,Nn);return h("flex",{gap:20,alignItems:"stretch",width:500,autoSize:!1},h(j,{fontSize:24},g("Breeze \u8BBE\u7F6E")),h("flex",null),h("flex",{gap:10},h(j,{fontSize:18},g("\u4E3B\u9898")),h("flex",{horizontal:!0,gap:10},Object.keys(sn).map(S=>h(ut,{key:S,selected:S===T,onClick:()=>{try{let w;sn[S]?w=P(sn[S],i?.theme,sn):w=void 0,u(w?{...i,theme:w}:{...i,theme:void 0})}catch(w){xi.println(w)}}},h(j,{fontSize:14},S))))),h("flex",{gap:10},h(j,{fontSize:18},g("\u52A8\u753B")),h("flex",{horizontal:!0,gap:10},Object.keys(Nn).map(S=>h(ut,{key:S,onClick:()=>{try{let w;Nn[S]?w=Nn[S]:w=void 0,u({...i,theme:{...i.theme,animation:w}})}catch(w){xi.println(w)}}},h(j,{fontSize:14},S))))),h("flex",{gap:10,alignItems:"stretch",justifyContent:"center"},h(j,{fontSize:18},g("\u6742\u9879")),h(yt,{label:g("\u8C03\u8BD5\u63A7\u5236\u53F0"),value:a,onChange:p}),h(yt,{label:g("\u5782\u76F4\u540C\u6B65"),value:It(i,"vsync")??!0,onChange:S=>{let w={...i};Nt(w,"vsync",S),u(w)}}),h(yt,{label:g("\u5FFD\u7565\u81EA\u7ED8\u83DC\u5355"),value:It(i,"ignore_owner_draw")??!0,onChange:S=>{let w={...i};Nt(w,"ignore_owner_draw",S),u(w)}}),h(yt,{label:g("\u5411\u4E0A\u5C55\u5F00\u65F6\u53CD\u5411\u6392\u5217"),value:It(i,"reverse_if_open_to_up")??!0,onChange:S=>{let w={...i};Nt(w,"reverse_if_open_to_up",S),u(w)}}),h(yt,{label:g("\u5C1D\u8BD5\u4F7F\u7528 Windows 11 \u5706\u89D2"),value:It(i,"theme.use_dwm_if_available")??!0,onChange:S=>{let w={...i};Nt(w,"theme.use_dwm_if_available",S),u(w)}}),h(yt,{label:g("\u4E9A\u514B\u529B\u80CC\u666F\u6548\u679C"),value:It(i,"theme.acrylic")??!0,onChange:S=>{let w={...i};Nt(w,"theme.acrylic",S),u(w)}}),h(yt,{label:g("\u952E\u76D8\u70ED\u952E"),value:It(i,"hotkeys")??!0,onChange:S=>{let w={...i};Nt(w,"hotkeys",S),u(w)}}),h(yt,{label:g("\u5728\u5DE6\u4E0A\u89D2\u663E\u793A\u8BBE\u7F6E\u6309\u94AE"),value:It(i,"show_settings_button")??!0,onChange:S=>{let w={...i};Nt(w,"show_settings_button",S),u(w)}})))}),Si=Ff;import*as oe from"mshell";var Ue=lt(Ke()),Uf=(0,Ue.memo)(()=>{let{updateData:i}=(0,Ue.useContext)(Tt),{setErrorMessage:u}=(0,Ue.useContext)(Mt),{currentPluginSource:a}=(0,Ue.useContext)(qt),{t:p}=it(),g=(0,Ue.useMemo)(()=>oe.breeze.version(),[]),[C,d]=(0,Ue.useState)(!1),[_,P]=(0,Ue.useState)(!1);if((0,Ue.useEffect)(()=>{d(oe.fs.exists(oe.breeze.data_directory()+"/shell_old.dll"))},[]),!i)return h(j,null,p("\u52A0\u8F7D\u4E2D..."));let N=i.shell.version,R=()=>{if(_)return;P(!0);let T=oe.breeze.data_directory()+"/shell.dll",$=oe.breeze.data_directory()+"/shell_old.dll",S=Qt[a]+i.shell.path,w=()=>{oe.network.download_async(S,T,()=>{oe.println(p("\u65B0\u7248\u672C\u5DF2\u4E0B\u8F7D\uFF0C\u5C06\u4E8E\u4E0B\u6B21\u91CD\u542F\u8D44\u6E90\u7BA1\u7406\u5668\u751F\u6548")),P(!1),d(!0)},H=>{oe.println(p("\u66F4\u65B0\u5931\u8D25: ")+H),P(!1),u(p("\u66F4\u65B0\u5931\u8D25: ")+H)})};try{if(oe.fs.exists(T))if(oe.fs.exists($))try{oe.fs.remove($),oe.fs.rename(T,$),w()}catch{oe.println(p("\u66F4\u65B0\u5931\u8D25: ")+"\u65E0\u6CD5\u79FB\u52A8\u5F53\u524D\u6587\u4EF6"),P(!1),u(p("\u66F4\u65B0\u5931\u8D25: ")+"\u65E0\u6CD5\u79FB\u52A8\u5F53\u524D\u6587\u4EF6")}else oe.fs.rename(T,$),w();else w()}catch(H){oe.println(p("\u66F4\u65B0\u5931\u8D25: ")+H),P(!1),u(p("\u66F4\u65B0\u5931\u8D25: ")+H)}};return h("flex",{gap:20},h(j,{fontSize:24},p("\u63D2\u4EF6\u5E02\u573A")),h("flex",{gap:10},h(j,null,`\u5F53\u524D\u7248\u672C: ${g}`),h(j,null,`\u6700\u65B0\u7248\u672C: ${N}`),h(ut,{onClick:g===N||_?()=>{}:R},h(j,null,_?p("\u66F4\u65B0\u4E2D..."):C?p("\u65B0\u7248\u672C\u5DF2\u4E0B\u8F7D\uFF0C\u5C06\u4E8E\u4E0B\u6B21\u91CD\u542F\u8D44\u6E90\u7BA1\u7406\u5668\u751F\u6548"):g===N?g+" (latest)":`${g} -> ${N}`))),h("flex",{gap:10},h(j,null,"\u66F4\u65B0\u65E5\u5FD7:"),h("flex",{enableScrolling:!0,maxHeight:500,width:550,gap:10},h(yi,{text:i.shell.changelog,maxWidth:550}))))}),wi=Uf;import*as me from"mshell";var Ye=lt(Ke()),Df=(0,Ye.memo)(()=>{let{updateData:i}=(0,Ye.useContext)(Tt),{setErrorMessage:u}=(0,Ye.useContext)(Mt),{currentPluginSource:a}=(0,Ye.useContext)(qt),{t:p}=it(),[g,C]=(0,Ye.useState)([]),[d,_]=(0,Ye.useState)(new Set);(0,Ye.useEffect)(()=>{i&&C(i.plugins)},[i]);let P=T=>{if(d.has(T.name))return;_(w=>new Set(w).add(T.name));let $=me.breeze.data_directory()+"/scripts/"+T.local_path,S=Qt[a]+T.path;me.network.get_async(S,w=>{me.fs.write($,w),me.println(p("\u63D2\u4EF6\u5B89\u88C5\u6210\u529F: ")+T.name),_(H=>{let Q=new Set(H);return Q.delete(T.name),Q})},w=>{me.println(w),u(p("\u63D2\u4EF6\u5B89\u88C5\u5931\u8D25: ")+T.name),_(H=>{let Q=new Set(H);return Q.delete(T.name),Q})})},[N,R]=(0,Ye.useState)(0);return h("flex",{gap:20},h(j,{fontSize:24},p("\u63D2\u4EF6\u5E02\u573A")),h("flex",{gap:10,alignItems:"stretch",width:570,height:500,autoSize:!1},h("flex",{enableScrolling:!0,maxHeight:500,alignItems:"stretch"},g.map(T=>{let $=null;me.fs.exists(me.breeze.data_directory()+"/scripts/"+T.local_path)&&($=me.breeze.data_directory()+"/scripts/"+T.local_path),me.fs.exists(me.breeze.data_directory()+"/scripts/"+T.local_path+".disabled")&&($=me.breeze.data_directory()+"/scripts/"+T.local_path+".disabled");let S=$!==null,w=S?me.fs.read($).match(/\/\/ @version:\s*(.*)/):null,H=w?w[1]:"\u672A\u5B89\u88C5",Q=S&&H!==T.version;return h("flex",{key:T.name,horizontal:!0,alignItems:"center"},h("flex",{autoSize:!1,width:4,height:20,borderRadius:2,backgroundColor:S?Q?"#FFA500":"#2979FF":me.breeze.is_light_theme()?"#C0C0C0aa":"#505050aa"}),h("flex",{gap:10,padding:10,borderRadius:8,flexGrow:1,horizontal:!0},h("flex",{gap:10,alignItems:"stretch",flexGrow:1},h(j,{fontSize:18},T.name),h(j,null,T.description)),h("flex",{gap:10,alignItems:"center",flexShrink:0},h(ut,{onClick:()=>P(T)},h(j,null,d.has(T.name)?p("\u5B89\u88C5\u4E2D..."):S?Q?`\u66F4\u65B0 (${H} -> ${T.version})`:"\u5DF2\u5B89\u88C5":"\u5B89\u88C5")))))}))))}),Ci=Df;import*as fn from"mshell";var Zt=lt(Ke()),Of=(0,Zt.memo)(()=>{let{order:i,update:u}=(0,Zt.useContext)(sr),{t:a}=it(),[p,g]=(0,Zt.useState)([]);(0,Zt.useEffect)(()=>{C()},[]);let C=()=>{let S=mi();g(S)},d=S=>{gi(S),C()},_=S=>{vi(S),C()},P=S=>i?.includes(S)||!1,N=S=>{let w=[...i||[]];if(w.includes(S)){let H=w.indexOf(S);w.splice(H,1)}else w.unshift(S);u(w)},R=S=>{xl(w=>{w.append_menu({name:P(S)?"\u53D6\u6D88\u4F18\u5148\u52A0\u8F7D":"\u8BBE\u4E3A\u4F18\u5148\u52A0\u8F7D",action(){N(S),w.close()}}),w.append_menu({name:a("\u5220\u9664"),action(){_(S),w.close()}}),on_plugin_menu[S]&&on_plugin_menu[S](w)})},T=p.filter(S=>P(S)),$=p.filter(S=>!P(S));return h("flex",{gap:20,width:580,height:550,autoSize:!1,alignItems:"stretch"},h(j,{fontSize:24},a("\u63D2\u4EF6\u914D\u7F6E")),h("flex",{enableScrolling:!0,maxHeight:500,alignItems:"stretch"},T.length>0&&h("flex",{gap:10,alignItems:"stretch",paddingBottom:10,paddingTop:10},h(j,{fontSize:16},a("\u4F18\u5148\u52A0\u8F7D\u63D2\u4EF6")),T.map(S=>{let w=fn.fs.exists(fn.breeze.data_directory()+"/scripts/"+S+".js");return h(Sl,{key:S,name:S,isEnabled:w,isPrioritized:!0,onToggle:()=>d(S),onMoreClick:R})}),h("flex",{height:1,autoSize:!1,backgroundColor:fn.breeze.is_light_theme()?"#E0E0E0":"#505050"})),h("flex",{gap:10,alignItems:"stretch"},T.length===0&&h(j,{fontSize:16},a("\u5DF2\u5B89\u88C5\u63D2\u4EF6")),$.map(S=>{let w=fn.fs.exists(fn.breeze.data_directory()+"/scripts/"+S+".js");return h(Sl,{key:S,name:S,isEnabled:w,isPrioritized:!1,onToggle:()=>d(S),onMoreClick:R})}))))}),zi=Of;var De=lt(Ke()),ia=()=>{let[i,u]=(0,De.useState)("context-menu"),[a,p]=(0,De.useState)({}),[g,C]=(0,De.useState)(!1),[d,_]=(0,De.useState)([]),[P,N]=(0,De.useState)(null),[R,T]=(0,De.useState)({}),[$,S]=(0,De.useState)(null),[w,H]=(0,De.useState)(null),[Q,ce]=(0,De.useState)("Enlysure"),[_t,st]=(0,De.useState)(null);(0,De.useEffect)(()=>{let we=wl.breeze.data_directory()+"/config.json",He=wl.fs.read(we),xt=JSON.parse(He);T(xt),p(xt.context_menu||{}),C(xt.debug_console||!1),_(xt.plugin_load_order||[])},[]);let dr=we=>{p(we);let He={...R,context_menu:we};T(He),or(He)},pr=we=>{C(we);let He={...R,debug_console:we};T(He),or(He)},Kt=we=>{_(we);let He={...R,plugin_load_order:we};T(He),or(He)};return h(ir.Provider,{value:{config:a,update:dr}},h(ur.Provider,{value:{value:g,update:pr}},h(sr.Provider,{value:{order:d,update:Kt}},h(Tt.Provider,{value:{updateData:P,setUpdateData:N}},h(Mt.Provider,{value:{errorMessage:$,setErrorMessage:S,loadingMessage:w,setLoadingMessage:H}},h(qt.Provider,{value:{currentPluginSource:Q,setCurrentPluginSource:ce,cachedPluginIndex:_t,setCachedPluginIndex:st}},h("flex",{horizontal:!0,width:di,height:_l,autoSize:!1,gap:10},h(_i,{activePage:i,setActivePage:u,sidebarWidth:pi,windowHeight:_l}),h("flex",{padding:20},i==="context-menu"&&h(Si,null),i==="update"&&h(wi,null),i==="plugin-store"&&h(Ci,null),i==="plugin-config"&&h(zi,null)))))))))},ua=ia;import*as Ln from"mshell";var cr=null,Cl=()=>{Ln.breeze.set_can_reload_js(!1);let i=Ln.breeze_ui.window.create_ex("Breeze Config",800,600,()=>{Ln.breeze.set_can_reload_js(!0),cr===i&&(cr=null)});cr&&cr.close(),cr=i;let u=Ln.breeze_ui.widgets_factory.create_flex_layout_widget();createRenderer(u).render(React.createElement(ua,null)),i.set_root_widget(u)};import{breeze as ca}from"mshell";import*as Oe from"mshell";var sa=()=>{Oe.menu_controller.add_menu_listener(i=>{let u=_=>()=>{i.menu.close(),Oe.infra.setTimeout(()=>{Oe.win32.simulate_hotkeys(_)},50),Oe.infra.setTimeout(()=>{Oe.win32.simulate_hotkeys(_)},70),Oe.infra.setTimeout(()=>{Oe.win32.simulate_hotkeys(_)},100)};for(let _ of i.menu.items)(_.data().name==="\u91CD\u547D\u540D"||_.data().name==="Rename")&&_.set_data({action:u(["f2"])});let a=Oe.breeze.is_light_theme()?'fill="#000000"':'fill="#FFFFFF"',p=Oe.breeze.user_language().startsWith("zh"),g=p?"\u65B0\u5EFA":"New",C=p?"\u6587\u4EF6\u5939":"Folder",d=p?"\u6587\u4EF6":"File";i.menu.append_item_after({name:g,submenu(_){_.append_item({name:C,action:u(["ctrl","shift","n"]),icon_svg:``}),_.append_item({name:d,action:u(["ctrl","n"]),icon_svg:``})}},-2)})};import{menu_controller as jf,value_reset as Hf}from"mshell";var aa=()=>{jf.add_menu_listener(i=>{for(let u of i.menu.items){let a=u.data();(a.name_resid==="10580@SHELL32.dll"||a.name==="\u6E05\u7A7A\u56DE\u6536\u7AD9")&&u.set_data({disabled:!1}),a.name?.startsWith("NVIDIA ")&&u.set_data({icon_svg:'',icon_bitmap:new Hf})}})};var fa=()=>{ca.current_process_name()=="OneCommander.exe"?sa():ca.current_process_name()=="explorer.exe"&&aa()};globalThis.h=fr.createElement;globalThis.Fragment=fr.Fragment;var da=``;if(je.fs.exists(je.breeze.data_directory()+"/shell_old.dll"))try{je.fs.remove(je.breeze.data_directory()+"/shell_old.dll")}catch(i){je.println("Failed to remove old shell.dll: ",i)}je.menu_controller.add_menu_listener(i=>{i.context.folder_view?.current_path.startsWith(je.breeze.data_directory().replaceAll("/","\\"))&&i.menu.prepend_menu({action(){Cl()},name:"Breeze Config",icon_svg:da}),je.breeze.should_show_settings_button()&&i.screenside_button.add_button(da,()=>{i.menu.close(),Cl()})});fa();globalThis.plugin=Os;globalThis.React=fr;globalThis.createRenderer=ra;globalThis.showConfigPage=Cl; + `)+e.join(" > ")}return null},a.getPublicRootInstance=function(e){if(e=e.current,!e.child)return null;switch(e.child.tag){case 5:return Tl(e.child.stateNode);default:return e.child.stateNode}},a.injectIntoDevTools=function(e){if(e={bundleType:e.bundleType,version:e.version,rendererPackageName:e.rendererPackageName,rendererConfig:e.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:_.ReactCurrentDispatcher,findHostInstanceByFiber:uf,findFiberByHostInstance:e.findFiberByHostInstance||sf,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1"},typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u")e=!1;else{var t=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(t.isDisabled||!t.supportsFiber)e=!0;else{try{Er=t.inject(e),pt=t}catch{}e=!!t.checkDCE}}return e},a.isAlreadyRendering=function(){return!1},a.observeVisibleRects=function(e,t,n,r){if(!Wn)throw Error(c(363));e=Uo(e,t);var l=Ua(e,n,r).disconnect;return{disconnect:function(){l()}}},a.registerMutableSourceForHydration=function(e,t){var n=t._getVersion;n=n(t._source),e.mutableSourceEagerHydrationData==null?e.mutableSourceEagerHydrationData=[t,n]:e.mutableSourceEagerHydrationData.push(t,n)},a.runWithPriority=function(e,t){var n=B;try{return B=e,t()}finally{B=n}},a.shouldError=function(){return null},a.shouldSuspend=function(){return!1},a.updateContainer=function(e,t,n,r){var l=t.current,o=we(),s=Qt(l);return n=ws(n),t.context===null?t.context=n:t.pendingContext=n,t=Nt(o,s),t.payload={element:e},r=r===void 0?null:r,r!==null&&(t.callback=r),e=Wt(l,t,s),e!==null&&(Xe(e,l,s,o),Dr(e,l,s)),s},a}});var la=Rn((ud,ra)=>{"use strict";ra.exports=na()});var vr=at($e());import*as Be from"mshell";import*as Ue from"mshell";var ei=(i,u)=>{let a=u.split("."),p=i;for(let v of a){if(p==null)return;p=p[v]}return p},Hs=(i,u,a)=>{let p=u.split("."),v=i;for(let S=0;Su?ar.breeze.get_translation_with_params(i,u):ar.breeze.get_translation(i),hl=()=>ar.breeze.is_rtl(),As=()=>ar.breeze.user_language();var vl=Ue.breeze.data_directory()+"/config/",Ws=new Set;Ue.fs.mkdir(vl);Ue.fs.watch(vl,(i,u)=>{for(let a of Ws)a(i,u)});globalThis.on_plugin_menu={};var Bs=(i,u={})=>{let a="config.json",{name:p,url:v}=i,S={},c=p.endsWith(".js")?p.slice(0,-3):p,_=u,z=new Set,N={i18n:{define:(L,I)=>{Ue.breeze.register_translations(L,I),S[L]=I},t:Ie,isRTL:hl},set_on_menu:L=>{globalThis.on_plugin_menu[c]=L},config_directory:vl+c+"/",config:{read_config(){if(Ue.fs.exists(N.config_directory+a))try{_=JSON.parse(Ue.fs.read(N.config_directory+a))}catch(L){Ue.println(`[${p}] ${Ie("error.config_parse_failed",{error:String(L)})}`)}},write_config(){Ue.fs.write(N.config_directory+a,JSON.stringify(_,null,4))},get(L){return ei(_,L)||ei(u,L)||null},set(L,I){Hs(_,L,I),N.config.write_config()},all(){return _},on_reload(L){let I=()=>{z.delete(L)};return z.add(L),I}},log(...L){Ue.println(`[${p}]`,...L)}};return Ue.fs.mkdir(N.config_directory),N.config.read_config(),Ws.add((L,I)=>{if(L.replace(vl,"")===`${c}\\${a}`){Ue.println(`[${p}] ${Ie("status.config_changed",{path:L,type:I})}`),N.config.read_config();for(let M of z)M(_)}}),N};var ia=at(la());import*as Fn from"mshell";var W=i=>({set:(u,a)=>{let p=Array.isArray(a)?a:[a];u.downcast()["set_"+i](...p)},get:u=>u.downcast()["get_"+i]()}),Rf=(i,u=4)=>({set:(a,p)=>{let v=Array.isArray(p)?p:[p];for(;v.lengtha.downcast()["get_"+i]()}),ci=i=>({set:(u,a)=>{u["set_"+i](Lf(a))},get:u=>Ff(u["get_"+i]())}),Lf=i=>{if(i.startsWith("#")){let u=i.slice(1);if(u.length===6)return[parseInt(u.slice(0,2),16)/255,parseInt(u.slice(2,4),16)/255,parseInt(u.slice(4,6),16)/255,1];if(u.length===8)return[parseInt(u.slice(0,2),16)/255,parseInt(u.slice(2,4),16)/255,parseInt(u.slice(4,6),16)/255,parseInt(u.slice(6,8),16)/255]}},Ff=i=>{let u=Math.round(i[0]*255).toString(16).padStart(2,"0"),a=Math.round(i[1]*255).toString(16).padStart(2,"0"),p=Math.round(i[2]*255).toString(16).padStart(2,"0"),v=Math.round(i[3]*255).toString(16).padStart(2,"0");return`#${u}${a}${p}${v}`},Uf={set:(i,u)=>{for(let a of u)i.set_animation(a,!0);i._last_animated_vars=u},get:i=>i._last_animated_vars},fi={animatedVars:Uf,x:W("x"),y:W("y"),width:W("width"),height:W("height")},Cl={text:{creator:Fn.breeze_ui.widgets_factory.create_text_widget,props:{text:{set:(i,u)=>{i.text=Array.isArray(u)?u.join(""):u},get:i=>i.text},fontSize:W("font_size"),color:ci("color"),maxWidth:W("max_width"),...fi}},flex:{creator:Fn.breeze_ui.widgets_factory.create_flex_layout_widget,props:{padding:Rf("padding"),paddingTop:W("padding_top"),paddingRight:W("padding_right"),paddingBottom:W("padding_bottom"),paddingLeft:W("padding_left"),onClick:W("on_click"),onMouseEnter:W("on_mouse_enter"),onMouseLeave:W("on_mouse_leave"),onMouseDown:W("on_mouse_down"),onMouseUp:W("on_mouse_up"),onMouseMove:W("on_mouse_move"),backgroundColor:ci("background_color"),borderColor:ci("border_color"),borderRadius:W("border_radius"),borderWidth:W("border_width"),backgroundPaint:W("background_paint"),borderPaint:W("border_paint"),horizontal:W("horizontal"),autoSize:W("auto_size"),justifyContent:W("justify_content"),alignItems:W("align_items"),gap:W("gap"),flexGrow:W("flex_grow"),flexShrink:W("flex_shrink"),maxHeight:W("max_height"),enableScrolling:W("enable_scrolling"),enableChildClipping:W("enable_child_clipping"),cropOverflow:W("crop_overflow"),...fi}},img:{creator:Fn.breeze_ui.widgets_factory.create_image_widget,props:{svg:W("svg"),...fi}},spacer:{creator:Fn.breeze_ui.widgets_factory.create_spacer_widget,props:{size:W("size")}}},ua={getPublicInstance(i){return i},getRootHostContext(i){return null},getChildHostContext(i,u,a){return i},prepareForCommit(i){return null},resetAfterCommit(i){},createInstance(i,u,a,p,v){try{if(!Cl[i])throw new Error(`Unknown component type: ${i}`);let S=Cl[i].creator();for(let c in u){if(c==="children")continue;let _=Cl[i]?.props?.[c];if(_)_.set(S,u[c]);else throw new Error(`Unknown property: ${c} for component type: ${i}`)}return S}catch(S){throw console.error(`Error creating instance of type ${i}:`,S,S.stack),S}},appendInitialChild(i,u){i.append_child(u)},finalizeInitialChildren(i,u,a,p,v){return!1},prepareUpdate(i,u,a,p,v,S){let c={};for(let _ in p)p[_]!==a[_]&&(c[_]=p[_]);return Object.keys(c).length>0?c:null},shouldSetTextContent(i,u){return!1},createTextInstance(i,u,a,p){let v=Fn.breeze_ui.widgets_factory.create_text_widget();return v.text=i,v},scheduleTimeout:setTimeout,cancelTimeout:clearTimeout,noTimeout:-1,isPrimaryRenderer:!0,warnsIfNotActing:!0,supportsMutation:!0,supportsPersistence:!1,supportsHydration:!1,getInstanceFromNode(i){throw new Error("getInstanceFromNode not implemented")},beforeActiveInstanceBlur(){},afterActiveInstanceBlur(){},preparePortalMount(i){throw new Error("preparePortalMount not implemented")},prepareScopeUpdate(i,u){throw new Error("prepareScopeUpdate not implemented")},getInstanceFromScope(i){throw new Error("getInstanceFromScope not implemented")},getCurrentEventPriority(){return 16},detachDeletedInstance(i){},commitMount(i,u,a,p){},commitUpdate(i,u,a,p,v,S){for(let c in v){if(c==="children")continue;let _=Cl[a].props[c];_&&v[c]!==p[c]&&_.set(i,v[c])}},clearContainer(i){for(let u of i.children())i.remove_child(u)},appendChild(i,u){i.append_child(u)},appendChildToContainer(i,u){i.append_child(u)},removeChild(i,u){i.remove_child(u)},removeChildFromContainer(i,u){i.remove_child(u)},commitTextUpdate(i,u,a){i.text=a},insertBefore(i,u,a){a?i.append_child_after(u,i.children().indexOf(a)-1):i.append_child(u)},resetTextContent(i){let u=i.downcast();"set_text"in u&&u.set_text("")}},oa=(0,ia.default)(ua),sa=i=>({render:u=>{let a=oa.createContainer(i,0,null,!1,null,"",p=>console.error(p),null);oa.updateContainer(u,a,null,null)}});import*as Il from"mshell";var Kt={"Github Raw":"https://raw.githubusercontent.com/breeze-shell/plugins-packed/refs/heads/main/",Enlysure:"https://breeze.enlysure.com/","Enlysure Shanghai":"https://breeze-c.enlysure.com/"},di='',pi='',gi='',mi='',hi='',vi='',yi=800,zl=600,_i=170,gn={default:null,compact:{radius:4,item_height:20,item_gap:2,item_radius:3,margin:4,padding:4,text_padding:6,icon_padding:3,right_icon_padding:16,multibutton_line_gap:-4},relaxed:{radius:6,item_height:24,item_gap:4,item_radius:8,margin:6,padding:6,text_padding:8,icon_padding:4,right_icon_padding:20,multibutton_line_gap:-6},rounded:{radius:12,item_radius:12},square:{radius:0,item_radius:0}},me={easing:"mutation"},Un={default:null,fast:{item:{opacity:{delay_scale:0},width:me,x:me},submenu_bg:{opacity:{delay_scale:0,duration:100}},main_bg:{opacity:me}},none:{item:{opacity:me,width:me,x:me,y:me},submenu_bg:{opacity:me,x:me,y:me,w:me,h:me},main_bg:{opacity:me,x:me,y:me,w:me,h:me}}};import*as ze from"mshell";var xi=at($e());import{menu_controller as Df}from"mshell";var Dn=()=>{let[i,u]=(0,xi.useState)(!1),[a,p]=(0,xi.useState)(!1);return{isHovered:i,isActive:a,onMouseEnter:()=>u(!0),onMouseLeave:()=>u(!1),onMouseDown:()=>p(!0),onMouseUp:()=>p(!1)}},kl=i=>{let u=Df.create_detached();i(u),u.show_at_cursor()},Lt=(i,u)=>u.split(".").reduce((a,p)=>a?.[p],i),Ft=(i,u,a)=>{let p=u.split("."),v=p.pop(),S=p.reduce((c,_)=>c[_]=c[_]||{},i);S[v]=a},ft=()=>{let i=As();return{t:Ie,currentLang:i,isRTL:hl}};var On=i=>{ze.fs.write(ze.breeze.data_directory()+"/config.json",JSON.stringify(i,null,4))},Si=()=>ze.fs.readdir(ze.breeze.data_directory()+"/scripts").map(i=>i.split("/").pop()).filter(i=>i.endsWith(".js")||i.endsWith(".disabled")).map(i=>i.replace(".js","").replace(".disabled","")),wi=i=>{let u=ze.breeze.data_directory()+"/scripts/"+i;ze.fs.exists(u+".js")?ze.fs.rename(u+".js",u+".js.disabled"):ze.fs.exists(u+".js.disabled")&&ze.fs.rename(u+".js.disabled",u+".js")},Ci=i=>{let u=ze.breeze.data_directory()+"/scripts/"+i;ze.fs.exists(u+".js")&&ze.fs.remove(u+".js"),ze.fs.exists(u+".js.disabled")&&ze.fs.remove(u+".js.disabled")};var Xt=at($e()),Pl=(0,Xt.createContext)(null),pr=(0,Xt.createContext)(null),gr=(0,Xt.createContext)(null),mr=(0,Xt.createContext)(null),Ut=(0,Xt.createContext)(null),Dt=(0,Xt.createContext)(null),Yt=(0,Xt.createContext)(null);import*as mn from"mshell";var Ot=at($e());import{breeze as $t}from"mshell";var bt=at($e()),jn=(i,u=14)=>h("img",{svg:i.replace("h(Fragment,null,i.split(` +`).map((a,p)=>a.trim().startsWith("# ")?h(O,{key:p,fontSize:22,maxWidth:u},a.trim().substring(2).trim()):a.trim().startsWith("## ")?h(O,{key:p,fontSize:20,maxWidth:u},a.trim().substring(3).trim()):a.trim().startsWith("### ")?h(O,{key:p,fontSize:18,maxWidth:u},a.trim().substring(4).trim()):a.trim().startsWith("#### ")?h(O,{key:p,fontSize:16,maxWidth:u},a.trim().substring(5).trim()):h(O,{key:p,fontSize:14,maxWidth:u},a))),et=(0,bt.memo)(({onClick:i,children:u,selected:a})=>{let p=$t.is_light_theme(),{isHovered:v,isActive:S,onMouseEnter:c,onMouseLeave:_,onMouseDown:z,onMouseUp:N}=Dn();return h("flex",{onClick:i,backgroundColor:S?p?"#c0c0c0cc":"#505050cc":v?p?"#e0e0e0cc":"#606060cc":p?"#f0f0f0cc":"#404040cc",borderRadius:8,paddingLeft:12,paddingRight:12,paddingTop:8,paddingBottom:8,autoSize:!0,justifyContent:"center",alignItems:"center",horizontal:!0,gap:6,borderWidth:a?2:0,borderColor:"#2979FF",onMouseEnter:c,onMouseLeave:_,onMouseDown:z,onMouseUp:N,animatedVars:[".r",".g",".b",".a"]},u)}),O=(0,bt.memo)(({children:i,fontSize:u=14,maxWidth:a=-1})=>{let p=$t.is_light_theme();return h("text",{text:i,fontSize:u,maxWidth:a,color:p?"#000000ff":"#ffffffff"})}),Of=(0,bt.memo)(({onClick:i,children:u,icon:a})=>h(et,{onClick:i},a?jn(a,14):null,h(O,{fontSize:14},u))),wt=({label:i,value:u,onChange:a})=>{let p=$t.is_light_theme(),{isHovered:v,isActive:S,onMouseEnter:c,onMouseLeave:_,onMouseDown:z,onMouseUp:N}=Dn();return h("flex",{horizontal:!0,alignItems:"center",gap:10,justifyContent:"space-between"},h(O,null,i),h("flex",{width:40,height:20,borderRadius:10,backgroundColor:u?"#0078D4":v?p?"#CCCCCCAA":"#555555AA":p?"#CCCCCC77":"#55555577",justifyContent:u?"end":"start",horizontal:!0,alignItems:"center",onClick:()=>a(!u),autoSize:!1,onMouseEnter:c,padding:v||S?2:3,onMouseLeave:_,onMouseDown:z,onMouseUp:N,animatedVars:[".r",".g",".b",".a"],borderWidth:.5,borderColor:u?"#00000000":p?"#5A5A5A5":"#CECDD0"},h("flex",{width:S?19:v?16:14,height:v||S?16:14,borderRadius:8,backgroundColor:u?p?"#FFFFFF":"#000000":p?"#5A5A5A":"#CECDD0",animatedVars:["x","width","height"],autoSize:!1})))},Hn=(0,bt.memo)(({onClick:i,icon:u,isActive:a,children:p})=>{let v=$t.is_light_theme(),{isHovered:S,isActive:c,onMouseEnter:_,onMouseLeave:z,onMouseDown:N,onMouseUp:L}=Dn();return h("flex",{onClick:i,backgroundColor:a?v?"#c0c0c077":"#50505077":c?v?"#c0c0c0cc":"#505050cc":S?v?"#e0e0e0cc":"#606060cc":v?"#e0e0e000":"#60606000",paddingLeft:0,paddingRight:12,paddingTop:8,paddingBottom:8,autoSize:!1,height:32,justifyContent:"start",alignItems:"center",horizontal:!0,gap:6,borderRadius:6,onMouseEnter:_,onMouseLeave:z,onMouseDown:N,onMouseUp:L,animatedVars:[".r",".g",".b",".a"]},h("flex",{width:3,height:a?15:0,backgroundColor:a?"#2979FF":"#00000000",borderRadius:3,autoSize:!1,animatedVars:[".a","height"]}),jn(u,14),h(O,{fontSize:14},p))}),aa=(0,bt.memo)(({isEnabled:i,onToggle:u})=>{let a=$t.is_light_theme(),{isHovered:p,isActive:v,onMouseEnter:S,onMouseLeave:c,onMouseDown:_,onMouseUp:z}=Dn();return h("flex",{width:20,height:20,borderRadius:4,borderWidth:1,borderColor:a?"#CCCCCC":"#555555",backgroundColor:i?v?"#1E5F99":p?"#3F7FBF":"#2979FF":v?a?"#c0c0c0cc":"#505050cc":p?a?"#e0e0e0cc":"#606060cc":a?"#e0e0e066":"#60606066",justifyContent:"center",alignItems:"center",onClick:u,onMouseEnter:S,onMouseLeave:c,onMouseDown:_,onMouseUp:z,animatedVars:[".r",".g",".b",".a"]},i?h("img",{svg:``,width:14,height:14}):h("flex",{width:14,height:14,autoSize:!1}))}),ca=(0,bt.memo)(({onClick:i})=>{let u=$t.is_light_theme(),{isHovered:a,isActive:p,onMouseEnter:v,onMouseLeave:S,onMouseDown:c,onMouseUp:_}=Dn();return h("flex",{width:32,height:32,borderRadius:16,justifyContent:"center",alignItems:"center",backgroundColor:p?u?"#c0c0c0cc":"#505050cc":a?u?"#e0e0e0cc":"#606060cc":"#00000000",onClick:i,onMouseEnter:v,onMouseLeave:S,onMouseDown:c,onMouseUp:_,animatedVars:[".r",".g",".b",".a"]},jn(hi,16))}),El=(0,bt.memo)(({name:i,isEnabled:u,isPrioritized:a,onToggle:p,onMoreClick:v})=>{let S=$t.is_light_theme();return h("flex",{horizontal:!0,alignItems:"center",gap:12,padding:12,borderRadius:8},h("flex",{width:8,height:8,borderRadius:4,backgroundColor:u?"#4CAF50":"#9E9E9E",autoSize:!1}),h("flex",{flexGrow:1},h(O,{fontSize:14},i),a&&h("flex",{padding:4},h(O,{fontSize:10},Ie("settings.priority_load_plugins")))),h("spacer",null),h(aa,{isEnabled:u,onToggle:p}),h(ca,{onClick:()=>v(i)}))});var jf=(0,Ot.memo)(({activePage:i,setActivePage:u,sidebarWidth:a,windowHeight:p})=>{let{t:v}=ft(),{updateData:S,setUpdateData:c}=(0,Ot.useContext)(Ut),{errorMessage:_,setErrorMessage:z,loadingMessage:N,setLoadingMessage:L}=(0,Ot.useContext)(Dt),{currentPluginSource:I,setCurrentPluginSource:Y,cachedPluginIndex:M,setCachedPluginIndex:j}=(0,Ot.useContext)(Yt);(0,Ot.useEffect)(()=>{if(_){let $=setTimeout(()=>{z(null)},3e3);return()=>clearTimeout($)}},[_,z]);let q=$=>{Y($),j(null),L(v("source.switching")),mn.network.get_async(Kt[$]+"plugins-index.json",ke=>{j(ke),c(JSON.parse(ke)),L(null)},ke=>{mn.println("Failed to fetch update data:",ke),z(v("common.load_failed")),L(null)})};return(0,Ot.useEffect)(()=>{q(I)},[I]),h("flex",{width:a,height:p,backgroundColor:mn.breeze.is_light_theme()?"#f0f0f077":"#40404077",padding:10,gap:10,alignItems:"stretch",autoSize:!1},h("flex",{horizontal:!0,alignItems:"center",gap:3,padding:10},jn(vi,24),h(O,{fontSize:18},"Breeze")),h(Hn,{onClick:()=>u("context-menu"),icon:di,isActive:i==="context-menu"},v("sidebar.main_config")),h(Hn,{onClick:()=>u("update"),icon:pi,isActive:i==="update"},v("sidebar.update")),h(Hn,{onClick:()=>u("plugin-store"),icon:gi,isActive:i==="plugin-store"},v("sidebar.plugin_store")),h(Hn,{onClick:()=>u("plugin-config"),icon:mi,isActive:i==="plugin-config"},v("sidebar.plugin_config")),h("spacer",null),_&&h("flex",{backgroundColor:"#FF4444AA",padding:8,borderRadius:6,paddingBottom:5},h("text",{text:_,fontSize:12,color:"#FFFFFFFF"})),N&&h("flex",{backgroundColor:"#0078D4AA",padding:8,borderRadius:6,paddingBottom:5},h("text",{text:N,fontSize:12,color:"#FFFFFFFF"})),h(et,{onClick:()=>{kl($=>{Object.keys(Kt).forEach(ke=>{$.append_menu({name:ke,action(){q(ke),$.close()},icon_svg:ke===I?``:void 0})})})}},h(O,{fontSize:12},`${v("sidebar.source")} - ${I}`)))}),ki=jf;import*as hn from"mshell";var Ct=at($e()),Hf=(0,Ct.memo)(()=>{let{config:i,update:u}=(0,Ct.useContext)(pr),{value:a,update:p}=(0,Ct.useContext)(gr),{config:v,update:S}=(0,Ct.useContext)(Pl),{t:c}=ft(),[_,z]=(0,Ct.useState)([]);(0,Ct.useEffect)(()=>{z(hn.breeze.available_languages())},[]);let N=v?.language||hn.breeze.user_language(),L=i?.theme,I=i?.theme?.animation,Y=R=>{if(!R)return[];let E=new Set;for(let De of Object.values(R))if(De)for(let dt of Object.keys(De))E.add(dt);return[...E]},M=(R,E,De)=>{let dt=Y(De),zt=R?{...R}:{};for(let kt in E)dt.includes(kt)||(zt[kt]=E[kt]);return zt},j=(R,E)=>!R||!E?!1:Object.keys(E).every(De=>JSON.stringify(R[De])===JSON.stringify(E[De])),q=(R,E)=>{if(!R)return"default";for(let[De,dt]of Object.entries(E))if(dt&&j(R,dt))return De;return"custom"},$=q(L,gn),ke=q(I,Un);return h("flex",{gap:20,alignItems:"stretch",width:500,autoSize:!1},h(O,{fontSize:24},c("settings.title")),h("flex",{gap:10},h(O,{fontSize:18},c("settings.language")||"Language"),h("flex",{horizontal:!0,gap:10},_.map(R=>h(et,{key:R,selected:R===N,onClick:()=>{hn.breeze.set_language(R),S({...v,language:R})}},h(O,{fontSize:14},R))))),h("flex",null),h("flex",{gap:10},h(O,{fontSize:18},c("settings.theme")),h("flex",{horizontal:!0,gap:10},Object.keys(gn).map(R=>h(et,{key:R,selected:R===$,onClick:()=>{try{let E;gn[R]?E=M(gn[R],i?.theme,gn):E=void 0,u(E?{...i,theme:E}:{...i,theme:void 0})}catch(E){hn.println(E)}}},h(O,{fontSize:14},c(`theme.${R}`)||R))))),h("flex",{gap:10},h(O,{fontSize:18},c("settings.animation")),h("flex",{horizontal:!0,gap:10},Object.keys(Un).map(R=>h(et,{key:R,onClick:()=>{try{let E;Un[R]?E=Un[R]:E=void 0,u({...i,theme:{...i.theme,animation:E}})}catch(E){hn.println(E)}}},h(O,{fontSize:14},c(`animation.${R}`)||R))))),h("flex",{gap:10,alignItems:"stretch",justifyContent:"center"},h(O,{fontSize:18},c("settings.misc")),h(wt,{label:c("settings.debug_console"),value:a,onChange:p}),h(wt,{label:c("settings.vsync"),value:Lt(i,"vsync")??!0,onChange:R=>{let E={...i};Ft(E,"vsync",R),u(E)}}),h(wt,{label:c("settings.ignore_owner_draw"),value:Lt(i,"ignore_owner_draw")??!0,onChange:R=>{let E={...i};Ft(E,"ignore_owner_draw",R),u(E)}}),h(wt,{label:c("settings.reverse_if_open_to_up"),value:Lt(i,"reverse_if_open_to_up")??!0,onChange:R=>{let E={...i};Ft(E,"reverse_if_open_to_up",R),u(E)}}),h(wt,{label:c("settings.use_dwm_round_corners"),value:Lt(i,"theme.use_dwm_if_available")??!0,onChange:R=>{let E={...i};Ft(E,"theme.use_dwm_if_available",R),u(E)}}),h(wt,{label:c("settings.acrylic_background"),value:Lt(i,"theme.acrylic")??!0,onChange:R=>{let E={...i};Ft(E,"theme.acrylic",R),u(E)}}),h(wt,{label:c("settings.keyboard_hotkeys"),value:Lt(i,"hotkeys")??!0,onChange:R=>{let E={...i};Ft(E,"hotkeys",R),u(E)}}),h(wt,{label:c("settings.show_settings_button"),value:Lt(i,"show_settings_button")??!0,onChange:R=>{let E={...i};Ft(E,"show_settings_button",R),u(E)}})))}),Pi=Hf;import*as se from"mshell";var Ae=at($e()),Af=(0,Ae.memo)(()=>{let{updateData:i}=(0,Ae.useContext)(Ut),{setErrorMessage:u}=(0,Ae.useContext)(Dt),{currentPluginSource:a}=(0,Ae.useContext)(Yt),{t:p}=ft(),v=(0,Ae.useMemo)(()=>se.breeze.version(),[]),[S,c]=(0,Ae.useState)(!1),[_,z]=(0,Ae.useState)(!1);if((0,Ae.useEffect)(()=>{c(se.fs.exists(se.breeze.data_directory()+"/shell_old.dll"))},[]),!i)return h(O,null,p("common.loading"));let N=i.shell.version,L=()=>{if(_)return;z(!0);let I=se.breeze.data_directory()+"/shell.dll",Y=se.breeze.data_directory()+"/shell_old.dll",M=Kt[a]+i.shell.path,j=()=>{se.network.download_async(M,I,()=>{se.println(p("plugins.update_downloaded")),z(!1),c(!0)},q=>{se.println(p("plugins.update_failed",{error:String(q)})),z(!1),u(p("plugins.update_failed",{error:String(q)}))})};try{if(se.fs.exists(I))if(se.fs.exists(Y))try{se.fs.remove(Y),se.fs.rename(I,Y),j()}catch{se.println(p("plugins.update_failed",{error:p("update.cannot_move_file")})),z(!1),u(p("plugins.update_failed",{error:p("update.cannot_move_file")}))}else se.fs.rename(I,Y),j();else j()}catch(q){se.println(p("plugins.update_failed",{error:String(q)})),z(!1),u(p("plugins.update_failed",{error:String(q)}))}};return h("flex",{gap:20},h(O,{fontSize:24},p("update.title")),h("flex",{gap:10},h(O,null,p("update.current_version",{version:v})),h(O,null,p("update.latest_version",{version:N})),h(et,{onClick:v===N||_?()=>{}:L},h(O,null,_?p("plugins.updating"):S?p("plugins.update_downloaded"):v===N?v+" "+p("common.latest"):`${v} -> ${N}`))),h("flex",{gap:10},h(O,null,p("update.changelog")),h("flex",{enableScrolling:!0,maxHeight:500,width:550,gap:10},h(zi,{text:i.shell.changelog,maxWidth:550}))))}),Ei=Af;import*as he from"mshell";var tt=at($e()),Wf=(0,tt.memo)(()=>{let{updateData:i}=(0,tt.useContext)(Ut),{setErrorMessage:u}=(0,tt.useContext)(Dt),{currentPluginSource:a}=(0,tt.useContext)(Yt),{t:p}=ft(),[v,S]=(0,tt.useState)([]),[c,_]=(0,tt.useState)(new Set);(0,tt.useEffect)(()=>{i&&S(i.plugins)},[i]);let z=I=>{if(c.has(I.name))return;_(j=>new Set(j).add(I.name));let Y=he.breeze.data_directory()+"/scripts/"+I.local_path,M=Kt[a]+I.path;he.network.get_async(M,j=>{he.fs.write(Y,j),he.println(p("plugins.install_success",{name:I.name})),_(q=>{let $=new Set(q);return $.delete(I.name),$})},j=>{he.println(j),u(p("plugins.install_failed",{name:I.name})),_(q=>{let $=new Set(q);return $.delete(I.name),$})})},[N,L]=(0,tt.useState)(0);return h("flex",{gap:20},h(O,{fontSize:24},p("plugins.store")),h("flex",{gap:10,alignItems:"stretch",width:570,height:500,autoSize:!1},h("flex",{enableScrolling:!0,maxHeight:500,alignItems:"stretch"},v.map(I=>{let Y=null;he.fs.exists(he.breeze.data_directory()+"/scripts/"+I.local_path)&&(Y=he.breeze.data_directory()+"/scripts/"+I.local_path),he.fs.exists(he.breeze.data_directory()+"/scripts/"+I.local_path+".disabled")&&(Y=he.breeze.data_directory()+"/scripts/"+I.local_path+".disabled");let M=Y!==null,j=M?he.fs.read(Y).match(/\/\/ @version:\s*(.*)/):null,q=j?j[1]:p("plugins.not_installed"),$=M&&q!==I.version;return h("flex",{key:I.name,horizontal:!0,alignItems:"center"},h("flex",{autoSize:!1,width:4,height:20,borderRadius:2,backgroundColor:M?$?"#FFA500":"#2979FF":he.breeze.is_light_theme()?"#C0C0C0aa":"#505050aa"}),h("flex",{gap:10,padding:10,borderRadius:8,flexGrow:1,horizontal:!0},h("flex",{gap:10,alignItems:"stretch",flexGrow:1},h(O,{fontSize:18},I.name),h(O,null,I.description)),h("flex",{gap:10,alignItems:"center",flexShrink:0},h(et,{onClick:()=>z(I)},h(O,null,c.has(I.name)?p("plugins.installing"):M?$?p("plugins.update",{from:q,to:I.version}):p("plugins.installed"):p("plugins.install"))))))}))))}),Ii=Wf;import*as vn from"mshell";var en=at($e()),Bf=(0,en.memo)(()=>{let{order:i,update:u}=(0,en.useContext)(mr),{t:a}=ft(),[p,v]=(0,en.useState)([]);(0,en.useEffect)(()=>{S()},[]);let S=()=>{let M=Si();v(M)},c=M=>{wi(M),S()},_=M=>{Ci(M),S()},z=M=>i?.includes(M)||!1,N=M=>{let j=[...i||[]];if(j.includes(M)){let q=j.indexOf(M);j.splice(q,1)}else j.unshift(M);u(j)},L=M=>{kl(j=>{j.append_menu({name:z(M)?a("menu.cancel_priority"):a("menu.set_priority"),action(){N(M),j.close()}}),j.append_menu({name:a("menu.delete"),action(){_(M),j.close()}}),on_plugin_menu[M]&&on_plugin_menu[M](j)})},I=p.filter(M=>z(M)),Y=p.filter(M=>!z(M));return h("flex",{gap:20,width:580,height:550,autoSize:!1,alignItems:"stretch"},h(O,{fontSize:24},a("plugins.config")),h("flex",{enableScrolling:!0,maxHeight:500,alignItems:"stretch"},I.length>0&&h("flex",{gap:10,alignItems:"stretch",paddingBottom:10,paddingTop:10},h(O,{fontSize:16},a("plugins.priority_load")),I.map(M=>{let j=vn.fs.exists(vn.breeze.data_directory()+"/scripts/"+M+".js");return h(El,{key:M,name:M,isEnabled:j,isPrioritized:!0,onToggle:()=>c(M),onMoreClick:L})}),h("flex",{height:1,autoSize:!1,backgroundColor:vn.breeze.is_light_theme()?"#E0E0E0":"#505050"})),h("flex",{gap:10,alignItems:"stretch"},I.length===0&&h(O,{fontSize:16},a("plugins.installed_plugins")),Y.map(M=>{let j=vn.fs.exists(vn.breeze.data_directory()+"/scripts/"+M+".js");return h(El,{key:M,name:M,isEnabled:j,isPrioritized:!1,onToggle:()=>c(M),onMoreClick:L})}))))}),Ni=Bf;var We=at($e()),Vf=({children:i,values:u})=>h(Pl.Provider,{value:u.global},h(pr.Provider,{value:u.contextMenu},h(gr.Provider,{value:u.debugConsole},h(mr.Provider,{value:u.pluginLoadOrder},h(Ut.Provider,{value:u.updateData},h(Dt.Provider,{value:u.notification},h(Yt.Provider,{value:u.pluginSource},i))))))),fa=()=>{let[i,u]=(0,We.useState)("context-menu"),[a,p]=(0,We.useState)({}),[v,S]=(0,We.useState)(!1),[c,_]=(0,We.useState)([]),[z,N]=(0,We.useState)(null),[L,I]=(0,We.useState)({}),[Y,M]=(0,We.useState)(null),[j,q]=(0,We.useState)(null),[$,ke]=(0,We.useState)("Enlysure"),[R,E]=(0,We.useState)(null);return(0,We.useEffect)(()=>{let te=Il.breeze.data_directory()+"/config.json",ve=Il.fs.read(te),tn=JSON.parse(ve);I(tn),p(tn.context_menu||{}),S(tn.debug_console||!1),_(tn.plugin_load_order||[])},[]),h(Vf,{values:{global:{config:L,update:te=>{let ve={...L,...te};I(ve),"context_menu"in te&&p(te.context_menu||{}),"debug_console"in te&&S(te.debug_console||!1),"plugin_load_order"in te&&_(te.plugin_load_order||[]),On(ve)}},contextMenu:{config:a,update:te=>{p(te);let ve={...L,context_menu:te};I(ve),On(ve)}},debugConsole:{value:v,update:te=>{S(te);let ve={...L,debug_console:te};I(ve),On(ve)}},pluginLoadOrder:{order:c,update:te=>{_(te);let ve={...L,plugin_load_order:te};I(ve),On(ve)}},updateData:{updateData:z,setUpdateData:N},notification:{errorMessage:Y,setErrorMessage:M,loadingMessage:j,setLoadingMessage:q},pluginSource:{currentPluginSource:$,setCurrentPluginSource:ke,cachedPluginIndex:R,setCachedPluginIndex:E}}},h("flex",{horizontal:!0,width:yi,height:zl,autoSize:!1,gap:10},h(ki,{activePage:i,setActivePage:u,sidebarWidth:_i,windowHeight:zl}),h("flex",{padding:20},i==="context-menu"&&h(Pi,null),i==="update"&&h(Ei,null),i==="plugin-store"&&h(Ii,null),i==="plugin-config"&&h(Ni,null))))},da=fa;import*as An from"mshell";var hr=null,Nl=()=>{An.breeze.set_can_reload_js(!1);let i=An.breeze_ui.window.create_ex("Breeze Config",800,600,()=>{An.breeze.set_can_reload_js(!0),hr===i&&(hr=null)});hr&&hr.close(),hr=i;let u=An.breeze_ui.widgets_factory.create_flex_layout_widget();createRenderer(u).render(React.createElement(da,null)),i.set_root_widget(u)};import{breeze as ma}from"mshell";import*as nt from"mshell";var pa=()=>{nt.menu_controller.add_menu_listener(i=>{let u=c=>()=>{i.menu.close(),nt.infra.setTimeout(()=>{nt.win32.simulate_hotkeys(c)},50),nt.infra.setTimeout(()=>{nt.win32.simulate_hotkeys(c)},70),nt.infra.setTimeout(()=>{nt.win32.simulate_hotkeys(c)},100)};for(let c of i.menu.items){let _=c.data().name;(_===Ie("menu.rename")||_==="Rename"||_==="\u91CD\u547D\u540D")&&c.set_data({action:u(["f2"])})}let a=nt.breeze.is_light_theme()?'fill="#000000"':'fill="#FFFFFF"',p=Ie("menu.new"),v=Ie("menu.folder"),S=Ie("menu.file");i.menu.append_item_after({name:p,submenu(c){c.append_item({name:v,action:u(["ctrl","shift","n"]),icon_svg:``}),c.append_item({name:S,action:u(["ctrl","n"]),icon_svg:``})}},-2)})};import{menu_controller as Qf,value_reset as qf}from"mshell";var ga=()=>{Qf.add_menu_listener(i=>{for(let u of i.menu.items){let a=u.data();(a.name_resid==="10580@SHELL32.dll"||a.name==="\u6E05\u7A7A\u56DE\u6536\u7AD9"||a.name===Ie("explorer.empty_recycle_bin")||a.name==="Empty Recycle Bin")&&u.set_data({disabled:!1}),a.name?.startsWith("NVIDIA ")&&u.set_data({icon_svg:'',icon_bitmap:new qf})}})};var ha=()=>{ma.current_process_name()=="OneCommander.exe"?pa():ma.current_process_name()=="explorer.exe"&&ga()};globalThis.h=vr.createElement;globalThis.Fragment=vr.Fragment;var va=``;if(Be.fs.exists(Be.breeze.data_directory()+"/shell_old.dll"))try{Be.fs.remove(Be.breeze.data_directory()+"/shell_old.dll")}catch(i){Be.println("Failed to remove old shell.dll: ",i)}Be.menu_controller.add_menu_listener(i=>{i.context.folder_view?.current_path.startsWith(Be.breeze.data_directory().replaceAll("/","\\"))&&i.menu.prepend_menu({action(){Nl()},name:"Breeze Config",icon_svg:va}),Be.breeze.should_show_settings_button()&&i.screenside_button.add_button(va,()=>{i.menu.close(),Nl()})});ha();globalThis.plugin=Bs;globalThis.React=vr;globalThis.createRenderer=sa;globalThis.showConfigPage=Nl; /*! Bundled license information: react/cjs/react.production.min.js: diff --git a/src/shell/script/ts/src/compats/explorer_compat.ts b/src/shell/script/ts/src/compats/explorer_compat.ts index de3f5f70..e92ac261 100644 --- a/src/shell/script/ts/src/compats/explorer_compat.ts +++ b/src/shell/script/ts/src/compats/explorer_compat.ts @@ -1,10 +1,11 @@ import { menu_controller, value_reset } from "mshell" +import { t } from "../shared/i18n" export const doExplorerCompat = () => { menu_controller.add_menu_listener(ctx => { for (const items of ctx.menu.items) { const data = items.data() - if (data.name_resid === '10580@SHELL32.dll' /* 清空回收站 */ || data.name === '清空回收站') { + if (data.name_resid === '10580@SHELL32.dll' /* 清空回收站 */ || data.name === '清空回收站' || data.name === t("explorer.empty_recycle_bin") || data.name === "Empty Recycle Bin") { items.set_data({ disabled: false }) diff --git a/src/shell/script/ts/src/compats/onecommander_compat.ts b/src/shell/script/ts/src/compats/onecommander_compat.ts index 7d46ab0c..b5570bb7 100644 --- a/src/shell/script/ts/src/compats/onecommander_compat.ts +++ b/src/shell/script/ts/src/compats/onecommander_compat.ts @@ -1,4 +1,5 @@ import * as shell from "mshell"; +import { t } from "../shared/i18n"; export const doOneCommanderCompat = () => { shell.menu_controller.add_menu_listener(m => { const do_action = (keys: string[]) => () => { @@ -15,7 +16,8 @@ export const doOneCommanderCompat = () => { } for (const i of m.menu.items) { - if (i.data().name === "重命名" || i.data().name === "Rename") { + const name = i.data().name; + if (name === t("menu.rename") || name === "Rename" || name === "重命名") { i.set_data({ action: do_action(['f2']) }) @@ -23,10 +25,9 @@ export const doOneCommanderCompat = () => { } const fill = shell.breeze.is_light_theme() ? "fill=\"#000000\"" : "fill=\"#FFFFFF\""; - const zh = shell.breeze.user_language().startsWith('zh'); - const NEW_NAME = zh ? "新建" : "New"; - const CREATE_FOLDER_NAME = zh ? "文件夹" : "Folder"; - const CREATE_FILE_NAME = zh ? "文件" : "File"; + const NEW_NAME = t("menu.new"); + const CREATE_FOLDER_NAME = t("menu.folder"); + const CREATE_FILE_NAME = t("menu.file"); m.menu.append_item_after({ name: NEW_NAME, submenu(m) { diff --git a/src/shell/script/ts/src/config_page/ConfigApp.tsx b/src/shell/script/ts/src/config_page/ConfigApp.tsx index 37abdb04..3b1bd5b9 100644 --- a/src/shell/script/ts/src/config_page/ConfigApp.tsx +++ b/src/shell/script/ts/src/config_page/ConfigApp.tsx @@ -7,14 +7,67 @@ import { PluginLoadOrderContext, UpdateDataContext, NotificationContext, - PluginSourceContext + PluginSourceContext, + GlobalConfigContext } from "./contexts"; import Sidebar from "./Sidebar"; import ContextMenuConfig from "./ContextMenuConfig"; import UpdatePage from "./UpdatePage"; import PluginStore from "./PluginStore"; import PluginConfig from "./PluginConfig"; -import { useState, useEffect } from "react"; +import { useState, useEffect, ReactNode } from "react"; + +interface ContextMenuSettings { + theme?: any; + animation?: any; + [key: string]: any; +} + +interface GlobalConfig { + context_menu?: ContextMenuSettings; + debug_console?: boolean; + plugin_load_order?: any[]; + language?: string; + [key: string]: any; +} + +interface ProviderValues { + global: { config: GlobalConfig; update: (configPatch: Partial) => void }; + contextMenu: { config: ContextMenuSettings; update: (newConfig: ContextMenuSettings) => void }; + debugConsole: { value: boolean; update: (value: boolean) => void }; + pluginLoadOrder: { order: any[]; update: (order: any[]) => void }; + updateData: { updateData: any; setUpdateData: (data: any) => void }; + notification: { + errorMessage: string | null; + setErrorMessage: (msg: string | null) => void; + loadingMessage: string | null; + setLoadingMessage: (msg: string | null) => void; + }; + pluginSource: { + currentPluginSource: string; + setCurrentPluginSource: (source: string) => void; + cachedPluginIndex: any; + setCachedPluginIndex: (index: any) => void; + }; +} + +const AppProviders = ({ children, values }: { children: ReactNode, values: ProviderValues }) => ( + + + + + + + + {children} + + + + + + + +); export const ConfigApp = () => { const [activePage, setActivePage] = useState('context-menu'); @@ -59,43 +112,48 @@ export const ConfigApp = () => { saveConfig(newGlobal); }; + const updateGlobalConfig = (configPatch: Partial) => { + const newGlobal = { ...config, ...configPatch }; + setConfig(newGlobal); + if ('context_menu' in configPatch) { + setContextMenuConfig(configPatch.context_menu || {}); + } + if ('debug_console' in configPatch) { + setDebugConsole(configPatch.debug_console || false); + } + if ('plugin_load_order' in configPatch) { + setPluginLoadOrder(configPatch.plugin_load_order || []); + } + saveConfig(newGlobal); + }; + + const providerValues = { + global: { config, update: updateGlobalConfig }, + contextMenu: { config: contextMenuConfig, update: updateContextMenu }, + debugConsole: { value: debugConsole, update: updateDebugConsole }, + pluginLoadOrder: { order: pluginLoadOrder, update: updatePluginLoadOrder }, + updateData: { updateData, setUpdateData }, + notification: { errorMessage, setErrorMessage, loadingMessage, setLoadingMessage }, + pluginSource: { currentPluginSource, setCurrentPluginSource, cachedPluginIndex, setCachedPluginIndex } + }; + return ( - - - - - - - - - - {activePage === 'context-menu' && } - {activePage === 'update' && } - {activePage === 'plugin-store' && } - {activePage === 'plugin-config' && } - - - - - - - - + + + + + {activePage === 'context-menu' && } + {activePage === 'update' && } + {activePage === 'plugin-store' && } + {activePage === 'plugin-config' && } + + + ); }; diff --git a/src/shell/script/ts/src/config_page/ContextMenuConfig.tsx b/src/shell/script/ts/src/config_page/ContextMenuConfig.tsx index 795d494a..ae0dcb53 100644 --- a/src/shell/script/ts/src/config_page/ContextMenuConfig.tsx +++ b/src/shell/script/ts/src/config_page/ContextMenuConfig.tsx @@ -1,14 +1,22 @@ import * as shell from "mshell"; import { Button, Text, Toggle } from "./components"; -import { ContextMenuContext, DebugConsoleContext } from "./contexts"; +import { ContextMenuContext, DebugConsoleContext, GlobalConfigContext } from "./contexts"; import { useTranslation, getNestedValue, setNestedValue } from "./utils"; import { theme_presets, animation_presets } from "./constants"; -import { memo, useContext } from "react"; +import { memo, useContext, useEffect, useState } from "react"; const ContextMenuConfig = memo(() => { const { config, update } = useContext(ContextMenuContext)!; const { value: debugConsole, update: updateDebugConsole } = useContext(DebugConsoleContext)!; + const { config: globalConfig, update: updateGlobal } = useContext(GlobalConfigContext)!; const { t } = useTranslation(); + // Language state + const [languages, setLanguages] = useState([]); + useEffect(() => { + setLanguages(shell.breeze.available_languages()); + }, []); + const currentLang = globalConfig?.language || shell.breeze.user_language(); + const currentTheme = config?.theme; const currentAnimation = config?.theme?.animation; @@ -41,13 +49,13 @@ const ContextMenuConfig = memo(() => { }; const getCurrentPreset = (current: any, presets: any) => { - if (!current) return "默认"; + if (!current) return "default"; for (const [name, preset] of Object.entries(presets)) { if (preset && checkPresetMatch(current, preset)) { return name; } } - return "自定义"; + return "custom"; }; const currentThemePreset = getCurrentPreset(currentTheme, theme_presets); @@ -55,10 +63,29 @@ const ContextMenuConfig = memo(() => { return ( - {t("Breeze 设置")} + {t("settings.title")} + + + {t("settings.language") || "Language"} + + {languages.map(lang => ( + + ))} + + + - {t("主题")} + {t("settings.theme")} {Object.keys(theme_presets).map(name => ( ))} - {t("动画")} + {t("settings.animation")} {Object.keys(animation_presets).map(name => ( ))} - {t("杂项")} - - { + {t("settings.misc")} + + { const newConfig = { ...config }; setNestedValue(newConfig, "vsync", v); update(newConfig); }} /> - { + { const newConfig = { ...config }; setNestedValue(newConfig, "ignore_owner_draw", v); update(newConfig); }} /> - { + { const newConfig = { ...config }; setNestedValue(newConfig, "reverse_if_open_to_up", v); update(newConfig); }} /> - { + { const newConfig = { ...config }; setNestedValue(newConfig, "theme.use_dwm_if_available", v); update(newConfig); }} /> - { + { const newConfig = { ...config }; setNestedValue(newConfig, "theme.acrylic", v); update(newConfig); }} /> - { + { const newConfig = { ...config }; setNestedValue(newConfig, "hotkeys", v); update(newConfig); }} /> - { + { const newConfig = { ...config }; setNestedValue(newConfig, "show_settings_button", v); update(newConfig); diff --git a/src/shell/script/ts/src/config_page/PluginConfig.tsx b/src/shell/script/ts/src/config_page/PluginConfig.tsx index 2f9cbf70..1e9676ff 100644 --- a/src/shell/script/ts/src/config_page/PluginConfig.tsx +++ b/src/shell/script/ts/src/config_page/PluginConfig.tsx @@ -48,14 +48,14 @@ const PluginConfig = memo(() => { const showContextMenu = (pluginName: string) => { showMenu(menu => { menu.append_menu({ - name: isPrioritized(pluginName) ? '取消优先加载' : '设为优先加载', + name: isPrioritized(pluginName) ? t('menu.cancel_priority') : t('menu.set_priority'), action() { togglePrioritize(pluginName); menu.close(); } }); menu.append_menu({ - name: t("删除"), + name: t("menu.delete"), action() { handleDeletePlugin(pluginName); menu.close(); @@ -72,12 +72,12 @@ const PluginConfig = memo(() => { return ( - {t("插件配置")} + {t("plugins.config")} {prioritizedPlugins.length > 0 && ( - {t("优先加载插件")} + {t("plugins.priority_load")} {prioritizedPlugins.map(name => { const isEnabled = shell.fs.exists(shell.breeze.data_directory() + '/scripts/' + name + '.js'); return ( @@ -96,7 +96,7 @@ const PluginConfig = memo(() => { )} - {prioritizedPlugins.length === 0 && {t("已安装插件")}} + {prioritizedPlugins.length === 0 && {t("plugins.installed_plugins")}} {regularPlugins.map(name => { const isEnabled = shell.fs.exists(shell.breeze.data_directory() + '/scripts/' + name + '.js'); return ( diff --git a/src/shell/script/ts/src/config_page/PluginStore.tsx b/src/shell/script/ts/src/config_page/PluginStore.tsx index 26fedcb4..f2268da0 100644 --- a/src/shell/script/ts/src/config_page/PluginStore.tsx +++ b/src/shell/script/ts/src/config_page/PluginStore.tsx @@ -28,7 +28,7 @@ const PluginStore = memo(() => { const url = PLUGIN_SOURCES[currentPluginSource] + plugin.path; shell.network.get_async(url, (data: string) => { shell.fs.write(path, data); - shell.println(t('插件安装成功: ') + plugin.name); + shell.println(t('plugins.install_success', { name: plugin.name })); setInstallingPlugins(prev => { const newSet = new Set(prev); newSet.delete(plugin.name); @@ -36,7 +36,7 @@ const PluginStore = memo(() => { }); }, (e: any) => { shell.println(e); - setErrorMessage(t('插件安装失败: ') + plugin.name); + setErrorMessage(t('plugins.install_failed', { name: plugin.name })); setInstallingPlugins(prev => { const newSet = new Set(prev); newSet.delete(plugin.name); @@ -49,7 +49,7 @@ const PluginStore = memo(() => { return ( - {t("插件市场")} + {t("plugins.store")} {plugins.map((plugin: any) => { @@ -62,7 +62,7 @@ const PluginStore = memo(() => { } const installed = install_path !== null; const local_version_match = installed ? shell.fs.read(install_path).match(/\/\/ @version:\s*(.*)/) : null; - const local_version = local_version_match ? local_version_match[1] : '未安装'; + const local_version = local_version_match ? local_version_match[1] : t('plugins.not_installed'); const have_update = installed && local_version !== plugin.version; return ( @@ -78,7 +78,7 @@ const PluginStore = memo(() => { diff --git a/src/shell/script/ts/src/config_page/Sidebar.tsx b/src/shell/script/ts/src/config_page/Sidebar.tsx index 2bdb9f05..f76dd52a 100644 --- a/src/shell/script/ts/src/config_page/Sidebar.tsx +++ b/src/shell/script/ts/src/config_page/Sidebar.tsx @@ -41,7 +41,7 @@ const Sidebar = memo(({ const handleSourceChange = (sourceName: string) => { setCurrentPluginSource(sourceName); setCachedPluginIndex(null); - setLoadingMessage(t("切换源中...")); + setLoadingMessage(t("source.switching")); shell.network.get_async(PLUGIN_SOURCES[sourceName] + 'plugins-index.json', (data: string) => { setCachedPluginIndex(data); @@ -49,7 +49,7 @@ const Sidebar = memo(({ setLoadingMessage(null); }, (e: any) => { shell.println('Failed to fetch update data:', e); - setErrorMessage(t("加载失败")); + setErrorMessage(t("common.load_failed")); setLoadingMessage(null); }); }; @@ -72,10 +72,10 @@ const Sidebar = memo(({ {iconElement(ICON_BREEZE, 24)} Breeze - setActivePage('context-menu')} icon={ICON_CONTEXT_MENU} isActive={activePage === 'context-menu'}>主配置 - setActivePage('update')} icon={ICON_UPDATE} isActive={activePage === 'update'}>更新 - setActivePage('plugin-store')} icon={ICON_PLUGIN_STORE} isActive={activePage === 'plugin-store'}>插件商店 - setActivePage('plugin-config')} icon={ICON_PLUGIN_CONFIG} isActive={activePage === 'plugin-config'}>插件配置 + setActivePage('context-menu')} icon={ICON_CONTEXT_MENU} isActive={activePage === 'context-menu'}>{t("sidebar.main_config")} + setActivePage('update')} icon={ICON_UPDATE} isActive={activePage === 'update'}>{t("sidebar.update")} + setActivePage('plugin-store')} icon={ICON_PLUGIN_STORE} isActive={activePage === 'plugin-store'}>{t("sidebar.plugin_store")} + setActivePage('plugin-config')} icon={ICON_PLUGIN_CONFIG} isActive={activePage === 'plugin-config'}>{t("sidebar.plugin_config")} {/* 错误提示 */} @@ -124,7 +124,7 @@ const Sidebar = memo(({ }); }); }}> - {`${t("更新源")} - ${currentPluginSource}`} + {`${t("sidebar.source")} - ${currentPluginSource}`} ); diff --git a/src/shell/script/ts/src/config_page/UpdatePage.tsx b/src/shell/script/ts/src/config_page/UpdatePage.tsx index d2cdddf8..3764d889 100644 --- a/src/shell/script/ts/src/config_page/UpdatePage.tsx +++ b/src/shell/script/ts/src/config_page/UpdatePage.tsx @@ -20,7 +20,7 @@ const UpdatePage = memo(() => { }, []); if (!updateData) { - return {t("加载中...")}; + return {t("common.loading")}; } const remote_version = updateData.shell.version; @@ -35,13 +35,13 @@ const UpdatePage = memo(() => { const downloadNewShell = () => { shell.network.download_async(url, shellPath, () => { - shell.println(t('新版本已下载,将于下次重启资源管理器生效')); + shell.println(t('plugins.update_downloaded')); setIsUpdating(false); set_exist_old_file(true); }, e => { - shell.println(t('更新失败: ') + e); + shell.println(t('plugins.update_failed', { error: String(e) })); setIsUpdating(false); - setErrorMessage(t('更新失败: ') + e); + setErrorMessage(t('plugins.update_failed', { error: String(e) })); }); }; @@ -53,9 +53,9 @@ const UpdatePage = memo(() => { shell.fs.rename(shellPath, shellOldPath); downloadNewShell(); } catch (e) { - shell.println(t('更新失败: ') + '无法移动当前文件'); + shell.println(t('plugins.update_failed', { error: t('update.cannot_move_file') })); setIsUpdating(false); - setErrorMessage(t('更新失败: ') + '无法移动当前文件'); + setErrorMessage(t('plugins.update_failed', { error: t('update.cannot_move_file') })); } } else { shell.fs.rename(shellPath, shellOldPath); @@ -65,26 +65,26 @@ const UpdatePage = memo(() => { downloadNewShell(); } } catch (e) { - shell.println(t('更新失败: ') + e); + shell.println(t('plugins.update_failed', { error: String(e) })); setIsUpdating(false); - setErrorMessage(t('更新失败: ') + e); + setErrorMessage(t('plugins.update_failed', { error: String(e) })); } }; return ( - {t("插件市场")} + {t("update.title")} - {`当前版本: ${current_version}`} - {`最新版本: ${remote_version}`} + {t("update.current_version", { version: current_version })} + {t("update.latest_version", { version: remote_version })} - 更新日志: + {t("update.changelog")} diff --git a/src/shell/script/ts/src/config_page/components.tsx b/src/shell/script/ts/src/config_page/components.tsx index 4b1650ef..10b3809b 100644 --- a/src/shell/script/ts/src/config_page/components.tsx +++ b/src/shell/script/ts/src/config_page/components.tsx @@ -2,18 +2,19 @@ import { breeze } from "mshell"; import { showMenu, useHoverActive } from "./utils"; import { type ReactNode } from "react"; import { ICON_MORE_VERT } from "./constants"; +import { t } from "../shared/i18n"; import { useState, useEffect, memo, createContext, useContext, useMemo } from "react"; // Icon element creator export const iconElement = (svg: string, width = 14) => ( - ); @@ -310,7 +311,7 @@ export const PluginItem = memo(({ {isPrioritized && ( - 优先加载 + {t("settings.priority_load_plugins")} )} diff --git a/src/shell/script/ts/src/config_page/constants.ts b/src/shell/script/ts/src/config_page/constants.ts index 530f1541..74430b32 100644 --- a/src/shell/script/ts/src/config_page/constants.ts +++ b/src/shell/script/ts/src/config_page/constants.ts @@ -1,41 +1,7 @@ import * as shell from "mshell"; -export const languages = { - 'zh-CN': { - "管理 Breeze Shell": "管理 Breeze Shell", - "插件市场": "插件市场", - "加载中...": "加载中...", - "更新中...": "更新中...", - "安装中...": "安装中...", - "新版本已下载,将于下次重启资源管理器生效": "新版本已下载,将于下次重启资源管理器生效", - "更新失败: ": "更新失败: ", - "插件安装成功: ": "插件安装成功: ", - "版本: ": "版本: ", - "作者: ": "作者: ", - "删除": "删除", - "Breeze 设置": "Breeze 设置", - "优先加载插件": "优先加载插件", - "调试控制台": "调试控制台", - "垂直同步": "垂直同步", - "忽略自绘菜单": "忽略自绘菜单", - "向上展开时反向排列": "向上展开时反向排列", - "尝试使用 Windows 11 圆角": "尝试使用 Windows 11 圆角", - "亚克力背景效果": "亚克力背景效果", - "主题": "主题", - "动画": "动画", - "当前源: ": "当前源: ", - "插件": "插件", - "插件源": "插件源", - "换源": "换源", - "请稍候": "请稍候", - "切换源中...": "切换源中...", - "加载失败": "加载失败", - "网络错误": "网络错误", - "切换源成功": "切换源成功" - }, - 'en-US': { - } -}; +// Note: Legacy local languages table removed. Use unified i18n system via shell.breeze and t() utility. + export const PLUGIN_SOURCES = { 'Github Raw': 'https://raw.githubusercontent.com/breeze-shell/plugins-packed/refs/heads/main/', @@ -58,8 +24,8 @@ export const SIDEBAR_WIDTH = 170; // Theme presets export const theme_presets = { - "默认": null, - "紧凑": { + "default": null, + "compact": { radius: 4.0, item_height: 20.0, item_gap: 2.0, @@ -71,7 +37,7 @@ export const theme_presets = { right_icon_padding: 16.0, multibutton_line_gap: -4.0 }, - "宽松": { + "relaxed": { radius: 6.0, item_height: 24.0, item_gap: 4.0, @@ -83,11 +49,11 @@ export const theme_presets = { right_icon_padding: 20.0, multibutton_line_gap: -6.0 }, - "圆角": { + "rounded": { radius: 12.0, item_radius: 12.0 }, - "方角": { + "square": { radius: 0.0, item_radius: 0.0 } @@ -99,8 +65,8 @@ export const anim_none = { }; export const animation_presets = { - "默认": null, - "快速": { + "default": null, + "fast": { "item": { "opacity": { "delay_scale": 0 @@ -118,7 +84,7 @@ export const animation_presets = { "opacity": anim_none, } }, - "无": { + "none": { "item": { "opacity": anim_none, "width": anim_none, diff --git a/src/shell/script/ts/src/config_page/contexts.tsx b/src/shell/script/ts/src/config_page/contexts.tsx index 103a534e..6be51662 100644 --- a/src/shell/script/ts/src/config_page/contexts.tsx +++ b/src/shell/script/ts/src/config_page/contexts.tsx @@ -1,5 +1,8 @@ import { createContext } from "react"; +// Context for global configuration +export const GlobalConfigContext = createContext<{ config: any; update: (c: any) => void } | null>(null); + // Context for context menu configuration export const ContextMenuContext = createContext<{ config: any; update: (c: any) => void } | null>(null); diff --git a/src/shell/script/ts/src/config_page/index.ts b/src/shell/script/ts/src/config_page/index.ts index 68f10328..d9c60049 100644 --- a/src/shell/script/ts/src/config_page/index.ts +++ b/src/shell/script/ts/src/config_page/index.ts @@ -51,7 +51,6 @@ export { // Export constants export { - languages, PLUGIN_SOURCES, ICON_CONTEXT_MENU, ICON_UPDATE, diff --git a/src/shell/script/ts/src/config_page/utils.ts b/src/shell/script/ts/src/config_page/utils.ts index 99c9c889..e6b35a10 100644 --- a/src/shell/script/ts/src/config_page/utils.ts +++ b/src/shell/script/ts/src/config_page/utils.ts @@ -1,5 +1,6 @@ import * as shell from "mshell"; import { theme_presets, animation_presets } from "./constants"; +import { t, currentLanguage, isRTL } from "../shared/i18n"; import { menu_controller } from "mshell"; import { useState, useEffect, memo } from "react"; @@ -34,48 +35,10 @@ export const setNestedValue = (obj: any, path: string, value: any) => { target[last] = value; }; -// Translation helper +// Translation helper using unified i18n system export const useTranslation = () => { - const currentLang = shell.breeze.user_language() === 'zh-CN' ? 'zh-CN' : 'en-US'; - const t = (key: string) => { - const languages = { - 'zh-CN': { - "管理 Breeze Shell": "管理 Breeze Shell", - "插件市场": "插件市场", - "加载中...": "加载中...", - "更新中...": "更新中...", - "安装中...": "安装中...", - "新版本已下载,将于下次重启资源管理器生效": "新版本已下载,将于下次重启资源管理器生效", - "更新失败: ": "更新失败: ", - "插件安装成功: ": "插件安装成功: ", - "版本: ": "版本: ", - "作者: ": "作者: ", - "删除": "删除", - "Breeze 设置": "Breeze 设置", - "优先加载插件": "优先加载插件", - "调试控制台": "调试控制台", - "垂直同步": "垂直同步", - "忽略自绘菜单": "忽略自绘菜单", - "向上展开时反向排列": "向上展开时反向排列", - "尝试使用 Windows 11 圆角": "尝试使用 Windows 11 圆角", - "亚克力背景效果": "亚克力背景效果", - "主题": "主题", - "动画": "动画", - "当前源: ": "当前源: ", - "插件": "插件", - "插件源": "插件源", - "换源": "换源", - "请稍候": "请稍候", - "切换源中...": "切换源中...", - "加载失败": "加载失败", - "网络错误": "网络错误", - "切换源成功": "切换源成功" - }, - 'en-US': {} - }; - return languages[currentLang][key] || key; - }; - return { t, currentLang }; + const currentLang = currentLanguage(); + return { t, currentLang, isRTL }; }; // Theme preset utilities @@ -108,13 +71,13 @@ export const checkPresetMatch = (current: any, preset: any) => { }; export const getCurrentPreset = (current: any, presets: any) => { - if (!current) return "默认"; + if (!current) return "default"; for (const [name, preset] of Object.entries(presets)) { if (preset && checkPresetMatch(current, preset)) { return name; } } - return "自定义"; + return "custom"; }; // Config file operations @@ -167,5 +130,5 @@ export const isPluginInstalled = (plugin: any) => { export const getPluginVersion = (installPath: string) => { const local_version_match = shell.fs.read(installPath).match(/\/\/ @version:\s*(.*)/); - return local_version_match ? local_version_match[1] : '未安装'; + return local_version_match ? local_version_match[1] : t('plugins.not_installed'); }; \ No newline at end of file diff --git a/src/shell/script/ts/src/menu/configMenu.ts b/src/shell/script/ts/src/menu/configMenu.ts index 32235b2a..f86e8993 100644 --- a/src/shell/script/ts/src/menu/configMenu.ts +++ b/src/shell/script/ts/src/menu/configMenu.ts @@ -5,6 +5,7 @@ import { splitIntoLines } from "../utils/string" import { getNestedValue, setNestedValue } from "../utils/object" import { config_dir_watch_callbacks } from "../plugin/core" import { languages, ICON_EMPTY, ICON_CHECKED, ICON_CHANGE, ICON_REPAIR } from "./constants" +import { t, currentLanguage } from "../shared/i18n" let cached_plugin_index: any = null @@ -20,10 +21,7 @@ if (shell.fs.exists(shell.breeze.data_directory() + '/shell_old.dll')) { let current_source = 'Enlysure' export const makeBreezeConfigMenu = (mainMenu) => { - const currentLang = shell.breeze.user_language() === 'zh-CN' ? 'zh-CN' : 'en-US' - const t = (key: string) => { - return languages[currentLang][key] || key - } + const currentLang = currentLanguage() const fg_color = shell.breeze.is_light_theme() ? 'black' : 'white' const ICON_CHECKED_COLORED = ICON_CHECKED.replaceAll('currentColor', fg_color) @@ -31,17 +29,17 @@ export const makeBreezeConfigMenu = (mainMenu) => { const ICON_REPAIR_COLORED = ICON_REPAIR.replaceAll('currentColor', fg_color) return { - name: t("管理 Breeze Shell"), + name: t("menu.manage"), submenu(sub) { sub.append_menu({ - name: t("插件市场 / 更新本体"), + name: t("menu.pluginMarket"), submenu(sub) { const updatePlugins = async (page) => { for (const m of sub.get_items().slice(1)) m.remove() sub.append_menu({ - name: t('加载中...') + name: t('status.loading') }) if (!cached_plugin_index) { @@ -59,7 +57,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { const upd = sub.append_menu({ name: exist_old_file ? - `新版本已下载,将于下次重启资源管理器生效` : + t('status.updatePending') : (current_version === remote_version ? (current_version + ' (latest)') : `${current_version} -> ${remote_version}`), @@ -71,7 +69,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { const url = PLUGIN_SOURCES[current_source] + data.shell.path upd.set_data({ - name: t('更新中...'), + name: t('status.updating'), icon_svg: ICON_REPAIR_COLORED, disabled: true }) @@ -79,13 +77,13 @@ export const makeBreezeConfigMenu = (mainMenu) => { const downloadNewShell = () => { shell.network.download_async(url, shellPath, () => { upd.set_data({ - name: t('新版本已下载,将于下次重启资源管理器生效'), + name: t('status.updatePending'), icon_svg: ICON_CHECKED_COLORED, disabled: true }) }, e => { upd.set_data({ - name: t('更新失败: ') + e, + name: t('status.updateFailed') + ': ' + e, icon_svg: ICON_REPAIR_COLORED, disabled: false }) @@ -101,7 +99,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { downloadNewShell() } catch (e) { upd.set_data({ - name: t('更新失败: ') + '无法移动当前文件', + name: t('status.updateFailed') + ': ' + t('error.cannotMoveFile'), icon_svg: ICON_REPAIR_COLORED, disabled: false }) @@ -115,7 +113,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { } } catch (e) { upd.set_data({ - name: t('更新失败: ') + e, + name: t('status.updateFailed') + ': ' + e, icon_svg: ICON_REPAIR_COLORED, disabled: false }) @@ -147,7 +145,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { const installed = install_path !== null const local_version_match = installed ? shell.fs.read(install_path).match(/\/\/ @version:\s*(.*)/) : null - const local_version = local_version_match ? local_version_match[1] : '未安装' + const local_version = local_version_match ? local_version_match[1] : t('plugins.not_installed') const have_update = installed && local_version !== plugin.version const disabled = installed && !have_update @@ -176,7 +174,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { disabled: true }) - shell.println(t('插件安装成功: ') + plugin.name) + shell.println(t('status.pluginInstalled') + ': ' + plugin.name) reload_local() }).catch(e => { @@ -205,10 +203,10 @@ export const makeBreezeConfigMenu = (mainMenu) => { submenu(sub) { preview_sub = sub sub.append_menu({ - name: t('版本: ') + plugin.version + name: t('plugin.version') + ': ' + plugin.version }) sub.append_menu({ - name: t('作者: ') + plugin.author + name: t('plugin.author') + ': ' + plugin.author }) for (const line of splitIntoLines(plugin.description, 40)) { @@ -224,7 +222,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { } const source = sub.append_menu({ - name: t('当前源: ') + current_source, + name: t('plugin.currentSource') + ': ' + current_source, submenu(sub) { for (const key in PLUGIN_SOURCES) { sub.append_menu({ @@ -233,7 +231,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { current_source = key cached_plugin_index = null source.set_data({ - name: t('当前源: ') + key + name: t('plugin.currentSource') + ': ' + key }) updatePlugins(1) }, @@ -247,7 +245,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { } }) sub.append_menu({ - name: t("Breeze 设置"), + name: t("menu.settings"), submenu(sub) { const current_config_path = shell.breeze.data_directory() + '/config.json' const current_config = shell.fs.read(current_config_path) @@ -261,7 +259,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { } sub.append_menu({ - name: "优先加载插件", + name: t("settings.priority_load_plugins"), submenu(sub) { const plugins = shell.fs.readdir(shell.breeze.data_directory() + '/scripts') .map(v => v.split('/').pop()) @@ -324,8 +322,8 @@ export const makeBreezeConfigMenu = (mainMenu) => { sub.append_spacer() const theme_presets = { - "默认": null, - "紧凑": { + "default": null, // "默认" + "compact": { // "紧凑" radius: 4.0, item_height: 20.0, item_gap: 2.0, @@ -337,7 +335,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { right_icon_padding: 16.0, multibutton_line_gap: -4.0 }, - "宽松": { + "relaxed": { // "宽松" radius: 6.0, item_height: 24.0, item_gap: 4.0, @@ -349,11 +347,11 @@ export const makeBreezeConfigMenu = (mainMenu) => { right_icon_padding: 20.0, multibutton_line_gap: -6.0 }, - "圆角": { + "rounded": { // "圆角" radius: 12.0, item_radius: 12.0 }, - "方角": { + "square": { // "方角" radius: 0.0, item_radius: 0.0 } @@ -363,8 +361,8 @@ export const makeBreezeConfigMenu = (mainMenu) => { easing: "mutation", } const animation_presets = { - "默认": null, - "快速": { + "default": null, // "默认" + "fast": { // "快速" "item": { "opacity": { "delay_scale": 0 @@ -382,7 +380,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { "opacity": anim_none, } }, - "无": { + "none": { // "无" "item": { "opacity": anim_none, "width": anim_none, @@ -438,21 +436,22 @@ export const makeBreezeConfigMenu = (mainMenu) => { }; const getCurrentPreset = (current, presets) => { - if (!current) return "默认"; + if (!current) return "default"; for (const [name, preset] of Object.entries(presets)) { if (preset && checkPresetMatch(current, preset)) { return name; } } - return "自定义"; + return "custom"; }; - const updateIconStatus = (sub, current, presets) => { + const updateIconStatus = (sub, current, presets, translationPrefix) => { try { const currentPreset = getCurrentPreset(current, presets); for (const _item of sub.get_items()) { const item = _item.data(); - if (item.name === currentPreset) { + // Match translated name + if (item.name === t(translationPrefix + currentPreset)) { _item.set_data({ icon_svg: ICON_CHECKED_COLORED, disabled: true @@ -466,11 +465,12 @@ export const makeBreezeConfigMenu = (mainMenu) => { } const lastItem = sub.get_items().pop() - if (lastItem.data().name === "自定义" && currentPreset !== "自定义") { + const customName = t("theme.custom"); + if (lastItem.data().name === customName && currentPreset !== "custom") { lastItem.remove() - } else if (currentPreset === "自定义") { + } else if (currentPreset === "custom") { sub.append_menu({ - name: "自定义", + name: customName, disabled: true, icon_svg: ICON_CHECKED_COLORED, }); @@ -481,13 +481,13 @@ export const makeBreezeConfigMenu = (mainMenu) => { } sub.append_menu({ - name: "主题", + name: t("settings.theme"), submenu(sub) { const currentTheme = config.context_menu?.theme; for (const [name, preset] of Object.entries(theme_presets)) { sub.append_menu({ - name, + name: t("theme." + name), action() { try { if (!preset) { @@ -496,7 +496,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { config.context_menu.theme = applyPreset(preset, config.context_menu.theme, theme_presets); } write_config(); - updateIconStatus(sub, config.context_menu.theme, theme_presets); + updateIconStatus(sub, config.context_menu.theme, theme_presets, "theme."); } catch (e) { shell.println(e, e.stack) } @@ -504,18 +504,18 @@ export const makeBreezeConfigMenu = (mainMenu) => { }); } - updateIconStatus(sub, currentTheme, theme_presets); + updateIconStatus(sub, currentTheme, theme_presets, "theme."); } }); sub.append_menu({ - name: "动画", + name: t("settings.animation"), submenu(sub) { const currentAnimation = config.context_menu?.theme?.animation; for (const [name, preset] of Object.entries(animation_presets)) { sub.append_menu({ - name, + name: t("animation." + name), action() { if (!preset) { if (config.context_menu?.theme) { @@ -527,24 +527,24 @@ export const makeBreezeConfigMenu = (mainMenu) => { config.context_menu.theme.animation = preset; } - updateIconStatus(sub, config.context_menu.theme?.animation, animation_presets); + updateIconStatus(sub, config.context_menu.theme?.animation, animation_presets, "animation."); write_config(); } }); } - updateIconStatus(sub, currentAnimation, animation_presets); + updateIconStatus(sub, currentAnimation, animation_presets, "animation."); } }); sub.append_spacer() - createBoolToggle(sub, "调试控制台", "debug_console", false); - createBoolToggle(sub, "垂直同步", "context_menu.vsync", true); - createBoolToggle(sub, "忽略自绘菜单", "context_menu.ignore_owner_draw", true); - createBoolToggle(sub, "向上展开时反向排列", "context_menu.reverse_if_open_to_up", true); - createBoolToggle(sub, "尝试使用 Windows 11 圆角", "context_menu.theme.use_dwm_if_available", true); - createBoolToggle(sub, "亚克力背景效果", "context_menu.theme.acrylic", true); + createBoolToggle(sub, t("settings.debugConsole"), "debug_console", false); + createBoolToggle(sub, t("settings.vsync"), "context_menu.vsync", true); + createBoolToggle(sub, t("settings.ignoreOwnerDraw"), "context_menu.ignore_owner_draw", true); + createBoolToggle(sub, t("settings.reverseIfOpenUp"), "context_menu.reverse_if_open_to_up", true); + createBoolToggle(sub, t("settings.useWin11RoundedCorners"), "context_menu.theme.use_dwm_if_available", true); + createBoolToggle(sub, t("settings.acrylicEffect"), "context_menu.theme.acrylic", true); } }) @@ -584,7 +584,7 @@ export const makeBreezeConfigMenu = (mainMenu) => { }, submenu(sub) { sub.append_menu({ - name: t('删除'), + name: t('action.delete'), action() { shell.fs.remove(shell.breeze.data_directory() + '/scripts/' + plugin) m.remove() diff --git a/src/shell/script/ts/src/menu/constants.ts b/src/shell/script/ts/src/menu/constants.ts index d40e55e3..5e81f4b5 100644 --- a/src/shell/script/ts/src/menu/constants.ts +++ b/src/shell/script/ts/src/menu/constants.ts @@ -1,22 +1,15 @@ import * as shell from "mshell" +// Legacy languages object - kept for backward compatibility +// New code should use shell.breeze.get_translation() instead export const languages = { - 'zh-CN': { - }, - 'en-US': { - '管理 Breeze Shell': 'Manage Breeze Shell', - '插件市场 / 更新本体': 'Plugin Market / Update Shell', - '加载中...': 'Loading...', - '更新中...': 'Updating...', - '新版本已下载,将于下次重启资源管理器生效': 'New version downloaded, will take effect next time the file manager is restarted', - '更新失败: ': 'Update failed: ', - '插件安装成功: ': 'Plugin installed: ', - '当前源: ': 'Current source: ', - '删除': 'Delete', - '版本: ': 'Version: ', - '作者: ': 'Author: ' - } -} + 'zh-CN': {}, + 'en-US': {} +}; + +import { t } from "../shared/i18n" + +export { t } export const ICON_EMPTY = new shell.value_reset() export const ICON_CHECKED = `` diff --git a/src/shell/script/ts/src/plugin/core.ts b/src/shell/script/ts/src/plugin/core.ts index d02492d0..5368b877 100644 --- a/src/shell/script/ts/src/plugin/core.ts +++ b/src/shell/script/ts/src/plugin/core.ts @@ -1,5 +1,6 @@ import * as shell from "mshell" import { getNestedValue, setNestedValue } from "../utils/object" +import { t, isRTL } from "../shared/i18n" export const config_directory_main = shell.breeze.data_directory() + '/config/'; @@ -28,12 +29,27 @@ export const plugin = (import_meta, default_config = {}) => { const plugin = { i18n: { - define: (lang, data) => { - languages[lang] = data + /** + * Define translations for a language + * @param lang Language code (e.g., "en-US", "zh-CN") + * @param data Object mapping keys to translations + */ + define: (lang: string, data: Record) => { + // Register with the unified i18n system + shell.breeze.register_translations(lang, data); + // Also keep local copy for backward compatibility + languages[lang] = data; }, - t: (key) => { - return languages[shell.breeze.user_language()][key] || key - } + /** + * Get a translated string + * @param key Translation key + * @param params Optional interpolation parameters + */ + t: t, + /** + * Check if current language is RTL + */ + isRTL: isRTL }, set_on_menu: (callback: (m: shell.menu_controller) => void) => { globalThis.on_plugin_menu[nameNoExt] = callback @@ -45,7 +61,7 @@ export const plugin = (import_meta, default_config = {}) => { try { config = JSON.parse(shell.fs.read(plugin.config_directory + CONFIG_FILE)) } catch (e) { - shell.println(`[${name}] 配置文件解析失败: ${e}`) + shell.println(`[${name}] ${t("error.config_parse_failed", { error: String(e) })}`) } } }, @@ -80,7 +96,7 @@ export const plugin = (import_meta, default_config = {}) => { config_dir_watch_callbacks.add((path, type) => { const relativePath = path.replace(config_directory_main, ''); if (relativePath === `${nameNoExt}\\${CONFIG_FILE}`) { - shell.println(`[${name}] 配置文件变更: ${path} ${type}`) + shell.println(`[${name}] ${t("status.config_changed", { path: path, type: type })}`) plugin.config.read_config() for (const callback of on_reload_callbacks) { callback(config) diff --git a/src/shell/script/ts/src/shared/i18n.ts b/src/shell/script/ts/src/shared/i18n.ts new file mode 100644 index 00000000..3a814bf7 --- /dev/null +++ b/src/shell/script/ts/src/shared/i18n.ts @@ -0,0 +1,31 @@ +import * as shell from "mshell" + +/** + * Get a translated string by key using the unified i18n system. + * @param key The translation key + * @param params Optional interpolation parameters + * @returns Translated string with placeholders replaced + */ +export const t = (key: string, params?: Record): string => { + // If params provided, use the C++ interpolation binding + if (params) { + return shell.breeze.get_translation_with_params(key, params); + } + + // Otherwise use simple translation lookup + return shell.breeze.get_translation(key); +}; + +/** + * Check if current language is RTL. + */ +export const isRTL = (): boolean => { + return shell.breeze.is_rtl(); +}; + +/** + * Get current language code from unified system. + */ +export const currentLanguage = (): string => { + return shell.breeze.user_language(); +}; diff --git a/src/shell/script/ts/test_i18n.js b/src/shell/script/ts/test_i18n.js new file mode 100644 index 00000000..36577cca --- /dev/null +++ b/src/shell/script/ts/test_i18n.js @@ -0,0 +1,77 @@ + +// Simple verification script for i18n interpolation logic + +const interpolate = (str, params) => { + // Match alphanumeric, underscores, dots, and hyphens (matches C++ regex) + return str.replace(/{([\w.-]+)}/g, (match, key) => { + return params.hasOwnProperty(key) ? params[key] : match; + }); +}; + +const tests = [ + { + name: "Basic interpolation", + template: "Hello {name}!", + params: { name: "World" }, + expected: "Hello World!" + }, + { + name: "Multiple params", + template: "{greeting} {name}!", + params: { greeting: "Hi", name: "User" }, + expected: "Hi User!" + }, + { + name: "Missing param", + template: "Hello {name}!", + params: {}, + expected: "Hello {name}!" + }, + { + name: "Unused param", + template: "Hello {name}!", + params: { name: "World", date: "Today" }, + expected: "Hello World!" + }, + { + name: "No placeholder", + template: "Hello World", + params: { name: "User" }, + expected: "Hello World" + }, + { + name: "Placeholder with dot", + template: "Hello {user.name}!", + params: { "user.name": "John Doe" }, + expected: "Hello John Doe!" + }, + { + name: "Placeholder with hyphen", + template: "Status: {my-status}", + params: { "my-status": "Active" }, + expected: "Status: Active" + } +]; + +let failed = 0; +console.log("Running i18n interpolation tests..."); + +tests.forEach(test => { + const result = interpolate(test.template, test.params); + if (result === test.expected) { + console.log(`[PASS] ${test.name}`); + } else { + console.error(`[FAIL] ${test.name}`); + console.error(` Expected: "${test.expected}"`); + console.error(` Actual: "${result}"`); + failed++; + } +}); + +if (failed === 0) { + console.log("\nAll tests passed!"); + process.exit(0); +} else { + console.error(`\n${failed} tests failed.`); + process.exit(1); +} diff --git a/src/shell/script/ts/yarn.lock b/src/shell/script/ts/yarn.lock index 6b5befd6..355ad131 100644 --- a/src/shell/script/ts/yarn.lock +++ b/src/shell/script/ts/yarn.lock @@ -1,221 +1,228 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 - - -"@esbuild/aix-ppc64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz#4e0f91776c2b340e75558f60552195f6fad09f18" - integrity sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA== - -"@esbuild/android-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz#bc766407f1718923f6b8079c8c61bf86ac3a6a4f" - integrity sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg== - -"@esbuild/android-arm@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.5.tgz#4290d6d3407bae3883ad2cded1081a234473ce26" - integrity sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA== - -"@esbuild/android-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.5.tgz#40c11d9cbca4f2406548c8a9895d321bc3b35eff" - integrity sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw== - -"@esbuild/darwin-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz#49d8bf8b1df95f759ac81eb1d0736018006d7e34" - integrity sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ== - -"@esbuild/darwin-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz#e27a5d92a14886ef1d492fd50fc61a2d4d87e418" - integrity sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ== - -"@esbuild/freebsd-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz#97cede59d638840ca104e605cdb9f1b118ba0b1c" - integrity sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw== - -"@esbuild/freebsd-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz#71c77812042a1a8190c3d581e140d15b876b9c6f" - integrity sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw== - -"@esbuild/linux-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz#f7b7c8f97eff8ffd2e47f6c67eb5c9765f2181b8" - integrity sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg== - -"@esbuild/linux-arm@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz#2a0be71b6cd8201fa559aea45598dffabc05d911" - integrity sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw== - -"@esbuild/linux-ia32@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz#763414463cd9ea6fa1f96555d2762f9f84c61783" - integrity sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA== - -"@esbuild/linux-loong64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz#428cf2213ff786a502a52c96cf29d1fcf1eb8506" - integrity sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg== - -"@esbuild/linux-mips64el@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz#5cbcc7fd841b4cd53358afd33527cd394e325d96" - integrity sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg== - -"@esbuild/linux-ppc64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz#0d954ab39ce4f5e50f00c4f8c4fd38f976c13ad9" - integrity sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ== - -"@esbuild/linux-riscv64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz#0e7dd30730505abd8088321e8497e94b547bfb1e" - integrity sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA== - -"@esbuild/linux-s390x@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz#5669af81327a398a336d7e40e320b5bbd6e6e72d" - integrity sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ== - -"@esbuild/linux-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz#b2357dd153aa49038967ddc1ffd90c68a9d2a0d4" - integrity sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw== - -"@esbuild/netbsd-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz#53b4dfb8fe1cee93777c9e366893bd3daa6ba63d" - integrity sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw== - -"@esbuild/netbsd-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz#a0206f6314ce7dc8713b7732703d0f58de1d1e79" - integrity sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ== - -"@esbuild/openbsd-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz#2a796c87c44e8de78001d808c77d948a21ec22fd" - integrity sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw== - -"@esbuild/openbsd-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz#28d0cd8909b7fa3953af998f2b2ed34f576728f0" - integrity sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg== - -"@esbuild/sunos-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz#a28164f5b997e8247d407e36c90d3fd5ddbe0dc5" - integrity sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA== - -"@esbuild/win32-arm64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz#6eadbead38e8bd12f633a5190e45eff80e24007e" - integrity sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw== - -"@esbuild/win32-ia32@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz#bab6288005482f9ed2adb9ded7e88eba9a62cc0d" - integrity sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ== - -"@esbuild/win32-x64@0.25.5": - version "0.25.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz#7fc114af5f6563f19f73324b5d5ff36ece0803d1" - integrity sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g== +# bun ./bun.lockb --hash: 0000000000000000-0000000000000000-0000000000000000-0000000000000000 + + +"@esbuild/aix-ppc64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz" + integrity sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA== + +"@esbuild/android-arm@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz" + integrity sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg== + +"@esbuild/android-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz" + integrity sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg== + +"@esbuild/android-x64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz" + integrity sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg== + +"@esbuild/darwin-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz" + integrity sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg== + +"@esbuild/darwin-x64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz" + integrity sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA== + +"@esbuild/freebsd-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz" + integrity sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg== + +"@esbuild/freebsd-x64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz" + integrity sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ== + +"@esbuild/linux-arm@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz" + integrity sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw== + +"@esbuild/linux-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz" + integrity sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ== + +"@esbuild/linux-ia32@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz" + integrity sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA== + +"@esbuild/linux-loong64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz" + integrity sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng== + +"@esbuild/linux-mips64el@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz" + integrity sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw== + +"@esbuild/linux-ppc64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz" + integrity sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA== + +"@esbuild/linux-riscv64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz" + integrity sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w== + +"@esbuild/linux-s390x@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz" + integrity sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg== + +"@esbuild/linux-x64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz" + integrity sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw== + +"@esbuild/netbsd-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz" + integrity sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg== + +"@esbuild/netbsd-x64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz" + integrity sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ== + +"@esbuild/openbsd-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz" + integrity sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A== + +"@esbuild/openbsd-x64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz" + integrity sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw== + +"@esbuild/openharmony-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz" + integrity sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg== + +"@esbuild/sunos-x64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz" + integrity sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w== + +"@esbuild/win32-arm64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz" + integrity sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg== + +"@esbuild/win32-ia32@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz" + integrity sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ== + +"@esbuild/win32-x64@0.25.12": + version "0.25.12" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz" + integrity sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA== "@types/prop-types@*": - version "15.7.14" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.14.tgz#1433419d73b2a7ebfc6918dcefd2ec0d5cd698f2" - integrity sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ== + version "15.7.15" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz" + integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== + +"@types/react@*", "@types/react@18": + version "18.3.27" + resolved "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz" + integrity sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w== + dependencies: + "@types/prop-types" "*" + csstype "^3.2.2" "@types/react-reconciler@^0.28.9": version "0.28.9" - resolved "https://registry.yarnpkg.com/@types/react-reconciler/-/react-reconciler-0.28.9.tgz#d24b4864c384e770c83275b3fe73fba00269c83b" + resolved "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz" integrity sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg== -"@types/react@18": - version "18.3.23" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.23.tgz#86ae6f6b95a48c418fecdaccc8069e0fbb63696a" - integrity sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w== - dependencies: - "@types/prop-types" "*" - csstype "^3.0.2" - breeze-shell-types@^0.0.14: version "0.0.14" - resolved "https://registry.yarnpkg.com/breeze-shell-types/-/breeze-shell-types-0.0.14.tgz#eccff81d132510e8e5d0a2ad954bda450fe80255" + resolved "https://registry.npmjs.org/breeze-shell-types/-/breeze-shell-types-0.0.14.tgz" integrity sha512-pggWZUNT2l+HRnIfhWHgkFJGAOZVq+olAfJE1b6WYeFSEJSzP5XANubSSeKojb7CgRXq2OsgQcMXJeYRAW0U9Q== -csstype@^3.0.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" - integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +csstype@^3.2.2: + version "3.2.3" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz" + integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== esbuild@^0.25.5: - version "0.25.5" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.5.tgz#71075054993fdfae76c66586f9b9c1f8d7edd430" - integrity sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ== + version "0.25.12" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz" + integrity sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg== optionalDependencies: - "@esbuild/aix-ppc64" "0.25.5" - "@esbuild/android-arm" "0.25.5" - "@esbuild/android-arm64" "0.25.5" - "@esbuild/android-x64" "0.25.5" - "@esbuild/darwin-arm64" "0.25.5" - "@esbuild/darwin-x64" "0.25.5" - "@esbuild/freebsd-arm64" "0.25.5" - "@esbuild/freebsd-x64" "0.25.5" - "@esbuild/linux-arm" "0.25.5" - "@esbuild/linux-arm64" "0.25.5" - "@esbuild/linux-ia32" "0.25.5" - "@esbuild/linux-loong64" "0.25.5" - "@esbuild/linux-mips64el" "0.25.5" - "@esbuild/linux-ppc64" "0.25.5" - "@esbuild/linux-riscv64" "0.25.5" - "@esbuild/linux-s390x" "0.25.5" - "@esbuild/linux-x64" "0.25.5" - "@esbuild/netbsd-arm64" "0.25.5" - "@esbuild/netbsd-x64" "0.25.5" - "@esbuild/openbsd-arm64" "0.25.5" - "@esbuild/openbsd-x64" "0.25.5" - "@esbuild/sunos-x64" "0.25.5" - "@esbuild/win32-arm64" "0.25.5" - "@esbuild/win32-ia32" "0.25.5" - "@esbuild/win32-x64" "0.25.5" + "@esbuild/aix-ppc64" "0.25.12" + "@esbuild/android-arm" "0.25.12" + "@esbuild/android-arm64" "0.25.12" + "@esbuild/android-x64" "0.25.12" + "@esbuild/darwin-arm64" "0.25.12" + "@esbuild/darwin-x64" "0.25.12" + "@esbuild/freebsd-arm64" "0.25.12" + "@esbuild/freebsd-x64" "0.25.12" + "@esbuild/linux-arm" "0.25.12" + "@esbuild/linux-arm64" "0.25.12" + "@esbuild/linux-ia32" "0.25.12" + "@esbuild/linux-loong64" "0.25.12" + "@esbuild/linux-mips64el" "0.25.12" + "@esbuild/linux-ppc64" "0.25.12" + "@esbuild/linux-riscv64" "0.25.12" + "@esbuild/linux-s390x" "0.25.12" + "@esbuild/linux-x64" "0.25.12" + "@esbuild/netbsd-arm64" "0.25.12" + "@esbuild/netbsd-x64" "0.25.12" + "@esbuild/openbsd-arm64" "0.25.12" + "@esbuild/openbsd-x64" "0.25.12" + "@esbuild/openharmony-arm64" "0.25.12" + "@esbuild/sunos-x64" "0.25.12" + "@esbuild/win32-arm64" "0.25.12" + "@esbuild/win32-ia32" "0.25.12" + "@esbuild/win32-x64" "0.25.12" "js-tokens@^3.0.0 || ^4.0.0": version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== loose-envify@^1.1.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" +react@18, react@^18.3.1: + version "18.3.1" + resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + react-reconciler@0.29.2: version "0.29.2" - resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.29.2.tgz#8ecfafca63549a4f4f3e4c1e049dd5ad9ac3a54f" + resolved "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.2.tgz" integrity sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg== dependencies: loose-envify "^1.1.0" scheduler "^0.23.2" -react@18: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" - scheduler@^0.23.2: version "0.23.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz" integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== dependencies: loose-envify "^1.1.0" diff --git a/src/shell/utils.cc b/src/shell/utils.cc index d4bb5230..bb0e5d92 100644 --- a/src/shell/utils.cc +++ b/src/shell/utils.cc @@ -1,5 +1,5 @@ -#include "utils.h" #define _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS +#include "utils.h" #include #include #include diff --git a/src/shell/utils.h b/src/shell/utils.h index f35a5228..d7923069 100644 --- a/src/shell/utils.h +++ b/src/shell/utils.h @@ -77,7 +77,7 @@ struct perf_counter { perf_counter(std::string name); }; -template constexpr std::string_view string_from_enum(E e) { +template constexpr std::string string_from_enum(E e) { return reflect::enum_name(e) | std::views::transform([](char c) { return c == '_' ? '-' : c; }) | std::ranges::to(); diff --git a/xmake.lua b/xmake.lua index bd1850b2..965cffbf 100644 --- a/xmake.lua +++ b/xmake.lua @@ -62,8 +62,9 @@ target("shell") add_packages("blook", "reflect-cpp", "wintoast", "cpptrace", "yalantinglibs", "breeze-ui") add_syslinks("oleacc", "ole32", "oleaut32", "uuid", "comctl32", "comdlg32", "gdi32", "user32", "shell32", "kernel32", "advapi32", "psapi", "Winhttp", "dbghelp") add_rules("utils.bin2c", { - extensions = {".js"} + extensions = {".js", ".json"} }) + add_files("resources/locales/en-US.json", "resources/locales/zh-CN.json") set_version(version) set_configdir("src/shell") add_configfiles("src/shell/build_info.h.in")