diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 00000000..60334c65
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,24 @@
+{
+ "parser": "@typescript-eslint/parser",
+ "extends": [
+ "plugin:react/recommended"
+ ],
+ "parserOptions": {
+ "ecmaFeatures": {
+ "jsx": true // Allows for the parsing of JSX
+ }
+ },
+ "rules": {
+ "react/prop-types": "off",
+ "@typescript-eslint/no-empty-interface": 0,
+ "no-unreachable": "warn",
+ "no-unused-vars": "warn",
+ "react/react-in-jsx-scope": "off",
+ "semi": ["error", "always"]
+ },
+ "settings": {
+ "react": {
+ "version": "detect"
+ }
+ }
+}
diff --git a/.gitignore b/.gitignore
index e7b75066..3619fecf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,36 @@ weights/
error.log
*.exe
*.ipynb
+
+
+# Added by WebUI migration
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+.vscode
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+.venv
+
+# Customize
+test-x86_64-pc-windows-msvc.spec
+/build
\ No newline at end of file
diff --git a/data.js b/data.js
new file mode 100644
index 00000000..152ab9e4
--- /dev/null
+++ b/data.js
@@ -0,0 +1,86 @@
+export const language_list = [{'language': 'Afrikaans', 'country': 'South Africa'}, {'language': 'Albanian', 'country': 'Albania'}, {'language': 'Amharic', 'country': 'Ethiopia'}, {'language': 'Arabic', 'country': 'Algeria'}, {'language': 'Arabic', 'country': 'Bahrain'}, {'language': 'Arabic', 'country': 'Egypt'}, {'language': 'Arabic', 'country': 'Israel'}, {'language': 'Arabic', 'country': 'Iraq'}, {'language': 'Arabic', 'country': 'Jordan'}, {'language': 'Arabic', 'country': 'Kuwait'}, {'language': 'Arabic', 'country': 'Lebanon'}, {'language': 'Arabic', 'country': 'Mauritania'}, {'language': 'Arabic', 'country': 'Morocco'}, {'language': 'Arabic', 'country': 'Oman'}, {'language': 'Arabic', 'country': 'Qatar'}, {'language': 'Arabic', 'country': 'Saudi Arabia'}, {'language': 'Arabic', 'country': 'Palestine'}, {'language': 'Arabic', 'country': 'Syria'}, {'language': 'Arabic', 'country': 'Tunisia'}, {'language': 'Arabic', 'country': 'United Arab Emirates'}, {'language': 'Arabic', 'country': 'Yemen'}, {'language': 'Armenian', 'country': 'Armenia'}, {'language': 'Azerbaijani', 'country': 'Azerbaijan'}, {'language': 'Basque', 'country': 'Spain'}, {'language': 'Bengali', 'country': 'Bangladesh'}, {'language': 'Bengali', 'country': 'India'}, {'language': 'Bosnian', 'country': 'Bosnia and Herzegovina'}, {'language': 'Bulgarian', 'country': 'Bulgaria'}, {'language': 'Catalan', 'country': 'Spain'}, {'language': 'Chinese Simplified', 'country': 'China'}, {'language': 'Chinese Simplified', 'country': 'Hong Kong'}, {'language': 'Chinese Traditional', 'country': 'Taiwan'}, {'language': 'Chinese Traditional', 'country': 'Hong Kong'}, {'language': 'Croatian', 'country': 'Croatia'}, {'language': 'Czech', 'country': 'Czech Republic'}, {'language': 'Danish', 'country': 'Denmark'}, {'language': 'Dutch', 'country': 'Belgium'}, {'language': 'Dutch', 'country': 'Netherlands'}, {'language': 'English', 'country': 'Australia'}, {'language': 'English', 'country': 'Canada'}, {'language': 'English', 'country': 'Ghana'}, {'language': 'English', 'country': 'Hong Kong'}, {'language': 'English', 'country': 'India'}, {'language': 'English', 'country': 'Ireland'}, {'language': 'English', 'country': 'Kenya'}, {'language': 'English', 'country': 'New Zealand'}, {'language': 'English', 'country': 'Nigeria'}, {'language': 'English', 'country': 'Philippines'}, {'language': 'English', 'country': 'Singapore'}, {'language': 'English', 'country': 'South Africa'}, {'language': 'English', 'country': 'Tanzania'}, {'language': 'English', 'country': 'United Kingdom'}, {'language': 'English', 'country': 'United States'}, {'language': 'Estonian', 'country': 'Estonia'}, {'language': 'Filipino', 'country': 'Philippines'}, {'language': 'Finnish', 'country': 'Finland'}, {'language': 'French', 'country': 'Belgium'}, {'language': 'French', 'country': 'Canada'}, {'language': 'French', 'country': 'France'}, {'language': 'French', 'country': 'Switzerland'}, {'language': 'Galician', 'country': 'Spain'}, {'language': 'Georgian', 'country': 'Georgia'}, {'language': 'German', 'country': 'Austria'}, {'language': 'German', 'country': 'Germany'}, {'language': 'German', 'country': 'Switzerland'}, {'language': 'Greek', 'country': 'Greece'}, {'language': 'Gujarati', 'country': 'India'}, {'language': 'Hebrew', 'country': 'Israel'}, {'language': 'Hindi', 'country': 'India'}, {'language': 'Hungarian', 'country': 'Hungary'}, {'language': 'Icelandic', 'country': 'Iceland'}, {'language': 'Indonesian', 'country': 'Indonesia'}, {'language': 'Italian', 'country': 'Italy'}, {'language': 'Italian', 'country': 'Switzerland'}, {'language': 'Japanese', 'country': 'Japan'}, {'language': 'Kannada', 'country': 'India'}, {'language': 'Kazakh', 'country': 'Kazakhstan'}, {'language': 'Khmer', 'country': 'Cambodia'}, {'language': 'Korean', 'country': 'South Korea'}, {'language': 'Lao', 'country': 'Laos'}, {'language': 'Latvian', 'country': 'Latvia'}, {'language': 'Lithuanian', 'country': 'Lithuania'}, {'language': 'Macedonian', 'country': 'North Macedonia'}, {'language': 'Malay', 'country': 'Malaysia'}, {'language': 'Malayalam', 'country': 'India'}, {'language': 'Mongolian', 'country': 'Mongolia'}, {'language': 'Nepali', 'country': 'Nepal'}, {'language': 'Norwegian', 'country': 'Norway'}, {'language': 'Persian', 'country': 'Iran'}, {'language': 'Polish', 'country': 'Poland'}, {'language': 'Portuguese', 'country': 'Brazil'}, {'language': 'Portuguese', 'country': 'Portugal'}, {'language': 'Romanian', 'country': 'Romania'}, {'language': 'Russian', 'country': 'Russia'}, {'language': 'Serbian', 'country': 'Serbia'}, {'language': 'Sinhala', 'country': 'Sri Lanka'}, {'language': 'Slovak', 'country': 'Slovakia'}, {'language': 'Slovenian', 'country': 'Slovenia'}, {'language': 'Spanish', 'country': 'Argentina'}, {'language': 'Spanish', 'country': 'Bolivia'}, {'language': 'Spanish', 'country': 'Chile'}, {'language': 'Spanish', 'country': 'Colombia'}, {'language': 'Spanish', 'country': 'Costa Rica'}, {'language': 'Spanish', 'country': 'Dominican Republic'}, {'language': 'Spanish', 'country': 'Ecuador'}, {'language': 'Spanish', 'country': 'El Salvador'}, {'language': 'Spanish', 'country': 'Guatemala'}, {'language': 'Spanish', 'country': 'Honduras'}, {'language': 'Spanish', 'country': 'Mexico'}, {'language': 'Spanish', 'country': 'Nicaragua'}, {'language': 'Spanish', 'country': 'Panama'}, {'language': 'Spanish', 'country': 'Paraguay'}, {'language': 'Spanish', 'country': 'Peru'}, {'language': 'Spanish', 'country': 'Puerto Rico'}, {'language': 'Spanish', 'country': 'Spain'}, {'language': 'Spanish', 'country': 'United States'}, {'language': 'Spanish', 'country': 'Uruguay'}, {'language': 'Spanish', 'country': 'Venezuela'}, {'language': 'Sundanese', 'country': 'Indonesia'}, {'language': 'Swahili', 'country': 'Kenya'}, {'language': 'Swahili', 'country': 'Tanzania'}, {'language': 'Swedish', 'country': 'Sweden'}, {'language': 'Tamil', 'country': 'India'}, {'language': 'Tamil', 'country': 'malaysia'}, {'language': 'Tamil', 'country': 'Singapore'}, {'language': 'Tamil', 'country': 'Sri Lanka'}, {'language': 'Telugu', 'country': 'India'}, {'language': 'Thai', 'country': 'Thailand'}, {'language': 'Turkish', 'country': 'Turkey'}, {'language': 'Ukrainian', 'country': 'Ukraine'}, {'language': 'Urdu', 'country': 'India'}, {'language': 'Urdu', 'country': 'Pakistan'}, {'language': 'Uzbek', 'country': 'Uzbekistan'}, {'language': 'Vietnamese', 'country': 'Vietnam'}];
+
+export const translator_list = [
+ { translator_key: "DeepL", translator_name: "DeepL", is_available: true },
+ { translator_key: "DeepL_API", translator_name: `DeepL\nAPI`, is_available: false },
+ { translator_key: "Google", translator_name: "Google", is_available: true },
+ { translator_key: "Bing", translator_name: "Bing", is_available: true },
+ { translator_key: "Papago", translator_name: "Papago", is_available: true },
+ { translator_key: "CTranslate2", translator_name: `Internal\n(Default)`, is_available: true },
+];
+
+
+export const generateTestData = (num) => {
+ const testDataArray = [];
+ const messagesJa = [
+ "今日はとてもいい天気ですね。",
+ "次の会議は何時に始まりますか?",
+ "新しいプロジェクトについて話しましょう。",
+ "お疲れ様です。今日は早く帰れますか?",
+ "この書類にサインをお願いします。",
+ "次の休暇はどこに行きますか?",
+ "先週のレポートを見ましたか?",
+ "この問題をどうやって解決しますか?",
+ "週末は何をする予定ですか?",
+ "新しいアイデアを聞かせてください。",
+ "こんにちは、調子はどうですか?",
+ "おはようございます、今日の予定は何ですか?",
+ "こんばんは、今日は楽しかったですか?",
+ "ありがとう、助かりました。",
+ "さようなら、また会いましょう。",
+ "はい、分かりました。",
+ "いいえ、ちょっと難しいです。",
+ "すみません、もう一度言ってください。",
+ "お願いします、手伝ってください。",
+ "お疲れ様です、今日も頑張りましょう。",
+ ];
+ const messagesEn = [
+ "The weather is very nice today.",
+ "What time does the next meeting start?",
+ "Let's talk about the new project.",
+ "Good job today. Can you leave early today?",
+ "Please sign this document.",
+ "Where are you going for the next vacation?",
+ "Did you see last week's report?",
+ "How do we solve this problem?",
+ "What are your plans for the weekend?",
+ "Tell me about your new idea.",
+ "Hello, how are you?",
+ "Good morning, what are your plans for today?",
+ "Good evening, did you have a good day?",
+ "Thank you, that was helpful.",
+ "Goodbye, see you again.",
+ "Yes, understood.",
+ "No, it's a bit difficult.",
+ "Sorry, could you say that again?",
+ "Please, help me out.",
+ "Good job today, let's do our best again tomorrow.",
+ ];
+ const statuses = ["sent", "received"];
+
+ for (let i = 0; i < num; i++) {
+ const uuid = crypto.randomUUID();
+ const date = new Date().toLocaleTimeString(
+ "ja-JP",
+ { hour12: false, hour: "2-digit", minute: "2-digit" }
+ );
+ const messageIndex = Math.floor(Math.random() * messagesJa.length);
+ const status = statuses[Math.floor(Math.random() * statuses.length)];
+
+ const testData = {
+ id: uuid,
+ category: status,
+ status: status,
+ created_at: date,
+ messages: {
+ original: messagesJa[messageIndex],
+ translated: [
+ messagesEn[messageIndex],
+ ],
+ },
+ };
+ testDataArray.push(testData);
+ }
+
+ return testDataArray;
+};
\ No newline at end of file
diff --git a/img/VRCT_now_downloading.png b/img/VRCT_now_downloading.png
deleted file mode 100644
index 8e372d87..00000000
Binary files a/img/VRCT_now_downloading.png and /dev/null differ
diff --git a/img/VRCT_starting_up.png b/img/VRCT_starting_up.png
deleted file mode 100644
index 9feac583..00000000
Binary files a/img/VRCT_starting_up.png and /dev/null differ
diff --git a/img/about_vrct/arrow_left.png b/img/about_vrct/arrow_left.png
deleted file mode 100644
index a1c4b35e..00000000
Binary files a/img/about_vrct/arrow_left.png and /dev/null differ
diff --git a/img/about_vrct/arrow_right.png b/img/about_vrct/arrow_right.png
deleted file mode 100644
index 69e005ba..00000000
Binary files a/img/about_vrct/arrow_right.png and /dev/null differ
diff --git a/img/about_vrct/contributors_github_icon.png b/img/about_vrct/contributors_github_icon.png
deleted file mode 100644
index 1c6e0727..00000000
Binary files a/img/about_vrct/contributors_github_icon.png and /dev/null differ
diff --git a/img/about_vrct/contributors_x_icon.png b/img/about_vrct/contributors_x_icon.png
deleted file mode 100644
index c17fb57d..00000000
Binary files a/img/about_vrct/contributors_x_icon.png and /dev/null differ
diff --git a/img/about_vrct/dev_github_icon.png b/img/about_vrct/dev_github_icon.png
deleted file mode 100644
index 8cbaaff7..00000000
Binary files a/img/about_vrct/dev_github_icon.png and /dev/null differ
diff --git a/img/about_vrct/dev_misya.png b/img/about_vrct/dev_misya.png
deleted file mode 100644
index 60317fff..00000000
Binary files a/img/about_vrct/dev_misya.png and /dev/null differ
diff --git a/img/about_vrct/dev_shiina.png b/img/about_vrct/dev_shiina.png
deleted file mode 100644
index 63b5785e..00000000
Binary files a/img/about_vrct/dev_shiina.png and /dev/null differ
diff --git a/img/about_vrct/dev_x_icon.png b/img/about_vrct/dev_x_icon.png
deleted file mode 100644
index dfd6d109..00000000
Binary files a/img/about_vrct/dev_x_icon.png and /dev/null differ
diff --git a/img/about_vrct/poster_showcase_pagination_button.png b/img/about_vrct/poster_showcase_pagination_button.png
deleted file mode 100644
index bbfee311..00000000
Binary files a/img/about_vrct/poster_showcase_pagination_button.png and /dev/null differ
diff --git a/img/about_vrct/poster_showcase_pagination_button_chato.png b/img/about_vrct/poster_showcase_pagination_button_chato.png
deleted file mode 100644
index a4df1d52..00000000
Binary files a/img/about_vrct/poster_showcase_pagination_button_chato.png and /dev/null differ
diff --git a/img/about_vrct/poster_tell_us_message_en.png b/img/about_vrct/poster_tell_us_message_en.png
deleted file mode 100644
index 1078b42f..00000000
Binary files a/img/about_vrct/poster_tell_us_message_en.png and /dev/null differ
diff --git a/img/about_vrct/poster_tell_us_message_ja.png b/img/about_vrct/poster_tell_us_message_ja.png
deleted file mode 100644
index 8e2b096d..00000000
Binary files a/img/about_vrct/poster_tell_us_message_ja.png and /dev/null differ
diff --git a/img/about_vrct/special_thanks_members.png b/img/about_vrct/special_thanks_members.png
deleted file mode 100644
index e3847657..00000000
Binary files a/img/about_vrct/special_thanks_members.png and /dev/null differ
diff --git a/img/about_vrct/special_thanks_message_and_you.png b/img/about_vrct/special_thanks_message_and_you.png
deleted file mode 100644
index f006ff15..00000000
Binary files a/img/about_vrct/special_thanks_message_and_you.png and /dev/null differ
diff --git a/img/about_vrct/special_thanks_tell_us_message_en.png b/img/about_vrct/special_thanks_tell_us_message_en.png
deleted file mode 100644
index c213e5bc..00000000
Binary files a/img/about_vrct/special_thanks_tell_us_message_en.png and /dev/null differ
diff --git a/img/about_vrct/special_thanks_tell_us_message_ja.png b/img/about_vrct/special_thanks_tell_us_message_ja.png
deleted file mode 100644
index f3274966..00000000
Binary files a/img/about_vrct/special_thanks_tell_us_message_ja.png and /dev/null differ
diff --git a/img/arrow_left_black.png b/img/arrow_left_black.png
deleted file mode 100644
index 5e3f8dfb..00000000
Binary files a/img/arrow_left_black.png and /dev/null differ
diff --git a/img/arrow_left_disabled.png b/img/arrow_left_disabled.png
deleted file mode 100644
index 5b5f3afa..00000000
Binary files a/img/arrow_left_disabled.png and /dev/null differ
diff --git a/img/arrow_left_white.png b/img/arrow_left_white.png
deleted file mode 100644
index 463d8a74..00000000
Binary files a/img/arrow_left_white.png and /dev/null differ
diff --git a/img/cancel_icon.png b/img/cancel_icon.png
deleted file mode 100644
index aa6c386e..00000000
Binary files a/img/cancel_icon.png and /dev/null differ
diff --git a/img/chato_delivering.png b/img/chato_delivering.png
deleted file mode 100644
index d38f1447..00000000
Binary files a/img/chato_delivering.png and /dev/null differ
diff --git a/img/chato_unpackaging.png b/img/chato_unpackaging.png
deleted file mode 100644
index 52eb66dc..00000000
Binary files a/img/chato_unpackaging.png and /dev/null differ
diff --git a/img/configuration_icon_black.png b/img/configuration_icon_black.png
deleted file mode 100644
index c97dfefe..00000000
Binary files a/img/configuration_icon_black.png and /dev/null differ
diff --git a/img/configuration_icon_disabled.png b/img/configuration_icon_disabled.png
deleted file mode 100644
index 03a4a217..00000000
Binary files a/img/configuration_icon_disabled.png and /dev/null differ
diff --git a/img/configuration_icon_white.png b/img/configuration_icon_white.png
deleted file mode 100644
index ee6e050e..00000000
Binary files a/img/configuration_icon_white.png and /dev/null differ
diff --git a/img/downloading_unpackaging_d.png b/img/downloading_unpackaging_d.png
deleted file mode 100644
index 5c3c7031..00000000
Binary files a/img/downloading_unpackaging_d.png and /dev/null differ
diff --git a/img/downloading_unpackaging_u.png b/img/downloading_unpackaging_u.png
deleted file mode 100644
index 684433d5..00000000
Binary files a/img/downloading_unpackaging_u.png and /dev/null differ
diff --git a/img/folder_open_icon_black.png b/img/folder_open_icon_black.png
deleted file mode 100644
index 988184b3..00000000
Binary files a/img/folder_open_icon_black.png and /dev/null differ
diff --git a/img/folder_open_icon_white.png b/img/folder_open_icon_white.png
deleted file mode 100644
index 3de75dfe..00000000
Binary files a/img/folder_open_icon_white.png and /dev/null differ
diff --git a/img/foreground_icon_black.png b/img/foreground_icon_black.png
deleted file mode 100644
index ff3594c2..00000000
Binary files a/img/foreground_icon_black.png and /dev/null differ
diff --git a/img/foreground_icon_disabled.png b/img/foreground_icon_disabled.png
deleted file mode 100644
index 91778b7b..00000000
Binary files a/img/foreground_icon_disabled.png and /dev/null differ
diff --git a/img/foreground_icon_white.png b/img/foreground_icon_white.png
deleted file mode 100644
index 50370ad1..00000000
Binary files a/img/foreground_icon_white.png and /dev/null differ
diff --git a/img/headphones_icon_black.png b/img/headphones_icon_black.png
deleted file mode 100644
index 2cb97ec2..00000000
Binary files a/img/headphones_icon_black.png and /dev/null differ
diff --git a/img/headphones_icon_disabled.png b/img/headphones_icon_disabled.png
deleted file mode 100644
index f81f812e..00000000
Binary files a/img/headphones_icon_disabled.png and /dev/null differ
diff --git a/img/headphones_icon_white.png b/img/headphones_icon_white.png
deleted file mode 100644
index 54f7359d..00000000
Binary files a/img/headphones_icon_white.png and /dev/null differ
diff --git a/img/help_icon_black.png b/img/help_icon_black.png
deleted file mode 100644
index 156ca026..00000000
Binary files a/img/help_icon_black.png and /dev/null differ
diff --git a/img/help_icon_white.png b/img/help_icon_white.png
deleted file mode 100644
index ee5cb936..00000000
Binary files a/img/help_icon_white.png and /dev/null differ
diff --git a/img/link_icon_black.png b/img/link_icon_black.png
deleted file mode 100644
index e4790914..00000000
Binary files a/img/link_icon_black.png and /dev/null differ
diff --git a/img/link_icon_white.png b/img/link_icon_white.png
deleted file mode 100644
index 58a56d45..00000000
Binary files a/img/link_icon_white.png and /dev/null differ
diff --git a/img/mic_icon_black.png b/img/mic_icon_black.png
deleted file mode 100644
index 1210b069..00000000
Binary files a/img/mic_icon_black.png and /dev/null differ
diff --git a/img/mic_icon_disabled.png b/img/mic_icon_disabled.png
deleted file mode 100644
index 542d2824..00000000
Binary files a/img/mic_icon_disabled.png and /dev/null differ
diff --git a/img/mic_icon_white.png b/img/mic_icon_white.png
deleted file mode 100644
index e1837463..00000000
Binary files a/img/mic_icon_white.png and /dev/null differ
diff --git a/img/narrow_arrow_down_black.png b/img/narrow_arrow_down_black.png
deleted file mode 100644
index e53829e5..00000000
Binary files a/img/narrow_arrow_down_black.png and /dev/null differ
diff --git a/img/narrow_arrow_down_white.png b/img/narrow_arrow_down_white.png
deleted file mode 100644
index 309560c8..00000000
Binary files a/img/narrow_arrow_down_white.png and /dev/null differ
diff --git a/img/overlay_br_sakura.png b/img/overlay_br_sakura.png
deleted file mode 100644
index 61e8ccd7..00000000
Binary files a/img/overlay_br_sakura.png and /dev/null differ
diff --git a/img/overlay_tl_sakura.png b/img/overlay_tl_sakura.png
deleted file mode 100644
index d6211f41..00000000
Binary files a/img/overlay_tl_sakura.png and /dev/null differ
diff --git a/img/redo_icon_black.png b/img/redo_icon_black.png
deleted file mode 100644
index 989581a3..00000000
Binary files a/img/redo_icon_black.png and /dev/null differ
diff --git a/img/redo_icon_white.png b/img/redo_icon_white.png
deleted file mode 100644
index 2a27e302..00000000
Binary files a/img/redo_icon_white.png and /dev/null differ
diff --git a/img/refresh_icon.png b/img/refresh_icon.png
deleted file mode 100644
index 408bc2a6..00000000
Binary files a/img/refresh_icon.png and /dev/null differ
diff --git a/img/refresh_update_icon.png b/img/refresh_update_icon.png
deleted file mode 100644
index c5acad15..00000000
Binary files a/img/refresh_update_icon.png and /dev/null differ
diff --git a/img/send_message_icon_black.png b/img/send_message_icon_black.png
deleted file mode 100644
index e4240e56..00000000
Binary files a/img/send_message_icon_black.png and /dev/null differ
diff --git a/img/send_message_icon_white.png b/img/send_message_icon_white.png
deleted file mode 100644
index cdead72b..00000000
Binary files a/img/send_message_icon_white.png and /dev/null differ
diff --git a/img/swap_icon_black.png b/img/swap_icon_black.png
deleted file mode 100644
index eec6f830..00000000
Binary files a/img/swap_icon_black.png and /dev/null differ
diff --git a/img/swap_icon_white.png b/img/swap_icon_white.png
deleted file mode 100644
index 8fa1cf53..00000000
Binary files a/img/swap_icon_white.png and /dev/null differ
diff --git a/img/translation_icon_black.png b/img/translation_icon_black.png
deleted file mode 100644
index 3e184a72..00000000
Binary files a/img/translation_icon_black.png and /dev/null differ
diff --git a/img/translation_icon_disabled.png b/img/translation_icon_disabled.png
deleted file mode 100644
index 533feb81..00000000
Binary files a/img/translation_icon_disabled.png and /dev/null differ
diff --git a/img/translation_icon_white.png b/img/translation_icon_white.png
deleted file mode 100644
index 706b0bbc..00000000
Binary files a/img/translation_icon_white.png and /dev/null differ
diff --git a/img/unpackage_icon.png b/img/unpackage_icon.png
deleted file mode 100644
index 8fd8e7d2..00000000
Binary files a/img/unpackage_icon.png and /dev/null differ
diff --git a/img/vrchat_chatbox_trasnlator_transcription.png b/img/vrchat_chatbox_trasnlator_transcription.png
deleted file mode 100644
index 9f2e401e..00000000
Binary files a/img/vrchat_chatbox_trasnlator_transcription.png and /dev/null differ
diff --git a/img/vrct_logo_for_light_mode.png b/img/vrct_logo_for_light_mode.png
deleted file mode 100644
index ad2b0b95..00000000
Binary files a/img/vrct_logo_for_light_mode.png and /dev/null differ
diff --git a/img/vrct_logo_mark_black.ico b/img/vrct_logo_mark_black.ico
deleted file mode 100644
index 7b711af3..00000000
Binary files a/img/vrct_logo_mark_black.ico and /dev/null differ
diff --git a/img/vrct_logo_mark_black.png b/img/vrct_logo_mark_black.png
deleted file mode 100644
index 4e4fce17..00000000
Binary files a/img/vrct_logo_mark_black.png and /dev/null differ
diff --git a/img/vrct_logo_mark_black_icon.png b/img/vrct_logo_mark_black_icon.png
deleted file mode 100644
index 1d73b8a8..00000000
Binary files a/img/vrct_logo_mark_black_icon.png and /dev/null differ
diff --git a/img/vrct_update_process.png b/img/vrct_update_process.png
deleted file mode 100644
index 27a77150..00000000
Binary files a/img/vrct_update_process.png and /dev/null differ
diff --git a/img/xsoverlay2.png b/img/xsoverlay2.png
deleted file mode 100644
index 20b4021a..00000000
Binary files a/img/xsoverlay2.png and /dev/null differ
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..4c5cbd7a
--- /dev/null
+++ b/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Tauri + React
+
+
+
+
+
+
+
diff --git a/locales/config.js b/locales/config.js
new file mode 100644
index 00000000..aca15b8a
--- /dev/null
+++ b/locales/config.js
@@ -0,0 +1,29 @@
+import i18n from "i18next";
+import { initReactI18next } from "react-i18next";
+
+import translation_en from "./en.json";
+import translation_ja from "./ja.json";
+import translation_ko from "./ko.json";
+import translation_zh_Hant from "./zh-Hant.json";
+
+
+const resources = {
+ en: { translation: translation_en },
+ ja: { translation: translation_ja },
+ ko: { translation: translation_ko },
+ zh_Hant: { translation: translation_zh_Hant },
+};
+
+i18n
+ .use(initReactI18next) // passes i18n down to react-i18next
+ .init({
+ resources,
+ lng: "en",
+ fallbackLng: "en",
+ debug: true,
+ interpolation: {
+ escapeValue: false // react already safes from xss
+ }
+ });
+
+export default i18n;
diff --git a/locales/en.json b/locales/en.json
new file mode 100644
index 00000000..3676aa50
--- /dev/null
+++ b/locales/en.json
@@ -0,0 +1,283 @@
+{
+ "main_window": {
+ "translation": "Translation",
+ "transcription_send": "Voice2Chatbox",
+ "transcription_receive": "Speaker2Log",
+ "foreground": "Foreground",
+ "language_settings": "Language Settings",
+ "your_language": "Your Language",
+ "translate_each_other_label": "Translate Each Other",
+ "swap_button_label": "Swap Languages",
+ "target_language": "Target Language",
+ "translator": "Translator",
+ "translator_ctranslate2": "Internal (Default)",
+ "textbox_tab_all": "All",
+ "textbox_tab_sent": "Sent",
+ "textbox_tab_received": "Received",
+ "textbox_tab_system": "System",
+ "textbox_system_message": {
+ "enabled_easter_egg": "Whoa! You caught us! There is something...like...easter-egg-ish function has enabled! It'll affect to Overlay(VR) for now;).",
+ "enabled_translation": "Translation feature is turned on.",
+ "disabled_translation": "Translation feature is turned off.",
+ "enabled_voice2chatbox": "Transcription from the microphone has started.",
+ "disabled_voice2chatbox": "Transcription from the microphone has been stopped.",
+ "enabled_speaker2log": "Transcription from the speaker has started.",
+ "disabled_speaker2log": "Transcription from the speaker has been stopped.",
+ "enabled_foreground": "The screen is fixed in the foreground.",
+ "disabled_foreground": "The foreground fixation has been released.",
+ "auth_key_success": "Auth key update completed.",
+ "auth_key_error": "Auth Key is incorrect or Usage limit reached.",
+ "no_mic_device_detected_error": "No mic device detected.",
+ "no_speaker_device_detected_error": "No speaker device detected.",
+ "translation_engine_limit_error": "It has automatically changed the translation engine. Access has been temporarily restricted due to an excessive number of requests to the translation engine. If you want to use the same translation engine, please wait for a while, restart VRCT, and try again.",
+ "detected_by_word_filter": "The word %{detected_message} has not been sent due to detection by the word filter.",
+ "selected_your_language": "\"Your Language\" has set to %{your_language}.",
+ "selected_target_language": "\"Target Language\" has set to %{target_language}.",
+ "switched_language_preset_tab": "Switched to Language Preset Tab No.%{tab_no}.\"",
+ "latest_language_setting": "Currently, \"Your Language\" is set to %{your_language}, and \"Target Language\" is set to %{target_language}.",
+ "opened_web_page_booth": "Opened Booth page in your web browser.",
+ "opened_web_page_vrct_documents": "Opened VRCT Documents page in your web browser.\nFor any issues, requests, or inquiries, please feel free to contact us through the links at the bottom of the documents page, the \"Contact Form,\" or via X (formerly Twitter)!"
+ },
+ "update_available": "New version is here!",
+ "state_text_enabled": "Enabled",
+ "state_text_disabled": "Disabled",
+ "cover_message": "The functionality is temporarily disabled until the settings window is closed.",
+ "close_settings_window": "Close the settings window",
+ "confirmation_message": {
+ "update_software": "Download the new version and automatically restart the app.\nIt'll take a while. Do it now?",
+ "deny_update_software": "Do it later",
+ "accept_update_software": "Update and Restart",
+ "updating": "Now updating...",
+ "detected_over_ui_size": "Current UI Size: %{current_ui_size}\nVRCT's window size may be larger than your display size.\n* Depending on your display size, you may need to adjust it multiple times.",
+ "deny_adjust_ui_size": "Keep it at this size",
+ "accept_adjust_ui_size": "Set it smaller and restart"
+ }
+ },
+ "selectable_language_window": {
+ "title_your_language": "Select Your Language",
+ "title_target_language": "Select Target Language",
+ "go_back_button": "Go Back"
+ },
+ "overlay_settings": {
+ "restore_default_settings": "Restore Default Settings",
+ "opacity": "Opacity",
+ "ui_scaling": "UI Scaling",
+ "x_position": "X-axis (left-right)",
+ "y_position": "Y-axis (up-down)",
+ "z_position": "Z-axis (front-back)",
+ "x_rotation": "X-axis rotation",
+ "y_rotation": "Y-axis rotation",
+ "z_rotation": "Z-axis rotation",
+ "display_duration": "Display duration",
+ "fadeout_duration": "Fadeout duration"
+ },
+ "config_window": {
+ "config_title": "Settings",
+ "compact_mode": "Compact Mode",
+ "version": "version %{version}",
+ "restart_message": "Apply changes with a restart.",
+ "common_error_message": {
+ "invalid_value": "Invalid value."
+ },
+ "side_menu_labels": {
+ "appearance": "Appearance",
+ "translation": "Translation",
+ "transcription": "Transcription",
+ "transcription_mic": "Mic",
+ "transcription_speaker": "Speaker",
+ "transcription_internal_model": "Transcription Model",
+ "vr": "VR",
+ "others": "Others",
+ "others_send_message_formats": "Message Formats (Send)",
+ "others_received_message_formats": "Message Formats (XSOverlay & Speaker2Chatbox)",
+ "others_speaker2chatbox": "Speaker2Chatbox",
+ "advanced_settings": "Advanced Settings",
+ "about_vrct": "About VRCT"
+ },
+ "transparency": {
+ "label": "Transparency",
+ "desc": "Change the main window's transparency."
+ },
+ "appearance_theme": {
+ "label": "Theme",
+ "desc": "Change the color theme."
+ },
+ "ui_size": {
+ "label": "UI Size"
+ },
+ "textbox_ui_size": {
+ "label": "Text Box Font Size",
+ "desc": "You can adjust the font size used in the logs relative to the UI size."
+ },
+ "message_box_ratio": {
+ "label": "Message Box Size",
+ "desc": "You can change the size of the input message box. It is in ratio to the text box.\n*No exact calculations."
+ },
+ "font_family": {
+ "label": "Font Family"
+ },
+ "ui_language": {
+ "label": "UI Language"
+ },
+ "to_restore_main_window_geometry": {
+ "label": "Remember The Main Window Position",
+ "desc": "Restore the position and size of the previous window upon startup."
+ },
+ "use_translation_feature": {
+ "label": "Use Translation Feature",
+ "desc": "You can't use the translation feature while this is turned off. Instead, the VRCT startup becomes a little faster. This is for users who don't need the translation feature and only use VRCT as a chatbox and transcription tool."
+ },
+ "ctranslate2_weight_type": {
+ "label": "Select Internal Translation Model",
+ "desc": "You can choose the translation model to use for the internal translation engine.",
+ "small": "Basic model (%{capacity})",
+ "large": "High accuracy model (%{capacity})"
+ },
+ "deepl_auth_key": {
+ "label": "DeepL Auth Key",
+ "desc": "Please select %{translator} on the main screen with DeepL_API when using. ※Some languages may not be supported.",
+ "open_auth_key_webpage": "Open DeepL Account Webpage",
+ "auth_key_success": "Auth key update completed.",
+ "auth_key_error": "Auth Key is incorrect or Usage limit reached."
+ },
+ "mic_host": {
+ "label": "Mic Host/Driver"
+ },
+ "mic_device": {
+ "label": "Mic Device"
+ },
+ "mic_dynamic_energy_threshold": {
+ "label_for_automatic": "Mic Energy Threshold (Current Setting: Automatic)",
+ "desc_for_automatic": "Automatically determine microphone input sensitivity.",
+ "label_for_manual": "Mic Energy Threshold (Current Setting: Manual)",
+ "desc_for_manual": "Manually determine the microphone input sensitivity using the slider. Press the microphone icon to input your voice and adjust the sensitivity while monitoring the volume.",
+ "error_message": "You can set it with a value between 0 to %{max}."
+ },
+ "mic_record_timeout": {
+ "label": "Mic Record Timeout",
+ "desc": "Detects silence and, when the specified number of seconds has passed, considers the mic input to have ended. (Second(s))",
+ "error_message": "It cannot be greater than '%{mic_phrase_timeout_label}' with a value of 0 or more."
+ },
+ "mic_phrase_timeout": {
+ "label": "Mic Phrase Timeout",
+ "desc": "Transcription processing is performed at intervals of the specified number of seconds.",
+ "error_message": "It cannot be set lower than '%{mic_record_timeout_label}' with a value of 0 or more."
+ },
+ "mic_max_phrase": {
+ "label": "Mic Max Words",
+ "desc": "It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs and send to VRChat.",
+ "error_message": "You can set a number equal to or greater than 0."
+ },
+ "mic_word_filter": {
+ "label": "Mic Word Filter",
+ "desc": "If a registered word is detected, the text will not be sent. To add multiple words at once, separate them with a \",\" (comma). \n*Duplicate words will not be registered.",
+ "add_button_label": "Add",
+ "count_desc": "Current registered word count: %{count}"
+ },
+ "speaker_device": {
+ "label": "Speaker Device"
+ },
+ "speaker_dynamic_energy_threshold": {
+ "label_for_automatic": "Speaker Energy Threshold (Current Setting: Automatic)",
+ "desc_for_automatic": "Automatically determine speaker input sensitivity.",
+ "label_for_manual": "Speaker Energy Threshold (Current Setting: Manual)",
+ "desc_for_manual": "Manually determine the speaker input sensitivity using the slider. Press the headphones icon to listen to the audio and adjust the sensitivity while monitoring the volume.",
+ "error_message": "You can set it with a value between 0 to %{max}.",
+ "no_device_error_message": "No speaker device detected."
+ },
+ "speaker_record_timeout": {
+ "label": "Speaker Record Timeout",
+ "desc": "Detects silence and, when the specified number of seconds has passed, considers the speaker input to have ended. (Second(s))",
+ "error_message": "It cannot be greater than '%{speaker_phrase_timeout_label}' with a value of 0 or more."
+ },
+ "speaker_phrase_timeout": {
+ "label": "Speaker Phrase Timeout",
+ "desc": "Transcription processing is performed at intervals of the specified number of seconds.",
+ "error_message": "It cannot be set lower than '%{speaker_record_timeout_label}' with a value of 0 or more."
+ },
+ "speaker_max_phrase": {
+ "label": "Speaker Max Words",
+ "desc": "It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs.",
+ "error_message": "You can set a number equal to or greater than 0."
+ },
+ "use_whisper_feature": {
+ "label": "Use Whisper Model As Transcription",
+ "desc": "In some languages, the accuracy of speech recognition may improve. During speech recognition usage, CPU usage increases, so please consider your PC specs before using this feature."
+ },
+ "whisper_weight_type": {
+ "label": "Select Whisper Model",
+ "desc": "Generally, models with larger capacity tend to have higher accuracy, but this also results in longer transcription times and increased CPU usage. Please refer to the documentation for explanations of each model.\n※Larger models, especially those exceeding medium size, can be challenging to run even depending on the CPU's performance.",
+ "model_template": "%{model_name} model (%{capacity})",
+ "recommended_model_template": "%{model_name} model (%{capacity}) (Recommended)"
+ },
+ "enable_overlay_small_log": {
+ "label": "Enable Overlay",
+ "open_overlay_settings": "Open Overlay Customized Settings"
+ },
+ "auto_clear_the_message_box": {
+ "label": "Auto Clear The Message Box"
+ },
+ "send_only_translated_messages": {
+ "label": "Send Only Translated Messages"
+ },
+ "send_message_button_type": {
+ "label": "Send Message Button",
+ "hide": "Hide (Use enter key to send)",
+ "show": "Show",
+ "show_and_disable_enter_key": "Show and disable to send when pressed enter key"
+ },
+ "notice_xsoverlay": {
+ "label": "Notification XSOverlay",
+ "desc": "Notify received messages by using XSOverlay's notification feature."
+ },
+ "auto_export_message_logs": {
+ "label": "Auto Export Message Logs",
+ "desc": "Automatically export the conversation messages as a text file."
+ },
+ "vrc_mic_mute_sync": {
+ "label": "VRC Mic Mute Sync",
+ "desc": "VRCT will not send the message to VRChat while VRChat's mic is muted.\n*There is a bit latency and Push-To-Talk is not supported."
+ },
+ "send_message_to_vrc": {
+ "label": "Send Message To VRChat",
+ "desc": "There is a way to use it without sending messages to VRChat, but it is not supported. Enable this feature when you intend to send a message to VRChat."
+ },
+ "send_message_format": {
+ "label": "Message Format",
+ "desc": "You can change the decoration of the message you want to send.\n[message] will be replaced with the message.",
+ "example_text": "This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.",
+ "error_message": "Cannot use the term '[message]'."
+ },
+ "send_message_format_with_t": {
+ "label": "Message Format (with Translation)",
+ "desc": "You can change the decoration of the message you want to send.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message.",
+ "example_text": "This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.",
+ "error_message": "Cannot use the terms '[message]' and '[translation]'."
+ },
+ "received_message_format": {
+ "label": "Format of Received Messages",
+ "desc": "Used for XSOverlay notification receiving feature.\n[message] will be replaced with the message. \n※It will be used in Speaker2Chatbox too.",
+ "example_text": "This is an example sentence. Actual display may vary, including font and line breaks.",
+ "error_message": "Cannot use the term '[message]'."
+ },
+ "received_message_format_with_t": {
+ "label": "Format of Received Messages (with Translation)",
+ "desc": "Used for XSOverlay notification receiving feature.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message.\n※It will be used in Speaker2Chatbox too.",
+ "example_text": "This is an example sentence. Actual display may vary, including font and line breaks.",
+ "error_message": "Cannot use the terms '[message]' and '[translation]'."
+ },
+ "send_received_message_to_vrc": {
+ "label": "Send Received Message To VRChat",
+ "desc": "Send the message you received from the speaker's sound to VRChat's chatbox. However, this feature is intended for users who genuinely need it. Please consult with the developer."
+ },
+ "osc_ip_address": {
+ "label": "OSC IP Address"
+ },
+ "osc_port": {
+ "label": "OSC Port"
+ },
+ "open_config_filepath": {
+ "label": "Open Config File"
+ }
+ }
+}
\ No newline at end of file
diff --git a/locales/en.yml b/locales/en.yml
deleted file mode 100644
index 9c5d47a6..00000000
--- a/locales/en.yml
+++ /dev/null
@@ -1,300 +0,0 @@
-main_window:
- translation: Translation
- transcription_send: Voice2Chatbox
- transcription_receive: Speaker2Log
- foreground: Foreground
-
- language_settings: Language Settings
- your_language: Your Language
- translate_each_other_label: Translate Each Other
- swap_button_label: Swap Languages
- target_language: Target Language
- translator: Translator
- translator_ctranslate2: Internal (Default)
-
- textbox_tab_all: All
- textbox_tab_sent: Sent
- textbox_tab_received: Received
- textbox_tab_system: System
-
- textbox_system_message:
- enabled_easter_egg: Whoa! You caught us! There is something...like...easter-egg-ish function has enabled! It'll affect to Overlay(VR) for now;).
- enabled_translation: Translation feature is turned on.
- disabled_translation: Translation feature is turned off.
- enabled_voice2chatbox: Transcription from the microphone has started.
- disabled_voice2chatbox: Transcription from the microphone has been stopped.
- enabled_speaker2log: Transcription from the speaker has started.
- disabled_speaker2log: Transcription from the speaker has been stopped.
- enabled_foreground: The screen is fixed in the foreground.
- disabled_foreground: The foreground fixation has been released.
-
- auth_key_success: Auth key update completed.
- auth_key_error: Auth Key is incorrect or Usage limit reached.
-
- no_mic_device_detected_error: No mic device detected.
- no_speaker_device_detected_error: No speaker device detected.
- translation_engine_limit_error: It has automatically changed the translation engine. Access has been temporarily restricted due to an excessive number of requests to the translation engine. If you want to use the same translation engine, please wait for a while, restart VRCT, and try again.
-
- detected_by_word_filter: The word %{detected_message} has not been sent due to detection by the word filter.
-
- selected_your_language: "\"Your Language\" has set to %{your_language}."
- selected_target_language: "\"Target Language\" has set to %{target_language}."
- switched_language_preset_tab: Switched to Language Preset Tab No.%{tab_no}."
- latest_language_setting: "Currently, \"Your Language\" is set to %{your_language}, and \"Target Language\" is set to %{target_language}."
-
- opened_web_page_booth: Opened Booth page in your web browser.
- opened_web_page_vrct_documents: "Opened VRCT Documents page in your web browser.\nFor any issues, requests, or inquiries, please feel free to contact us through the links at the bottom of the documents page, the \"Contact Form,\" or via X (formerly Twitter)!"
-
- update_available: New version is here!
- state_text_enabled: Enabled
- state_text_disabled: Disabled
-
- cover_message: The functionality is temporarily disabled until the settings window is closed.
-
- confirmation_message:
- update_software: "Download the new version and automatically restart the app.\nIt'll take a while. Do it now?"
- deny_update_software: Do it later
- accept_update_software: Update and Restart
- updating: Now updating...
-
- detected_over_ui_size: "Current UI Size: %{current_ui_size}\nVRCT's window size may be larger than your display size.\n* Depending on your display size, you may need to adjust it multiple times."
- deny_adjust_ui_size: "Keep it at this size"
- accept_adjust_ui_size: "Set it smaller and restart"
-
-
-selectable_language_window:
- title_your_language: Select Your Language
- title_target_language: Select Target Language
- go_back_button: Go Back
-
-
-overlay_settings:
- restore_default_settings: Restore Default Settings
- opacity: Opacity
- ui_scaling: UI Scaling
- x_position: X-axis (left-right)
- y_position: Y-axis (up-down)
- z_position: Z-axis (front-back)
- x_rotation: X-axis rotation
- y_rotation: Y-axis rotation
- z_rotation: Z-axis rotation
- display_duration: Display duration
- fadeout_duration: Fadeout duration
-
-
-config_window:
- config_title: Settings
- compact_mode: Compact Mode
- version: version %{version}
- restart_message: Apply changes with a restart.
- common_error_message:
- invalid_value: Invalid value.
-
- side_menu_labels:
- appearance: Appearance
- translation: Translation
- transcription: Transcription
- transcription_mic: Mic
- transcription_speaker: Speaker
- transcription_internal_model: Transcription Model
- vr: VR
- others: Others
- others_send_message_formats: Message Formats (Send)
- others_received_message_formats: Message Formats (XSOverlay & Speaker2Chatbox)
- others_speaker2chatbox: Speaker2Chatbox
- advanced_settings: Advanced Settings
-
-
- transparency:
- label: Transparency
- desc: Change the main window's transparency.
-
- appearance_theme:
- label: Theme
- desc: Change the color theme.
-
- ui_size:
- label: UI Size
-
- textbox_ui_size:
- label: Text Box Font Size
- desc: You can adjust the font size used in the logs relative to the UI size.
-
- message_box_ratio:
- label: Message Box Size
- desc: "You can change the size of the input message box. It is in ratio to the text box.\n*No exact calculations."
-
- font_family:
- label: Font Family
-
- ui_language:
- label: UI Language
-
- to_restore_main_window_geometry:
- label: Remember The Main Window Position
- desc: Restore the position and size of the previous window upon startup.
-
- use_translation_feature:
- label: Use Translation Feature
- desc: You can't use the translation feature while this is turned off. Instead, the VRCT startup becomes a little faster. This is for users who don't need the translation feature and only use VRCT as a chatbox and transcription tool.
-
- ctranslate2_weight_type:
- label: Select Internal Translation Model
- desc: You can choose the translation model to use for the internal translation engine.
- small: "Basic model (%{capacity})"
- large: "High accuracy model (%{capacity})"
-
- deepl_auth_key:
- label: DeepL Auth Key
- desc: Please select %{translator} on the main screen with DeepL_API when using. ※Some languages may not be supported.
- open_auth_key_webpage: Open DeepL Account Webpage
- auth_key_success: Auth key update completed.
- auth_key_error: Auth Key is incorrect or Usage limit reached.
-
- mic_host:
- label: Mic Host/Driver
-
- mic_device:
- label: Mic Device
-
- mic_dynamic_energy_threshold:
- label_for_automatic: "Mic Energy Threshold (Current Setting: Automatic)"
- desc_for_automatic: "Automatically determine microphone input sensitivity."
- label_for_manual: "Mic Energy Threshold (Current Setting: Manual)"
- desc_for_manual: "Manually determine the microphone input sensitivity using the slider. Press the microphone icon to input your voice and adjust the sensitivity while monitoring the volume."
- error_message: You can set it with a value between 0 to %{max}.
-
- mic_record_timeout:
- label: Mic Record Timeout
- desc: Detects silence and, when the specified number of seconds has passed, considers the mic input to have ended. (Second(s))
- error_message: It cannot be greater than '%{mic_phrase_timeout_label}' with a value of 0 or more.
-
- mic_phrase_timeout:
- label: Mic Phrase Timeout
- desc: Transcription processing is performed at intervals of the specified number of seconds.
- error_message: It cannot be set lower than '%{mic_record_timeout_label}' with a value of 0 or more.
-
- mic_max_phrase:
- label: Mic Max Words
- desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs and send to VRChat.
- error_message: You can set a number equal to or greater than 0.
-
- mic_word_filter:
- label: Mic Word Filter
- desc: "If a registered word is detected, the text will not be sent. To add multiple words at once, separate them with a \",\" (comma). \n*Duplicate words will not be registered."
- add_button_label: Add
- count_desc: "Current registered word count: %{count}"
-
-
- speaker_device:
- label: Speaker Device
-
- speaker_dynamic_energy_threshold:
- label_for_automatic: "Speaker Energy Threshold (Current Setting: Automatic)"
- desc_for_automatic: "Automatically determine speaker input sensitivity."
- label_for_manual: "Speaker Energy Threshold (Current Setting: Manual)"
- desc_for_manual: "Manually determine the speaker input sensitivity using the slider. Press the headphones icon to listen to the audio and adjust the sensitivity while monitoring the volume."
- error_message: You can set it with a value between 0 to %{max}.
- no_device_error_message: No speaker device detected.
-
- speaker_record_timeout:
- label: Speaker Record Timeout
- desc: Detects silence and, when the specified number of seconds has passed, considers the speaker input to have ended. (Second(s))
- error_message: It cannot be greater than '%{speaker_phrase_timeout_label}' with a value of 0 or more.
-
- speaker_phrase_timeout:
- label: Speaker Phrase Timeout
- desc: Transcription processing is performed at intervals of the specified number of seconds.
- error_message: It cannot be set lower than '%{speaker_record_timeout_label}' with a value of 0 or more.
-
- speaker_max_phrase:
- label: Speaker Max Words
- desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs.
- error_message: You can set a number equal to or greater than 0.
-
- use_whisper_feature:
- label: Use Whisper Model As Transcription
- desc: In some languages, the accuracy of speech recognition may improve. During speech recognition usage, CPU usage increases, so please consider your PC specs before using this feature.
-
- whisper_weight_type:
- label: Select Whisper Model
- desc: "Generally, models with larger capacity tend to have higher accuracy, but this also results in longer transcription times and increased CPU usage. Please refer to the documentation for explanations of each model.\n※Larger models, especially those exceeding medium size, can be challenging to run even depending on the CPU's performance."
- model_template: "%{model_name} model (%{capacity})"
- recommended_model_template: "%{model_name} model (%{capacity}) (Recommended)"
-
-
- enable_overlay_small_log:
- label: Enable Overlay
- # desc:
- open_overlay_settings: Open Overlay Customized Settings
-
- auto_clear_the_message_box:
- label: Auto Clear The Message Box
-
- send_only_translated_messages:
- label: Send Only Translated Messages
-
- send_message_button_type:
- label: Send Message Button
- hide: Hide (Use enter key to send)
- show: Show
- show_and_disable_enter_key: Show and disable to send when pressed enter key
-
- notice_xsoverlay:
- label: Notification XSOverlay
- desc: Notify received messages by using XSOverlay's notification feature.
-
- auto_export_message_logs:
- label: Auto Export Message Logs
- desc: Automatically export the conversation messages as a text file.
-
- vrc_mic_mute_sync:
- label: VRC Mic Mute Sync
- desc: "VRCT will not send the message to VRChat while VRChat's mic is muted.\n*There is a bit latency and Push-To-Talk is not supported."
-
- send_message_to_vrc:
- label: Send Message To VRChat
- desc: There is a way to use it without sending messages to VRChat, but it is not supported. Enable this feature when you intend to send a message to VRChat.
-
-
- send_message_format:
- label: Message Format
- desc: "You can change the decoration of the message you want to send.\n[message] will be replaced with the message."
- example_text: This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.
- error_message: "Cannot use the term '[message]'."
-
- send_message_format_with_t:
- label: Message Format (with Translation)
- desc: "You can change the decoration of the message you want to send.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message."
- example_text: This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.
- error_message: "Cannot use the terms '[message]' and '[translation]'."
-
- received_message_format:
- label: Format of Received Messages
- desc: "Used for XSOverlay notification receiving feature.\n[message] will be replaced with the message. \n※It will be used in Speaker2Chatbox too."
- example_text: This is an example sentence. Actual display may vary, including font and line breaks.
- error_message: "Cannot use the term '[message]'."
-
- received_message_format_with_t:
- label: Format of Received Messages (with Translation)
- desc: "Used for XSOverlay notification receiving feature.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message.\n※It will be used in Speaker2Chatbox too."
- example_text: This is an example sentence. Actual display may vary, including font and line breaks.
- error_message: "Cannot use the terms '[message]' and '[translation]'."
-
-
- # Note: Speaker2Chatbox localization is fine only in English. Do not translate it into other languages.
- # Speaker2Chatbox
- send_received_message_to_vrc:
- label: Send Received Message To VRChat
- desc: Send the message you received from the speaker's sound to VRChat's chatbox. However, this feature is intended for users who genuinely need it. Please consult with the developer.
- # Speaker2Chatbox
-
-
- osc_ip_address:
- label: OSC IP Address
-
- osc_port:
- label: OSC Port
-
- open_config_filepath:
- label: Open Config File
\ No newline at end of file
diff --git a/locales/ja.json b/locales/ja.json
new file mode 100644
index 00000000..d74b7413
--- /dev/null
+++ b/locales/ja.json
@@ -0,0 +1,274 @@
+{
+ "main_window": {
+ "translation": "翻訳",
+ "transcription_send": "音声認識(マイク)",
+ "transcription_receive": "音声認識(スピーカー)",
+ "foreground": "最前面表示",
+ "language_settings": "言語設定",
+ "your_language": "あなたの言語",
+ "translate_each_other_label": "双方向に翻訳",
+ "swap_button_label": "言語を入れ替え",
+ "target_language": "相手の言語",
+ "translator": "翻訳エンジン",
+ "translator_ctranslate2": "オフライン翻訳 (Default)",
+ "textbox_tab_all": "全て",
+ "textbox_tab_sent": "送信",
+ "textbox_tab_received": "受信",
+ "textbox_tab_system": "システム",
+ "textbox_system_message": {
+ "enabled_translation": "翻訳機能をONにしました。",
+ "disabled_translation": "翻訳機能をOFFしました。",
+ "enabled_voice2chatbox": "マイクからの音声入力、文字起こしを開始します。",
+ "disabled_voice2chatbox": "マイクからの音声入力、文字起こしを終了しました。",
+ "enabled_speaker2log": "スピーカーからの音声聞き取り、文字起こしを開始します。",
+ "disabled_speaker2log": "スピーカーからの音声聞き取り、文字起こしを終了しました。",
+ "enabled_foreground": "画面を常に最前面へ固定します。",
+ "disabled_foreground": "最前面への固定を解除しました。",
+ "auth_key_success": "認証キーの更新が完了しました。",
+ "auth_key_error": "認証キーが間違っているか、API使用制限が上限に達しています。",
+ "no_mic_device_detected_error": "マイクデバイスが検出されませんでした。",
+ "no_speaker_device_detected_error": "スピーカーデバイスが検出されませんでした。",
+ "translation_engine_limit_error": "翻訳エンジンを自動的に変更しました。対象翻訳エンジンへのリクエストが多すぎるため、一時的にアクセスが制限されています。同じ翻訳エンジンを使用したい場合はしばらく待ってから、VRCTの再起動をしてもう一度試してみてください。",
+ "detected_by_word_filter": "ワードフィルターに登録されている単語 %{detected_message} が検出されたため送信しませんでした。",
+ "selected_your_language": "「あなたの言語」 を %{your_language} に設定しました。",
+ "selected_target_language": "「相手の言語」 を %{target_language} に設定しました。",
+ "switched_language_preset_tab": "言語プリセット番号 %{tab_no} に切り替わりました。",
+ "latest_language_setting": "現在「あなたの言語」は %{your_language}、「相手の言語」は %{target_language} に設定されています。",
+ "opened_web_page_booth": "お使いのブラウザで、Boothのページを開きました。",
+ "opened_web_page_vrct_documents": "お使いのブラウザで、VRCTのドキュメントを開きました。使用方法などはそちらに記載されています。\n不具合、ご要望、その他お問い合わせはドキュメント最下部にあるLinks、「お問合せフォーム」もしくはX (元Twitter) にて気軽にご連絡ください!"
+ },
+ "update_available": "新しいバージョンが出ました!",
+ "state_text_enabled": "有効",
+ "state_text_disabled": "無効",
+ "cover_message": "設定画面が閉じられるまで、一時的に機能を停止しています。",
+ "confirmation_message": {
+ "update_software": "新しいバージョンをダウンロードしてアプリを再起動します。\n少し時間がかかります。今すぐ行いますか?",
+ "deny_update_software": "後でする",
+ "accept_update_software": "アップデートして再起動",
+ "updating": "アップデート中...",
+ "detected_over_ui_size": "現在のUI サイズ: %{current_ui_size}\nVRCTのウィンドウサイズが、お使いのディスプレイサイズより大きい可能性があります。\n※ディスプレイサイズによっては、何度か再設定が必要な場合があります。",
+ "deny_adjust_ui_size": "このサイズのままで良い",
+ "accept_adjust_ui_size": "小さく設定して再起動"
+ }
+ },
+ "selectable_language_window": {
+ "title_your_language": "あなたの言語",
+ "title_target_language": "相手の言語",
+ "go_back_button": "戻る"
+ },
+ "overlay_settings": {
+ "restore_default_settings": "初期値に戻す",
+ "opacity": "透明度",
+ "ui_scaling": "サイズ",
+ "x_position": "X軸(左右)",
+ "y_position": "Y軸(上下)",
+ "z_position": "Z軸(前後)",
+ "x_rotation": "X軸の回転",
+ "y_rotation": "Y軸の回転",
+ "z_rotation": "Z軸の回転",
+ "display_duration": "表示時間",
+ "fadeout_duration": "フェードアウト時間"
+ },
+ "config_window": {
+ "config_title": "設定",
+ "compact_mode": "コンパクトモード",
+ "version": "バージョン %{version}",
+ "restart_message": "再起動して変更を適用する。",
+ "common_error_message": {
+ "invalid_value": "無効な値です。"
+ },
+ "side_menu_labels": {
+ "appearance": "デザイン",
+ "translation": "翻訳",
+ "transcription": "音声認識",
+ "transcription_mic": "マイク",
+ "transcription_speaker": "スピーカー",
+ "transcription_internal_model": "音声認識モデル",
+ "others": "その他",
+ "others_send_message_formats": "メッセージフォーマット (送信)",
+ "others_received_message_formats": "メッセージフォーマット (XSOverlay & Speaker2Chatbox)",
+ "advanced_settings": "高度な設定"
+ },
+ "transparency": {
+ "label": "透明度",
+ "desc": "メイン画面の透明度を変更できます。"
+ },
+ "appearance_theme": {
+ "label": "外観テーマ",
+ "desc": "カラーテーマを変更できます。"
+ },
+ "ui_size": {
+ "label": "UIサイズ"
+ },
+ "textbox_ui_size": {
+ "label": "テキストボックス フォントサイズ",
+ "desc": "ログに表示されるフォントのサイズを、UIサイズを基準にして倍率を変えられます。"
+ },
+ "message_box_ratio": {
+ "label": "メッセージ入力欄のサイズ",
+ "desc": "メッセージ入力欄のサイズを変更できます。テキストボックスとの比率となっています。\n※厳密な計算はしていません。"
+ },
+ "font_family": {
+ "label": "使用フォント"
+ },
+ "ui_language": {
+ "label": "UIの言語 / UI Language"
+ },
+ "to_restore_main_window_geometry": {
+ "label": "メイン画面の位置を記憶する",
+ "desc": "起動時、前回の画面の位置とサイズを復元します。"
+ },
+ "use_translation_feature": {
+ "label": "翻訳機能を使用する",
+ "desc": "オフにしている間は、翻訳機能を使わない代わり、VRCTの起動が少し速くなります。\n翻訳機能を必要とせず、VRCTをチャット送信と文字起こしツールとしてのみ使用するユーザー用です。"
+ },
+ "ctranslate2_weight_type": {
+ "label": "オフライン翻訳のタイプ",
+ "desc": "翻訳エンジン(オフライン翻訳)で翻訳する際に、使用する翻訳モデルを選択できます。",
+ "small": "通常モデル (%{capacity})",
+ "large": "高精度モデル (%{capacity})"
+ },
+ "deepl_auth_key": {
+ "label": "DeepL 認証キー",
+ "desc": "使用の際は、メイン画面にある %{translator} をDeepL_APIに変更してください。\n※対応していない言語もあります。",
+ "open_auth_key_webpage": "DeepLアカウントページを開く",
+ "auth_key_success": "認証キーの更新が完了しました。",
+ "auth_key_error": "認証キーが間違っているか、API使用制限が上限に達しています。"
+ },
+ "mic_host": {
+ "label": "マイク(ホスト/ドライバー)"
+ },
+ "mic_device": {
+ "label": "マイク (デバイス)"
+ },
+ "mic_dynamic_energy_threshold": {
+ "label_for_automatic": "マイク入力感度の調整 (現在の設定: 自動)",
+ "desc_for_automatic": "マイクの入力感度を自動的に調節する。",
+ "label_for_manual": "マイク入力感度の調整 (現在の設定: 手動)",
+ "desc_for_manual": "スライダーを調整して入力感度を手動で決められます。マイクのアイコンを押すと、実際に声を入力し、音量を確認しながら調節できます。",
+ "error_message": "0 から %{max} までの数値で設定できます。"
+ },
+ "mic_record_timeout": {
+ "label": "入力が終了したとみなす無音時間",
+ "desc": "無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。",
+ "error_message": "0 以上で 「%{mic_phrase_timeout_label}」より大きくすることはできません。"
+ },
+ "mic_phrase_timeout": {
+ "label": "一度に文字起こしする時間の長さ",
+ "desc": "設定された秒数ごとに文字起こし処理が行われます。",
+ "error_message": "0 以上で 「%{mic_record_timeout_label}」より小さくすることはできません。"
+ },
+ "mic_max_phrase": {
+ "label": "送信するまでに保持する単語数",
+ "desc": "文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をVRChatへ送信し、ログに表示します。",
+ "error_message": "0以上の数値を設定できます。"
+ },
+ "mic_word_filter": {
+ "label": "ワードフィルター",
+ "desc": "登録された単語を検出すると、その文章は送信されません。\n「,」カンマで区切ると、まとめて複数の単語を追加できます。\n※重複した単語は登録されません。",
+ "add_button_label": "追加",
+ "count_desc": "現在登録されている単語数: %{count}"
+ },
+ "speaker_device": {
+ "label": "スピーカー (デバイス)"
+ },
+ "speaker_dynamic_energy_threshold": {
+ "label_for_automatic": "スピーカー入力感度の調整 (現在の設定: 自動)",
+ "desc_for_automatic": "スピーカーの入力感度を自動的に調節する。",
+ "label_for_manual": "スピーカー入力感度の調整 (現在の設定: 手動)",
+ "desc_for_manual": "スライダーを調整して入力感度を手動で決められます。ヘッドフォンのアイコンを押すと、実際に音声を聞き取り、音量を確認しながら調節できます。",
+ "error_message": "0 から %{max} までの数値で設定できます。",
+ "no_device_error_message": "スピーカーデバイスが検出されませんでした。"
+ },
+ "speaker_record_timeout": {
+ "label": "入力が終了したとみなす無音時間",
+ "desc": "無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。",
+ "error_message": "0 以上で 「%{speaker_phrase_timeout_label}」より大きくすることはできません。"
+ },
+ "speaker_phrase_timeout": {
+ "label": "一度に文字起こしする時間の長さ",
+ "desc": "設定された秒数ごとに文字起こし処理が行われます。",
+ "error_message": "0 以上で 「%{speaker_record_timeout_label}」より小さくすることはできません。"
+ },
+ "speaker_max_phrase": {
+ "label": "ログとして表示するまでに保持する単語数",
+ "desc": "文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をログに表示します。",
+ "error_message": "0以上の数値を設定できます。"
+ },
+ "use_whisper_feature": {
+ "label": "音声認識にWhisperモデルを使用する",
+ "desc": "一部の言語では、音声認識の精度が向上するかもしれません。音声認識使用中、CPUの使用率が上がるので、お使いのPCスペックと相談してこの機能を使用してください。"
+ },
+ "whisper_weight_type": {
+ "label": "Whisperモデルのタイプ",
+ "desc": "基本的に、容量が多いモデルほど精度は高いですが、文字起こしまでの時間が伸び、CPU使用率も増加します。各モデルの説明はドキュメントをご覧ください。\n※特にmediumより容量の大きいモデルは、CPUの性能によっては使用すらも困難です。",
+ "model_template": "%{model_name} モデル (%{capacity})",
+ "recommended_model_template": "%{model_name} モデル (%{capacity}) (推奨)"
+ },
+ "enable_overlay_small_log": {
+ "label": "Overlay機能を有効",
+ "open_overlay_settings": "Overlay詳細設定を開く"
+ },
+ "auto_clear_the_message_box": {
+ "label": "送信後はチャットボックスを空にする"
+ },
+ "send_only_translated_messages": {
+ "label": "翻訳後のメッセージのみ送信する"
+ },
+ "send_message_button_type": {
+ "label": "メッセージ送信ボタン",
+ "hide": "非表示 (エンターキーを使って送信)",
+ "show": "表示",
+ "show_and_disable_enter_key": "表示し、エンターキーでの送信を無効"
+ },
+ "notice_xsoverlay": {
+ "label": "XSOverlayでの通知受け取り機能を有効",
+ "desc": "文字起こし (受信) されたメッセージをXSOverlayの機能を使って通知として受け取れます。"
+ },
+ "auto_export_message_logs": {
+ "label": "会話ログを自動的に保存する",
+ "desc": "テキストファイルとしてログがlogsフォルダ内に保存されます。"
+ },
+ "vrc_mic_mute_sync": {
+ "label": "VRCマイクミュート同期",
+ "desc": "VRChatのマイクがミュートされている間は、メッセージをVRChatに送信しません。\n※若干の遅延はあります。また、Push-To-Talkは非対応です。"
+ },
+ "send_message_to_vrc": {
+ "label": "VRChatにメッセージを送信する",
+ "desc": "サポート対象外ですが、VRChatにメッセージを送信せずに使う方法があります。送信したい場合、この機能を有効にする事を忘れないでください。"
+ },
+ "send_message_format": {
+ "label": "送信するメッセージのフォーマット",
+ "desc": "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換されます。",
+ "example_text": "これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。",
+ "error_message": "[message]という文字は使えません。"
+ },
+ "send_message_format_with_t": {
+ "label": "送信するメッセージのフォーマット(翻訳付き)",
+ "desc": "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、[translation]が翻訳されたメッセージに置換されます。",
+ "example_text": "これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。",
+ "error_message": "[message]と[translation]という文字は使えません。"
+ },
+ "received_message_format": {
+ "label": "受信するメッセージのフォーマット",
+ "desc": "XSOverlay通知受け取り機能で使用されます。\n[message]がメッセージに置換されます。\n※Speaker2Chatboxでの送信機能にも使われます。",
+ "example_text": "これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。",
+ "error_message": "[message]という文字は使えません。"
+ },
+ "received_message_format_with_t": {
+ "label": "受信するメッセージのフォーマット(翻訳付き)",
+ "desc": "XSOverlay通知受け取り機能で使用されます。\n[message]がメッセージに置換され、[translation]が翻訳されたメッセージに置換されます。\n※Speaker2Chatboxでの送信機能にも使われます。",
+ "example_text": "これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。",
+ "error_message": "[message]と[translation]という文字は使えません。"
+ },
+ "osc_ip_address": {
+ "label": "OSC IP Address"
+ },
+ "osc_port": {
+ "label": "OSC Port"
+ },
+ "open_config_filepath": {
+ "label": "設定ファイルを開く"
+ }
+ }
+}
\ No newline at end of file
diff --git a/locales/ja.yml b/locales/ja.yml
deleted file mode 100644
index 93eb8757..00000000
--- a/locales/ja.yml
+++ /dev/null
@@ -1,292 +0,0 @@
-main_window:
- translation: 翻訳
- transcription_send: 音声認識(マイク)
- transcription_receive: 音声認識(スピーカー)
- foreground: 最前面表示
-
- language_settings: 言語設定
- your_language: あなたの言語
- translate_each_other_label: 双方向に翻訳
- swap_button_label: 言語を入れ替え
- target_language: 相手の言語
- translator: 翻訳エンジン
- translator_ctranslate2: オフライン翻訳 (Default)
-
- textbox_tab_all: 全て
- textbox_tab_sent: 送信
- textbox_tab_received: 受信
- textbox_tab_system: システム
-
- textbox_system_message:
- enabled_translation: 翻訳機能をONにしました。
- disabled_translation: 翻訳機能をOFFしました。
- enabled_voice2chatbox: マイクからの音声入力、文字起こしを開始します。
- disabled_voice2chatbox: マイクからの音声入力、文字起こしを終了しました。
- enabled_speaker2log: スピーカーからの音声聞き取り、文字起こしを開始します。
- disabled_speaker2log: スピーカーからの音声聞き取り、文字起こしを終了しました。
- enabled_foreground: 画面を常に最前面へ固定します。
- disabled_foreground: 最前面への固定を解除しました。
-
- auth_key_success: 認証キーの更新が完了しました。
- auth_key_error: 認証キーが間違っているか、API使用制限が上限に達しています。
-
- no_mic_device_detected_error: マイクデバイスが検出されませんでした。
- no_speaker_device_detected_error: スピーカーデバイスが検出されませんでした。
- translation_engine_limit_error: 翻訳エンジンを自動的に変更しました。対象翻訳エンジンへのリクエストが多すぎるため、一時的にアクセスが制限されています。同じ翻訳エンジンを使用したい場合はしばらく待ってから、VRCTの再起動をしてもう一度試してみてください。
-
- detected_by_word_filter: ワードフィルターに登録されている単語 %{detected_message} が検出されたため送信しませんでした。
-
- selected_your_language: 「あなたの言語」 を %{your_language} に設定しました。
- selected_target_language: 「相手の言語」 を %{target_language} に設定しました。
- switched_language_preset_tab: 言語プリセット番号 %{tab_no} に切り替わりました。
- latest_language_setting: 現在「あなたの言語」は %{your_language}、「相手の言語」は %{target_language} に設定されています。
-
- opened_web_page_booth: お使いのブラウザで、Boothのページを開きました。
- opened_web_page_vrct_documents: "お使いのブラウザで、VRCTのドキュメントを開きました。使用方法などはそちらに記載されています。\n不具合、ご要望、その他お問い合わせはドキュメント最下部にあるLinks、「お問合せフォーム」もしくはX (元Twitter) にて気軽にご連絡ください!"
-
- update_available: 新しいバージョンが出ました!
- state_text_enabled: 有効
- state_text_disabled: 無効
-
- cover_message: 設定画面が閉じられるまで、一時的に機能を停止しています。
-
- confirmation_message:
- update_software: "新しいバージョンをダウンロードしてアプリを再起動します。\n少し時間がかかります。今すぐ行いますか?"
- deny_update_software: 後でする
- accept_update_software: アップデートして再起動
- updating: アップデート中...
-
- detected_over_ui_size: "現在のUI サイズ: %{current_ui_size}\nVRCTのウィンドウサイズが、お使いのディスプレイサイズより大きい可能性があります。\n※ディスプレイサイズによっては、何度か再設定が必要な場合があります。"
- deny_adjust_ui_size: このサイズのままで良い
- accept_adjust_ui_size: 小さく設定して再起動
-
-
-selectable_language_window:
- title_your_language: あなたの言語
- title_target_language: 相手の言語
- go_back_button: 戻る
-
-
-overlay_settings:
- restore_default_settings: 初期値に戻す
- opacity: 透明度
- ui_scaling: サイズ
- x_position: X軸(左右)
- y_position: Y軸(上下)
- z_position: Z軸(前後)
- x_rotation: X軸の回転
- y_rotation: Y軸の回転
- z_rotation: Z軸の回転
- display_duration: 表示時間
- fadeout_duration: フェードアウト時間
-
-
-config_window:
- config_title: 設定
- compact_mode: コンパクトモード
- version: バージョン %{version}
- restart_message: 再起動して変更を適用する。
- common_error_message:
- invalid_value: 無効な値です。
-
- side_menu_labels:
- appearance: デザイン
- translation: 翻訳
- transcription: 音声認識
- transcription_mic: マイク
- transcription_speaker: スピーカー
- transcription_internal_model: 音声認識モデル
- others: その他
- others_send_message_formats: メッセージフォーマット (送信)
- others_received_message_formats: メッセージフォーマット (XSOverlay & Speaker2Chatbox)
- advanced_settings: 高度な設定
-
-
- transparency:
- label: 透明度
- desc: メイン画面の透明度を変更できます。
-
- appearance_theme:
- label: 外観テーマ
- desc: カラーテーマを変更できます。
-
- ui_size:
- label: UIサイズ
-
- textbox_ui_size:
- label: テキストボックス フォントサイズ
- desc: ログに表示されるフォントのサイズを、UIサイズを基準にして倍率を変えられます。
-
- message_box_ratio:
- label: メッセージ入力欄のサイズ
- desc: "メッセージ入力欄のサイズを変更できます。テキストボックスとの比率となっています。\n※厳密な計算はしていません。"
-
- font_family:
- label: 使用フォント
-
- ui_language:
- label: UIの言語 / UI Language
-
- to_restore_main_window_geometry:
- label: メイン画面の位置を記憶する
- desc: 起動時、前回の画面の位置とサイズを復元します。
-
- use_translation_feature:
- label: 翻訳機能を使用する
- desc: "オフにしている間は、翻訳機能を使わない代わり、VRCTの起動が少し速くなります。\n翻訳機能を必要とせず、VRCTをチャット送信と文字起こしツールとしてのみ使用するユーザー用です。"
-
- ctranslate2_weight_type:
- label: オフライン翻訳のタイプ
- desc: 翻訳エンジン(オフライン翻訳)で翻訳する際に、使用する翻訳モデルを選択できます。
- small: "通常モデル (%{capacity})"
- large: "高精度モデル (%{capacity})"
-
- deepl_auth_key:
- label: DeepL 認証キー
- desc: "使用の際は、メイン画面にある %{translator} をDeepL_APIに変更してください。\n※対応していない言語もあります。"
- open_auth_key_webpage: DeepLアカウントページを開く
- auth_key_success: 認証キーの更新が完了しました。
- auth_key_error: 認証キーが間違っているか、API使用制限が上限に達しています。
-
- mic_host:
- label: マイク(ホスト/ドライバー)
-
- mic_device:
- label: マイク (デバイス)
-
- mic_dynamic_energy_threshold:
- label_for_automatic: "マイク入力感度の調整 (現在の設定: 自動)"
- desc_for_automatic: マイクの入力感度を自動的に調節する。
- label_for_manual: "マイク入力感度の調整 (現在の設定: 手動)"
- desc_for_manual: スライダーを調整して入力感度を手動で決められます。マイクのアイコンを押すと、実際に声を入力し、音量を確認しながら調節できます。
- error_message: 0 から %{max} までの数値で設定できます。
-
- mic_record_timeout:
- label: 入力が終了したとみなす無音時間
- desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。
- error_message: 0 以上で 「%{mic_phrase_timeout_label}」より大きくすることはできません。
-
- mic_phrase_timeout:
- label: 一度に文字起こしする時間の長さ
- desc: 設定された秒数ごとに文字起こし処理が行われます。
- error_message: 0 以上で 「%{mic_record_timeout_label}」より小さくすることはできません。
-
- mic_max_phrase:
- label: 送信するまでに保持する単語数
- desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をVRChatへ送信し、ログに表示します。
- error_message: 0以上の数値を設定できます。
-
- mic_word_filter:
- label: ワードフィルター
- desc: "登録された単語を検出すると、その文章は送信されません。\n「,」カンマで区切ると、まとめて複数の単語を追加できます。\n※重複した単語は登録されません。"
- add_button_label: 追加
- count_desc: "現在登録されている単語数: %{count}"
-
-
- speaker_device:
- label: スピーカー (デバイス)
-
- speaker_dynamic_energy_threshold:
- label_for_automatic: "スピーカー入力感度の調整 (現在の設定: 自動)"
- desc_for_automatic: スピーカーの入力感度を自動的に調節する。
- label_for_manual: "スピーカー入力感度の調整 (現在の設定: 手動)"
- desc_for_manual: スライダーを調整して入力感度を手動で決められます。ヘッドフォンのアイコンを押すと、実際に音声を聞き取り、音量を確認しながら調節できます。
- error_message: 0 から %{max} までの数値で設定できます。
- no_device_error_message: スピーカーデバイスが検出されませんでした。
-
- speaker_record_timeout:
- label: 入力が終了したとみなす無音時間
- desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。
- error_message: 0 以上で 「%{speaker_phrase_timeout_label}」より大きくすることはできません。
-
- speaker_phrase_timeout:
- label: 一度に文字起こしする時間の長さ
- desc: 設定された秒数ごとに文字起こし処理が行われます。
- error_message: 0 以上で 「%{speaker_record_timeout_label}」より小さくすることはできません。
-
- speaker_max_phrase:
- label: ログとして表示するまでに保持する単語数
- desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をログに表示します。
- error_message: 0以上の数値を設定できます。
-
- use_whisper_feature:
- label: 音声認識にWhisperモデルを使用する
- desc: 一部の言語では、音声認識の精度が向上するかもしれません。音声認識使用中、CPUの使用率が上がるので、お使いのPCスペックと相談してこの機能を使用してください。
-
- whisper_weight_type:
- label: Whisperモデルのタイプ
- desc: "基本的に、容量が多いモデルほど精度は高いですが、文字起こしまでの時間が伸び、CPU使用率も増加します。各モデルの説明はドキュメントをご覧ください。\n※特にmediumより容量の大きいモデルは、CPUの性能によっては使用すらも困難です。"
- model_template: "%{model_name} モデル (%{capacity})"
- recommended_model_template: "%{model_name} モデル (%{capacity}) (推奨)"
-
-
- enable_overlay_small_log:
- label: Overlay機能を有効
- # desc:
- open_overlay_settings: Overlay詳細設定を開く
-
-
-
- auto_clear_the_message_box:
- label: 送信後はチャットボックスを空にする
-
- send_only_translated_messages:
- label: 翻訳後のメッセージのみ送信する
-
- send_message_button_type:
- label: メッセージ送信ボタン
- hide: 非表示 (エンターキーを使って送信)
- show: 表示
- show_and_disable_enter_key: 表示し、エンターキーでの送信を無効
-
- notice_xsoverlay:
- label: XSOverlayでの通知受け取り機能を有効
- desc: 文字起こし (受信) されたメッセージをXSOverlayの機能を使って通知として受け取れます。
-
- auto_export_message_logs:
- label: 会話ログを自動的に保存する
- desc: テキストファイルとしてログがlogsフォルダ内に保存されます。
-
- vrc_mic_mute_sync:
- label: VRCマイクミュート同期
- desc: "VRChatのマイクがミュートされている間は、メッセージをVRChatに送信しません。\n※若干の遅延はあります。また、Push-To-Talkは非対応です。"
-
-
- send_message_to_vrc:
- label: VRChatにメッセージを送信する
- desc: "サポート対象外ですが、VRChatにメッセージを送信せずに使う方法があります。送信したい場合、この機能を有効にする事を忘れないでください。"
-
-
- send_message_format:
- label: 送信するメッセージのフォーマット
- desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換されます。"
- example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
- error_message: "[message]という文字は使えません。"
-
- send_message_format_with_t:
- label: 送信するメッセージのフォーマット(翻訳付き)
- desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、[translation]が翻訳されたメッセージに置換されます。"
- example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
- error_message: "[message]と[translation]という文字は使えません。"
-
- received_message_format:
- label: 受信するメッセージのフォーマット
- desc: "XSOverlay通知受け取り機能で使用されます。\n[message]がメッセージに置換されます。\n※Speaker2Chatboxでの送信機能にも使われます。"
- example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
- error_message: "[message]という文字は使えません。"
-
- received_message_format_with_t:
- label: 受信するメッセージのフォーマット(翻訳付き)
- desc: "XSOverlay通知受け取り機能で使用されます。\n[message]がメッセージに置換され、[translation]が翻訳されたメッセージに置換されます。\n※Speaker2Chatboxでの送信機能にも使われます。"
- example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
- error_message: "[message]と[translation]という文字は使えません。"
-
-
- osc_ip_address:
- label: OSC IP Address
-
- osc_port:
- label: OSC Port
-
- open_config_filepath:
- label: 設定ファイルを開く
\ No newline at end of file
diff --git a/locales/ko.json b/locales/ko.json
new file mode 100644
index 00000000..3329c8d1
--- /dev/null
+++ b/locales/ko.json
@@ -0,0 +1,252 @@
+{
+ "main_window": {
+ "translation": "번역",
+ "transcription_send": "음성인식 (마이크)",
+ "transcription_receive": "음성인식 (스피커)",
+ "foreground": "항상 위로",
+ "language_settings": "언어 설정",
+ "your_language": "당신의 언어",
+ "translate_each_other_label": "양방향으로 번역",
+ "swap_button_label": "언어 교체",
+ "target_language": "상대방의 언어",
+ "translator": "번역 엔진",
+ "translator_ctranslate2": "오프라인 번역 (기본값)",
+ "textbox_tab_all": "전체",
+ "textbox_tab_sent": "전송",
+ "textbox_tab_received": "수신",
+ "textbox_tab_system": "시스템",
+ "textbox_system_message": {
+ "enabled_translation": "번역 기능을 시작합니다.",
+ "disabled_translation": "번역 기능이 중지되었습니다.",
+ "enabled_voice2chatbox": "마이크에서의 음성인식을 시작합니다.",
+ "disabled_voice2chatbox": "마이크에서의 음성인식이 중지되었습니다.",
+ "enabled_speaker2log": "스피커에서의 음성인식을 시작합니다.",
+ "disabled_speaker2log": "스피커에서의 음성인식이 중지되었습니다.",
+ "enabled_foreground": "화면을 항상 위로 고정합니다.",
+ "disabled_foreground": "화면 고정이 해제되었습니다.",
+ "auth_key_success": "인증키 갱신이 완료되었습니다.",
+ "auth_key_error": "인증 키가 잘못되었거나 API 사용 제한이 상한선에 도달했습니다.",
+ "no_mic_device_detected_error": "마이크 디바이스를 찾지 못했습니다.",
+ "no_speaker_device_detected_error": "스피커 디바이스를 찾지 못했습니다.",
+ "translation_engine_limit_error": "번역 엔진을 자동으로 변경했습니다. 대상 번역 엔진에 대한 요청이 너무 많아 일시적으로 접근이 제한되었습니다. 해당 번역 엔진을 사용하려면 잠시 기다린 후 VRCT를 재시작하여 다시 시도해 보시기 바랍니다",
+ "detected_by_word_filter": "단어 필터에 등록된 단어 %{detected_message}(이)가 감지되어 전송하지 않았습니다.",
+ "selected_your_language": "'당신의 언어'가 %{your_language}(으)로 설정되었습니다.",
+ "selected_target_language": "'상대방의 언어'가 %{target_language}(으)로 설정되었습니다.",
+ "switched_language_preset_tab": "언어 프리셋 번호 %{tab_no}로 전환되었습니다.",
+ "latest_language_setting": "현재 '당신의 언어'는 %{your_language}, '상대방의 언어'는 %{target_language}(으)로 설정되어 있습니다.",
+ "opened_web_page_booth": "브라우저에서 Booth 페이지를 열었습니다.",
+ "opened_web_page_vrct_documents": "웹 브라우저에서 VRCT 문서 페이지가 열렸습니다.\n문제, 요청 또는 문의 사항이 있는 경우 문서 페이지 하단의 링크, '문의 양식' 또는 X(구 트위터)를 통해 언제든지 문의해 주세요!"
+ },
+ "update_available": "새로운 버전이 나왔습니다!",
+ "cover_message": "설정 화면이 닫힐 때까지 일시적으로 기능을 정지하고 있습니다.",
+ "confirmation_message": {
+ "update_software": "새 버전을 다운로드하고 재시작합니다. \n 조금 시간이 걸립니다. 지금 시작할까요?",
+ "deny_update_software": "나중에 하기",
+ "accept_update_software": "업데이트 및 재시작",
+ "updating": "업데이트 중...",
+ "detected_over_ui_size": "현재 UI 크기: %{current_ui_size}\nVRCT의 창 크기가 사용자의 디스플레이 크기보다 클 수 있습니다. \n* 디스플레이 크기에 따라 여러 번 재설정해야 할 수도 있습니다.",
+ "deny_adjust_ui_size": "지금 상태를 유지",
+ "accept_adjust_ui_size": "작게 줄이고 재시작"
+ }
+ },
+ "selectable_language_window": {
+ "title_your_language": "당신의 언어",
+ "title_target_language": "상대방의 언어",
+ "go_back_button": "돌아가기"
+ },
+ "config_window": {
+ "config_title": "설정",
+ "compact_mode": "컴팩트 모드",
+ "version": "버전 %{version}",
+ "restart_message": "재시작하여 변경 사항을 적용합니다.",
+ "common_error_message": {
+ "invalid_value": "유효하지 않은 값입니다."
+ },
+ "side_menu_labels": {
+ "appearance": "모양",
+ "translation": "번역",
+ "transcription": "음성인식",
+ "transcription_mic": "마이크",
+ "transcription_speaker": "스피커",
+ "transcription_internal_model": "내부 엔진",
+ "others": "기타",
+ "others_send_message_formats": "메시지 형식 (전송)",
+ "others_received_message_formats": "메시지 형식 (수신)",
+ "others_speaker2chatbox": "스피커->챗박스",
+ "advanced_settings": "고급 설정"
+ },
+ "transparency": {
+ "label": "투명도",
+ "desc": "메인 화면의 투명도를 변경합니다."
+ },
+ "appearance_theme": {
+ "label": "테마",
+ "desc": "색상 테마를 변경합니다."
+ },
+ "ui_size": {
+ "label": "UI 크기"
+ },
+ "textbox_ui_size": {
+ "label": "텍스트 박스 글자 크기",
+ "desc": "로그에 표시되는 글자 크기의 배율을 UI 크기에 따라 변경합니다."
+ },
+ "message_box_ratio": {
+ "label": "메시지 입력란 크기",
+ "desc": "메시지 입력란의 크기를 변경합니다. 텍스트 박스와의 비율로 설정되어 있습니다. \n* 정확한 계산은 하지 않았습니다."
+ },
+ "font_family": {
+ "label": "폰트"
+ },
+ "ui_language": {
+ "label": "UI 언어 / UI Language"
+ },
+ "to_restore_main_window_geometry": {
+ "label": "메인 화면 위치 기억",
+ "desc": "시작 시 이전 화면의 위치와 크기를 복원합니다."
+ },
+ "use_translation_feature": {
+ "label": "번역 기능 사용",
+ "desc": "번역 기능이 꺼져 있는 동안에는 번역을 하지 않는 대신 VRCT가 조금 더 빠르게 실행됩니다. \n 번역 기능이 필요하지 않고 VRCT를 채팅 전송 및 음성 인식 도구로만 사용하는 사용자를 위한 기능입니다."
+ },
+ "ctranslate2_weight_type": {
+ "label": "번역 모델",
+ "desc": "오프라인 번역 시의 번역 모델을 변경합니다.",
+ "small": "일반 모델 (%{capacity})",
+ "large": "정밀 모델 (%{capacity})"
+ },
+ "deepl_auth_key": {
+ "label": "DeepL 인증키",
+ "desc": "사용시 메인화면에 있는 %{translator}를 DeepL_API로 변경해 주세요.\n지원하지 않는 언어도 있습니다.",
+ "open_auth_key_webpage": "DeepL 계정 페이지 열기",
+ "auth_key_success": "인증키 갱신이 완료되었습니다.",
+ "auth_key_error": "인증키가 잘못되었거나 API 사용 제한이 상한에 도달했습니다."
+ },
+ "mic_host": {
+ "label": "마이크 호스트/드라이버"
+ },
+ "mic_device": {
+ "label": "마이크 장치"
+ },
+ "mic_dynamic_energy_threshold": {
+ "label_for_automatic": "음성 입력 최소 볼륨 (현재 설정: 자동)",
+ "desc_for_automatic": "마이크의 입력 감도를 자동으로 조절합니다.",
+ "label_for_manual": "음성 입력 최소 볼륨 (현재 설정: 수동)",
+ "desc_for_manual": "슬라이더를 움직여 입력 감도를 수동으로 조절합니다. 마이크 아이콘을 누르면 실제 음성의 볼륨을 확인하며 감도를 조절할 수 있습니다.",
+ "error_message": "0에서 %{max}까지의 숫자로만 설정할 수 있습니다."
+ },
+ "mic_record_timeout": {
+ "label": "최대 무음 시간",
+ "desc": "무음을 감지하고 설정된 시간(초)만큼의 시간이 지나면 음성 입력이 종료된 것으로 판단합니다.",
+ "error_message": "0 이상에서 '%{mic_phrase_timeout_label}'보다 클 수 없습니다."
+ },
+ "mic_phrase_timeout": {
+ "label": "최대 인식 시간",
+ "desc": "설정된 초 단위로 음성인식 처리가 이루어집니다.",
+ "error_message": "0 이상에서 '%{mic_record_timeout_label}'보다 작을 수 없습니다."
+ },
+ "mic_max_phrase": {
+ "label": "최대 입력 절(phrases) 수",
+ "desc": "인식된 단어 수의 하한값으로, 이 수치를 초과하는 경우에만 결과를 VRChat으로 전송하고 로그에 표시합니다.",
+ "error_message": "0 이상의 숫자만 설정할 수 있습니다."
+ },
+ "mic_word_filter": {
+ "label": "단어 필터",
+ "desc": "등록된 단어가 감지되면 해당 문장은 전송되지 않습니다. \n ',' 쉼표로 구분하면 여러 단어를 추가할 수 있습니다. \n* 중복된 단어는 등록되지 않습니다.",
+ "add_button_label": "추가",
+ "count_desc": "현재 등록되어 있는 단어 수: %{count}"
+ },
+ "speaker_device": {
+ "label": "스피커 장치"
+ },
+ "speaker_dynamic_energy_threshold": {
+ "label_for_automatic": "음성 입력 최소 볼륨 (현재 설정: 자동)",
+ "desc_for_automatic": "스피커의 입력 감도를 자동으로 조절합니다.",
+ "label_for_manual": "음성 입력 최소 볼륨 (현재 설정: 수동)",
+ "desc_for_manual": "슬라이더를 움직여 입력 감도를 수동으로 조절합니다. 헤드폰 아이콘을 누르면 실제 음성의 볼륨을 확인하며 감도를 조절할 수 있습니다.",
+ "error_message": "0에서 %{max}까지의 숫자로만 설정할 수 있습니다.",
+ "no_device_error_message": "스피커 디바이스를 찾지 못했습니다."
+ },
+ "speaker_record_timeout": {
+ "label": "최대 무음 시간",
+ "desc": "무음을 감지하고 설정된 시간(초)만큼의 시간이 지나면 음성 입력이 종료된 것으로 판단합니다.",
+ "error_message": "0 이상에서 '%{speaker_phrase_timeout_label}'보다 클 수 없습니다."
+ },
+ "speaker_phrase_timeout": {
+ "label": "최대 인식 시간",
+ "desc": "설정된 초 단위로 음성인식 처리가 이루어집니다.",
+ "error_message": "0 이상에서 '%{speaker_record_timeout_label}'보다 작을 수 없습니다."
+ },
+ "speaker_max_phrase": {
+ "label": "최대 입력 절(phrases) 수",
+ "desc": "식된 단어 수의 하한값으로, 이 수치를 초과하는 경우에만 결과를 로그에 표시합니다.",
+ "error_message": "0 이상의 숫자만 설정할 수 있습니다."
+ },
+ "use_whisper_feature": {
+ "label": "음성 인식에 Whisper 모델을 사용",
+ "desc": "일부 언어에서는 음성 인식의 정확도가 향상될 수 있어요. 음성 인식 중 CPU 사용률이 올라가기 때문에 사용하시는 PC의 사양을 고려하여 이 기능을 사용해주세요."
+ },
+ "whisper_weight_type": {
+ "label": "Whisper 모델 타입",
+ "desc": "기본적으로 용량이 많은 모델일수록 정밀도는 높지만, 음성 인식의 시간이 늘어나며 CPU 사용률도 늘어나요.각 모델의 설명은 문서를 참조해주세요.\n※특히 medium보다 용량이 큰 모델은 CPU의 성능에 따라서는 사용조차 어려울 수 있어요. ",
+ "model_template": "%{model_name} 모델 (%{capacity})",
+ "recommended_model_template": "%{model_name} 모델 (%{capacity}) (권장)"
+ },
+ "auto_clear_the_message_box": {
+ "label": "챗박스 자동 삭제"
+ },
+ "send_only_translated_messages": {
+ "label": "번역된 메시지만 전송"
+ },
+ "send_message_button_type": {
+ "label": "메시지 전송 버튼",
+ "hide": "숨김 (Enter 키를 사용하여 전송)",
+ "show": "표시",
+ "show_and_disable_enter_key": "표시 (Enter 키 전송 비활성화)"
+ },
+ "notice_xsoverlay": {
+ "label": "XSOverlay에서 알림 수신 기능 활성화",
+ "desc": "수신된 메시지를 XSOverlay의 기능을 통해 알림으로 받아볼 수 있습니다."
+ },
+ "auto_export_message_logs": {
+ "label": "대화 로그 자동 저장",
+ "desc": "logs 폴더에 텍스트 파일로 로그가 저장됩니다."
+ },
+ "send_message_to_vrc": {
+ "label": "VRChat에 메시지 전송",
+ "desc": "VRChat에 메시지를 보내지 않고 사용할 수 있는 방법이 있지만 지원되지 않습니다. VRChat에 메시지를 보내려면 이 기능을 활성화하세요."
+ },
+ "send_message_format": {
+ "label": "메시지 형식",
+ "desc": "메시지가 실제로 보이는 형식을 변경합니다. \n[message]가 메시지로 대체됩니다.",
+ "example_text": "이것은 예문입니다. 폰트, 줄바꿈 등 실제 표시와 다를 수 있습니다.",
+ "error_message": "[message]라는 문자는 사용할 수 없습니다."
+ },
+ "send_message_format_with_t": {
+ "label": "메시지 형식 (번역 포함)",
+ "desc": "메시지가 실제로 보이는 형식을 변경합니다. \n[message]는 메시지로, [translation]은 번역된 메시지로 대체됩니다.\nXSOverlay의 알림에서도 사용됩니다.",
+ "example_text": "예문입니다. 글꼴, 줄 바꿈 등이 실제 표시와 다를 수 있습니다.",
+ "error_message": "[message]와 [translation]이라는 문자는 사용할 수 없습니다."
+ },
+ "received_message_format": {
+ "label": "메시지 형식",
+ "desc": "메시지가 실제로 보이는 형식을 변경합니다. \n[message]가 메시지로 대체됩니다.",
+ "example_text": "이것은 예문입니다. 폰트, 줄바꿈 등 실제 표시와 다를 수 있습니다.",
+ "error_message": "[message]라는 문자는 사용할 수 없습니다."
+ },
+ "received_message_format_with_t": {
+ "label": "메시지 형식 (번역 포함)",
+ "desc": "메시지가 실제로 보이는 형식을 변경합니다. \n[message]는 메시지로, [translation]은 번역된 메시지로 대체됩니다.\nXSOverlay의 알림에서도 사용됩니다.",
+ "example_text": "이것은 예문입니다. 폰트, 줄바꿈 등 실제 표시와 다를 수 있습니다.",
+ "error_message": "[message]와 [translation]이라는 문자는 사용할 수 없습니다."
+ },
+ "osc_ip_address": {
+ "label": "OSC IP 주소"
+ },
+ "osc_port": {
+ "label": "OSC 포트"
+ },
+ "open_config_filepath": {
+ "label": "설정 파일 열기"
+ }
+ }
+}
\ No newline at end of file
diff --git a/locales/ko.yml b/locales/ko.yml
deleted file mode 100644
index ed8f8ddf..00000000
--- a/locales/ko.yml
+++ /dev/null
@@ -1,264 +0,0 @@
-main_window:
- translation: 번역
- transcription_send: 음성인식 (마이크)
- transcription_receive: 음성인식 (스피커)
- foreground: 항상 위로
-
- language_settings: 언어 설정
- your_language: 당신의 언어
- translate_each_other_label: 양방향으로 번역
- swap_button_label: 언어 교체
- target_language: 상대방의 언어
- translator: 번역 엔진
- translator_ctranslate2: 오프라인 번역 (기본값)
-
- textbox_tab_all: 전체
- textbox_tab_sent: 전송
- textbox_tab_received: 수신
- textbox_tab_system: 시스템
-
- textbox_system_message:
- enabled_translation: 번역 기능을 시작합니다.
- disabled_translation: 번역 기능이 중지되었습니다.
- enabled_voice2chatbox: 마이크에서의 음성인식을 시작합니다.
- disabled_voice2chatbox: 마이크에서의 음성인식이 중지되었습니다.
- enabled_speaker2log: 스피커에서의 음성인식을 시작합니다.
- disabled_speaker2log: 스피커에서의 음성인식이 중지되었습니다.
- enabled_foreground: 화면을 항상 위로 고정합니다.
- disabled_foreground: 화면 고정이 해제되었습니다.
-
- auth_key_success: 인증키 갱신이 완료되었습니다.
- auth_key_error: 인증 키가 잘못되었거나 API 사용 제한이 상한선에 도달했습니다.
-
- no_mic_device_detected_error: 마이크 디바이스를 찾지 못했습니다.
- no_speaker_device_detected_error: 스피커 디바이스를 찾지 못했습니다.
- translation_engine_limit_error: 번역 엔진을 자동으로 변경했습니다. 대상 번역 엔진에 대한 요청이 너무 많아 일시적으로 접근이 제한되었습니다. 해당 번역 엔진을 사용하려면 잠시 기다린 후 VRCT를 재시작하여 다시 시도해 보시기 바랍니다
-
- detected_by_word_filter: 단어 필터에 등록된 단어 %{detected_message}(이)가 감지되어 전송하지 않았습니다.
-
- selected_your_language: "'당신의 언어'가 %{your_language}(으)로 설정되었습니다."
- selected_target_language: "'상대방의 언어'가 %{target_language}(으)로 설정되었습니다."
- switched_language_preset_tab: 언어 프리셋 번호 %{tab_no}로 전환되었습니다.
- latest_language_setting: "현재 '당신의 언어'는 %{your_language}, '상대방의 언어'는 %{target_language}(으)로 설정되어 있습니다."
-
- opened_web_page_booth: 브라우저에서 Booth 페이지를 열었습니다.
- opened_web_page_vrct_documents: "웹 브라우저에서 VRCT 문서 페이지가 열렸습니다.\n문제, 요청 또는 문의 사항이 있는 경우 문서 페이지 하단의 링크, '문의 양식' 또는 X(구 트위터)를 통해 언제든지 문의해 주세요!"
-
- update_available: 새로운 버전이 나왔습니다!
-
- cover_message: 설정 화면이 닫힐 때까지 일시적으로 기능을 정지하고 있습니다.
-
- confirmation_message:
- update_software: "새 버전을 다운로드하고 재시작합니다. \n 조금 시간이 걸립니다. 지금 시작할까요?"
- deny_update_software: 나중에 하기
- accept_update_software: 업데이트 및 재시작
- updating: 업데이트 중...
-
- detected_over_ui_size: "현재 UI 크기: %{current_ui_size}\nVRCT의 창 크기가 사용자의 디스플레이 크기보다 클 수 있습니다. \n* 디스플레이 크기에 따라 여러 번 재설정해야 할 수도 있습니다."
- deny_adjust_ui_size: "지금 상태를 유지"
- accept_adjust_ui_size: "작게 줄이고 재시작"
-
-
-selectable_language_window:
- title_your_language: 당신의 언어
- title_target_language: 상대방의 언어
- go_back_button: 돌아가기
-
-
-config_window:
- config_title: 설정
- compact_mode: 컴팩트 모드
- version: 버전 %{version}
- restart_message: 재시작하여 변경 사항을 적용합니다.
- common_error_message:
- invalid_value: 유효하지 않은 값입니다.
-
- side_menu_labels:
- appearance: 모양
- translation: 번역
- transcription: 음성인식
- transcription_mic: 마이크
- transcription_speaker: 스피커
- transcription_internal_model: 내부 엔진
- others: 기타
- others_send_message_formats: 메시지 형식 (전송)
- others_received_message_formats: 메시지 형식 (수신)
- others_speaker2chatbox: 스피커->챗박스
- advanced_settings: 고급 설정
-
-
- transparency:
- label: 투명도
- desc: 메인 화면의 투명도를 변경합니다.
-
- appearance_theme:
- label: 테마
- desc: 색상 테마를 변경합니다.
-
- ui_size:
- label: UI 크기
-
- textbox_ui_size:
- label: 텍스트 박스 글자 크기
- desc: 로그에 표시되는 글자 크기의 배율을 UI 크기에 따라 변경합니다.
-
- message_box_ratio:
- label: 메시지 입력란 크기
- desc: "메시지 입력란의 크기를 변경합니다. 텍스트 박스와의 비율로 설정되어 있습니다. \n* 정확한 계산은 하지 않았습니다."
-
- font_family:
- label: 폰트
-
- ui_language:
- label: UI 언어 / UI Language
-
- to_restore_main_window_geometry:
- label: 메인 화면 위치 기억
- desc: 시작 시 이전 화면의 위치와 크기를 복원합니다.
-
- use_translation_feature:
- label: 번역 기능 사용
- desc: "번역 기능이 꺼져 있는 동안에는 번역을 하지 않는 대신 VRCT가 조금 더 빠르게 실행됩니다. \n 번역 기능이 필요하지 않고 VRCT를 채팅 전송 및 음성 인식 도구로만 사용하는 사용자를 위한 기능입니다."
-
- ctranslate2_weight_type:
- label: 번역 모델
- desc: "오프라인 번역 시의 번역 모델을 변경합니다."
- small: "일반 모델 (%{capacity})"
- large: "정밀 모델 (%{capacity})"
-
- deepl_auth_key:
- label: DeepL 인증키
- desc: "사용시 메인화면에 있는 %{translator}를 DeepL_API로 변경해 주세요.\n지원하지 않는 언어도 있습니다."
- open_auth_key_webpage: DeepL 계정 페이지 열기
- auth_key_success: 인증키 갱신이 완료되었습니다.
- auth_key_error: 인증키가 잘못되었거나 API 사용 제한이 상한에 도달했습니다.
-
- mic_host:
- label: 마이크 호스트/드라이버
-
- mic_device:
- label: 마이크 장치
-
- mic_dynamic_energy_threshold:
- label_for_automatic: "음성 입력 최소 볼륨 (현재 설정: 자동)"
- desc_for_automatic: "마이크의 입력 감도를 자동으로 조절합니다."
- label_for_manual: "음성 입력 최소 볼륨 (현재 설정: 수동)"
- desc_for_manual: "슬라이더를 움직여 입력 감도를 수동으로 조절합니다. 마이크 아이콘을 누르면 실제 음성의 볼륨을 확인하며 감도를 조절할 수 있습니다."
- error_message: 0에서 %{max}까지의 숫자로만 설정할 수 있습니다.
-
- mic_record_timeout:
- label: 최대 무음 시간
- desc: 무음을 감지하고 설정된 시간(초)만큼의 시간이 지나면 음성 입력이 종료된 것으로 판단합니다.
- error_message: 0 이상에서 '%{mic_phrase_timeout_label}'보다 클 수 없습니다.
-
- mic_phrase_timeout:
- label: 최대 인식 시간
- desc: 설정된 초 단위로 음성인식 처리가 이루어집니다.
- error_message: 0 이상에서 '%{mic_record_timeout_label}'보다 작을 수 없습니다.
-
- mic_max_phrase:
- label: 최대 입력 절(phrases) 수
- desc: 인식된 단어 수의 하한값으로, 이 수치를 초과하는 경우에만 결과를 VRChat으로 전송하고 로그에 표시합니다.
- error_message: 0 이상의 숫자만 설정할 수 있습니다.
-
- mic_word_filter:
- label: 단어 필터
- desc: "등록된 단어가 감지되면 해당 문장은 전송되지 않습니다. \n ',' 쉼표로 구분하면 여러 단어를 추가할 수 있습니다. \n* 중복된 단어는 등록되지 않습니다."
- add_button_label: 추가
- count_desc: "현재 등록되어 있는 단어 수: %{count}"
-
-
- speaker_device:
- label: 스피커 장치
-
- speaker_dynamic_energy_threshold:
- label_for_automatic: "음성 입력 최소 볼륨 (현재 설정: 자동)"
- desc_for_automatic: "스피커의 입력 감도를 자동으로 조절합니다."
- label_for_manual: "음성 입력 최소 볼륨 (현재 설정: 수동)"
- desc_for_manual: "슬라이더를 움직여 입력 감도를 수동으로 조절합니다. 헤드폰 아이콘을 누르면 실제 음성의 볼륨을 확인하며 감도를 조절할 수 있습니다."
- error_message: 0에서 %{max}까지의 숫자로만 설정할 수 있습니다.
- no_device_error_message: 스피커 디바이스를 찾지 못했습니다.
-
- speaker_record_timeout:
- label: 최대 무음 시간
- desc: 무음을 감지하고 설정된 시간(초)만큼의 시간이 지나면 음성 입력이 종료된 것으로 판단합니다.
- error_message: 0 이상에서 '%{speaker_phrase_timeout_label}'보다 클 수 없습니다.
-
- speaker_phrase_timeout:
- label: 최대 인식 시간
- desc: 설정된 초 단위로 음성인식 처리가 이루어집니다.
- error_message: 0 이상에서 '%{speaker_record_timeout_label}'보다 작을 수 없습니다.
-
- speaker_max_phrase:
- label: 최대 입력 절(phrases) 수
- desc: 식된 단어 수의 하한값으로, 이 수치를 초과하는 경우에만 결과를 로그에 표시합니다.
- error_message: 0 이상의 숫자만 설정할 수 있습니다.
-
- use_whisper_feature:
- label: 음성 인식에 Whisper 모델을 사용
- desc: 일부 언어에서는 음성 인식의 정확도가 향상될 수 있어요. 음성 인식 중 CPU 사용률이 올라가기 때문에 사용하시는 PC의 사양을 고려하여 이 기능을 사용해주세요.
-
- whisper_weight_type:
- label: Whisper 모델 타입
- desc: "기본적으로 용량이 많은 모델일수록 정밀도는 높지만, 음성 인식의 시간이 늘어나며 CPU 사용률도 늘어나요.각 모델의 설명은 문서를 참조해주세요.\n※특히 medium보다 용량이 큰 모델은 CPU의 성능에 따라서는 사용조차 어려울 수 있어요. "
- model_template: "%{model_name} 모델 (%{capacity})"
- recommended_model_template: "%{model_name} 모델 (%{capacity}) (권장)"
-
- auto_clear_the_message_box:
- label: 챗박스 자동 삭제
-
- send_only_translated_messages:
- label: 번역된 메시지만 전송
-
- send_message_button_type:
- label: 메시지 전송 버튼
- hide: 숨김 (Enter 키를 사용하여 전송)
- show: 표시
- show_and_disable_enter_key: 표시 (Enter 키 전송 비활성화)
-
- notice_xsoverlay:
- label: XSOverlay에서 알림 수신 기능 활성화
- desc: 수신된 메시지를 XSOverlay의 기능을 통해 알림으로 받아볼 수 있습니다.
-
- auto_export_message_logs:
- label: 대화 로그 자동 저장
- desc: logs 폴더에 텍스트 파일로 로그가 저장됩니다.
-
- send_message_to_vrc:
- label: VRChat에 메시지 전송
- desc: "VRChat에 메시지를 보내지 않고 사용할 수 있는 방법이 있지만 지원되지 않습니다. VRChat에 메시지를 보내려면 이 기능을 활성화하세요."
-
-
- send_message_format:
- label: 메시지 형식
- desc: "메시지가 실제로 보이는 형식을 변경합니다. \n[message]가 메시지로 대체됩니다."
- example_text: 이것은 예문입니다. 폰트, 줄바꿈 등 실제 표시와 다를 수 있습니다.
- error_message: "[message]라는 문자는 사용할 수 없습니다."
-
- send_message_format_with_t:
- label: 메시지 형식 (번역 포함)
- desc: "메시지가 실제로 보이는 형식을 변경합니다. \n[message]는 메시지로, [translation]은 번역된 메시지로 대체됩니다.\nXSOverlay의 알림에서도 사용됩니다."
- example_text: 예문입니다. 글꼴, 줄 바꿈 등이 실제 표시와 다를 수 있습니다.
- error_message: "[message]와 [translation]이라는 문자는 사용할 수 없습니다."
-
- received_message_format:
- label: 메시지 형식
- desc: "메시지가 실제로 보이는 형식을 변경합니다. \n[message]가 메시지로 대체됩니다."
- example_text: 이것은 예문입니다. 폰트, 줄바꿈 등 실제 표시와 다를 수 있습니다.
- error_message: "[message]라는 문자는 사용할 수 없습니다."
-
- received_message_format_with_t:
- label: 메시지 형식 (번역 포함)
- desc: "메시지가 실제로 보이는 형식을 변경합니다. \n[message]는 메시지로, [translation]은 번역된 메시지로 대체됩니다.\nXSOverlay의 알림에서도 사용됩니다."
- example_text: 이것은 예문입니다. 폰트, 줄바꿈 등 실제 표시와 다를 수 있습니다.
- error_message: "[message]와 [translation]이라는 문자는 사용할 수 없습니다."
-
-
- osc_ip_address:
- label: OSC IP 주소
-
- osc_port:
- label: OSC 포트
-
- open_config_filepath:
- label: 설정 파일 열기
\ No newline at end of file
diff --git a/locales/zh-Hant.json b/locales/zh-Hant.json
new file mode 100644
index 00000000..80bcac5c
--- /dev/null
+++ b/locales/zh-Hant.json
@@ -0,0 +1,277 @@
+{
+ "main_window": {
+ "translation": "翻譯",
+ "transcription_send": "麥克風轉文字",
+ "transcription_receive": "喇叭轉文字",
+ "foreground": "最上層顯示",
+ "language_settings": "語言設定",
+ "your_language": "你的語言",
+ "translate_each_other_label": "互相翻譯",
+ "swap_button_label": "交換語言",
+ "target_language": "目標語言",
+ "translator": "翻譯器",
+ "translator_ctranslate2": "離線翻譯(預設)",
+ "textbox_tab_all": "全部",
+ "textbox_tab_sent": "已發送",
+ "textbox_tab_received": "已接收",
+ "textbox_tab_system": "系統",
+ "textbox_system_message": {
+ "enabled_easter_egg": "你找到了彩蛋!看看你的 VR Overlay 有沒有什麼變化?",
+ "enabled_translation": "翻譯功能已啟用。",
+ "disabled_translation": "翻譯功能已停用。",
+ "enabled_voice2chatbox": "麥克風轉文字已啟用。",
+ "disabled_voice2chatbox": "麥克風轉文字已停用。",
+ "enabled_speaker2log": "喇叭轉文字已啟用。",
+ "disabled_speaker2log": "喇叭轉文字已停用。",
+ "enabled_foreground": "最上層顯示已啟用。",
+ "disabled_foreground": "最上層顯示已停用。",
+ "auth_key_success": "授權金鑰更新完成。",
+ "auth_key_error": "授權金鑰錯誤或已達使用上限。",
+ "no_mic_device_detected_error": "未偵測到麥克風。",
+ "no_speaker_device_detected_error": "未偵測到喇叭。",
+ "translation_engine_limit_error": "翻譯引擎已自動變更。由於請求太頻繁,已被這個翻譯引擎暫時受限。如果你想使用相同的翻譯引擎,請稍等片刻,重新啟動 VRCT 並重試。",
+ "detected_by_word_filter": "由於詞語過濾器的偵測,「%{detected_message}」未被發送。",
+ "selected_your_language": "「你的語言」已設為 %{your_language}。",
+ "selected_target_language": "「目標語言」已設為 %{target_language}。",
+ "switched_language_preset_tab": "已切換到第 %{tab_no} 個語言設定。",
+ "latest_language_setting": "目前「你的語言」設為 %{your_language},「目標語言」設為 %{target_language}。",
+ "opened_web_page_booth": "已在瀏覽器中打開 Booth 頁面。",
+ "opened_web_page_vrct_documents": "已在瀏覽器中打開VRCT文件頁面。\n如有任何問題、請求或查詢,請通過文件頁面底部的連結、「聯絡表單」或 X (Twitter) 聯絡我們!"
+ },
+ "update_available": "有新版本可供使用!",
+ "state_text_enabled": "啟用",
+ "state_text_disabled": "停用",
+ "cover_message": "VRCT 功能在設定視窗關閉前暫時停用。",
+ "confirmation_message": {
+ "update_software": "下載新版本並自動更新 VRCT。\n會花一些時間,現在更新嗎?",
+ "deny_update_software": "稍後再說",
+ "accept_update_software": "更新",
+ "updating": "正在更新...",
+ "detected_over_ui_size": "介面大小:%{current_ui_size}\nVRCT 的視窗大小可能超過你的螢幕大小。",
+ "deny_adjust_ui_size": "保持目前大小",
+ "accept_adjust_ui_size": "縮小介面並重新啟動"
+ }
+ },
+ "selectable_language_window": {
+ "title_your_language": "選擇你的語言",
+ "title_target_language": "選擇目標語言",
+ "go_back_button": "返回"
+ },
+ "overlay_settings": {
+ "restore_default_settings": "恢復預設設定",
+ "opacity": "透明度",
+ "ui_scaling": "介面縮放",
+ "x_position": "X軸(左右)",
+ "y_position": "Y軸(上下)",
+ "z_position": "Z軸(前後)",
+ "x_rotation": "X軸旋轉",
+ "y_rotation": "Y軸旋轉",
+ "z_rotation": "Z軸旋轉",
+ "display_duration": "顯示持續時間",
+ "fadeout_duration": "淡出持續時間"
+ },
+ "config_window": {
+ "config_title": "設定",
+ "compact_mode": "精簡模式",
+ "version": "版本 %{version}",
+ "restart_message": "重新啟動以應用變更。",
+ "common_error_message": {
+ "invalid_value": "無效值。"
+ },
+ "side_menu_labels": {
+ "appearance": "外觀",
+ "translation": "翻譯",
+ "transcription": "轉錄",
+ "transcription_mic": "麥克風",
+ "transcription_speaker": "喇叭",
+ "transcription_internal_model": "轉錄模型",
+ "vr": "VR",
+ "others": "其他",
+ "others_send_message_formats": "訊息格式(發送)",
+ "others_received_message_formats": "訊息格式(XSOverlay & 喇叭轉文字)",
+ "others_speaker2chatbox": "喇叭轉文字",
+ "advanced_settings": "進階設定"
+ },
+ "transparency": {
+ "label": "透明度",
+ "desc": "變更主視窗的透明度。"
+ },
+ "appearance_theme": {
+ "label": "主題",
+ "desc": "變更配色主題。"
+ },
+ "ui_size": {
+ "label": "介面大小"
+ },
+ "textbox_ui_size": {
+ "label": "訊息框字體大小",
+ "desc": "你可以根據介面大小調整記錄中使用的字體大小。"
+ },
+ "message_box_ratio": {
+ "label": "訊息框大小",
+ "desc": "你可以依介面比例縮放輸入訊息框。\n*可能不準確。"
+ },
+ "font_family": {
+ "label": "字型"
+ },
+ "ui_language": {
+ "label": "介面語言"
+ },
+ "to_restore_main_window_geometry": {
+ "label": "記住主視窗位置",
+ "desc": "啟動時恢復上次視窗的位置和大小。"
+ },
+ "use_translation_feature": {
+ "label": "使用翻譯功能",
+ "desc": "當此功能關閉時,無法使用翻譯功能。但 VRCT 會啟動得更快。適合不需要翻譯功能、只使用VRCT作為聊天框和轉錄工具的使用者。"
+ },
+ "ctranslate2_weight_type": {
+ "label": "選擇離線翻譯模型",
+ "desc": "你可以選擇用於離線翻譯引擎的翻譯模型。",
+ "small": "基本模型(%{capacity})",
+ "large": "高準確率模型(%{capacity})"
+ },
+ "deepl_auth_key": {
+ "label": "DeepL 授權金鑰",
+ "desc": "使用 DeepL API 時請在主螢幕選擇 %{translator}。※可能不支援某些語言。",
+ "open_auth_key_webpage": "打開 DeepL 帳號頁面",
+ "auth_key_success": "授權金鑰更新完成。",
+ "auth_key_error": "授權金鑰錯誤或已達使用上限。"
+ },
+ "mic_host": {
+ "label": "麥克風 Host/Driver"
+ },
+ "mic_device": {
+ "label": "麥克風裝置"
+ },
+ "mic_dynamic_energy_threshold": {
+ "label_for_automatic": "麥克風能量閾值(當前設置:自動)",
+ "desc_for_automatic": "自動判定麥克風輸入靈敏度。",
+ "label_for_manual": "麥克風能量閾值(當前設置:手動)",
+ "desc_for_manual": "使用滑桿調整麥克風輸入靈敏度,你可以按下麥克風圖示來測試。",
+ "error_message": "可以設置 0 到 %{max} 之間的值。"
+ },
+ "mic_record_timeout": {
+ "label": "麥克風音訊 - 判定結束時間",
+ "desc": "麥克風未收到音訊後,結束一段話的判定時間(秒)。",
+ "error_message": "不能大於「%{mic_phrase_timeout_label}」,應為 0 或更高。"
+ },
+ "mic_phrase_timeout": {
+ "label": "麥克風音訊 - 紀錄間隔時間",
+ "desc": "每隔多久要紀錄一次音訊。",
+ "error_message": "不能小於「%{mic_record_timeout_label}」,應為 0 或更高。"
+ },
+ "mic_max_phrase": {
+ "label": "麥克風音訊 - 最大單詞數量",
+ "desc": "只有在單詞超過此數量時,才會記錄結果並發送到 VRChat。",
+ "error_message": "可以設置為 0 或更高的數值。"
+ },
+ "mic_word_filter": {
+ "label": "麥克風單詞過濾器",
+ "desc": "如果偵測到清單內的單詞,則不會發送訊息。要一次新增多個詞語,請用「,」(半形逗號)分隔。\n*重複詞語會被忽略。",
+ "add_button_label": "新增",
+ "count_desc": "當前註冊詞語數量:%{count}"
+ },
+ "speaker_device": {
+ "label": "喇叭裝置"
+ },
+ "speaker_dynamic_energy_threshold": {
+ "label_for_automatic": "喇叭能量閾值(當前設置:自動)",
+ "desc_for_automatic": "自動確定喇叭輸入靈敏度。",
+ "label_for_manual": "喇叭能量閾值(當前設置:手動)",
+ "desc_for_manual": "使用滑桿調整喇叭輸入靈敏度,你可以按下喇叭圖示來測試。",
+ "error_message": "可以設置 0 到 %{max} 之間的值。",
+ "no_device_error_message": "未偵測到喇叭裝置。"
+ },
+ "speaker_record_timeout": {
+ "label": "喇叭音訊 - 判定結束時間",
+ "desc": "偵測到靜音並在指定秒數後認為喇叭輸入已結束。(秒)",
+ "error_message": "不能大於「%{speaker_phrase_timeout_label}」,應為 0 或更高。"
+ },
+ "speaker_phrase_timeout": {
+ "label": "喇叭音訊 - 紀錄間隔時間",
+ "desc": "以指定秒數間隔進行轉錄處理。",
+ "error_message": "不能小於「%{speaker_record_timeout_label}」,應為 0 或更高。"
+ },
+ "speaker_max_phrase": {
+ "label": "喇叭音訊 - 最大單詞數量",
+ "desc": "只有在單詞超過此數量時,才會記錄結果並發送到 VRChat。",
+ "error_message": "可以設置 0 或更高的數值。"
+ },
+ "use_whisper_feature": {
+ "label": "使用 Whisper 模型進行轉錄",
+ "desc": "在某些語言中,語音識別的準確性可能會提高。使用語音識別時,CPU使用率會增加,請根據你的PC規格考慮是否使用此功能。"
+ },
+ "whisper_weight_type": {
+ "label": "選擇 Whisper 模型",
+ "desc": "一般來說,容量較大的模型往往具有更高的準確性,但這也導致轉錄時間較長和CPU使用率增加。請參考文檔了解各模型的說明。\n※特別是超過中等大小的模型,根據CPU性能可能難以運行。",
+ "model_template": "%{model_name}模型(%{capacity})",
+ "recommended_model_template": "%{model_name}模型(%{capacity})(推薦)"
+ },
+ "enable_overlay_small_log": {
+ "label": "啟用 Overlay",
+ "open_overlay_settings": "打開 Overlay 自定義設定"
+ },
+ "auto_clear_the_message_box": {
+ "label": "自動清除 Chatbox"
+ },
+ "send_only_translated_messages": {
+ "label": "僅發送翻譯訊息"
+ },
+ "send_message_button_type": {
+ "label": "發送訊息按鈕",
+ "hide": "隱藏(使用 Enter 鍵發送)",
+ "show": "顯示",
+ "show_and_disable_enter_key": "顯示並停用 Enter 鍵發送"
+ },
+ "notice_xsoverlay": {
+ "label": "XSOverlay 通知",
+ "desc": "從 XSOverlay 的通知功能接收訊息。"
+ },
+ "auto_export_message_logs": {
+ "label": "自動匯出訊息記錄",
+ "desc": "自動將對話訊息匯出為文字文件。"
+ },
+ "vrc_mic_mute_sync": {
+ "label": "VRC 麥克風靜音同步",
+ "desc": "當 VRChat 的麥克風靜音時,VRCT 將不會向 VRChat 發送訊息。\n*存在一些延遲且不支援按鍵發話 (PTT)。"
+ },
+ "send_message_to_vrc": {
+ "label": "發送訊息到 VRChat",
+ "desc": "當你打算向 VRChat 發送訊息時啟用此功能。"
+ },
+ "send_message_format": {
+ "label": "發送的訊息格式",
+ "desc": "你可以設定要發送的訊息格式。\n[message] 將被替換為訊息。",
+ "example_text": "這是一個範例。字體、換行等可能與實際顯示不同。",
+ "error_message": "不能使用 [message] 。"
+ },
+ "send_message_format_with_t": {
+ "label": "發送的訊息格式(帶翻譯)",
+ "desc": "你可以設定要發送的訊息格式。\n[message] 將被替換為訊息,並且 [translation] 將被替換為翻譯訊息。",
+ "example_text": "這是一個範例。字體、換行等可能與實際顯示不同。",
+ "error_message": "不能使用 [message] 和 [translation] 。"
+ },
+ "received_message_format": {
+ "label": "接收的訊息格式",
+ "desc": "用於 XSOverlay 的通知接收功能。\n[message] 將被替換為訊息。\n※它也將用於喇叭轉文字功能。",
+ "example_text": "這是一個範例。字體、換行等可能與實際顯示不同。",
+ "error_message": "不能使用 [message] 。"
+ },
+ "received_message_format_with_t": {
+ "label": "接收的訊息格式(附翻譯)",
+ "desc": "用於 XSOverlay 的通知接收功能。\n[message] 將被替換為訊息,並且 [translation] 將被替換為翻譯訊息。\n※它也將用於喇叭轉文字功能。",
+ "example_text": "這是一個範例。字體、換行等可能與實際顯示不同。",
+ "error_message": "不能使用 [message] 和 [translation] 。"
+ },
+ "osc_ip_address": {
+ "label": "OSC IP 位址"
+ },
+ "osc_port": {
+ "label": "OSC 端口"
+ },
+ "open_config_filepath": {
+ "label": "打開設定文件"
+ }
+ }
+}
\ No newline at end of file
diff --git a/locales/zh-Hant.yml b/locales/zh-Hant.yml
deleted file mode 100644
index df58c089..00000000
--- a/locales/zh-Hant.yml
+++ /dev/null
@@ -1,283 +0,0 @@
-main_window:
- translation: 翻譯
- transcription_send: 麥克風轉文字
- transcription_receive: 喇叭轉文字
- foreground: 最上層顯示
-
- language_settings: 語言設定
- your_language: 你的語言
- translate_each_other_label: 互相翻譯
- swap_button_label: 交換語言
- target_language: 目標語言
- translator: 翻譯器
- translator_ctranslate2: 離線翻譯(預設)
-
- textbox_tab_all: 全部
- textbox_tab_sent: 已發送
- textbox_tab_received: 已接收
- textbox_tab_system: 系統
-
- textbox_system_message:
- enabled_easter_egg: 你找到了彩蛋!看看你的 VR Overlay 有沒有什麼變化?
- enabled_translation: 翻譯功能已啟用。
- disabled_translation: 翻譯功能已停用。
- enabled_voice2chatbox: 麥克風轉文字已啟用。
- disabled_voice2chatbox: 麥克風轉文字已停用。
- enabled_speaker2log: 喇叭轉文字已啟用。
- disabled_speaker2log: 喇叭轉文字已停用。
- enabled_foreground: 最上層顯示已啟用。
- disabled_foreground: 最上層顯示已停用。
-
- auth_key_success: 授權金鑰更新完成。
- auth_key_error: 授權金鑰錯誤或已達使用上限。
-
- no_mic_device_detected_error: 未偵測到麥克風。
- no_speaker_device_detected_error: 未偵測到喇叭。
- translation_engine_limit_error: 翻譯引擎已自動變更。由於請求太頻繁,已被這個翻譯引擎暫時受限。如果你想使用相同的翻譯引擎,請稍等片刻,重新啟動 VRCT 並重試。
-
- detected_by_word_filter: 由於詞語過濾器的偵測,「%{detected_message}」未被發送。
-
- selected_your_language: "「你的語言」已設為 %{your_language}。"
- selected_target_language: "「目標語言」已設為 %{target_language}。"
- switched_language_preset_tab: 已切換到第 %{tab_no} 個語言設定。
- latest_language_setting: "目前「你的語言」設為 %{your_language},「目標語言」設為 %{target_language}。"
-
- opened_web_page_booth: 已在瀏覽器中打開 Booth 頁面。
- opened_web_page_vrct_documents: "已在瀏覽器中打開VRCT文件頁面。\n如有任何問題、請求或查詢,請通過文件頁面底部的連結、「聯絡表單」或 X (Twitter) 聯絡我們!"
-
- update_available: 有新版本可供使用!
- state_text_enabled: 啟用
- state_text_disabled: 停用
-
- cover_message: VRCT 功能在設定視窗關閉前暫時停用。
-
- confirmation_message:
- update_software: "下載新版本並自動更新 VRCT。\n會花一些時間,現在更新嗎?"
- deny_update_software: 稍後再說
- accept_update_software: 更新
- updating: 正在更新...
-
- detected_over_ui_size: "介面大小:%{current_ui_size}\nVRCT 的視窗大小可能超過你的螢幕大小。"
- deny_adjust_ui_size: "保持目前大小"
- accept_adjust_ui_size: "縮小介面並重新啟動"
-
-selectable_language_window:
- title_your_language: 選擇你的語言
- title_target_language: 選擇目標語言
- go_back_button: 返回
-
-overlay_settings:
- restore_default_settings: 恢復預設設定
- opacity: 透明度
- ui_scaling: 介面縮放
- x_position: X軸(左右)
- y_position: Y軸(上下)
- z_position: Z軸(前後)
- x_rotation: X軸旋轉
- y_rotation: Y軸旋轉
- z_rotation: Z軸旋轉
- display_duration: 顯示持續時間
- fadeout_duration: 淡出持續時間
-
-config_window:
- config_title: 設定
- compact_mode: 精簡模式
- version: 版本 %{version}
- restart_message: 重新啟動以應用變更。
- common_error_message:
- invalid_value: 無效值。
-
- side_menu_labels:
- appearance: 外觀
- translation: 翻譯
- transcription: 轉錄
- transcription_mic: 麥克風
- transcription_speaker: 喇叭
- transcription_internal_model: 轉錄模型
- vr: VR
- others: 其他
- others_send_message_formats: 訊息格式(發送)
- others_received_message_formats: 訊息格式(XSOverlay & 喇叭轉文字)
- others_speaker2chatbox: 喇叭轉文字
- advanced_settings: 進階設定
-
- transparency:
- label: 透明度
- desc: 變更主視窗的透明度。
-
- appearance_theme:
- label: 主題
- desc: 變更配色主題。
-
- ui_size:
- label: 介面大小
-
- textbox_ui_size:
- label: 訊息框字體大小
- desc: 你可以根據介面大小調整記錄中使用的字體大小。
-
- message_box_ratio:
- label: 訊息框大小
- desc: "你可以依介面比例縮放輸入訊息框。\n*可能不準確。"
-
- font_family:
- label: 字型
-
- ui_language:
- label: 介面語言
-
- to_restore_main_window_geometry:
- label: 記住主視窗位置
- desc: 啟動時恢復上次視窗的位置和大小。
-
- use_translation_feature:
- label: 使用翻譯功能
- desc: 當此功能關閉時,無法使用翻譯功能。但 VRCT 會啟動得更快。適合不需要翻譯功能、只使用VRCT作為聊天框和轉錄工具的使用者。
-
- ctranslate2_weight_type:
- label: 選擇離線翻譯模型
- desc: 你可以選擇用於離線翻譯引擎的翻譯模型。
- small: "基本模型(%{capacity})"
- large: "高準確率模型(%{capacity})"
-
- deepl_auth_key:
- label: DeepL 授權金鑰
- desc: 使用 DeepL API 時請在主螢幕選擇 %{translator}。※可能不支援某些語言。
- open_auth_key_webpage: 打開 DeepL 帳號頁面
- auth_key_success: 授權金鑰更新完成。
- auth_key_error: 授權金鑰錯誤或已達使用上限。
-
- mic_host:
- label: 麥克風 Host/Driver
-
- mic_device:
- label: 麥克風裝置
-
- mic_dynamic_energy_threshold:
- label_for_automatic: "麥克風能量閾值(當前設置:自動)"
- desc_for_automatic: "自動判定麥克風輸入靈敏度。"
- label_for_manual: "麥克風能量閾值(當前設置:手動)"
- desc_for_manual: "使用滑桿調整麥克風輸入靈敏度,你可以按下麥克風圖示來測試。"
- error_message: 可以設置 0 到 %{max} 之間的值。
-
- mic_record_timeout:
- label: 麥克風音訊 - 判定結束時間
- desc: 麥克風未收到音訊後,結束一段話的判定時間(秒)。
- error_message: 不能大於「%{mic_phrase_timeout_label}」,應為 0 或更高。
-
- mic_phrase_timeout:
- label: 麥克風音訊 - 紀錄間隔時間
- desc: 每隔多久要紀錄一次音訊。
- error_message: 不能小於「%{mic_record_timeout_label}」,應為 0 或更高。
-
- mic_max_phrase:
- label: 麥克風音訊 - 最大單詞數量
- desc: 只有在單詞超過此數量時,才會記錄結果並發送到 VRChat。
- error_message: 可以設置為 0 或更高的數值。
-
- mic_word_filter:
- label: 麥克風單詞過濾器
- desc: "如果偵測到清單內的單詞,則不會發送訊息。要一次新增多個詞語,請用「,」(半形逗號)分隔。\n*重複詞語會被忽略。"
- add_button_label: 新增
- count_desc: "當前註冊詞語數量:%{count}"
-
- speaker_device:
- label: 喇叭裝置
-
- speaker_dynamic_energy_threshold:
- label_for_automatic: "喇叭能量閾值(當前設置:自動)"
- desc_for_automatic: "自動確定喇叭輸入靈敏度。"
- label_for_manual: "喇叭能量閾值(當前設置:手動)"
- desc_for_manual: "使用滑桿調整喇叭輸入靈敏度,你可以按下喇叭圖示來測試。"
- error_message: 可以設置 0 到 %{max} 之間的值。
- no_device_error_message: 未偵測到喇叭裝置。
-
- speaker_record_timeout:
- label: 喇叭音訊 - 判定結束時間
- desc: 偵測到靜音並在指定秒數後認為喇叭輸入已結束。(秒)
- error_message: 不能大於「%{speaker_phrase_timeout_label}」,應為 0 或更高。
-
- speaker_phrase_timeout:
- label: 喇叭音訊 - 紀錄間隔時間
- desc: 以指定秒數間隔進行轉錄處理。
- error_message: 不能小於「%{speaker_record_timeout_label}」,應為 0 或更高。
-
- speaker_max_phrase:
- label: 喇叭音訊 - 最大單詞數量
- desc: 只有在單詞超過此數量時,才會記錄結果並發送到 VRChat。
- error_message: 可以設置 0 或更高的數值。
-
- use_whisper_feature:
- label: 使用 Whisper 模型進行轉錄
- desc: 在某些語言中,語音識別的準確性可能會提高。使用語音識別時,CPU使用率會增加,請根據你的PC規格考慮是否使用此功能。
-
- whisper_weight_type:
- label: 選擇 Whisper 模型
- desc: "一般來說,容量較大的模型往往具有更高的準確性,但這也導致轉錄時間較長和CPU使用率增加。請參考文檔了解各模型的說明。\n※特別是超過中等大小的模型,根據CPU性能可能難以運行。"
- model_template: "%{model_name}模型(%{capacity})"
- recommended_model_template: "%{model_name}模型(%{capacity})(推薦)"
-
- enable_overlay_small_log:
- label: 啟用 Overlay
- open_overlay_settings: 打開 Overlay 自定義設定
-
- auto_clear_the_message_box:
- label: 自動清除 Chatbox
-
- send_only_translated_messages:
- label: 僅發送翻譯訊息
-
- send_message_button_type:
- label: 發送訊息按鈕
- hide: 隱藏(使用 Enter 鍵發送)
- show: 顯示
- show_and_disable_enter_key: 顯示並停用 Enter 鍵發送
-
- notice_xsoverlay:
- label: XSOverlay 通知
- desc: 從 XSOverlay 的通知功能接收訊息。
-
- auto_export_message_logs:
- label: 自動匯出訊息記錄
- desc: 自動將對話訊息匯出為文字文件。
-
- vrc_mic_mute_sync:
- label: VRC 麥克風靜音同步
- desc: "當 VRChat 的麥克風靜音時,VRCT 將不會向 VRChat 發送訊息。\n*存在一些延遲且不支援按鍵發話 (PTT)。"
-
- send_message_to_vrc:
- label: 發送訊息到 VRChat
- desc: 當你打算向 VRChat 發送訊息時啟用此功能。
-
- send_message_format:
- label: 發送的訊息格式
- desc: "你可以設定要發送的訊息格式。\n[message] 將被替換為訊息。"
- example_text: 這是一個範例。字體、換行等可能與實際顯示不同。
- error_message: "不能使用 [message] 。"
-
- send_message_format_with_t:
- label: 發送的訊息格式(帶翻譯)
- desc: "你可以設定要發送的訊息格式。\n[message] 將被替換為訊息,並且 [translation] 將被替換為翻譯訊息。"
- example_text: 這是一個範例。字體、換行等可能與實際顯示不同。
- error_message: "不能使用 [message] 和 [translation] 。"
-
- received_message_format:
- label: 接收的訊息格式
- desc: "用於 XSOverlay 的通知接收功能。\n[message] 將被替換為訊息。\n※它也將用於喇叭轉文字功能。"
- example_text: 這是一個範例。字體、換行等可能與實際顯示不同。
- error_message: "不能使用 [message] 。"
-
- received_message_format_with_t:
- label: 接收的訊息格式(附翻譯)
- desc: "用於 XSOverlay 的通知接收功能。\n[message] 將被替換為訊息,並且 [translation] 將被替換為翻譯訊息。\n※它也將用於喇叭轉文字功能。"
- example_text: 這是一個範例。字體、換行等可能與實際顯示不同。
- error_message: "不能使用 [message] 和 [translation] 。"
-
- osc_ip_address:
- label: OSC IP 位址
-
- osc_port:
- label: OSC 端口
-
- open_config_filepath:
- label: 打開設定文件
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..5ac4d52c
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,5380 @@
+{
+ "name": "tauri-app",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "tauri-app",
+ "version": "0.0.0",
+ "dependencies": {
+ "@tauri-apps/api": "^1",
+ "@typescript-eslint/eslint-plugin": "^7.11.0",
+ "@typescript-eslint/parser": "^7.11.0",
+ "clsx": "^2.1.1",
+ "eslint": "^8.57.0",
+ "eslint-plugin-react": "^7.34.2",
+ "i18next": "^23.11.5",
+ "jotai": "^2.8.3",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-i18next": "^14.1.2",
+ "react-resizable-layout": "^0.7.2"
+ },
+ "devDependencies": {
+ "@tauri-apps/cli": "^1.5.14",
+ "@vitejs/plugin-react": "^4.2.1",
+ "sass": "^1.77.4",
+ "vite": "^5.0.0",
+ "vite-plugin-svgr": "^4.2.0"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
+ "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.24.7",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz",
+ "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz",
+ "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.24.7",
+ "@babel/generator": "^7.24.7",
+ "@babel/helper-compilation-targets": "^7.24.7",
+ "@babel/helper-module-transforms": "^7.24.7",
+ "@babel/helpers": "^7.24.7",
+ "@babel/parser": "^7.24.7",
+ "@babel/template": "^7.24.7",
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz",
+ "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.24.7",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz",
+ "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.24.7",
+ "@babel/helper-validator-option": "^7.24.7",
+ "browserslist": "^4.22.2",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
+ "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
+ "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.24.7",
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz",
+ "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
+ "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz",
+ "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.24.7",
+ "@babel/helper-module-imports": "^7.24.7",
+ "@babel/helper-simple-access": "^7.24.7",
+ "@babel/helper-split-export-declaration": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz",
+ "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
+ "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
+ "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz",
+ "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
+ "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz",
+ "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz",
+ "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.24.7",
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
+ "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.24.7",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
+ "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz",
+ "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz",
+ "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz",
+ "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz",
+ "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.24.7",
+ "@babel/parser": "^7.24.7",
+ "@babel/types": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz",
+ "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.24.7",
+ "@babel/generator": "^7.24.7",
+ "@babel/helper-environment-visitor": "^7.24.7",
+ "@babel/helper-function-name": "^7.24.7",
+ "@babel/helper-hoist-variables": "^7.24.7",
+ "@babel/helper-split-export-declaration": "^7.24.7",
+ "@babel/parser": "^7.24.7",
+ "@babel/types": "^7.24.7",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz",
+ "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.24.7",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz",
+ "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.57.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+ "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.14",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+ "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
+ "deprecated": "Use @eslint/config-array instead",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.2",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead"
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
+ "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
+ "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
+ "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
+ "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
+ "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
+ "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
+ "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
+ "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
+ "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
+ "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
+ "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
+ "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
+ "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
+ "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
+ "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
+ "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
+ "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
+ "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
+ "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
+ "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-dynamic-title": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
+ "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-svg-em-dimensions": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
+ "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-transform-react-native-svg": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz",
+ "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-plugin-transform-svg-component": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
+ "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/babel-preset": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz",
+ "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==",
+ "dev": true,
+ "dependencies": {
+ "@svgr/babel-plugin-add-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0",
+ "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0",
+ "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0",
+ "@svgr/babel-plugin-svg-dynamic-title": "8.0.0",
+ "@svgr/babel-plugin-svg-em-dimensions": "8.0.0",
+ "@svgr/babel-plugin-transform-react-native-svg": "8.1.0",
+ "@svgr/babel-plugin-transform-svg-component": "8.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@svgr/core": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
+ "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "camelcase": "^6.2.0",
+ "cosmiconfig": "^8.1.3",
+ "snake-case": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ }
+ },
+ "node_modules/@svgr/hast-util-to-babel-ast": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
+ "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.21.3",
+ "entities": "^4.4.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ }
+ },
+ "node_modules/@svgr/plugin-jsx": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
+ "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.21.3",
+ "@svgr/babel-preset": "8.1.0",
+ "@svgr/hast-util-to-babel-ast": "8.0.0",
+ "svg-parser": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/gregberge"
+ },
+ "peerDependencies": {
+ "@svgr/core": "*"
+ }
+ },
+ "node_modules/@tauri-apps/api": {
+ "version": "1.5.6",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.5.6.tgz",
+ "integrity": "sha512-LH5ToovAHnDVe5Qa9f/+jW28I6DeMhos8bNDtBOmmnaDpPmJmYLyHdeDblAWWWYc7KKRDg9/66vMuKyq0WIeFA==",
+ "engines": {
+ "node": ">= 14.6.0",
+ "npm": ">= 6.6.0",
+ "yarn": ">= 1.19.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/tauri"
+ }
+ },
+ "node_modules/@tauri-apps/cli": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.5.14.tgz",
+ "integrity": "sha512-JOSMKymlg116UdEXSj69eg5p1OtZnQkUE0qIGbtNDO1sk3X/KgBN6+oHBW0BzPStp/W0AjBgrMWCqjHPwEpOug==",
+ "dev": true,
+ "bin": {
+ "tauri": "tauri.js"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/tauri"
+ },
+ "optionalDependencies": {
+ "@tauri-apps/cli-darwin-arm64": "1.5.14",
+ "@tauri-apps/cli-darwin-x64": "1.5.14",
+ "@tauri-apps/cli-linux-arm-gnueabihf": "1.5.14",
+ "@tauri-apps/cli-linux-arm64-gnu": "1.5.14",
+ "@tauri-apps/cli-linux-arm64-musl": "1.5.14",
+ "@tauri-apps/cli-linux-x64-gnu": "1.5.14",
+ "@tauri-apps/cli-linux-x64-musl": "1.5.14",
+ "@tauri-apps/cli-win32-arm64-msvc": "1.5.14",
+ "@tauri-apps/cli-win32-ia32-msvc": "1.5.14",
+ "@tauri-apps/cli-win32-x64-msvc": "1.5.14"
+ }
+ },
+ "node_modules/@tauri-apps/cli-darwin-arm64": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.5.14.tgz",
+ "integrity": "sha512-lxoSOp3KKSqzHJa7iT32dukPGMlfsTuja1xXSgwR8o/fqzpYJY7FY/3ZxesP8HR66FcK+vtqa//HNqeOQ0mHkA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-darwin-x64": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.5.14.tgz",
+ "integrity": "sha512-EXSwN1n5spfG8FoXuyc90ACtmDJXzaZ1gxyENaq9xEpQoo7j/Q1vb6qXxmr6azKr8zmqY4h08ZFbv3exh93xJg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.5.14.tgz",
+ "integrity": "sha512-Yb8BH/KYR7Tl+de40sZPfrqbhcU3Jlu+UPIrnXt05sjn48xqIps74Xjz8zzVp0TuHxUp8FmIGtCVhQgsbrsvvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-arm64-gnu": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.5.14.tgz",
+ "integrity": "sha512-QrKHP4gRaHiup478rPBZ+BmNd88yze9jMmheoNy9mN1K/aECRmTHO+tWhsxv5moFHZzRhO0QDWxxvTtiaPXaGg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-arm64-musl": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.14.tgz",
+ "integrity": "sha512-Hb1C1VMxmUcyGjW/K/INKF87zzzgLEVRmWZZnQd7M1P4uue4xPyIwUELSdX12Z2jREPgmLW4AXPD0m6wsNu7iw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-x64-gnu": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.5.14.tgz",
+ "integrity": "sha512-kD9v/UwPDuhIgq2TJj/s2/7rqk+vmExVV6xHPKI8vVbIvlNAOZqmx3fpxjej1241vhJ/piGd/m6q6YMWGsL0oQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-linux-x64-musl": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.14.tgz",
+ "integrity": "sha512-204Drgg9Zx0+THKndqASz4+iPCwqA3gQVF9C0CDIArNXrjPyJjVvW8VP5CHiZYaTNWxlz/ltyxluM6UFWbXNFw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-win32-arm64-msvc": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-1.5.14.tgz",
+ "integrity": "sha512-sqPSni2MnWNCm+8YZnLdWCclxfSHaYqKuPFSz8q7Tn1G1m/cA9gyPoC1G0esHftY7bu/ZM5lB4kM3I4U0KlLiA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-win32-ia32-msvc": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.5.14.tgz",
+ "integrity": "sha512-8xN8W0zTs8oFsQmvYLxHFeqhzVI7oTaPK1xQMc5gbpFP45jN41c21aCXfjnvzT+h90EfCHUF9EWj2HTEJSb7Iw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tauri-apps/cli-win32-x64-msvc": {
+ "version": "1.5.14",
+ "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.5.14.tgz",
+ "integrity": "sha512-U0slee5tNM2PYECBpPHavLSwkT3szGMZ+qhcikQQbDan84bQdLn/kHWjyXOgLJs4KSve4+KxcrN+AVqj0VyHnw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.6",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+ "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz",
+ "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "7.14.1",
+ "@typescript-eslint/type-utils": "7.14.1",
+ "@typescript-eslint/utils": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.3.1",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^7.0.0",
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz",
+ "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "7.14.1",
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/typescript-estree": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz",
+ "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==",
+ "dependencies": {
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz",
+ "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "7.14.1",
+ "@typescript-eslint/utils": "7.14.1",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz",
+ "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==",
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz",
+ "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==",
+ "dependencies": {
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz",
+ "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "7.14.1",
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/typescript-estree": "7.14.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.56.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz",
+ "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==",
+ "dependencies": {
+ "@typescript-eslint/types": "7.14.1",
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || >=20.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz",
+ "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.24.5",
+ "@babel/plugin-transform-react-jsx-self": "^7.24.5",
+ "@babel/plugin-transform-react-jsx-source": "^7.24.1",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.14.2"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
+ "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+ "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
+ "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "is-string": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/array.prototype.findlast": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
+ "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
+ "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
+ "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.toreversed": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz",
+ "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ }
+ },
+ "node_modules/array.prototype.tosorted": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+ "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
+ "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.22.3",
+ "es-errors": "^1.2.1",
+ "get-intrinsic": "^1.2.3",
+ "is-array-buffer": "^3.0.4",
+ "is-shared-array-buffer": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.23.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz",
+ "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001629",
+ "electron-to-chromium": "^1.4.796",
+ "node-releases": "^2.0.14",
+ "update-browserslist-db": "^1.0.16"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+ "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001638",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz",
+ "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "node_modules/cosmiconfig": {
+ "version": "8.3.6",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
+ "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
+ "dev": true,
+ "dependencies": {
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0",
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+ "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+ "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+ "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "dev": true,
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.812",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz",
+ "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==",
+ "dev": true
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.23.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
+ "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "arraybuffer.prototype.slice": "^1.0.3",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "data-view-buffer": "^1.0.1",
+ "data-view-byte-length": "^1.0.1",
+ "data-view-byte-offset": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.0.3",
+ "es-to-primitive": "^1.2.1",
+ "function.prototype.name": "^1.1.6",
+ "get-intrinsic": "^1.2.4",
+ "get-symbol-description": "^1.0.2",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
+ "has-symbols": "^1.0.3",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.0.7",
+ "is-array-buffer": "^3.0.4",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.1",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.3",
+ "is-string": "^1.0.7",
+ "is-typed-array": "^1.1.13",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.13.1",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.5",
+ "regexp.prototype.flags": "^1.5.2",
+ "safe-array-concat": "^1.1.2",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.trim": "^1.2.9",
+ "string.prototype.trimend": "^1.0.8",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-length": "^1.0.1",
+ "typed-array-byte-offset": "^1.0.2",
+ "typed-array-length": "^1.0.6",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.15"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+ "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-iterator-helpers": {
+ "version": "1.0.19",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz",
+ "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-set-tostringtag": "^2.0.3",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "globalthis": "^1.0.3",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.7",
+ "iterator.prototype": "^1.1.2",
+ "safe-array-concat": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
+ "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+ "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
+ "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
+ "dependencies": {
+ "hasown": "^2.0.0"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+ "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.57.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+ "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.0",
+ "@humanwhocodes/config-array": "^0.11.14",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-react": {
+ "version": "7.34.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz",
+ "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==",
+ "dependencies": {
+ "array-includes": "^3.1.8",
+ "array.prototype.findlast": "^1.2.5",
+ "array.prototype.flatmap": "^1.3.2",
+ "array.prototype.toreversed": "^1.1.2",
+ "array.prototype.tosorted": "^1.1.4",
+ "doctrine": "^2.1.0",
+ "es-iterator-helpers": "^1.0.19",
+ "estraverse": "^5.3.0",
+ "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+ "minimatch": "^3.1.2",
+ "object.entries": "^1.1.8",
+ "object.fromentries": "^2.0.8",
+ "object.hasown": "^1.1.4",
+ "object.values": "^1.2.0",
+ "prop-types": "^15.8.1",
+ "resolve": "^2.0.0-next.5",
+ "semver": "^6.3.1",
+ "string.prototype.matchall": "^4.0.11"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/eslint/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/eslint/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
+ },
+ "node_modules/fastq": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
+ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw=="
+ },
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+ "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "functions-have-names": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
+ "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "hasown": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
+ "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/html-parse-stringify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
+ "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
+ "dependencies": {
+ "void-elements": "3.1.0"
+ }
+ },
+ "node_modules/i18next": {
+ "version": "23.11.5",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.5.tgz",
+ "integrity": "sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://locize.com"
+ },
+ {
+ "type": "individual",
+ "url": "https://locize.com/i18next.html"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ }
+ ],
+ "dependencies": {
+ "@babel/runtime": "^7.23.2"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
+ "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz",
+ "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==",
+ "dev": true
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
+ "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.0",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
+ "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "node_modules/is-async-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
+ "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz",
+ "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
+ "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
+ "dependencies": {
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+ "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz",
+ "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==",
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+ "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+ "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
+ "dependencies": {
+ "call-bind": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+ "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+ "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
+ "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
+ "dependencies": {
+ "which-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+ "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
+ "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+ },
+ "node_modules/iterator.prototype": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz",
+ "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "get-intrinsic": "^1.2.1",
+ "has-symbols": "^1.0.3",
+ "reflect.getprototypeof": "^1.0.4",
+ "set-function-name": "^2.0.1"
+ }
+ },
+ "node_modules/jotai": {
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.8.3.tgz",
+ "integrity": "sha512-pR4plVvdbzB6zyt7VLLHPMAkcRSKhRIvZKd+qkifQLa3CEziEo1uwZjePj4acTmQrboiISBlYSdCz3gWcr1Nkg==",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=17.0.0",
+ "react": ">=17.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsx-ast-utils": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "object.assign": "^4.1.4",
+ "object.values": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "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"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
+ "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
+ },
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "dev": true,
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "dev": true
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
+ "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
+ "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.entries": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz",
+ "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.hasown": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz",
+ "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
+ "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+ "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+ "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.38",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+ "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/react": {
+ "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"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-i18next": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz",
+ "integrity": "sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.9",
+ "html-parse-stringify": "^3.0.1"
+ },
+ "peerDependencies": {
+ "i18next": ">= 23.2.3",
+ "react": ">= 16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/react-refresh": {
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
+ "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-resizable-layout": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/react-resizable-layout/-/react-resizable-layout-0.7.2.tgz",
+ "integrity": "sha512-GrVzAecB6+osdAx5PPP3G8R9n7A2uDd3NL+PyrHWNRaVBivZmW/o0+yFjQdS5Bo016A2fIP11fAhefsknWN4aw==",
+ "peerDependencies": {
+ "react": ">=17.0.0",
+ "react-dom": ">=17.0.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz",
+ "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.1",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4",
+ "globalthis": "^1.0.3",
+ "which-builtin-type": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
+ "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "set-function-name": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "2.0.0-next.5",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
+ "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
+ "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "1.0.5"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.18.0",
+ "@rollup/rollup-android-arm64": "4.18.0",
+ "@rollup/rollup-darwin-arm64": "4.18.0",
+ "@rollup/rollup-darwin-x64": "4.18.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.18.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.18.0",
+ "@rollup/rollup-linux-arm64-musl": "4.18.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.18.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.18.0",
+ "@rollup/rollup-linux-x64-gnu": "4.18.0",
+ "@rollup/rollup-linux-x64-musl": "4.18.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.18.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.18.0",
+ "@rollup/rollup-win32-x64-msvc": "4.18.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+ "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4",
+ "has-symbols": "^1.0.3",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
+ "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.1.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/sass": {
+ "version": "1.77.6",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz",
+ "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+ "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4",
+ "object-inspect": "^1.13.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/snake-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
+ "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
+ "dev": true,
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz",
+ "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.7",
+ "regexp.prototype.flags": "^1.5.2",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
+ "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
+ "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/svg-parser": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
+ "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
+ "dev": true
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
+ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
+ "dev": true
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+ "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
+ "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
+ "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
+ "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
+ "peer": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
+ "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.2",
+ "picocolors": "^1.0.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz",
+ "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.38",
+ "rollup": "^4.13.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-svgr": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.2.0.tgz",
+ "integrity": "sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==",
+ "dev": true,
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.5",
+ "@svgr/core": "^8.1.0",
+ "@svgr/plugin-jsx": "^8.1.0"
+ },
+ "peerDependencies": {
+ "vite": "^2.6.0 || 3 || 4 || 5"
+ }
+ },
+ "node_modules/void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+ "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "dependencies": {
+ "is-bigint": "^1.0.1",
+ "is-boolean-object": "^1.1.0",
+ "is-number-object": "^1.0.4",
+ "is-string": "^1.0.5",
+ "is-symbol": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz",
+ "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==",
+ "dependencies": {
+ "function.prototype.name": "^1.1.5",
+ "has-tostringtag": "^1.0.0",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.0.5",
+ "is-finalizationregistry": "^1.0.2",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.1.4",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.0.2",
+ "which-collection": "^1.0.1",
+ "which-typed-array": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
+ "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..32eafbb1
--- /dev/null
+++ b/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "tauri-app",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "setup-python": "install.bat",
+ "build-python": "pyinstaller -F src-python/test.py --distpath src-tauri/bin --clean -n test-x86_64-pc-windows-msvc",
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "tauri": "tauri"
+ },
+ "dependencies": {
+ "@tauri-apps/api": "^1",
+ "@typescript-eslint/eslint-plugin": "^7.11.0",
+ "@typescript-eslint/parser": "^7.11.0",
+ "clsx": "^2.1.1",
+ "eslint": "^8.57.0",
+ "eslint-plugin-react": "^7.34.2",
+ "i18next": "^23.11.5",
+ "jotai": "^2.8.3",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-i18next": "^14.1.2",
+ "react-resizable-layout": "^0.7.2"
+ },
+ "devDependencies": {
+ "@tauri-apps/cli": "^1.5.14",
+ "@vitejs/plugin-react": "^4.2.1",
+ "sass": "^1.77.4",
+ "vite": "^5.0.0",
+ "vite-plugin-svgr": "^4.2.0"
+ }
+}
diff --git a/requirements.txt b/requirements.txt
index 4f4a6213..a392be22 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,12 +1,9 @@
pillow == 10.0.0
PyAudioWPatch == 0.2.12.6
python-osc == 1.8.3
-customtkinter == 5.2.0
deepl == 1.15.0
flashtext == 2.7
pyyaml == 6.0.1
-python-i18n == 0.3.9
-CTkToolTip == 0.8
pyinstaller==6.2.0
transformers[torch]==4.37.2
sentencepiece==0.1.99
diff --git a/src-python/test.py b/src-python/test.py
new file mode 100644
index 00000000..9276f4e4
--- /dev/null
+++ b/src-python/test.py
@@ -0,0 +1,40 @@
+import sys
+import json
+import time
+
+def main():
+ received_data = sys.stdin.readline().strip()
+ received_data = json.loads(received_data)
+
+ with open('process.log', 'a') as f:
+ f.write(f"received_data: {received_data}\n")
+
+ if received_data:
+ response_data = {
+ "status": "ok",
+ "id": received_data["id"],
+ "data": received_data["data"],
+ }
+ response = json.dumps(response_data)
+ time.sleep(2)
+ print(response, flush=True)
+
+
+ # with open('process.log', 'a') as f:
+ # f.write(f"Received data: {received_data}\n")
+ # f.write(f"Response: {response}\n")
+
+ # # 標準出力に結果を出力
+ # for i in range(10):
+ # print(str(i), flush=True)
+ # time.sleep(1)
+
+if __name__ == "__main__":
+ try:
+ print(json.dumps({"init_key_from_py": "Initialization from Python."}), flush=True)
+ while True:
+ main()
+ except Exception:
+ import traceback
+ with open('error.log', 'a') as f:
+ traceback.print_exc(file=f)
\ No newline at end of file
diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore
new file mode 100644
index 00000000..a52506d9
--- /dev/null
+++ b/src-tauri/.gitignore
@@ -0,0 +1,11 @@
+# Generated by Cargo
+# will have compiled files and executables
+/target/
+
+# Generated by Tauri
+# will have schema files for capabilities auto-completion
+/gen/schemas
+
+
+# Customize
+/bin
\ No newline at end of file
diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
new file mode 100644
index 00000000..60f50f38
--- /dev/null
+++ b/src-tauri/Cargo.lock
@@ -0,0 +1,3765 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "alloc-no-stdlib"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
+
+[[package]]
+name = "alloc-stdlib"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
+dependencies = [
+ "alloc-no-stdlib",
+]
+
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
+
+[[package]]
+name = "atk"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd"
+dependencies = [
+ "atk-sys",
+ "bitflags 1.3.2",
+ "glib",
+ "libc",
+]
+
+[[package]]
+name = "atk-sys"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6"
+dependencies = [
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
+
+[[package]]
+name = "backtrace"
+version = "0.3.71"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "base64"
+version = "0.21.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
+
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
+
+[[package]]
+name = "block"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "brotli"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391"
+dependencies = [
+ "alloc-no-stdlib",
+ "alloc-stdlib",
+ "brotli-decompressor",
+]
+
+[[package]]
+name = "brotli-decompressor"
+version = "2.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f"
+dependencies = [
+ "alloc-no-stdlib",
+ "alloc-stdlib",
+]
+
+[[package]]
+name = "bstr"
+version = "1.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
+[[package]]
+name = "bytemuck"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "bytes"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
+
+[[package]]
+name = "cairo-rs"
+version = "0.15.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc"
+dependencies = [
+ "bitflags 1.3.2",
+ "cairo-sys-rs",
+ "glib",
+ "libc",
+ "thiserror",
+]
+
+[[package]]
+name = "cairo-sys-rs"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8"
+dependencies = [
+ "glib-sys",
+ "libc",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "cargo_toml"
+version = "0.15.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "599aa35200ffff8f04c1925aa1acc92fa2e08874379ef42e210a80e527e60838"
+dependencies = [
+ "serde",
+ "toml 0.7.8",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.98"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f"
+
+[[package]]
+name = "cesu8"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
+
+[[package]]
+name = "cfb"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
+dependencies = [
+ "byteorder",
+ "fnv",
+ "uuid",
+]
+
+[[package]]
+name = "cfg-expr"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7"
+dependencies = [
+ "smallvec",
+]
+
+[[package]]
+name = "cfg-expr"
+version = "0.15.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
+dependencies = [
+ "smallvec",
+ "target-lexicon",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chrono"
+version = "0.4.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "num-traits",
+ "serde",
+ "windows-targets 0.52.5",
+]
+
+[[package]]
+name = "cocoa"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a"
+dependencies = [
+ "bitflags 1.3.2",
+ "block",
+ "cocoa-foundation",
+ "core-foundation",
+ "core-graphics",
+ "foreign-types",
+ "libc",
+ "objc",
+]
+
+[[package]]
+name = "cocoa-foundation"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7"
+dependencies = [
+ "bitflags 1.3.2",
+ "block",
+ "core-foundation",
+ "core-graphics-types",
+ "libc",
+ "objc",
+]
+
+[[package]]
+name = "color_quant"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
+
+[[package]]
+name = "combine"
+version = "4.6.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
+dependencies = [
+ "bytes",
+ "memchr",
+]
+
+[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
+[[package]]
+name = "core-foundation"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
+
+[[package]]
+name = "core-graphics"
+version = "0.22.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "core-graphics-types",
+ "foreign-types",
+ "libc",
+]
+
+[[package]]
+name = "core-graphics-types"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "libc",
+]
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "cssparser"
+version = "0.27.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a"
+dependencies = [
+ "cssparser-macros",
+ "dtoa-short",
+ "itoa 0.4.8",
+ "matches",
+ "phf 0.8.0",
+ "proc-macro2",
+ "quote",
+ "smallvec",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "cssparser-macros"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
+dependencies = [
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "ctor"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
+dependencies = [
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "darling"
+version = "0.20.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.20.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.20.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "deranged"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+dependencies = [
+ "powerfmt",
+ "serde",
+]
+
+[[package]]
+name = "derive_more"
+version = "0.99.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
+dependencies = [
+ "convert_case",
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
+[[package]]
+name = "dirs-next"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
+dependencies = [
+ "cfg-if",
+ "dirs-sys-next",
+]
+
+[[package]]
+name = "dirs-sys-next"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi",
+]
+
+[[package]]
+name = "dispatch"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
+
+[[package]]
+name = "dtoa"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653"
+
+[[package]]
+name = "dtoa-short"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74"
+dependencies = [
+ "dtoa",
+]
+
+[[package]]
+name = "dunce"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
+
+[[package]]
+name = "embed-resource"
+version = "2.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d"
+dependencies = [
+ "cc",
+ "memchr",
+ "rustc_version",
+ "toml 0.8.2",
+ "vswhom",
+ "winreg",
+]
+
+[[package]]
+name = "embed_plist"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7"
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "errno"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+
+[[package]]
+name = "fdeflate"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
+dependencies = [
+ "simd-adler32",
+]
+
+[[package]]
+name = "field-offset"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
+dependencies = [
+ "memoffset",
+ "rustc_version",
+]
+
+[[package]]
+name = "filetime"
+version = "0.2.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall 0.4.1",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futf"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843"
+dependencies = [
+ "mac",
+ "new_debug_unreachable",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "futures-task"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
+
+[[package]]
+name = "futures-util"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
+dependencies = [
+ "futures-core",
+ "futures-macro",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "gdk"
+version = "0.15.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6e05c1f572ab0e1f15be94217f0dc29088c248b14f792a5ff0af0d84bcda9e8"
+dependencies = [
+ "bitflags 1.3.2",
+ "cairo-rs",
+ "gdk-pixbuf",
+ "gdk-sys",
+ "gio",
+ "glib",
+ "libc",
+ "pango",
+]
+
+[[package]]
+name = "gdk-pixbuf"
+version = "0.15.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a"
+dependencies = [
+ "bitflags 1.3.2",
+ "gdk-pixbuf-sys",
+ "gio",
+ "glib",
+ "libc",
+]
+
+[[package]]
+name = "gdk-pixbuf-sys"
+version = "0.15.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7"
+dependencies = [
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "gdk-sys"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88"
+dependencies = [
+ "cairo-sys-rs",
+ "gdk-pixbuf-sys",
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "pango-sys",
+ "pkg-config",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "gdkwayland-sys"
+version = "0.15.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cca49a59ad8cfdf36ef7330fe7bdfbe1d34323220cc16a0de2679ee773aee2c2"
+dependencies = [
+ "gdk-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "pkg-config",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "gdkx11-sys"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4b7f8c7a84b407aa9b143877e267e848ff34106578b64d1e0a24bf550716178"
+dependencies = [
+ "gdk-sys",
+ "glib-sys",
+ "libc",
+ "system-deps 6.2.2",
+ "x11",
+]
+
+[[package]]
+name = "generator"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
+dependencies = [
+ "cc",
+ "libc",
+ "log",
+ "rustversion",
+ "windows 0.48.0",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.9.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "gimli"
+version = "0.28.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
+
+[[package]]
+name = "gio"
+version = "0.15.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b"
+dependencies = [
+ "bitflags 1.3.2",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "gio-sys",
+ "glib",
+ "libc",
+ "once_cell",
+ "thiserror",
+]
+
+[[package]]
+name = "gio-sys"
+version = "0.15.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d"
+dependencies = [
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps 6.2.2",
+ "winapi",
+]
+
+[[package]]
+name = "glib"
+version = "0.15.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d"
+dependencies = [
+ "bitflags 1.3.2",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-task",
+ "glib-macros",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "once_cell",
+ "smallvec",
+ "thiserror",
+]
+
+[[package]]
+name = "glib-macros"
+version = "0.15.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10c6ae9f6fa26f4fb2ac16b528d138d971ead56141de489f8111e259b9df3c4a"
+dependencies = [
+ "anyhow",
+ "heck 0.4.1",
+ "proc-macro-crate",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "glib-sys"
+version = "0.15.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4"
+dependencies = [
+ "libc",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "globset"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
+dependencies = [
+ "aho-corasick",
+ "bstr",
+ "log",
+ "regex-automata 0.4.6",
+ "regex-syntax 0.8.3",
+]
+
+[[package]]
+name = "gobject-sys"
+version = "0.15.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a"
+dependencies = [
+ "glib-sys",
+ "libc",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "gtk"
+version = "0.15.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92e3004a2d5d6d8b5057d2b57b3712c9529b62e82c77f25c1fecde1fd5c23bd0"
+dependencies = [
+ "atk",
+ "bitflags 1.3.2",
+ "cairo-rs",
+ "field-offset",
+ "futures-channel",
+ "gdk",
+ "gdk-pixbuf",
+ "gio",
+ "glib",
+ "gtk-sys",
+ "gtk3-macros",
+ "libc",
+ "once_cell",
+ "pango",
+ "pkg-config",
+]
+
+[[package]]
+name = "gtk-sys"
+version = "0.15.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84"
+dependencies = [
+ "atk-sys",
+ "cairo-sys-rs",
+ "gdk-pixbuf-sys",
+ "gdk-sys",
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "pango-sys",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "gtk3-macros"
+version = "0.15.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "684c0456c086e8e7e9af73ec5b84e35938df394712054550e81558d21c44ab0d"
+dependencies = [
+ "anyhow",
+ "proc-macro-crate",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+
+[[package]]
+name = "heck"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "html5ever"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7"
+dependencies = [
+ "log",
+ "mac",
+ "markup5ever",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "http"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa 1.0.11",
+]
+
+[[package]]
+name = "http-range"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "ico"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3804960be0bb5e4edb1e1ad67afd321a9ecfd875c3e65c099468fd2717d7cae"
+dependencies = [
+ "byteorder",
+ "png",
+]
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "idna"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "ignore"
+version = "0.4.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1"
+dependencies = [
+ "crossbeam-deque",
+ "globset",
+ "log",
+ "memchr",
+ "regex-automata 0.4.6",
+ "same-file",
+ "walkdir",
+ "winapi-util",
+]
+
+[[package]]
+name = "image"
+version = "0.24.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
+dependencies = [
+ "bytemuck",
+ "byteorder",
+ "color_quant",
+ "num-traits",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.12.3",
+ "serde",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.5",
+ "serde",
+]
+
+[[package]]
+name = "infer"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f551f8c3a39f68f986517db0d1759de85881894fdc7db798bd2a9df9cb04b7fc"
+dependencies = [
+ "cfb",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
+
+[[package]]
+name = "itoa"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+
+[[package]]
+name = "javascriptcore-rs"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf053e7843f2812ff03ef5afe34bb9c06ffee120385caad4f6b9967fcd37d41c"
+dependencies = [
+ "bitflags 1.3.2",
+ "glib",
+ "javascriptcore-rs-sys",
+]
+
+[[package]]
+name = "javascriptcore-rs-sys"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "905fbb87419c5cde6e3269537e4ea7d46431f3008c5d057e915ef3f115e7793c"
+dependencies = [
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps 5.0.0",
+]
+
+[[package]]
+name = "jni"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c"
+dependencies = [
+ "cesu8",
+ "combine",
+ "jni-sys",
+ "log",
+ "thiserror",
+ "walkdir",
+]
+
+[[package]]
+name = "jni-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
+
+[[package]]
+name = "js-sys"
+version = "0.3.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "json-patch"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b"
+dependencies = [
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
+[[package]]
+name = "kuchikiki"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8"
+dependencies = [
+ "cssparser",
+ "html5ever",
+ "indexmap 1.9.3",
+ "matches",
+ "selectors",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.155"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+
+[[package]]
+name = "libredox"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
+dependencies = [
+ "bitflags 2.5.0",
+ "libc",
+]
+
+[[package]]
+name = "line-wrap"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+
+[[package]]
+name = "lock_api"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
+
+[[package]]
+name = "loom"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
+dependencies = [
+ "cfg-if",
+ "generator",
+ "scoped-tls",
+ "serde",
+ "serde_json",
+ "tracing",
+ "tracing-subscriber",
+]
+
+[[package]]
+name = "mac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
+
+[[package]]
+name = "malloc_buf"
+version = "0.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "markup5ever"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016"
+dependencies = [
+ "log",
+ "phf 0.10.1",
+ "phf_codegen 0.10.0",
+ "string_cache",
+ "string_cache_codegen",
+ "tendril",
+]
+
+[[package]]
+name = "matchers"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
+dependencies = [
+ "regex-automata 0.1.10",
+]
+
+[[package]]
+name = "matches"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
+
+[[package]]
+name = "memchr"
+version = "2.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
+
+[[package]]
+name = "memoffset"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "miniz_oxide"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
+dependencies = [
+ "adler",
+ "simd-adler32",
+]
+
+[[package]]
+name = "ndk"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4"
+dependencies = [
+ "bitflags 1.3.2",
+ "jni-sys",
+ "ndk-sys",
+ "num_enum",
+ "thiserror",
+]
+
+[[package]]
+name = "ndk-context"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
+
+[[package]]
+name = "ndk-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97"
+dependencies = [
+ "jni-sys",
+]
+
+[[package]]
+name = "new_debug_unreachable"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
+
+[[package]]
+name = "nodrop"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
+
+[[package]]
+name = "nu-ansi-term"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
+dependencies = [
+ "overload",
+ "winapi",
+]
+
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "num_enum"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
+dependencies = [
+ "num_enum_derive",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "objc"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
+dependencies = [
+ "malloc_buf",
+ "objc_exception",
+]
+
+[[package]]
+name = "objc_exception"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "objc_id"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
+dependencies = [
+ "objc",
+]
+
+[[package]]
+name = "object"
+version = "0.32.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "open"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8"
+dependencies = [
+ "pathdiff",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "os_pipe"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "overload"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
+
+[[package]]
+name = "pango"
+version = "0.15.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f"
+dependencies = [
+ "bitflags 1.3.2",
+ "glib",
+ "libc",
+ "once_cell",
+ "pango-sys",
+]
+
+[[package]]
+name = "pango-sys"
+version = "0.15.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa"
+dependencies = [
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall 0.5.1",
+ "smallvec",
+ "windows-targets 0.52.5",
+]
+
+[[package]]
+name = "pathdiff"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+[[package]]
+name = "phf"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
+dependencies = [
+ "phf_macros 0.8.0",
+ "phf_shared 0.8.0",
+ "proc-macro-hack",
+]
+
+[[package]]
+name = "phf"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
+dependencies = [
+ "phf_shared 0.10.0",
+]
+
+[[package]]
+name = "phf"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
+dependencies = [
+ "phf_macros 0.11.2",
+ "phf_shared 0.11.2",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
+dependencies = [
+ "phf_generator 0.8.0",
+ "phf_shared 0.8.0",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"
+dependencies = [
+ "phf_generator 0.10.0",
+ "phf_shared 0.10.0",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
+dependencies = [
+ "phf_shared 0.8.0",
+ "rand 0.7.3",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
+dependencies = [
+ "phf_shared 0.10.0",
+ "rand 0.8.5",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
+dependencies = [
+ "phf_shared 0.11.2",
+ "rand 0.8.5",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
+dependencies = [
+ "phf_generator 0.8.0",
+ "phf_shared 0.8.0",
+ "proc-macro-hack",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
+dependencies = [
+ "phf_generator 0.11.2",
+ "phf_shared 0.11.2",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
+
+[[package]]
+name = "plist"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9"
+dependencies = [
+ "base64 0.21.7",
+ "indexmap 2.2.6",
+ "line-wrap",
+ "quick-xml",
+ "serde",
+ "time",
+]
+
+[[package]]
+name = "png"
+version = "0.17.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
+dependencies = [
+ "bitflags 1.3.2",
+ "crc32fast",
+ "fdeflate",
+ "flate2",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "precomputed-hash"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
+
+[[package]]
+name = "proc-macro-crate"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
+dependencies = [
+ "once_cell",
+ "toml_edit 0.19.15",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.20+deprecated"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quick-xml"
+version = "0.31.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom 0.1.16",
+ "libc",
+ "rand_chacha 0.2.2",
+ "rand_core 0.5.1",
+ "rand_hc",
+ "rand_pcg",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha 0.3.1",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom 0.1.16",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom 0.2.15",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "raw-window-handle"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
+
+[[package]]
+name = "redox_syscall"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
+dependencies = [
+ "bitflags 2.5.0",
+]
+
+[[package]]
+name = "redox_users"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
+dependencies = [
+ "getrandom 0.2.15",
+ "libredox",
+ "thiserror",
+]
+
+[[package]]
+name = "regex"
+version = "1.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata 0.4.6",
+ "regex-syntax 0.8.3",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+dependencies = [
+ "regex-syntax 0.6.29",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax 0.8.3",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "rustix"
+version = "0.38.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+dependencies = [
+ "bitflags 2.5.0",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
+
+[[package]]
+name = "ryu"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "scoped-tls"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "selectors"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe"
+dependencies = [
+ "bitflags 1.3.2",
+ "cssparser",
+ "derive_more",
+ "fxhash",
+ "log",
+ "matches",
+ "phf 0.8.0",
+ "phf_codegen 0.8.0",
+ "precomputed-hash",
+ "servo_arc",
+ "smallvec",
+ "thin-slice",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.202"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.202"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.117"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
+dependencies = [
+ "indexmap 2.2.6",
+ "itoa 1.0.11",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_repr"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde_with"
+version = "3.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20"
+dependencies = [
+ "base64 0.22.1",
+ "chrono",
+ "hex",
+ "indexmap 1.9.3",
+ "indexmap 2.2.6",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "serde_with_macros",
+ "time",
+]
+
+[[package]]
+name = "serde_with_macros"
+version = "3.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "serialize-to-javascript"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb"
+dependencies = [
+ "serde",
+ "serde_json",
+ "serialize-to-javascript-impl",
+]
+
+[[package]]
+name = "serialize-to-javascript-impl"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "servo_arc"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432"
+dependencies = [
+ "nodrop",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "sharded-slab"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "shared_child"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "simd-adler32"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
+
+[[package]]
+name = "siphasher"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+
+[[package]]
+name = "soup2"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2b4d76501d8ba387cf0fefbe055c3e0a59891d09f0f995ae4e4b16f6b60f3c0"
+dependencies = [
+ "bitflags 1.3.2",
+ "gio",
+ "glib",
+ "libc",
+ "once_cell",
+ "soup2-sys",
+]
+
+[[package]]
+name = "soup2-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "009ef427103fcb17f802871647a7fa6c60cbb654b4c4e4c0ac60a31c5f6dc9cf"
+dependencies = [
+ "bitflags 1.3.2",
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "libc",
+ "system-deps 5.0.0",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
+name = "state"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b"
+dependencies = [
+ "loom",
+]
+
+[[package]]
+name = "string_cache"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
+dependencies = [
+ "new_debug_unreachable",
+ "once_cell",
+ "parking_lot",
+ "phf_shared 0.10.0",
+ "precomputed-hash",
+ "serde",
+]
+
+[[package]]
+name = "string_cache_codegen"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988"
+dependencies = [
+ "phf_generator 0.10.0",
+ "phf_shared 0.10.0",
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.65"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "system-deps"
+version = "5.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e"
+dependencies = [
+ "cfg-expr 0.9.1",
+ "heck 0.3.3",
+ "pkg-config",
+ "toml 0.5.11",
+ "version-compare 0.0.11",
+]
+
+[[package]]
+name = "system-deps"
+version = "6.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
+dependencies = [
+ "cfg-expr 0.15.8",
+ "heck 0.5.0",
+ "pkg-config",
+ "toml 0.8.2",
+ "version-compare 0.2.0",
+]
+
+[[package]]
+name = "tao"
+version = "0.16.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "575c856fc21e551074869dcfaad8f706412bd5b803dfa0fbf6881c4ff4bfafab"
+dependencies = [
+ "bitflags 1.3.2",
+ "cairo-rs",
+ "cc",
+ "cocoa",
+ "core-foundation",
+ "core-graphics",
+ "crossbeam-channel",
+ "dispatch",
+ "gdk",
+ "gdk-pixbuf",
+ "gdk-sys",
+ "gdkwayland-sys",
+ "gdkx11-sys",
+ "gio",
+ "glib",
+ "glib-sys",
+ "gtk",
+ "image",
+ "instant",
+ "jni",
+ "lazy_static",
+ "libc",
+ "log",
+ "ndk",
+ "ndk-context",
+ "ndk-sys",
+ "objc",
+ "once_cell",
+ "parking_lot",
+ "png",
+ "raw-window-handle",
+ "scopeguard",
+ "serde",
+ "tao-macros",
+ "unicode-segmentation",
+ "uuid",
+ "windows 0.39.0",
+ "windows-implement",
+ "x11-dl",
+]
+
+[[package]]
+name = "tao-macros"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "tar"
+version = "0.4.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909"
+dependencies = [
+ "filetime",
+ "libc",
+ "xattr",
+]
+
+[[package]]
+name = "target-lexicon"
+version = "0.12.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
+
+[[package]]
+name = "tauri"
+version = "1.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77567d2b3b74de4588d544147142d02297f3eaa171a25a065252141d8597a516"
+dependencies = [
+ "anyhow",
+ "cocoa",
+ "dirs-next",
+ "dunce",
+ "embed_plist",
+ "encoding_rs",
+ "flate2",
+ "futures-util",
+ "getrandom 0.2.15",
+ "glib",
+ "glob",
+ "gtk",
+ "heck 0.5.0",
+ "http",
+ "ignore",
+ "objc",
+ "once_cell",
+ "open",
+ "os_pipe",
+ "percent-encoding",
+ "rand 0.8.5",
+ "raw-window-handle",
+ "regex",
+ "semver",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "serialize-to-javascript",
+ "shared_child",
+ "state",
+ "tar",
+ "tauri-macros",
+ "tauri-runtime",
+ "tauri-runtime-wry",
+ "tauri-utils",
+ "tempfile",
+ "thiserror",
+ "tokio",
+ "url",
+ "uuid",
+ "webkit2gtk",
+ "webview2-com",
+ "windows 0.39.0",
+]
+
+[[package]]
+name = "tauri-app"
+version = "0.0.0"
+dependencies = [
+ "serde",
+ "serde_json",
+ "tauri",
+ "tauri-build",
+]
+
+[[package]]
+name = "tauri-build"
+version = "1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab30cba12974d0f9b09794f61e72cad6da2142d3ceb81e519321bab86ce53312"
+dependencies = [
+ "anyhow",
+ "cargo_toml",
+ "dirs-next",
+ "heck 0.5.0",
+ "json-patch",
+ "semver",
+ "serde",
+ "serde_json",
+ "tauri-utils",
+ "tauri-winres",
+ "walkdir",
+]
+
+[[package]]
+name = "tauri-codegen"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3a1d90db526a8cdfd54444ad3f34d8d4d58fa5c536463915942393743bd06f8"
+dependencies = [
+ "base64 0.21.7",
+ "brotli",
+ "ico",
+ "json-patch",
+ "plist",
+ "png",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "semver",
+ "serde",
+ "serde_json",
+ "sha2",
+ "tauri-utils",
+ "thiserror",
+ "time",
+ "uuid",
+ "walkdir",
+]
+
+[[package]]
+name = "tauri-macros"
+version = "1.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a582d75414250122e4a597b9dd7d3c910a2c77906648fc2ac9353845ff0feec"
+dependencies = [
+ "heck 0.5.0",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "tauri-codegen",
+ "tauri-utils",
+]
+
+[[package]]
+name = "tauri-runtime"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd7ffddf36d450791018e63a3ddf54979b9581d9644c584a5fb5611e6b5f20b4"
+dependencies = [
+ "gtk",
+ "http",
+ "http-range",
+ "rand 0.8.5",
+ "raw-window-handle",
+ "serde",
+ "serde_json",
+ "tauri-utils",
+ "thiserror",
+ "url",
+ "uuid",
+ "webview2-com",
+ "windows 0.39.0",
+]
+
+[[package]]
+name = "tauri-runtime-wry"
+version = "0.14.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1989b3b4d611f5428b3414a4abae6fa6df30c7eb8ed33250ca90a5f7e5bb3655"
+dependencies = [
+ "cocoa",
+ "gtk",
+ "percent-encoding",
+ "rand 0.8.5",
+ "raw-window-handle",
+ "tauri-runtime",
+ "tauri-utils",
+ "uuid",
+ "webkit2gtk",
+ "webview2-com",
+ "windows 0.39.0",
+ "wry",
+]
+
+[[package]]
+name = "tauri-utils"
+version = "1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "450b17a7102e5d46d4bdabae0d1590fd27953e704e691fc081f06c06d2253b35"
+dependencies = [
+ "brotli",
+ "ctor",
+ "dunce",
+ "glob",
+ "heck 0.5.0",
+ "html5ever",
+ "infer",
+ "json-patch",
+ "kuchikiki",
+ "log",
+ "memchr",
+ "phf 0.11.2",
+ "proc-macro2",
+ "quote",
+ "semver",
+ "serde",
+ "serde_json",
+ "serde_with",
+ "thiserror",
+ "url",
+ "walkdir",
+ "windows-version",
+]
+
+[[package]]
+name = "tauri-winres"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb"
+dependencies = [
+ "embed-resource",
+ "toml 0.7.8",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "rustix",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "tendril"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0"
+dependencies = [
+ "futf",
+ "mac",
+ "utf-8",
+]
+
+[[package]]
+name = "thin-slice"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
+
+[[package]]
+name = "thiserror"
+version = "1.0.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
+[[package]]
+name = "time"
+version = "0.3.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
+dependencies = [
+ "deranged",
+ "itoa 1.0.11",
+ "num-conv",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
+[[package]]
+name = "time-macros"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "tokio"
+version = "1.37.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
+dependencies = [
+ "backtrace",
+ "bytes",
+ "num_cpus",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit 0.19.15",
+]
+
+[[package]]
+name = "toml"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit 0.20.2",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.19.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
+dependencies = [
+ "indexmap 2.2.6",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
+dependencies = [
+ "indexmap 2.2.6",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "tracing"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
+dependencies = [
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.65",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
+dependencies = [
+ "once_cell",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
+dependencies = [
+ "log",
+ "once_cell",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
+dependencies = [
+ "matchers",
+ "nu-ansi-term",
+ "once_cell",
+ "regex",
+ "sharded-slab",
+ "smallvec",
+ "thread_local",
+ "tracing",
+ "tracing-core",
+ "tracing-log",
+]
+
+[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
+
+[[package]]
+name = "url"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
+name = "uuid"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
+dependencies = [
+ "getrandom 0.2.15",
+]
+
+[[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
+[[package]]
+name = "version-compare"
+version = "0.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b"
+
+[[package]]
+name = "version-compare"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "vswhom"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
+dependencies = [
+ "libc",
+ "vswhom-sys",
+]
+
+[[package]]
+name = "vswhom-sys"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "walkdir"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.65",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.65",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
+
+[[package]]
+name = "webkit2gtk"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8f859735e4a452aeb28c6c56a852967a8a76c8eb1cc32dbf931ad28a13d6370"
+dependencies = [
+ "bitflags 1.3.2",
+ "cairo-rs",
+ "gdk",
+ "gdk-sys",
+ "gio",
+ "gio-sys",
+ "glib",
+ "glib-sys",
+ "gobject-sys",
+ "gtk",
+ "gtk-sys",
+ "javascriptcore-rs",
+ "libc",
+ "once_cell",
+ "soup2",
+ "webkit2gtk-sys",
+]
+
+[[package]]
+name = "webkit2gtk-sys"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d76ca6ecc47aeba01ec61e480139dda143796abcae6f83bcddf50d6b5b1dcf3"
+dependencies = [
+ "atk-sys",
+ "bitflags 1.3.2",
+ "cairo-sys-rs",
+ "gdk-pixbuf-sys",
+ "gdk-sys",
+ "gio-sys",
+ "glib-sys",
+ "gobject-sys",
+ "gtk-sys",
+ "javascriptcore-rs-sys",
+ "libc",
+ "pango-sys",
+ "pkg-config",
+ "soup2-sys",
+ "system-deps 6.2.2",
+]
+
+[[package]]
+name = "webview2-com"
+version = "0.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4a769c9f1a64a8734bde70caafac2b96cada12cd4aefa49196b3a386b8b4178"
+dependencies = [
+ "webview2-com-macros",
+ "webview2-com-sys",
+ "windows 0.39.0",
+ "windows-implement",
+]
+
+[[package]]
+name = "webview2-com-macros"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "webview2-com-sys"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aac48ef20ddf657755fdcda8dfed2a7b4fc7e4581acce6fe9b88c3d64f29dee7"
+dependencies = [
+ "regex",
+ "serde",
+ "serde_json",
+ "thiserror",
+ "windows 0.39.0",
+ "windows-bindgen",
+ "windows-metadata",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
+dependencies = [
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a"
+dependencies = [
+ "windows-implement",
+ "windows_aarch64_msvc 0.39.0",
+ "windows_i686_gnu 0.39.0",
+ "windows_i686_msvc 0.39.0",
+ "windows_x86_64_gnu 0.39.0",
+ "windows_x86_64_msvc 0.39.0",
+]
+
+[[package]]
+name = "windows"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
+dependencies = [
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-bindgen"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68003dbd0e38abc0fb85b939240f4bce37c43a5981d3df37ccbaaa981b47cb41"
+dependencies = [
+ "windows-metadata",
+ "windows-tokens",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+dependencies = [
+ "windows-targets 0.52.5",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7"
+dependencies = [
+ "syn 1.0.109",
+ "windows-tokens",
+]
+
+[[package]]
+name = "windows-metadata"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278"
+
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.5",
+ "windows_aarch64_msvc 0.52.5",
+ "windows_i686_gnu 0.52.5",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc 0.52.5",
+ "windows_x86_64_gnu 0.52.5",
+ "windows_x86_64_gnullvm 0.52.5",
+ "windows_x86_64_msvc 0.52.5",
+]
+
+[[package]]
+name = "windows-tokens"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597"
+
+[[package]]
+name = "windows-version"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515"
+dependencies = [
+ "windows-targets 0.52.5",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
+
+[[package]]
+name = "winnow"
+version = "0.5.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "winreg"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
+dependencies = [
+ "cfg-if",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "wry"
+version = "0.24.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00711278ed357350d44c749c286786ecac644e044e4da410d466212152383b45"
+dependencies = [
+ "base64 0.13.1",
+ "block",
+ "cocoa",
+ "core-graphics",
+ "crossbeam-channel",
+ "dunce",
+ "gdk",
+ "gio",
+ "glib",
+ "gtk",
+ "html5ever",
+ "http",
+ "kuchikiki",
+ "libc",
+ "log",
+ "objc",
+ "objc_id",
+ "once_cell",
+ "serde",
+ "serde_json",
+ "sha2",
+ "soup2",
+ "tao",
+ "thiserror",
+ "url",
+ "webkit2gtk",
+ "webkit2gtk-sys",
+ "webview2-com",
+ "windows 0.39.0",
+ "windows-implement",
+]
+
+[[package]]
+name = "x11"
+version = "2.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e"
+dependencies = [
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "x11-dl"
+version = "2.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f"
+dependencies = [
+ "libc",
+ "once_cell",
+ "pkg-config",
+]
+
+[[package]]
+name = "xattr"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f"
+dependencies = [
+ "libc",
+ "linux-raw-sys",
+ "rustix",
+]
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
new file mode 100644
index 00000000..b1889c5d
--- /dev/null
+++ b/src-tauri/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "tauri-app"
+version = "0.0.0"
+description = "A Tauri App"
+authors = ["you"]
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[build-dependencies]
+tauri-build = { version = "1", features = [] }
+
+[dependencies]
+tauri = { version = "1", features = [ "window-set-always-on-top", "window-create", "window-close", "shell-sidecar", "shell-open", "devtools"] }
+serde = { version = "1", features = ["derive"] }
+serde_json = "1"
+
+[features]
+# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
+custom-protocol = ["tauri/custom-protocol"]
diff --git a/src-tauri/build.rs b/src-tauri/build.rs
new file mode 100644
index 00000000..2ba80a8b
--- /dev/null
+++ b/src-tauri/build.rs
@@ -0,0 +1,3 @@
+fn main() {
+ tauri_build::build()
+}
diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png
new file mode 100644
index 00000000..6be5e50e
Binary files /dev/null and b/src-tauri/icons/128x128.png differ
diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png
new file mode 100644
index 00000000..e81becee
Binary files /dev/null and b/src-tauri/icons/128x128@2x.png differ
diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png
new file mode 100644
index 00000000..a437dd51
Binary files /dev/null and b/src-tauri/icons/32x32.png differ
diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png
new file mode 100644
index 00000000..0ca4f271
Binary files /dev/null and b/src-tauri/icons/Square107x107Logo.png differ
diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png
new file mode 100644
index 00000000..b81f8203
Binary files /dev/null and b/src-tauri/icons/Square142x142Logo.png differ
diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png
new file mode 100644
index 00000000..624c7bfb
Binary files /dev/null and b/src-tauri/icons/Square150x150Logo.png differ
diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png
new file mode 100644
index 00000000..c021d2ba
Binary files /dev/null and b/src-tauri/icons/Square284x284Logo.png differ
diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png
new file mode 100644
index 00000000..62197002
Binary files /dev/null and b/src-tauri/icons/Square30x30Logo.png differ
diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png
new file mode 100644
index 00000000..f9bc0483
Binary files /dev/null and b/src-tauri/icons/Square310x310Logo.png differ
diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png
new file mode 100644
index 00000000..d5fbfb2a
Binary files /dev/null and b/src-tauri/icons/Square44x44Logo.png differ
diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png
new file mode 100644
index 00000000..63440d79
Binary files /dev/null and b/src-tauri/icons/Square71x71Logo.png differ
diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png
new file mode 100644
index 00000000..f3f705af
Binary files /dev/null and b/src-tauri/icons/Square89x89Logo.png differ
diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png
new file mode 100644
index 00000000..45563882
Binary files /dev/null and b/src-tauri/icons/StoreLogo.png differ
diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns
new file mode 100644
index 00000000..12a5bcee
Binary files /dev/null and b/src-tauri/icons/icon.icns differ
diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico
new file mode 100644
index 00000000..b3636e4b
Binary files /dev/null and b/src-tauri/icons/icon.ico differ
diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png
new file mode 100644
index 00000000..e1cd2619
Binary files /dev/null and b/src-tauri/icons/icon.png differ
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
new file mode 100644
index 00000000..7bb53643
--- /dev/null
+++ b/src-tauri/src/main.rs
@@ -0,0 +1,17 @@
+// Prevents additional console window on Windows in release, DO NOT REMOVE!!
+#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
+
+// use tauri::command;
+use tauri::Manager;
+fn main() {
+ tauri::Builder::default()
+ .setup(|app| {
+ #[cfg(debug_assertions)]
+ app.get_window("main").unwrap().open_devtools(); // `main` is the first window from tauri.conf.json without an explicit label
+ Ok(())
+ })
+ // .invoke_handler(tauri::generate_handler![greet, run_python_script])
+ .run(tauri::generate_context!())
+ .expect("error while running tauri application");
+
+}
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
new file mode 100644
index 00000000..d2ac4a51
--- /dev/null
+++ b/src-tauri/tauri.conf.json
@@ -0,0 +1,57 @@
+{
+ "build": {
+ "beforeDevCommand": "npm run build-python && npm run dev",
+ "beforeBuildCommand": "npm run build-python && npm run build",
+ "devPath": "http://localhost:1420",
+ "distDir": "../dist"
+ },
+ "package": {
+ "productName": "tauri-app",
+ "version": "0.0.0"
+ },
+ "tauri": {
+ "allowlist": {
+ "all": false,
+ "window": {
+ "create": true,
+ "close": true,
+ "setAlwaysOnTop": true
+ },
+ "shell": {
+ "all": false,
+ "open": true,
+ "sidecar": true,
+ "scope": [
+ {
+ "name": "bin/test", "sidecar": true,"args": true
+ }
+ ]
+ }
+ },
+ "windows": [
+ {
+ "title": "tauri-app",
+ "width": 870,
+ "height": 654
+ }
+ ],
+ "security": {
+ "csp": null
+ },
+ "bundle": {
+ "active": true,
+ "targets": "all",
+ "identifier": "com.tauri-test.dev",
+ "icon": [
+ "icons/32x32.png",
+ "icons/128x128.png",
+ "icons/128x128@2x.png",
+ "icons/icon.icns",
+ "icons/icon.ico"
+ ],
+ "externalBin": [
+ "bin/test"
+ ]
+ }
+ }
+}
diff --git a/src-ui/assets/about_vrct/contributors_github_icon.png b/src-ui/assets/about_vrct/contributors_github_icon.png
new file mode 100644
index 00000000..7742d535
Binary files /dev/null and b/src-ui/assets/about_vrct/contributors_github_icon.png differ
diff --git a/img/about_vrct/contributors_members.png b/src-ui/assets/about_vrct/contributors_members.png
similarity index 100%
rename from img/about_vrct/contributors_members.png
rename to src-ui/assets/about_vrct/contributors_members.png
diff --git a/img/about_vrct/contributors_section_title.png b/src-ui/assets/about_vrct/contributors_section_title.png
similarity index 100%
rename from img/about_vrct/contributors_section_title.png
rename to src-ui/assets/about_vrct/contributors_section_title.png
diff --git a/src-ui/assets/about_vrct/contributors_x_icon.png b/src-ui/assets/about_vrct/contributors_x_icon.png
new file mode 100644
index 00000000..26f5f0c4
Binary files /dev/null and b/src-ui/assets/about_vrct/contributors_x_icon.png differ
diff --git a/src-ui/assets/about_vrct/dev_github_icon.png b/src-ui/assets/about_vrct/dev_github_icon.png
new file mode 100644
index 00000000..f6fcee5c
Binary files /dev/null and b/src-ui/assets/about_vrct/dev_github_icon.png differ
diff --git a/src-ui/assets/about_vrct/dev_misya.png b/src-ui/assets/about_vrct/dev_misya.png
new file mode 100644
index 00000000..8557922f
Binary files /dev/null and b/src-ui/assets/about_vrct/dev_misya.png differ
diff --git a/img/about_vrct/dev_section_title.png b/src-ui/assets/about_vrct/dev_section_title.png
similarity index 100%
rename from img/about_vrct/dev_section_title.png
rename to src-ui/assets/about_vrct/dev_section_title.png
diff --git a/src-ui/assets/about_vrct/dev_shiina.png b/src-ui/assets/about_vrct/dev_shiina.png
new file mode 100644
index 00000000..62c40845
Binary files /dev/null and b/src-ui/assets/about_vrct/dev_shiina.png differ
diff --git a/src-ui/assets/about_vrct/dev_x_icon.png b/src-ui/assets/about_vrct/dev_x_icon.png
new file mode 100644
index 00000000..50534df7
Binary files /dev/null and b/src-ui/assets/about_vrct/dev_x_icon.png differ
diff --git a/img/about_vrct/localization_members.png b/src-ui/assets/about_vrct/localization_members.png
similarity index 100%
rename from img/about_vrct/localization_members.png
rename to src-ui/assets/about_vrct/localization_members.png
diff --git a/img/about_vrct/localization_title.png b/src-ui/assets/about_vrct/localization_section_title.png
similarity index 100%
rename from img/about_vrct/localization_title.png
rename to src-ui/assets/about_vrct/localization_section_title.png
diff --git a/img/about_vrct/poster_showcase_section_title.png b/src-ui/assets/about_vrct/poster_showcase_section_title.png
similarity index 100%
rename from img/about_vrct/poster_showcase_section_title.png
rename to src-ui/assets/about_vrct/poster_showcase_section_title.png
diff --git a/img/about_vrct/project_link_booth.png b/src-ui/assets/about_vrct/project_link_booth.png
similarity index 100%
rename from img/about_vrct/project_link_booth.png
rename to src-ui/assets/about_vrct/project_link_booth.png
diff --git a/img/about_vrct/project_link_contact_us.png b/src-ui/assets/about_vrct/project_link_contact_us.png
similarity index 100%
rename from img/about_vrct/project_link_contact_us.png
rename to src-ui/assets/about_vrct/project_link_contact_us.png
diff --git a/img/about_vrct/project_link_documents.png b/src-ui/assets/about_vrct/project_link_documents.png
similarity index 100%
rename from img/about_vrct/project_link_documents.png
rename to src-ui/assets/about_vrct/project_link_documents.png
diff --git a/img/about_vrct/project_link_vrct_github.png b/src-ui/assets/about_vrct/project_link_vrct_github.png
similarity index 100%
rename from img/about_vrct/project_link_vrct_github.png
rename to src-ui/assets/about_vrct/project_link_vrct_github.png
diff --git a/img/about_vrct/showcased_worlds/bar_asagao.png b/src-ui/assets/about_vrct/showcased_worlds/bar_asagao.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/bar_asagao.png
rename to src-ui/assets/about_vrct/showcased_worlds/bar_asagao.png
diff --git a/img/about_vrct/showcased_worlds/cafe_cian.png b/src-ui/assets/about_vrct/showcased_worlds/cafe_cian.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/cafe_cian.png
rename to src-ui/assets/about_vrct/showcased_worlds/cafe_cian.png
diff --git a/img/about_vrct/showcased_worlds/chakachaka_multipurpose_room.png b/src-ui/assets/about_vrct/showcased_worlds/chakachaka_multipurpose_room.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/chakachaka_multipurpose_room.png
rename to src-ui/assets/about_vrct/showcased_worlds/chakachaka_multipurpose_room.png
diff --git a/img/about_vrct/showcased_worlds/ehon_no_heikousekai_jimusho.png b/src-ui/assets/about_vrct/showcased_worlds/ehon_no_heikousekai_jimusho.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/ehon_no_heikousekai_jimusho.png
rename to src-ui/assets/about_vrct/showcased_worlds/ehon_no_heikousekai_jimusho.png
diff --git a/img/about_vrct/showcased_worlds/ikoiba.png b/src-ui/assets/about_vrct/showcased_worlds/ikoiba.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/ikoiba.png
rename to src-ui/assets/about_vrct/showcased_worlds/ikoiba.png
diff --git a/img/about_vrct/showcased_worlds/ippaidou.png b/src-ui/assets/about_vrct/showcased_worlds/ippaidou.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/ippaidou.png
rename to src-ui/assets/about_vrct/showcased_worlds/ippaidou.png
diff --git a/img/about_vrct/showcased_worlds/japanese_culture_osenbeito.png b/src-ui/assets/about_vrct/showcased_worlds/japanese_culture_osenbeito.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/japanese_culture_osenbeito.png
rename to src-ui/assets/about_vrct/showcased_worlds/japanese_culture_osenbeito.png
diff --git a/img/about_vrct/showcased_worlds/kimodameshi.png b/src-ui/assets/about_vrct/showcased_worlds/kimodameshi.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/kimodameshi.png
rename to src-ui/assets/about_vrct/showcased_worlds/kimodameshi.png
diff --git a/img/about_vrct/showcased_worlds/kokekkopiyopiyo.png b/src-ui/assets/about_vrct/showcased_worlds/kokekkopiyopiyo.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/kokekkopiyopiyo.png
rename to src-ui/assets/about_vrct/showcased_worlds/kokekkopiyopiyo.png
diff --git a/img/about_vrct/showcased_worlds/kr_jp_exchange.png b/src-ui/assets/about_vrct/showcased_worlds/kr_jp_exchange.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/kr_jp_exchange.png
rename to src-ui/assets/about_vrct/showcased_worlds/kr_jp_exchange.png
diff --git a/img/about_vrct/showcased_worlds/kuroinu_work_room.png b/src-ui/assets/about_vrct/showcased_worlds/kuroinu_work_room.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/kuroinu_work_room.png
rename to src-ui/assets/about_vrct/showcased_worlds/kuroinu_work_room.png
diff --git a/img/about_vrct/showcased_worlds/language_exchange_tervern.png b/src-ui/assets/about_vrct/showcased_worlds/language_exchange_tervern.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/language_exchange_tervern.png
rename to src-ui/assets/about_vrct/showcased_worlds/language_exchange_tervern.png
diff --git a/img/about_vrct/showcased_worlds/mamehinata_dogrun.png b/src-ui/assets/about_vrct/showcased_worlds/mamehinata_dogrun.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/mamehinata_dogrun.png
rename to src-ui/assets/about_vrct/showcased_worlds/mamehinata_dogrun.png
diff --git a/img/about_vrct/showcased_worlds/monogatari_meetup.png b/src-ui/assets/about_vrct/showcased_worlds/monogatari_meetup.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/monogatari_meetup.png
rename to src-ui/assets/about_vrct/showcased_worlds/monogatari_meetup.png
diff --git a/img/about_vrct/showcased_worlds/nihongokurabu.png b/src-ui/assets/about_vrct/showcased_worlds/nihongokurabu.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/nihongokurabu.png
rename to src-ui/assets/about_vrct/showcased_worlds/nihongokurabu.png
diff --git a/img/about_vrct/showcased_worlds/parallel_collar.png b/src-ui/assets/about_vrct/showcased_worlds/parallel_collar.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/parallel_collar.png
rename to src-ui/assets/about_vrct/showcased_worlds/parallel_collar.png
diff --git a/img/about_vrct/showcased_worlds/re_yatuha_room.png b/src-ui/assets/about_vrct/showcased_worlds/re_yatuha_room.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/re_yatuha_room.png
rename to src-ui/assets/about_vrct/showcased_worlds/re_yatuha_room.png
diff --git a/img/about_vrct/showcased_worlds/silakan_datang_ke_rumahku.png b/src-ui/assets/about_vrct/showcased_worlds/silakan_datang_ke_rumahku.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/silakan_datang_ke_rumahku.png
rename to src-ui/assets/about_vrct/showcased_worlds/silakan_datang_ke_rumahku.png
diff --git a/img/about_vrct/showcased_worlds/smokerz_guild_v2.png b/src-ui/assets/about_vrct/showcased_worlds/smokerz_guild_v2.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/smokerz_guild_v2.png
rename to src-ui/assets/about_vrct/showcased_worlds/smokerz_guild_v2.png
diff --git a/img/about_vrct/showcased_worlds/stretch_club_starting_from_minus.png b/src-ui/assets/about_vrct/showcased_worlds/stretch_club_starting_from_minus.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/stretch_club_starting_from_minus.png
rename to src-ui/assets/about_vrct/showcased_worlds/stretch_club_starting_from_minus.png
diff --git a/img/about_vrct/showcased_worlds/study_japanese_world_japanichijou.png b/src-ui/assets/about_vrct/showcased_worlds/study_japanese_world_japanichijou.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/study_japanese_world_japanichijou.png
rename to src-ui/assets/about_vrct/showcased_worlds/study_japanese_world_japanichijou.png
diff --git a/img/about_vrct/showcased_worlds/sushi_guru_annex.png b/src-ui/assets/about_vrct/showcased_worlds/sushi_guru_annex.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/sushi_guru_annex.png
rename to src-ui/assets/about_vrct/showcased_worlds/sushi_guru_annex.png
diff --git a/img/about_vrct/showcased_worlds/sushi_stand_guruguru.png b/src-ui/assets/about_vrct/showcased_worlds/sushi_stand_guruguru.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/sushi_stand_guruguru.png
rename to src-ui/assets/about_vrct/showcased_worlds/sushi_stand_guruguru.png
diff --git a/img/about_vrct/showcased_worlds/tyuuniti_kouryuukai.png b/src-ui/assets/about_vrct/showcased_worlds/tyuuniti_kouryuukai.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/tyuuniti_kouryuukai.png
rename to src-ui/assets/about_vrct/showcased_worlds/tyuuniti_kouryuukai.png
diff --git a/img/about_vrct/showcased_worlds/uj_club.png b/src-ui/assets/about_vrct/showcased_worlds/uj_club.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/uj_club.png
rename to src-ui/assets/about_vrct/showcased_worlds/uj_club.png
diff --git a/img/about_vrct/showcased_worlds/usanezumi_shrine2.png b/src-ui/assets/about_vrct/showcased_worlds/usanezumi_shrine2.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/usanezumi_shrine2.png
rename to src-ui/assets/about_vrct/showcased_worlds/usanezumi_shrine2.png
diff --git a/img/about_vrct/showcased_worlds/yuttari_eikaiwa.png b/src-ui/assets/about_vrct/showcased_worlds/yuttari_eikaiwa.png
similarity index 100%
rename from img/about_vrct/showcased_worlds/yuttari_eikaiwa.png
rename to src-ui/assets/about_vrct/showcased_worlds/yuttari_eikaiwa.png
diff --git a/src-ui/assets/about_vrct/special_thanks_members.png b/src-ui/assets/about_vrct/special_thanks_members.png
new file mode 100644
index 00000000..80be4a66
Binary files /dev/null and b/src-ui/assets/about_vrct/special_thanks_members.png differ
diff --git a/img/about_vrct/special_thanks_message_en.png b/src-ui/assets/about_vrct/special_thanks_message_en.png
similarity index 100%
rename from img/about_vrct/special_thanks_message_en.png
rename to src-ui/assets/about_vrct/special_thanks_message_en.png
diff --git a/img/about_vrct/special_thanks_message_ja.png b/src-ui/assets/about_vrct/special_thanks_message_ja.png
similarity index 100%
rename from img/about_vrct/special_thanks_message_ja.png
rename to src-ui/assets/about_vrct/special_thanks_message_ja.png
diff --git a/img/about_vrct/special_thanks_section_title.png b/src-ui/assets/about_vrct/special_thanks_section_title.png
similarity index 100%
rename from img/about_vrct/special_thanks_section_title.png
rename to src-ui/assets/about_vrct/special_thanks_section_title.png
diff --git a/img/about_vrct/vrchat_disclaimer.png b/src-ui/assets/about_vrct/vrchat_disclaimer.png
similarity index 100%
rename from img/about_vrct/vrchat_disclaimer.png
rename to src-ui/assets/about_vrct/vrchat_disclaimer.png
diff --git a/img/about_vrct/vrct_logo_for_about_vrct.png b/src-ui/assets/about_vrct/vrct_logo_for_about_vrct.png
similarity index 100%
rename from img/about_vrct/vrct_logo_for_about_vrct.png
rename to src-ui/assets/about_vrct/vrct_logo_for_about_vrct.png
diff --git a/img/about_vrct/poster_images_authors_en.png b/src-ui/assets/about_vrct/vrct_posters/authors/poster_images_authors_en.png
similarity index 100%
rename from img/about_vrct/poster_images_authors_en.png
rename to src-ui/assets/about_vrct/vrct_posters/authors/poster_images_authors_en.png
diff --git a/img/about_vrct/poster_images_authors_ja.png b/src-ui/assets/about_vrct/vrct_posters/authors/poster_images_authors_ja.png
similarity index 100%
rename from img/about_vrct/poster_images_authors_ja.png
rename to src-ui/assets/about_vrct/vrct_posters/authors/poster_images_authors_ja.png
diff --git a/img/about_vrct/poster_images_authors_m_en.png b/src-ui/assets/about_vrct/vrct_posters/authors/poster_images_authors_m_en.png
similarity index 100%
rename from img/about_vrct/poster_images_authors_m_en.png
rename to src-ui/assets/about_vrct/vrct_posters/authors/poster_images_authors_m_en.png
diff --git a/img/about_vrct/poster_images_authors_m_ja.png b/src-ui/assets/about_vrct/vrct_posters/authors/poster_images_authors_m_ja.png
similarity index 100%
rename from img/about_vrct/poster_images_authors_m_ja.png
rename to src-ui/assets/about_vrct/vrct_posters/authors/poster_images_authors_m_ja.png
diff --git a/img/about_vrct/vrct_posters/iya_vrct_manga_en.png b/src-ui/assets/about_vrct/vrct_posters/iya_vrct_manga_en.png
similarity index 100%
rename from img/about_vrct/vrct_posters/iya_vrct_manga_en.png
rename to src-ui/assets/about_vrct/vrct_posters/iya_vrct_manga_en.png
diff --git a/img/about_vrct/vrct_posters/iya_vrct_manga_ja.png b/src-ui/assets/about_vrct/vrct_posters/iya_vrct_manga_ja.png
similarity index 100%
rename from img/about_vrct/vrct_posters/iya_vrct_manga_ja.png
rename to src-ui/assets/about_vrct/vrct_posters/iya_vrct_manga_ja.png
diff --git a/img/about_vrct/vrct_posters/iya_vrct_manga_ko.png b/src-ui/assets/about_vrct/vrct_posters/iya_vrct_manga_ko.png
similarity index 100%
rename from img/about_vrct/vrct_posters/iya_vrct_manga_ko.png
rename to src-ui/assets/about_vrct/vrct_posters/iya_vrct_manga_ko.png
diff --git a/img/about_vrct/vrct_posters/iya_vrct_poster_cn.png b/src-ui/assets/about_vrct/vrct_posters/iya_vrct_poster_cn.png
similarity index 100%
rename from img/about_vrct/vrct_posters/iya_vrct_poster_cn.png
rename to src-ui/assets/about_vrct/vrct_posters/iya_vrct_poster_cn.png
diff --git a/img/about_vrct/vrct_posters/iya_vrct_poster_en.png b/src-ui/assets/about_vrct/vrct_posters/iya_vrct_poster_en.png
similarity index 100%
rename from img/about_vrct/vrct_posters/iya_vrct_poster_en.png
rename to src-ui/assets/about_vrct/vrct_posters/iya_vrct_poster_en.png
diff --git a/img/about_vrct/vrct_posters/iya_vrct_poster_ja.png b/src-ui/assets/about_vrct/vrct_posters/iya_vrct_poster_ja.png
similarity index 100%
rename from img/about_vrct/vrct_posters/iya_vrct_poster_ja.png
rename to src-ui/assets/about_vrct/vrct_posters/iya_vrct_poster_ja.png
diff --git a/img/about_vrct/vrct_posters/iya_vrct_poster_ko.png b/src-ui/assets/about_vrct/vrct_posters/iya_vrct_poster_ko.png
similarity index 100%
rename from img/about_vrct/vrct_posters/iya_vrct_poster_ko.png
rename to src-ui/assets/about_vrct/vrct_posters/iya_vrct_poster_ko.png
diff --git a/src-ui/assets/arrow_left.svg b/src-ui/assets/arrow_left.svg
new file mode 100644
index 00000000..3c024b0e
--- /dev/null
+++ b/src-ui/assets/arrow_left.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/img/vrct_logo_mark_white.png b/src-ui/assets/chato_white.png
similarity index 100%
rename from img/vrct_logo_mark_white.png
rename to src-ui/assets/chato_white.png
diff --git a/img/vrct_logo_mark_white_square.png b/src-ui/assets/chato_white_square.png
similarity index 100%
rename from img/vrct_logo_mark_white_square.png
rename to src-ui/assets/chato_white_square.png
diff --git a/src-ui/assets/configuration.svg b/src-ui/assets/configuration.svg
new file mode 100644
index 00000000..30040dd3
--- /dev/null
+++ b/src-ui/assets/configuration.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src-ui/assets/foreground.svg b/src-ui/assets/foreground.svg
new file mode 100644
index 00000000..fdc2e961
--- /dev/null
+++ b/src-ui/assets/foreground.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src-ui/assets/headphones.svg b/src-ui/assets/headphones.svg
new file mode 100644
index 00000000..f10c55ce
--- /dev/null
+++ b/src-ui/assets/headphones.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src-ui/assets/help.svg b/src-ui/assets/help.svg
new file mode 100644
index 00000000..2f67b2ae
--- /dev/null
+++ b/src-ui/assets/help.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src-ui/assets/mic.svg b/src-ui/assets/mic.svg
new file mode 100644
index 00000000..cdf9b3bd
--- /dev/null
+++ b/src-ui/assets/mic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src-ui/assets/narrow_arrow_down.svg b/src-ui/assets/narrow_arrow_down.svg
new file mode 100644
index 00000000..c97aef15
--- /dev/null
+++ b/src-ui/assets/narrow_arrow_down.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src-ui/assets/send_message.svg b/src-ui/assets/send_message.svg
new file mode 100644
index 00000000..d1ed3d32
--- /dev/null
+++ b/src-ui/assets/send_message.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src-ui/assets/translation.svg b/src-ui/assets/translation.svg
new file mode 100644
index 00000000..3038de79
--- /dev/null
+++ b/src-ui/assets/translation.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/img/vrct_logo_for_dark_mode.png b/src-ui/assets/vrct_logo_for_dark_mode.png
similarity index 100%
rename from img/vrct_logo_for_dark_mode.png
rename to src-ui/assets/vrct_logo_for_dark_mode.png
diff --git a/src-ui/store.js b/src-ui/store.js
new file mode 100644
index 00000000..bdd91866
--- /dev/null
+++ b/src-ui/store.js
@@ -0,0 +1,190 @@
+import {
+ atom,
+ useAtomValue,
+ useSetAtom
+} from "jotai";
+
+import { translator_list, generateTestData } from "@data";
+
+export const store = {
+ backend_subprocess: null,
+ config_window: null,
+ log_box_ref: null,
+};
+
+const createAtomWithHook = (initialValue, property_names) => {
+ const atomInstance = atom(initialValue);
+
+ const useHook = () => {
+ const currentAtom = useAtomValue(atomInstance);
+
+ const setAtom = useSetAtom(atomInstance);
+
+ const updateAtom = (value) => {
+ setAtom(value);
+ };
+
+ const addAtom = (value) => {
+ setAtom((old_value) => [...old_value, value]);
+ };
+
+ return {
+ [property_names.current]: currentAtom,
+ [property_names.update]: updateAtom,
+ [property_names.add]: addAtom,
+ };
+ };
+
+ return { atomInstance, useHook };
+};
+
+import { loadable } from "jotai/utils";
+const createAsyncAtomWithHook = (initialValue, property_names) => {
+ const atomInstance = atom(initialValue);
+ const asyncAtom = atom(async (get) => get(atomInstance));
+
+ const loadableAtom = loadable(asyncAtom);
+
+ const useHook = () => {
+ const asyncCurrentAtom = useAtomValue(loadableAtom);
+ // const currentAtom = useAtomValue(atomInstance);
+
+ const setAtom = useSetAtom(atomInstance);
+ const updateAtom = (value) => {
+ setAtom(value);
+ };
+
+ const asyncSetAtom = useSetAtom(atom(null, async (get, set, payloadAsyncFunc, ...args) => {
+ set(atomInstance, payloadAsyncFunc(...args));
+ }));
+ const asyncUpdateAtom = async (asyncFunction, ...args) => {
+ asyncSetAtom(asyncFunction, ...args);
+ };
+
+ const addAtom = (value) => {
+ setAtom((old_value) => [...old_value, value]);
+ };
+ const asyncAddAtom = useSetAtom(atom(null, async (get, set, payloadAsyncFunc, ...args) => {
+ const ald_value = await get(atomInstance);
+ set(atomInstance, payloadAsyncFunc([...ald_value, ...args]));
+ }));
+
+ return {
+ [property_names.current]: asyncCurrentAtom,
+ [property_names.update]: updateAtom,
+ [property_names.async_update]: asyncUpdateAtom,
+ [property_names.add]: addAtom,
+ [property_names.async_add]: asyncAddAtom,
+ };
+ };
+
+ return { atomInstance, useHook };
+};
+
+export const { atomInstance: uiLanguage, useHook: useUiLanguage } = createAtomWithHook("en", {
+ current: "currentUiLanguage",
+ update: "updateUiLanguage",
+});
+
+
+export const { atomInstance: State_Translation, useHook: useState_Translation } = createAsyncAtomWithHook(false, {
+ current: "currentState_Translation",
+ update: "updateState_Translation",
+ async_update: "asyncUpdateState_Translation",
+});
+export const { atomInstance: State_TranscriptionSend, useHook: useState_TranscriptionSend } = createAsyncAtomWithHook(false, {
+ current: "currentState_TranscriptionSend",
+ update: "updateState_TranscriptionSend",
+ async_update: "asyncUpdateState_TranscriptionSend",
+});
+export const { atomInstance: State_TranscriptionReceive, useHook: useState_TranscriptionReceive } = createAsyncAtomWithHook(false, {
+ current: "currentState_TranscriptionReceive",
+ update: "updateState_TranscriptionReceive",
+ async_update: "asyncUpdateState_TranscriptionReceive",
+});
+export const { atomInstance: State_Foreground, useHook: useState_Foreground } = createAsyncAtomWithHook(false, {
+ current: "currentState_Foreground",
+ update: "updateState_Foreground",
+ async_update: "asyncUpdateState_Foreground",
+});
+
+
+
+export const { atomInstance: messageLogs, useHook: useMessageLogs } = createAtomWithHook(generateTestData(20), {
+ current: "currentMessageLogs",
+ update: "updateMessageLogs",
+ add: "addMessageLogs",
+});
+
+export const { atomInstance: isCompactMode, useHook: useIsCompactMode } = createAtomWithHook(false, {
+ current: "currentIsCompactMode",
+ update: "updateIsCompactMode",
+});
+
+export const { atomInstance: isOpenedLanguageSelector, useHook: useIsOpenedLanguageSelector } = createAtomWithHook(
+ { your_language: false, target_language: false },
+ {
+ current: "currentIsOpenedLanguageSelector",
+ update: "updateIsOpenedLanguageSelector",
+ }
+);
+
+export const { atomInstance: selectedTab, useHook: useSelectedTab } = createAtomWithHook(1, {
+ current: "currentSelectedTab",
+ update: "updateSelectedTab",
+});
+
+
+export const { atomInstance: isOpenedConfigWindow, useHook: useIsOpenedConfigWindow } = createAtomWithHook(false, {
+ current: "currentIsOpenedConfigWindow",
+ update: "updateIsOpenedConfigWindow",
+} );
+
+export const { atomInstance: selectedConfigTab, useHook: useSelectedConfigTab } = createAtomWithHook("appearance", {
+ current: "currentSelectedConfigTab",
+ update: "updateSelectedConfigTab",
+});
+
+export const { atomInstance: openedDropdownMenu, useHook: useOpenedDropdownMenu } = createAtomWithHook("", {
+ current: "currentOpenedDropdownMenu",
+ update: "updateOpenedDropdownMenu",
+});
+
+
+export const { atomInstance: selectedMicDevice, useHook: useSelectedMicDevice } = createAsyncAtomWithHook("device b", {
+ current: "currentSelectedMicDevice",
+ update: "updateSelectedMicDevice",
+});
+const test_list = {
+ a: "Device A",
+ "device b": "Device B",
+};
+export const { atomInstance: micDeviceList, useHook: useMicDeviceList } = createAtomWithHook(test_list, {
+ current: "currentMicDeviceList",
+ update: "updateMicDeviceList",
+});
+
+export const { atomInstance: translatorList, useHook: useTranslatorList } = createAtomWithHook(translator_list, {
+ current: "currentTranslatorList",
+ update: "updateTranslatorList",
+});
+
+export const { atomInstance: selectedTranslator, useHook: useSelectedTranslator } = createAtomWithHook("CTranslate2", {
+ current: "currentSelectedTranslator",
+ update: "updateSelectedTranslator",
+});
+
+export const { atomInstance: openedTranslatorSelector, useHook: useOpenedTranslatorSelector } = createAtomWithHook(false, {
+ current: "currentOpenedTranslatorSelector",
+ update: "updateOpenedTranslatorSelector",
+});
+
+export const { atomInstance: vrctPosterIndex, useHook: useVrctPosterIndex } = createAtomWithHook(0, {
+ current: "currentVrctPosterIndex",
+ update: "updateVrctPosterIndex",
+});
+
+export const { atomInstance: posterShowcaseWorldPageIndex, useHook: usePosterShowcaseWorldPageIndex } = createAtomWithHook(0, {
+ current: "currentPosterShowcaseWorldPageIndex",
+ update: "updatePosterShowcaseWorldPageIndex",
+});
\ No newline at end of file
diff --git a/src-ui/utils/chunkArray.js b/src-ui/utils/chunkArray.js
new file mode 100644
index 00000000..ee3d47cb
--- /dev/null
+++ b/src-ui/utils/chunkArray.js
@@ -0,0 +1,7 @@
+export const chunkArray = (array, size) => {
+ const chunked = [];
+ for (let i = 0; i < array.length; i += size) {
+ chunked.push(array.slice(i, i + size));
+ }
+ return chunked;
+};
\ No newline at end of file
diff --git a/src-ui/utils/logics/scrollToBottom.js b/src-ui/utils/logics/scrollToBottom.js
new file mode 100644
index 00000000..a2cb2a48
--- /dev/null
+++ b/src-ui/utils/logics/scrollToBottom.js
@@ -0,0 +1,27 @@
+export const scrollToBottom = (ref, smooth = false) => {
+ const element = ref.current;
+ const scroll_height = element.scrollHeight - element.clientHeight;
+
+ if (smooth) {
+ const duration = 300; // スクロールにかける時間(ミリ秒)
+ const start_time = performance.now();
+ const scroll_top = element.scrollTop;
+
+ const scroll = (current_time) => {
+ const elapsed = current_time - start_time;
+ const progress = Math.min(elapsed / duration, 1);
+ const ease_in_out_quad = (t) => t < 0.5
+ ? 2 * t * t
+ : -1 + (4 - 2 * t) * t;
+ element.scrollTop = scroll_top + (scroll_height - scroll_top) * ease_in_out_quad(progress);
+
+ if (progress < 1) {
+ requestAnimationFrame(scroll);
+ }
+ };
+
+ requestAnimationFrame(scroll);
+ } else {
+ element.scrollTop = scroll_height;
+ }
+};
diff --git a/src-ui/utils/logics/useMainFunction.js b/src-ui/utils/logics/useMainFunction.js
new file mode 100644
index 00000000..1dbc5325
--- /dev/null
+++ b/src-ui/utils/logics/useMainFunction.js
@@ -0,0 +1,81 @@
+import { getCurrent } from "@tauri-apps/api/window";
+
+import {
+ useState_Translation,
+ useState_TranscriptionSend,
+ useState_TranscriptionReceive,
+ useState_Foreground,
+} from "@store";
+
+import { useStdoutToPython } from "./useStdoutToPython";
+
+export const useMainFunction = () => {
+ const {
+ currentState_Translation,
+ updateState_Translation,
+ asyncUpdateState_Translation,
+ } = useState_Translation();
+ const {
+ currentState_TranscriptionSend,
+ updateState_TranscriptionSend,
+ asyncUpdateState_TranscriptionSend,
+ } = useState_TranscriptionSend();
+ const {
+ currentState_TranscriptionReceive,
+ updateState_TranscriptionReceive,
+ asyncUpdateState_TranscriptionReceive,
+ } = useState_TranscriptionReceive();
+ const {
+ currentState_Foreground,
+ updateState_Foreground,
+ } = useState_Foreground();
+
+ const { asyncStdoutToPython } = useStdoutToPython();
+
+ const asyncPending = () => new Promise(() => {});
+ return {
+ toggleTranslation: () => {
+ asyncStdoutToPython({id: "/controller/callback_toggle_translation", data: !currentState_Translation.data});
+ asyncUpdateState_Translation(asyncPending);
+ },
+ currentState_Translation: currentState_Translation,
+ updateState_Translation: (payload) => {
+ updateState_Translation(payload.data);
+ },
+
+ toggleTranscriptionSend: () => {
+ asyncStdoutToPython({id: "/controller/callback_toggle_transcription_send", data: !currentState_TranscriptionSend.data});
+ asyncUpdateState_TranscriptionSend(asyncPending);
+ },
+ currentState_TranscriptionSend: currentState_TranscriptionSend,
+ updateState_TranscriptionSend: (payload) => {
+ updateState_TranscriptionSend(payload.data);
+ },
+
+ toggleTranscriptionReceive: () => {
+ asyncStdoutToPython({id: "/controller/callback_toggle_transcription_receive", data: !currentState_TranscriptionReceive.data});
+ asyncUpdateState_TranscriptionReceive(asyncPending);
+ },
+ currentState_TranscriptionReceive: currentState_TranscriptionReceive,
+ updateState_TranscriptionReceive: (payload) => {
+ updateState_TranscriptionReceive(payload.data);
+ },
+
+ toggleForeground: () => {
+ const main_window = getCurrent();
+ const is_foreground_enabled = !currentState_Foreground.data;
+ main_window.setAlwaysOnTop(is_foreground_enabled);
+ updateState_Foreground(is_foreground_enabled);
+
+ },
+ currentState_Foreground: currentState_Foreground,
+ };
+};
+
+const asyncTestFunction = (...args) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(...args);
+ }, 3000);
+ });
+};
\ No newline at end of file
diff --git a/src-ui/utils/logics/useMessage.js b/src-ui/utils/logics/useMessage.js
new file mode 100644
index 00000000..79281fd8
--- /dev/null
+++ b/src-ui/utils/logics/useMessage.js
@@ -0,0 +1,55 @@
+import {
+ useMessageLogs,
+} from "@store";
+
+import { useStdoutToPython } from "./useStdoutToPython";
+
+export const useMessage = () => {
+ const { currentMessageLogs, addMessageLogs, updateMessageLogs } = useMessageLogs();
+ const { asyncStdoutToPython } = useStdoutToPython();
+
+ return {
+ sendMessage: (message) => {
+ asyncStdoutToPython({id: "send_message", data: message});
+ const uuid = crypto.randomUUID();
+ const date = new Date().toLocaleTimeString(
+ "ja-JP",
+ {hour12: false, hour: "2-digit", minute:"2-digit"},
+ );
+
+ addMessageLogs({
+ id: uuid,
+ category: "sent",
+ status: "pending",
+ created_at: date,
+ messages: {
+ original: message,
+ translated: [
+ message,
+ ],
+ },
+ });
+
+ setTimeout(() => {
+ const updateItemById = (id) => (prevItems) => {
+ return prevItems.map(item => {
+ if (item.id === id) {
+ item.status = "ok";
+ }
+ return item;
+ });
+ };
+ updateMessageLogs(updateItemById(uuid));
+ }, 3000);
+ },
+ currentMessageLogs: currentMessageLogs,
+ };
+};
+
+// const asyncTestFunction = (...args) => {
+// return new Promise((resolve) => {
+// setTimeout(() => {
+// resolve(...args);
+// }, 3000);
+// });
+// };
\ No newline at end of file
diff --git a/src-ui/utils/logics/useStartPython.js b/src-ui/utils/logics/useStartPython.js
new file mode 100644
index 00000000..5a4399b4
--- /dev/null
+++ b/src-ui/utils/logics/useStartPython.js
@@ -0,0 +1,53 @@
+import { Command } from "@tauri-apps/api/shell";
+import { store } from "@store";
+
+import { useMainFunction } from "./useMainFunction";
+
+export const useStartPython = () => {
+ const {
+ updateState_Translation,
+ updateState_TranscriptionSend,
+ updateState_TranscriptionReceive,
+ } = useMainFunction();
+
+ const routes = {
+ "/controller/callback_toggle_translation": updateState_Translation,
+ "/controller/callback_toggle_transcription_send": updateState_TranscriptionSend,
+ "/controller/callback_toggle_transcription_receive": updateState_TranscriptionReceive,
+ };
+
+ const receiveRoutes = (parsed_data) => {
+ if (parsed_data.status === "ok") {
+ const route = routes[parsed_data.id];
+ if (route) {
+ route({ data: parsed_data.data });
+ } else {
+ console.error(`Invalid path: ${parsed_data.id}`);
+ }
+ } else {
+ console.log("Received data status is not 'ok'.", parsed_data);
+ }
+ };
+
+
+ const asyncStartPython = async () => {
+ const command = Command.sidecar("bin/test");
+ command.on("error", error => console.error(`error: "${error}"`));
+ command.stdout.on("data", (line) => {
+ let parsed_data = "";
+ try {
+ parsed_data = JSON.parse(line);
+ } catch (error) {
+ console.log(error);
+ parsed_data = line;
+ }
+ console.log("from python:", parsed_data);
+ receiveRoutes(parsed_data);
+ });
+ command.stderr.on("data", line => console.error("stderr:", line));
+ const backend_subprocess = await command.spawn();
+ store.backend_subprocess = backend_subprocess;
+ };
+
+ return { asyncStartPython };
+};
\ No newline at end of file
diff --git a/src-ui/utils/logics/useStdoutToPython.js b/src-ui/utils/logics/useStdoutToPython.js
new file mode 100644
index 00000000..a631545d
--- /dev/null
+++ b/src-ui/utils/logics/useStdoutToPython.js
@@ -0,0 +1,17 @@
+import { store } from "@store";
+
+export const useStdoutToPython = () => {
+ const asyncStdoutToPython = async (value) => {
+ // send to python
+ const backend_subprocess = store.backend_subprocess;
+ if (backend_subprocess) {
+ await backend_subprocess.write(JSON.stringify(value) + "\n").then(() => {
+ }).catch((err) => {
+ console.log(err);
+ });
+ } else {
+ console.error("Backend subprocess is not found.", backend_subprocess);
+ }
+ };
+ return { asyncStdoutToPython };
+};
\ No newline at end of file
diff --git a/src-ui/utils/mixins.scss b/src-ui/utils/mixins.scss
new file mode 100644
index 00000000..3532f992
--- /dev/null
+++ b/src-ui/utils/mixins.scss
@@ -0,0 +1,107 @@
+// デフォルト変数
+$default_loader_size: 2rem !default;
+$default_loader_line_width: 0.2rem !default;
+
+// Loader Mixin
+@mixin loader($loader_size: $default_loader_size, $loader_line_width: $default_loader_line_width, $position: right, $position_amount: 0) {
+ $half_line_width: calc($loader_line_width / 2);
+ $calc_translate: calc(-50% + #{$half_line_width});
+
+ position: absolute;
+ top: calc(50% - #{$half_line_width});
+ #{$position}: $position_amount;
+ transform: translate($calc_translate, $calc_translate);
+ width: $loader_size;
+ height: $loader_size;
+ border-radius: 50%;
+ display: inline-block;
+ border-top: $loader_line_width solid var(--dark_400_color);
+ border-right: $loader_line_width solid transparent;
+ animation: rotate_animation 0.6s linear infinite;
+
+ &::after {
+ content: '';
+ position: absolute;
+ width: $loader_size;
+ height: $loader_size;
+ border-radius: 50%;
+ border-bottom: $loader_line_width solid var(--primary_400_color);
+ border-left: $loader_line_width solid transparent;
+ }
+
+ // @keyframes
+ @keyframes rotate_animation {
+ 0% {
+ transform: translate($calc_translate, $calc_translate) rotate(0deg);
+ }
+ 100% {
+ transform: translate($calc_translate, $calc_translate) rotate(360deg);
+ }
+ }
+}
+
+
+
+$toggle_background_color_on: var(--primary_400_color);
+$toggle_background_color_off: var(--dark_775_color);
+$toggle_control_color: var(--dark_400_color);
+$toggle_width: 4rem;
+$toggle_height: 1.6rem;
+$toggle_gutter: 0.1rem;
+$toggle_radius: 50%;
+$toggle_control_speed: .15s;
+$toggle_control_ease: ease-out;
+
+$toggle_radius: calc($toggle_height / 2);
+$toggle_control_size: $toggle_height - calc($toggle_gutter * 2);
+
+@mixin toggle_control_styles {
+ display: block;
+ position: relative;
+ height: 100%;
+ width: auto;
+ padding-left: $toggle_width;
+ .control {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: $toggle_height;
+ width: $toggle_width;
+ border-radius: $toggle_radius;
+ background-color: $toggle_background_color_off;
+ // transition: background-color $toggle_control_speed $toggle_control_ease;
+ &:after {
+ content: "";
+ position: absolute;
+ left: $toggle_gutter;
+ top: $toggle_gutter;
+ width: $toggle_control_size;
+ height: $toggle_control_size;
+ border-radius: $toggle_radius;
+ background: $toggle_control_color;
+ transition: left $toggle_control_speed $toggle_control_ease;
+ }
+ &.is_hovered {
+ background-color: var(--dark_725_color);
+ }
+ &.is_mouse_down {
+ background-color: var(--dark_825_color);
+ }
+ &.is_active {
+ background-color: $toggle_background_color_on;
+ &.is_hovered {
+ background-color: var(--primary_350_color);
+ }
+ &.is_mouse_down {
+ background-color: var(--primary_700_color);
+ }
+ &:after {
+ left: $toggle_width - $toggle_control_size - $toggle_gutter;
+ }
+ }
+ }
+}
+
+.toggle_control {
+ @include toggle_control_styles;
+}
\ No newline at end of file
diff --git a/src-ui/utils/randomIntMinMax.js b/src-ui/utils/randomIntMinMax.js
new file mode 100644
index 00000000..f0882ea6
--- /dev/null
+++ b/src-ui/utils/randomIntMinMax.js
@@ -0,0 +1,9 @@
+export const randomIntMinMax = (min, max) => {
+ if (min === max) return min;
+ if (max === undefined) {
+ max = min;
+ min = 0;
+ }
+ const int = Math.floor(Math.random() * (max - min + 1)) + min;
+ return int;
+};
diff --git a/src-ui/utils/reset.css b/src-ui/utils/reset.css
new file mode 100644
index 00000000..c8104a66
--- /dev/null
+++ b/src-ui/utils/reset.css
@@ -0,0 +1,418 @@
+/*! destyle.css v4.0.1 | MIT License | https://github.com/nicolas-cusan/destyle.css */
+
+/* Reset box-model and set borders */
+/* ============================================ */
+
+*,
+::before,
+::after {
+ box-sizing: border-box;
+ border-style: solid;
+ border-width: 0;
+ min-width: 0;
+}
+
+/* Document */
+/* ============================================ */
+
+/**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ * 3. Remove gray overlay on links for iOS.
+ */
+
+html {
+ line-height: 1.15; /* 1 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+ -webkit-tap-highlight-color: transparent; /* 3*/
+}
+
+/* Sections */
+/* ============================================ */
+
+/**
+ * Remove the margin in all browsers.
+ */
+
+body {
+ margin: 0;
+}
+
+/**
+ * Render the `main` element consistently in IE.
+ */
+
+main {
+ display: block;
+}
+
+/* Vertical rhythm */
+/* ============================================ */
+
+p,
+table,
+blockquote,
+address,
+pre,
+iframe,
+form,
+figure,
+dl {
+ margin: 0;
+}
+
+/* Headings */
+/* ============================================ */
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-size: inherit;
+ font-weight: inherit;
+ margin: 0;
+}
+
+/* Lists (enumeration) */
+/* ============================================ */
+
+ul,
+ol {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+/* Lists (definition) */
+/* ============================================ */
+
+dt {
+ font-weight: bold;
+}
+
+dd {
+ margin-left: 0;
+}
+
+/* Grouping content */
+/* ============================================ */
+
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+ box-sizing: content-box; /* 1 */
+ height: 0; /* 1 */
+ overflow: visible; /* 2 */
+ border-top-width: 1px;
+ margin: 0;
+ clear: both;
+ color: inherit;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+ font-family: monospace, monospace; /* 1 */
+ font-size: inherit; /* 2 */
+}
+
+address {
+ font-style: inherit;
+}
+
+/* Text-level semantics */
+/* ============================================ */
+
+/**
+ * Remove the gray background on active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+ text-decoration: none;
+ color: inherit;
+}
+
+/**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+abbr[title] {
+ text-decoration: underline dotted; /* 2 */
+}
+
+/**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+code,
+kbd,
+samp {
+ font-family: monospace, monospace; /* 1 */
+ font-size: inherit; /* 2 */
+}
+
+/**
+ * Add the correct font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/* Replaced content */
+/* ============================================ */
+
+/**
+ * Prevent vertical alignment issues.
+ */
+
+svg,
+img,
+embed,
+object,
+iframe {
+ vertical-align: bottom;
+}
+
+/* Forms */
+/* ============================================ */
+
+/**
+ * Reset form fields to make them styleable.
+ * 1. Make form elements stylable across systems iOS especially.
+ * 2. Inherit text-transform from parent.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ -webkit-appearance: none; /* 1 */
+ appearance: none;
+ vertical-align: middle;
+ color: inherit;
+ font: inherit;
+ background: transparent;
+ padding: 0;
+ margin: 0;
+ border-radius: 0;
+ text-align: inherit;
+ text-transform: inherit; /* 2 */
+
+ /* Customize */
+ outline: none;
+}
+
+/**
+ * Correct cursors for clickable elements.
+ */
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ cursor: pointer;
+}
+
+button:disabled,
+[type="button"]:disabled,
+[type="reset"]:disabled,
+[type="submit"]:disabled {
+ cursor: default;
+}
+
+/**
+ * Improve outlines for Firefox and unify style with input elements & buttons.
+ */
+
+:-moz-focusring {
+ outline: auto;
+}
+
+select:disabled {
+ opacity: inherit;
+}
+
+/**
+ * Remove padding
+ */
+
+option {
+ padding: 0;
+}
+
+/**
+ * Reset to invisible
+ */
+
+fieldset {
+ margin: 0;
+ padding: 0;
+ min-width: 0;
+}
+
+legend {
+ padding: 0;
+}
+
+/**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+progress {
+ vertical-align: baseline;
+}
+
+/**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * Correct the outline style in Safari.
+ */
+
+[type="search"] {
+ outline-offset: -2px; /* 1 */
+}
+
+/**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Fix font inheritance.
+ */
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
+}
+
+/**
+ * Fix appearance for Firefox
+ */
+[type="number"] {
+ appearance: textfield;
+}
+
+/**
+ * Clickable labels
+ */
+
+label[for] {
+ cursor: pointer;
+}
+
+/* Interactive */
+/* ============================================ */
+
+/*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+details {
+ display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+ display: list-item;
+}
+
+/*
+ * Remove outline for editable content.
+ */
+
+[contenteditable]:focus {
+ outline: auto;
+}
+
+/* Tables */
+/* ============================================ */
+
+/**
+1. Correct table border color inheritance in all Chrome and Safari.
+*/
+
+table {
+ border-color: inherit; /* 1 */
+ border-collapse: collapse;
+}
+
+caption {
+ text-align: left;
+}
+
+td,
+th {
+ vertical-align: top;
+ padding: 0;
+}
+
+th {
+ text-align: left;
+ font-weight: bold;
+}
\ No newline at end of file
diff --git a/src-ui/utils/root.css b/src-ui/utils/root.css
new file mode 100644
index 00000000..1cc2a409
--- /dev/null
+++ b/src-ui/utils/root.css
@@ -0,0 +1,40 @@
+@import "./reset.css";
+@import "./variables.css";
+
+:root {
+ font-size: 62.5%;
+ color: #F2F2F2;
+ font-family: "Yu Gothic UI";
+}
+
+* {
+ &::-webkit-scrollbar {
+ width: 0.8rem;
+ }
+ &::-webkit-scrollbar-track {
+ background-color: var(--dark_925_color);
+ border-radius: 0.4rem;
+ }
+ &::-webkit-scrollbar-thumb {
+ background-color: var(--dark_800_color);
+ border-radius: 0.4rem;
+ }
+}
+
+p, img, button {
+ user-select: none;
+}
+
+html, body {
+ height: 100%;
+}
+
+
+#root {
+ height: 100%;
+}
+
+/* SVG内のすべての要素にfillを適用 (colorの調整をcssでするため) */
+svg {
+ fill: currentColor;
+}
\ No newline at end of file
diff --git a/src-ui/utils/useSvg.jsx b/src-ui/utils/useSvg.jsx
new file mode 100644
index 00000000..2da6e814
--- /dev/null
+++ b/src-ui/utils/useSvg.jsx
@@ -0,0 +1,9 @@
+import React from "react";
+
+export const useSvg = (svg_component, ...props) => {
+ const svgWithClass = svg_component
+ ? React.cloneElement(svg_component, ...props)
+ : null;
+
+ return svgWithClass;
+};
\ No newline at end of file
diff --git a/src-ui/utils/useWindow.js b/src-ui/utils/useWindow.js
new file mode 100644
index 00000000..797a9b78
--- /dev/null
+++ b/src-ui/utils/useWindow.js
@@ -0,0 +1,43 @@
+import { WebviewWindow } from "@tauri-apps/api/window";
+import { store, useIsOpenedConfigWindow } from "@store";
+import { getCurrent } from "@tauri-apps/api/window";
+
+export const useWindow = () => {
+ const { updateIsOpenedConfigWindow } = useIsOpenedConfigWindow();
+
+ const createConfigWindow = async () => {
+ const main_window = getCurrent();
+ if (store.config_window === null) {
+ const config_window = new WebviewWindow("vrct_config_window",{
+ url: "./src-ui/windows/config_window/index.html",
+ center: true,
+ width: 1080,
+ height: 700,
+ });
+
+ config_window.once("tauri://created", function () {
+ store.config_window = config_window;
+ updateIsOpenedConfigWindow(true);
+ });
+ config_window.once("tauri://error", function (e) {
+ console.log(e);
+ });
+
+ const unlisten_d = config_window.once("tauri://destroyed", (event) => {
+ store.config_window = null;
+ updateIsOpenedConfigWindow(false);
+ unlisten_d();
+ });
+
+ main_window.onCloseRequested((event) => {
+ config_window.close();
+ });
+ }
+ };
+
+ const closeConfigWindow = () => {
+ store.config_window.close();
+ };
+
+ return { createConfigWindow, closeConfigWindow };
+};
\ No newline at end of file
diff --git a/src-ui/utils/variables.css b/src-ui/utils/variables.css
new file mode 100644
index 00000000..1703fa73
--- /dev/null
+++ b/src-ui/utils/variables.css
@@ -0,0 +1,51 @@
+:root {
+ --primary_100_color: #b7ded8;
+ --primary_150_color: #a1d4cc;
+ --primary_200_color: #8acac0;
+ --primary_250_color: #76bfb4;
+ --primary_300_color: #61b4a7;
+ --primary_350_color: #55ac9e;
+ --primary_400_color: #48a495;
+ --primary_450_color: #429c8c;
+ --primary_500_color: #3b9483;
+ --primary_600_color: #368777;
+ --primary_650_color: #347f6f;
+ --primary_700_color: #317767;
+ --primary_750_color: #2f6f60;
+ --primary_800_color: #2c6759;
+ --primary_900_color: #214b3f;
+
+ --sent_400_color: #6197b4;
+ --received_300_color: #a861b4;
+
+ --dark_basic_text_color: #f2f2f2;
+ --dark_100_color: #f5f7fb;
+ --dark_200_color: #f1f2f6;
+ --dark_300_color: #e9eaee;
+ --dark_350_color: #d8d9dd;
+ --dark_400_color: #c7c8cc;
+ --dark_450_color: #b8b9bd;
+ --dark_500_color: #a9aaae;
+ --dark_600_color: #7f8084;
+ --dark_650_color: #75767a;
+ --dark_700_color: #6a6c6f;
+ --dark_725_color: #636467;
+ --dark_750_color: #5b5c5f;
+ --dark_775_color: #535457;
+ --dark_800_color: #4b4c4f;
+ --dark_825_color: #434447;
+ --dark_850_color: #3a3b3e;
+ --dark_863_color: #36373a;
+ --dark_875_color: #323336;
+ --dark_888_color: #2e2f32;
+ --dark_900_color: #292a2d;
+ --dark_925_color: #242528;
+ --dark_950_color: #1f2022;
+ --dark_975_color: #1a1b1d;
+ --dark_1000_color: #151517;
+
+
+ --main_window_topbar_height: 4.8rem;
+ --config_window_sidebar_width: 22rem;
+ --config_window_topbar_height: 5.2rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/ConfigWindow.jsx b/src-ui/windows/config_window/ConfigWindow.jsx
new file mode 100644
index 00000000..7820ffaf
--- /dev/null
+++ b/src-ui/windows/config_window/ConfigWindow.jsx
@@ -0,0 +1,20 @@
+import "../../../locales/config.js";
+import "@utils/root.css";
+
+import styles from "./ConfigWindow.module.scss";
+
+import { Topbar } from "./topbar/Topbar";
+import { SidebarSection } from "./sidebar_section/SidebarSection";
+import { SettingSection } from "./setting_section/SettingSection.jsx";
+
+export const ConfigWindow = () => {
+ return (
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/ConfigWindow.module.scss b/src-ui/windows/config_window/ConfigWindow.module.scss
new file mode 100644
index 00000000..45c74b22
--- /dev/null
+++ b/src-ui/windows/config_window/ConfigWindow.module.scss
@@ -0,0 +1,16 @@
+.container {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ background-color: var(--dark_950_color);
+ overflow: hidden;
+}
+
+.main_container {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ padding-top: var(--config_window_topbar_height);
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/index.html b/src-ui/windows/config_window/index.html
new file mode 100644
index 00000000..348eea1d
--- /dev/null
+++ b/src-ui/windows/config_window/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Config Window
+
+
+
+
+
+
+
diff --git a/src-ui/windows/config_window/index.jsx b/src-ui/windows/config_window/index.jsx
new file mode 100644
index 00000000..abf09419
--- /dev/null
+++ b/src-ui/windows/config_window/index.jsx
@@ -0,0 +1,15 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+// import "../locales/config.js";
+import { ConfigWindow } from "./ConfigWindow";
+// import "./reset.css";
+// import "./root.css";
+// import { useWindow } from "@utils/useWindow";
+
+
+ReactDOM.createRoot(document.getElementById("root")).render(
+
+
+ ,
+);
+
diff --git a/src-ui/windows/config_window/setting_section/SettingSection.jsx b/src-ui/windows/config_window/setting_section/SettingSection.jsx
new file mode 100644
index 00000000..cfa4c9a2
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/SettingSection.jsx
@@ -0,0 +1,12 @@
+import styles from "./SettingSection.module.scss";
+import { SettingBox } from "./setting_box/SettingBox";
+
+export const SettingSection = () => {
+ return (
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/SettingSection.module.scss b/src-ui/windows/config_window/setting_section/SettingSection.module.scss
new file mode 100644
index 00000000..31ad539b
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/SettingSection.module.scss
@@ -0,0 +1,10 @@
+.scroll_container {
+ width: 100%;
+ margin-left: 4rem;
+ overflow-y: auto;
+ overflow-x: hidden;
+}
+
+.container {
+ margin: 4rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/Appearance/Appearance.jsx b/src-ui/windows/config_window/setting_section/setting_box/Appearance/Appearance.jsx
new file mode 100644
index 00000000..d67fa1cc
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/Appearance/Appearance.jsx
@@ -0,0 +1,25 @@
+import { useSettingBox } from "../useSettingBox";
+import { useSelectedMicDevice, useMicDeviceList } from "@store";
+export const Appearance = () => {
+ const { currentSelectedMicDevice, updateSelectedMicDevice } = useSelectedMicDevice();
+ const { currentMicDeviceList } = useMicDeviceList();
+ const { DropdownMenuContainer } = useSettingBox();
+
+ const selectFunction = (selected_data) => {
+ const asyncFunction = () => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(selected_data.selected_id);
+ }, 3000);
+ });
+ };
+ updateSelectedMicDevice(asyncFunction);
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/SettingBox.jsx b/src-ui/windows/config_window/setting_section/setting_box/SettingBox.jsx
new file mode 100644
index 00000000..65e30c0b
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/SettingBox.jsx
@@ -0,0 +1,18 @@
+import styles from "./SettingBox.module.scss";
+import { useSelectedConfigTab } from "@store";
+
+import { Appearance } from "./appearance/Appearance";
+import { AboutVrct } from "./about_vrct/AboutVrct";
+
+export const SettingBox = () => {
+ const { currentSelectedConfigTab } = useSelectedConfigTab();
+ switch (currentSelectedConfigTab) {
+ case "appearance":
+ return ;
+ case "about_vrct":
+ return ;
+
+ default:
+ return null;
+ }
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/SettingBox.module.scss b/src-ui/windows/config_window/setting_section/setting_box/SettingBox.module.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/src-ui/windows/config_window/setting_section/setting_box/about_vrct/AboutVrct.jsx b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/AboutVrct.jsx
new file mode 100644
index 00000000..d47d6396
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/AboutVrct.jsx
@@ -0,0 +1,135 @@
+import styles from "./AboutVrct.module.scss";
+import dev_section_title from "@images/about_vrct/dev_section_title.png";
+import dev_misya from "@images/about_vrct/dev_misya.png";
+import dev_shiina from "@images/about_vrct/dev_shiina.png";
+import vrct_logo_for_about_vrct from "@images/about_vrct/vrct_logo_for_about_vrct.png";
+import contributors_section_title from "@images/about_vrct/contributors_section_title.png";
+import contributors_members from "@images/about_vrct/contributors_members.png";
+import localization_section_title from "@images/about_vrct/localization_section_title.png";
+import localization_members from "@images/about_vrct/localization_members.png";
+
+import special_thanks_section_title from "@images/about_vrct/special_thanks_section_title.png";
+import special_thanks_members from "@images/about_vrct/special_thanks_members.png";
+import special_thanks_message_en from "@images/about_vrct/special_thanks_message_en.png";
+import special_thanks_message_ja from "@images/about_vrct/special_thanks_message_ja.png";
+
+import poster_showcase_section_title from "@images/about_vrct/poster_showcase_section_title.png";
+
+import vrchat_disclaimer from "@images/about_vrct/vrchat_disclaimer.png";
+
+import clsx from "clsx";
+import { useTranslation } from "react-i18next";
+import { useUiLanguage } from "@store";
+import { PosterShowcaseContents } from "./poster_showcase_contents/PosterShowcaseContents";
+
+export const AboutVrct = () => {
+ const { t } = useTranslation();
+ const { currentUiLanguage } = useUiLanguage();
+ return (
+
+
+

+
+
+

+
+
+
+
+

+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+

+
+

+
+
+
+
+
+
+
+
+
+
+

+

+
+
+
+

+

+ {
+ currentUiLanguage === "ja"
+ ?

+ :

+ }
+
+
+
+
+

+
+
+
+
+

+
+
+
+
+ );
+};
+
+import dev_x_icon from "@images/about_vrct/dev_x_icon.png";
+import dev_github_icon from "@images/about_vrct/dev_github_icon.png";
+import contributors_x_icon from "@images/about_vrct/contributors_x_icon.png";
+import contributors_github_icon from "@images/about_vrct/contributors_github_icon.png";
+
+import project_link_booth from "@images/about_vrct/project_link_booth.png";
+import project_link_documents from "@images/about_vrct/project_link_documents.png";
+import project_link_vrct_github from "@images/about_vrct/project_link_vrct_github.png";
+import project_link_contact_us from "@images/about_vrct/project_link_contact_us.png";
+
+const about_vrct_links = {
+ dev_misya_x: { img: dev_x_icon, href: "https://twitter.com/misya_ai" },
+ dev_misya_github: { img: dev_github_icon, href: "https://github.com/misyaguziya" },
+ dev_shiina_x: { img: dev_x_icon, href: "https://twitter.com/Shiina_12siy" },
+
+ project_link_booth: { img: project_link_booth, href: "https://misyaguziya.booth.pm/items/5155325" },
+ project_link_documents: { img: project_link_documents, href: "https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246" },
+ project_link_vrct_github: { img: project_link_vrct_github, href: "https://github.com/misyaguziya/VRCT" },
+ project_link_contact_us: { img: project_link_contact_us, href: "https://docs.google.com/forms/d/e/1FAIpQLSei-xoydOY60ivXqhOjaTzNN8PiBQIDcNhzfy6cw2sjYkcg_g/viewform" },
+
+ contributors_done_san_x: { img: contributors_x_icon, href: "https://twitter.com/done_vrc" },
+ contributors_iya_x: { img: contributors_x_icon, href: "https://twitter.com/IYAA_HHHH" },
+ contributors_rera_x: { img: contributors_x_icon, href: "https://twitter.com/rerassi" },
+ contributors_rera_github: { img: contributors_github_icon, href: "https://github.com/soumt-r" },
+ contributors_poposuke_x: { img: contributors_x_icon, href: "https://twitter.com/sig_popo" },
+ contributors_kumaguma_x: { img: contributors_x_icon, href: "https://twitter.com/K_kumaguma_A" },
+};
+
+const OpenLinkContainer = ({className, href_id}) => {
+ const href = about_vrct_links[href_id].href;
+ const img = about_vrct_links[href_id].img;
+ return (
+
+ {/* for adjust size to their parent component's width. */}
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/about_vrct/AboutVrct.module.scss b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/AboutVrct.module.scss
new file mode 100644
index 00000000..2d7c43b4
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/AboutVrct.module.scss
@@ -0,0 +1,171 @@
+.container {
+ display: flex;
+ gap: 2.2rem;
+ flex-direction: column;
+ width: 72rem;
+ // background-color: gray;
+}
+
+.section_title {
+ height: 1.2rem;
+ object-fit: contain;
+ object-position: left;
+ &.the_developers {
+ margin-bottom: 0.8rem;
+ }
+ &.contributors {
+ margin-bottom: 0.8rem;
+ }
+ &.special_thanks {
+ margin-bottom: 0.6rem;
+ }
+ &.poster_showcase {
+ margin-bottom: 0.6rem;
+ }
+}
+
+.dev_section {
+ display: flex;
+ flex-direction: column;
+}
+.dev_section_wrapper {
+ display: flex;
+ justify-content: space-between;
+}
+.dev_card_wrapper {
+ width: 34.6rem;
+ position: relative;
+}
+.dev_card_img {
+ width: 100%;
+}
+
+@mixin dev_sns_styles($right) {
+ position: absolute;
+ right: $right;
+ bottom: 1.2rem;
+ width: 2.8rem;
+ padding: 0.4rem;
+ border-radius: 0.4rem;
+ &:hover {
+ background-color: var(--dark_800_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color)
+ }
+}
+.dev_misya_x {
+ @include dev_sns_styles(6rem);
+}
+.dev_misya_github {
+ @include dev_sns_styles(3rem);
+}
+.dev_shiina_x {
+ @include dev_sns_styles(3rem);
+}
+
+
+.project_links_and_logo_section {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ text-align: center;
+ padding: 0 5.5rem;
+}
+.about_vrct_logo {
+ width: 20rem;
+ object-fit: contain;
+}
+.project_links_wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 0.2rem;
+ align-items: start;
+}
+
+.project_link {
+ height: 2.6rem;
+ padding: 0.4rem 1rem;
+ border-radius: 0.4rem;
+ &:hover {
+ background-color: var(--dark_850_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color)
+ }
+}
+
+.contributors_img_wrapper {
+ position: relative;
+}
+.contributors_img {
+ width: 100%;
+}
+
+@mixin contributors_sns_styles($top, $left) {
+ position: absolute;
+ left: $left;
+ top: $top;
+ width: 2.4rem;
+ padding: 0.4rem;
+ border-radius: 0.4rem;
+ &:hover {
+ background-color: var(--dark_825_color);
+ }
+ &:active {
+ background-color: var(--dark_888_color)
+ }
+}
+
+$first_line_top: 6.2rem;
+.contributors_done_san_x {
+ @include contributors_sns_styles($first_line_top, 2rem);
+}
+.contributors_iya_x {
+ @include contributors_sns_styles($first_line_top, 27.6rem);
+}
+.contributors_rera_x {
+ @include contributors_sns_styles($first_line_top, 52.2rem);
+}
+.contributors_rera_github {
+ @include contributors_sns_styles($first_line_top, 55rem);
+}
+
+$second_line_top: 16.6rem;
+.contributors_poposuke_x {
+ @include contributors_sns_styles($second_line_top, 14.8rem);
+}
+.contributors_kumaguma_x {
+ @include contributors_sns_styles($second_line_top, 40.8rem);
+}
+
+.localization_section {
+ display: flex;
+ flex-direction: column;
+}
+.localization_members_img {
+ width: 100%;
+}
+
+.special_thanks_section {
+ display: flex;
+ flex-direction: column;
+}
+.special_thanks_members_img {
+ width: 100%;
+ margin-bottom: 0.4rem;
+}
+.special_thanks_message_img {
+ width: 100%;
+}
+
+
+.poster_showcase_section {
+ display: flex;
+ flex-direction: column;
+}
+
+.vrchat_disclaimer {
+ width: 100%;
+ margin-top: 8rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.jsx b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.jsx
new file mode 100644
index 00000000..25bed537
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.jsx
@@ -0,0 +1,12 @@
+import styles from "./PosterShowcaseContents.module.scss";
+import { PostersContents } from "./posters_contents/PostersContents";
+import { PosterShowcaseWorldsContents } from "./poster_showcase_worlds_contents/PosterShowcaseWorldsContents";
+
+export const PosterShowcaseContents = () => {
+ return (
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.module.scss b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.module.scss
new file mode 100644
index 00000000..c7b760b7
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/PosterShowcaseContents.module.scss
@@ -0,0 +1,6 @@
+.container {
+ display: flex;
+ justify-content: space-between;
+ align-items: start;
+ gap: 2rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.jsx b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.jsx
new file mode 100644
index 00000000..c088040f
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.jsx
@@ -0,0 +1,91 @@
+import clsx from "clsx";
+import styles from "./PosterShowcaseWorldsContents.module.scss";
+import { usePosterShowcaseWorldPageIndex } from "@store";
+const images = import.meta.glob("@images/about_vrct/showcased_worlds/*.{png,jpg,jpeg,svg}", { eager: true });
+
+const getImageByFileName = (file_name) => {
+ const imagePath = Object.keys(images).find((path) => path.includes(file_name));
+ return imagePath ? images[imagePath]?.default : null;
+};
+
+import poster_showcase_worlds_settings from "./poster_showcase_worlds_settings";
+import { chunkArray } from "@utils/chunkArray";
+
+export const PosterShowcaseWorldsContents = () => {
+ const { currentPosterShowcaseWorldPageIndex } = usePosterShowcaseWorldPageIndex();
+ const poster_showcase_world_images = poster_showcase_worlds_settings.map((setting) => ({
+ img: getImageByFileName(setting.image_file_name),
+ x_post_num: setting.x_post_num
+ }));
+
+ const chunked_poster_showcase_world_images = chunkArray(poster_showcase_world_images, 8);
+ const target_poster_showcase_world_images = chunked_poster_showcase_world_images[currentPosterShowcaseWorldPageIndex];
+
+
+ return (
+
+
+ {target_poster_showcase_world_images.map((poster, index) => {
+ let content = (
+
+

+
+ );
+ if (poster.x_post_num !== null) {
+ content = (
+
+ {content}
+
+ );
+ }
+ const class_names = clsx(styles.poster_showcase_world_wrapper, {
+ [styles.clickable]: (poster.x_post_num !== null)
+ });
+ return (
+
+ {content}
+
+ );
+ })}
+
+
+
+ );
+};
+
+import chat_white_square from "@images/chato_white_square.png";
+import { useEffect } from "react";
+import { randomIntMinMax } from "@utils/randomIntMinMax";
+const PosterShowcaseWorldsPagination = ({ page_length }) => {
+ const { currentPosterShowcaseWorldPageIndex, updatePosterShowcaseWorldPageIndex } = usePosterShowcaseWorldPageIndex();
+
+ useEffect(() => {
+ updatePosterShowcaseWorldPageIndex(randomIntMinMax(page_length -1));
+ },[page_length]);
+
+ const setPage = (index) => {
+ updatePosterShowcaseWorldPageIndex(index);
+ };
+
+ const getClassNames = (index, baseClass) => clsx(baseClass, {
+ [styles.is_active]: (currentPosterShowcaseWorldPageIndex === index),
+ });
+
+ return (
+
+ {[...Array(page_length).keys()].map((index) => {
+ return (
+
setPage(index)}>
+
+

+
+
+
+ );
+ })}
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.module.scss b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.module.scss
new file mode 100644
index 00000000..a8afb0d0
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/PosterShowcaseWorldsContents.module.scss
@@ -0,0 +1,123 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ gap: 1rem;
+ justify-content: space-between;
+}
+$image_height: 2.8rem;
+$y_padding: 0.4rem;
+$image_height_gap: 0.4rem;
+.poster_showcase_world_container {
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: $image_height_gap;
+ height: calc( (($image_height + ($y_padding*2)) * 8) + ($image_height_gap * (8 - 1)) );
+}
+.poster_showcase_world_wrapper {
+ display: flex;
+ padding: $y_padding 0.6rem $y_padding 0.8rem;
+ border-radius: 0.4rem 0 0 0.4rem;
+ &.clickable {
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_850_color);
+ }
+ &:active {
+ background-color: var(--dark_925_color);
+ }
+ }
+
+}
+.poster_showcase_world_img {
+ height: $image_height;
+}
+
+.pagination_container {
+ display: flex;
+ justify-content: space-between;
+ gap: 6%;
+ margin: 0 2.6rem;
+}
+
+$animation_duration: .15s;
+.pagination_box {
+ width: 100%;
+ cursor: pointer;
+ &:active .pagination_chato_img {
+ animation: tremble_animation $animation_duration ease-out;
+ }
+ &:active.is_active .pagination_chato_img {
+ transform: translate(-50%, -50%) rotate(-22deg);
+ }
+ &.is_active .pagination_chato_img {
+ top: 48%;
+ animation: rotate_animation $animation_duration ease-out;
+ }
+ &:hover {
+ & .pagination_chato_img {
+ top: 108%;
+ }
+ &.is_active .pagination_chato_img {
+ animation: tremble_animation $animation_duration ease-out;
+ }
+ }
+}
+
+.indicator_box {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+}
+
+.indicator {
+ width: 100%;
+ height: 0.2rem;
+ background-color: var(--dark_800_color);
+ &.is_active {
+ background-color: var(--primary_400_color);
+ }
+}
+
+.pagination_num {
+ font-size: 1.8rem;
+ padding: 1rem;
+ color: var(--dark_600_color);
+ &.is_active {
+ color: var(--primary_300_color);
+ }
+}
+
+.chato_box {
+ position: relative;
+ width: 100%;
+ height: 6rem;
+ overflow: hidden;
+}
+
+.pagination_chato_img {
+ position: absolute;
+ top: 200%;
+ left: 51%;
+ transform: translate(-50%, -50%) rotate(22deg);
+ width: 2.8rem;
+ transition: top $animation_duration ease-out;
+}
+@keyframes rotate_animation {
+ 0% {
+ transform: translate(-50%, -50%) rotate(22deg);
+ }
+ 100% {
+ transform: translate(-50%, -50%) rotate(360deg + 22deg);
+ }
+}
+
+@keyframes tremble_animation {
+ 0% { left: 51%; }
+ 25% { left: 55%; }
+ 50% { left: 45%; }
+ 75% { left: 48%; }
+ 100% { left: 51%; }
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/poster_showcase_worlds_settings.js b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/poster_showcase_worlds_settings.js
new file mode 100644
index 00000000..654c2286
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/poster_showcase_worlds_contents/poster_showcase_worlds_settings.js
@@ -0,0 +1,63 @@
+const poster_showcase_worlds_settings = [
+ // トサカひよ
+ { image_file_name: "kokekkopiyopiyo", x_post_num: "1779076974369276014" },
+
+ // MiuJepang
+ { image_file_name: "ippaidou", x_post_num: "1787801976354513319" },
+ { image_file_name: "nihongokurabu", x_post_num: "1779004631936614893" },
+ { image_file_name: "language_exchange_tervern", x_post_num: "1779749425923150317" },
+ { image_file_name: "japanese_culture_osenbeito", x_post_num: "1788522972409721137" },
+ { image_file_name: "silakan_datang_ke_rumahku", x_post_num: "1788522607631056941" },
+ { image_file_name: "uj_club", x_post_num: "1780791654196388201" },
+ { image_file_name: "sushi_stand_guruguru", x_post_num: "1788523302404952218" },
+ { image_file_name: "sushi_guru_annex", x_post_num: null },
+
+ // poposuke_sig
+ { image_file_name: "usanezumi_shrine2", x_post_num: "1781224020383506649" },
+
+ // KUROINU_YOUHEI
+ { image_file_name: "kuroinu_work_room", x_post_num: "1779750007564112146" },
+
+ // いちや_ICHIYA
+ { image_file_name: "ehon_no_heikousekai_jimusho", x_post_num: "1780792306976850285" },
+ { image_file_name: "ikoiba", x_post_num: "1782723006923780580" },
+ { image_file_name: "kimodameshi", x_post_num: "1781224391692714133" },
+ { image_file_name: "parallel_collar", x_post_num: null },
+
+ // HayaTikaze
+ { image_file_name: "study_japanese_world_japanichijou", x_post_num: "1781539871829766550" },
+
+ // aji_3
+ { image_file_name: "yuttari_eikaiwa", x_post_num: "1779002892999078046" },
+
+ // 八葉そるち
+ { image_file_name: "re_yatuha_room", x_post_num: "1779830390435590196" },
+
+ // chakamoto
+ { image_file_name: "chakachaka_multipurpose_room", x_post_num: null },
+
+ // MloYolM (よるむ)
+ { image_file_name: "cafe_cian", x_post_num: "1787802552907739504" },
+
+ // ミラクル・オルカ
+ { image_file_name: "mamehinata_dogrun", x_post_num: "1782723423179100471" },
+
+ // いんく(Eenkoo)
+ { image_file_name: "tyuuniti_kouryuukai", x_post_num: null },
+
+ // 1ban_meno
+ { image_file_name: "bar_asagao", x_post_num: "1788523857642758370" },
+
+ // 沈黙静寂
+ { image_file_name: "monogatari_meetup", x_post_num: "1781538415789674976" },
+
+ // tommie_500
+ { image_file_name: "stretch_club_starting_from_minus", x_post_num: null },
+
+ // MiMi_Sorahana # VRC日韓交流会 (KRJPEX.1355)
+ { image_file_name: "kr_jp_exchange", x_post_num: null },
+
+ // Ein(アイン)
+ { image_file_name: "smokerz_guild_v2", x_post_num: null },
+];
+export default poster_showcase_worlds_settings;
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.jsx b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.jsx
new file mode 100644
index 00000000..37a508b6
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.jsx
@@ -0,0 +1,69 @@
+import clsx from "clsx";
+import styles from "./PostersContents.module.scss";
+import { useUiLanguage } from "@store";
+
+import { useVrctPosterIndex } from "@store";
+import ArrowLeftSvg from "@images/arrow_left.svg?react";
+
+import iya_vrct_poster_ja from "@images/about_vrct/vrct_posters/iya_vrct_poster_ja.png";
+import iya_vrct_poster_en from "@images/about_vrct/vrct_posters/iya_vrct_poster_en.png";
+import iya_vrct_poster_cn from "@images/about_vrct/vrct_posters/iya_vrct_poster_cn.png";
+import iya_vrct_poster_ko from "@images/about_vrct/vrct_posters/iya_vrct_poster_ko.png";
+import iya_vrct_manga_ja from "@images/about_vrct/vrct_posters/iya_vrct_manga_ja.png";
+import iya_vrct_manga_en from "@images/about_vrct/vrct_posters/iya_vrct_manga_en.png";
+import iya_vrct_manga_ko from "@images/about_vrct/vrct_posters/iya_vrct_manga_ko.png";
+
+const poster_images = [
+ { img: iya_vrct_poster_ja, poster_type: "poster" },
+ { img: iya_vrct_poster_en, poster_type: "poster" },
+ { img: iya_vrct_poster_cn, poster_type: "poster" },
+ { img: iya_vrct_poster_ko, poster_type: "poster" },
+ { img: iya_vrct_manga_ja, poster_type: "manga" },
+ { img: iya_vrct_manga_en, poster_type: "manga" },
+ { img: iya_vrct_manga_ko, poster_type: "manga" },
+];
+
+import poster_images_authors_ja from "@images/about_vrct/vrct_posters/authors/poster_images_authors_ja.png";
+import poster_images_authors_en from "@images/about_vrct/vrct_posters/authors/poster_images_authors_en.png";
+import poster_images_authors_m_ja from "@images/about_vrct/vrct_posters/authors/poster_images_authors_m_ja.png";
+import poster_images_authors_m_en from "@images/about_vrct/vrct_posters/authors/poster_images_authors_m_en.png";
+
+export const PostersContents = () => {
+ const { currentVrctPosterIndex, updateVrctPosterIndex } = useVrctPosterIndex();
+ const { currentUiLanguage } = useUiLanguage();
+
+
+ const updateIndex = (delta) => {
+ const newIndex = (currentVrctPosterIndex + delta + poster_images.length) % poster_images.length;
+ updateVrctPosterIndex(newIndex);
+ };
+
+ const current_poster = poster_images[currentVrctPosterIndex];
+ const current_poster_authors_img_ja = (current_poster.poster_type === "poster") ? poster_images_authors_ja : poster_images_authors_m_ja;
+ const current_poster_authors_img_en = (current_poster.poster_type === "poster") ? poster_images_authors_en : poster_images_authors_m_en;
+
+ return (
+
+
+
+

+
+
+ {
+ currentUiLanguage === "ja"
+ ?

+ :

+ }
+
+ );
+};
diff --git a/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.module.scss b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.module.scss
new file mode 100644
index 00000000..739fe78d
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/about_vrct/poster_showcase_contents/posters_contents/PostersContents.module.scss
@@ -0,0 +1,46 @@
+.poster_pagination_container {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+.poster_pagination_wrapper {
+ display: flex;
+}
+
+$poster_img_width: 18rem;
+.poster_img {
+ width: $poster_img_width;
+}
+
+$poster_pagination_button_width: 4.6rem;
+.poster_pagination_button {
+ width: $poster_pagination_button_width;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: var(--dark_700_color);
+ &:hover {
+ background-color: var(--dark_900_color);
+ }
+ &:active {
+ background-color: var(--dark_925_color);
+ }
+ &.poster_prev {
+ border-radius: 0.8rem 0 0 0.8rem;
+ }
+ &.poster_next {
+ border-radius: 0 0.8rem 0.8rem 0;
+ }
+}
+
+.poster_pagination_svg {
+ width: 3.2rem;
+ &.poster_next_svg {
+ transform: rotate(180deg);
+ }
+}
+
+.poster_authors_img {
+ width: $poster_img_width + $poster_pagination_button_width;
+}
diff --git a/src-ui/windows/config_window/setting_section/setting_box/components/dropdown_menu/DropdownMenu.jsx b/src-ui/windows/config_window/setting_section/setting_box/components/dropdown_menu/DropdownMenu.jsx
new file mode 100644
index 00000000..8a90a5fe
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/components/dropdown_menu/DropdownMenu.jsx
@@ -0,0 +1,58 @@
+import styles from "./DropdownMenu.module.scss";
+
+import clsx from "clsx";
+
+import { useOpenedDropdownMenu } from "@store";
+
+export const DropdownMenu = (props) => {
+
+ const { updateOpenedDropdownMenu, currentOpenedDropdownMenu } = useOpenedDropdownMenu();
+ const openDropdownMenu = () => {
+ updateOpenedDropdownMenu(props.dropdown_id);
+ };
+
+ const selectValue = (key) => {
+ updateOpenedDropdownMenu("");
+ props.selectFunction({
+ dropdown_id: props.dropdown_id,
+ selected_id: key,
+ });
+ };
+
+ const dropdown_content_wrapper_class_name = clsx(styles["dropdown_content_wrapper"], {
+ [styles["is_opened"]]: (currentOpenedDropdownMenu === props.dropdown_id) ? true : false
+ });
+
+ const dropdown_toggle_button_class_name = clsx(styles["dropdown_toggle_button"], {
+ [styles["is_loading"]]: (props.state === "loading") ? true : false
+ });
+
+
+ return (
+
+
+ {(props.state === "loading")
+ ?
Loading...
+ :
{props.list[props.selected_id]}
+ }
+ {(props.state === "loading")
+ ?
+ : null
+ }
+
+
+
+ {
+ Object.entries(props.list).map(([key, value]) => {
+ return (
+
selectValue(key)}>
+
{value}
+
+ );
+ })
+ }
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/components/dropdown_menu/DropdownMenu.module.scss b/src-ui/windows/config_window/setting_section/setting_box/components/dropdown_menu/DropdownMenu.module.scss
new file mode 100644
index 00000000..98fd69d0
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/components/dropdown_menu/DropdownMenu.module.scss
@@ -0,0 +1,64 @@
+@import "@scss_mixins";
+
+.container {
+ position: relative;
+}
+
+.dropdown_toggle_button {
+ position: relative;
+ background-color: var(--dark_925_color);
+ min-width: 20rem;
+ padding: 0.6rem 0.8rem;
+ &:hover {
+ background-color: var(--dark_850_color);
+ }
+ &:active {
+ background-color: var(--dark_950_color);
+ }
+ &.is_loading {
+ pointer-events: none;
+ }
+}
+
+.dropdown_selected_text {
+ font-size: 1.4rem;
+}
+
+.dropdown_content_wrapper {
+ display: none;
+ position: absolute;
+ top: 100%; // Position it below the toggle button
+ left: 0;
+ width: 100%;
+ z-index: 1;
+ &.is_opened {
+ display: block;
+ }
+}
+
+.dropdown_content {
+ background-color: var(--dark_900_color);
+ border: 0.1rem solid var(--dark_600_color);
+ display: flex;
+ flex-direction: column;
+ gap: 0.1rem;
+}
+
+.value_button {
+ background-color: var(--dark_875_color);
+ padding: 0.8rem;
+ &:hover {
+ background-color: var(--dark_800_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color);
+ }
+}
+
+.value_text {
+ font-size: 1.2rem;
+}
+
+.loader {
+ @include loader(2rem, 0.2rem, right, 0);
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/components/label_component/LabelComponent.jsx b/src-ui/windows/config_window/setting_section/setting_box/components/label_component/LabelComponent.jsx
new file mode 100644
index 00000000..4f49e33e
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/components/label_component/LabelComponent.jsx
@@ -0,0 +1,10 @@
+import styles from "./LabelComponent.module.scss";
+
+export const LabelComponent = (props) => {
+ return (
+
+
{props.label}
+
{props.desc}
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/components/label_component/LabelComponent.module.scss b/src-ui/windows/config_window/setting_section/setting_box/components/label_component/LabelComponent.module.scss
new file mode 100644
index 00000000..b6baee06
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/components/label_component/LabelComponent.module.scss
@@ -0,0 +1,3 @@
+.label_component {
+
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/useSettingBox.jsx b/src-ui/windows/config_window/setting_section/setting_box/useSettingBox.jsx
new file mode 100644
index 00000000..f311ffad
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/useSettingBox.jsx
@@ -0,0 +1,23 @@
+import styles from "./useSettingBox.module.scss";
+import { LabelComponent } from "./components/label_component/LabelComponent";
+import { DropdownMenu } from "./components/dropdown_menu/DropdownMenu";
+import { useOpenedDropdownMenu } from "@store";
+
+export const useSettingBox = () => {
+ const { updateOpenedDropdownMenu } = useOpenedDropdownMenu();
+
+ const DropdownMenuContainer = (props) => {
+ const onMouseLeaveFunction = () => {
+ updateOpenedDropdownMenu("");
+ };
+
+ return (
+
+
+
+
+ );
+ };
+
+ return { DropdownMenuContainer };
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/setting_section/setting_box/useSettingBox.module.scss b/src-ui/windows/config_window/setting_section/setting_box/useSettingBox.module.scss
new file mode 100644
index 00000000..90cccd5f
--- /dev/null
+++ b/src-ui/windows/config_window/setting_section/setting_box/useSettingBox.module.scss
@@ -0,0 +1,8 @@
+.container {
+ display: flex;
+ width: 100%;
+ justify-content: space-between;
+ align-items: center;
+ background-color: var(--dark_888_color);
+ padding: 2rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/sidebar_section/SidebarSection.jsx b/src-ui/windows/config_window/sidebar_section/SidebarSection.jsx
new file mode 100644
index 00000000..3c033b72
--- /dev/null
+++ b/src-ui/windows/config_window/sidebar_section/SidebarSection.jsx
@@ -0,0 +1,46 @@
+import styles from "./SidebarSection.module.scss";
+
+export const SidebarSection = () => {
+ return (
+
+ );
+};
+
+
+import clsx from "clsx";
+import { useTranslation } from "react-i18next";
+import { useSelectedConfigTab } from "@store";
+
+const Tab = (props) => {
+ const { t } = useTranslation();
+ const { updateSelectedConfigTab, currentSelectedConfigTab } = useSelectedConfigTab();
+ const onclickFunction = () => {
+ updateSelectedConfigTab(props.tab_id);
+ };
+
+ const tab_container_class_names = clsx(styles["tab_container"], {
+ [styles["is_selected"]]: (currentSelectedConfigTab === props.tab_id) ? true : false
+ });
+ const switch_indicator_class_names = clsx(styles["switch_indicator"], {
+ [styles["is_selected"]]: (currentSelectedConfigTab === props.tab_id) ? true : false
+ });
+
+ return (
+
+
{t(`config_window.side_menu_labels.${props.tab_id}`)}
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/sidebar_section/SidebarSection.module.scss b/src-ui/windows/config_window/sidebar_section/SidebarSection.module.scss
new file mode 100644
index 00000000..fa0c7c49
--- /dev/null
+++ b/src-ui/windows/config_window/sidebar_section/SidebarSection.module.scss
@@ -0,0 +1,63 @@
+.container {
+ width: var(--config_window_sidebar_width);
+ flex-shrink: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 5.8rem 0rem 5.8rem 2.8rem;
+ max-height: 60rem;
+}
+
+.tabs_wrapper {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 0.1rem;
+ flex: 1;
+}
+
+.tab_container {
+ position: relative;
+ width: 100%;
+ display: flex;
+ justify-content: left;
+ align-items: center;
+ color: var(--dark_basic_text_color);
+ padding: 0.8rem 0 0.8rem 1.8rem;
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_800_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color);
+ }
+ &.is_selected {
+ background-color: inherit;
+ color: var(--primary_200_color);
+ cursor: default;
+ pointer-events: none;
+ }
+}
+
+.switch_indicator {
+ display: none;
+ &.is_selected {
+ display: block;
+ position: absolute;
+ top: 50%;
+ left: 0rem;
+ transform: translate(-50%, -50%);
+ width: 0.2rem;
+ height: 2.6rem;
+ border-radius: 0.1rem;
+ background-color: var(--primary_300_color);
+ }
+}
+
+.tab_text {
+ font-size: 1.8rem;
+}
+
+.separated_tabs_wrapper {
+ // padding-bottom: 1.2rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/topbar/Topbar.jsx b/src-ui/windows/config_window/topbar/Topbar.jsx
new file mode 100644
index 00000000..636da096
--- /dev/null
+++ b/src-ui/windows/config_window/topbar/Topbar.jsx
@@ -0,0 +1,17 @@
+import styles from "./Topbar.module.scss";
+
+import { TitleBox } from "./title_box/TitleBox";
+import { SectionTitleBox } from "./section_title_box/SectionTitleBox";
+import { CompactSwitchBox } from "./compact_switch_box/CompactSwitchBox";
+
+export const Topbar = () => {
+ return (
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/topbar/Topbar.module.scss b/src-ui/windows/config_window/topbar/Topbar.module.scss
new file mode 100644
index 00000000..d0cd2c64
--- /dev/null
+++ b/src-ui/windows/config_window/topbar/Topbar.module.scss
@@ -0,0 +1,12 @@
+.container {
+ width: 100%;
+ height: 0%;
+}
+
+.wrapper {
+ height: var(--config_window_topbar_height);
+ background-color: var(--dark_850_color);
+ display: flex;
+ justify-content: space-between;
+ flex-shrink: 0;
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/topbar/compact_switch_box/CompactSwitchBox.jsx b/src-ui/windows/config_window/topbar/compact_switch_box/CompactSwitchBox.jsx
new file mode 100644
index 00000000..580e2276
--- /dev/null
+++ b/src-ui/windows/config_window/topbar/compact_switch_box/CompactSwitchBox.jsx
@@ -0,0 +1,12 @@
+import { useTranslation } from "react-i18next";
+
+import styles from "./CompactSwitchBox.module.scss";
+
+export const CompactSwitchBox = () => {
+ const { t } = useTranslation();
+ return (
+
+
{t("config_window.compact_mode")}
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/topbar/compact_switch_box/CompactSwitchBox.module.scss b/src-ui/windows/config_window/topbar/compact_switch_box/CompactSwitchBox.module.scss
new file mode 100644
index 00000000..f824b7d0
--- /dev/null
+++ b/src-ui/windows/config_window/topbar/compact_switch_box/CompactSwitchBox.module.scss
@@ -0,0 +1,9 @@
+.container {
+ // flex: 0;
+ // width: 100%;
+ width: 14rem;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/topbar/section_title_box/SectionTitleBox.jsx b/src-ui/windows/config_window/topbar/section_title_box/SectionTitleBox.jsx
new file mode 100644
index 00000000..90ac7570
--- /dev/null
+++ b/src-ui/windows/config_window/topbar/section_title_box/SectionTitleBox.jsx
@@ -0,0 +1,13 @@
+import { useTranslation } from "react-i18next";
+import styles from "./SectionTitleBox.module.scss";
+import { useSelectedConfigTab } from "@store";
+
+export const SectionTitleBox = () => {
+ const { t } = useTranslation();
+ const { currentSelectedConfigTab } = useSelectedConfigTab();
+ return (
+
+
{t(`config_window.side_menu_labels.${currentSelectedConfigTab}`)}
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/topbar/section_title_box/SectionTitleBox.module.scss b/src-ui/windows/config_window/topbar/section_title_box/SectionTitleBox.module.scss
new file mode 100644
index 00000000..bb022d2e
--- /dev/null
+++ b/src-ui/windows/config_window/topbar/section_title_box/SectionTitleBox.module.scss
@@ -0,0 +1,13 @@
+.container {
+ flex: 1;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: left;
+ align-items: center;
+ padding-left: 2rem;
+}
+
+.title {
+ font-size: 2.2rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/config_window/topbar/title_box/TitleBox.jsx b/src-ui/windows/config_window/topbar/title_box/TitleBox.jsx
new file mode 100644
index 00000000..32a1d5ad
--- /dev/null
+++ b/src-ui/windows/config_window/topbar/title_box/TitleBox.jsx
@@ -0,0 +1,14 @@
+import { useTranslation } from "react-i18next";
+
+import styles from "./TitleBox.module.scss";
+import chato_img from "@images/chato_white.png";
+
+export const TitleBox = () => {
+ const { t } = useTranslation();
+ return (
+
+

+
{t("config_window.config_title")}
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/config_window/topbar/title_box/TitleBox.module.scss b/src-ui/windows/config_window/topbar/title_box/TitleBox.module.scss
new file mode 100644
index 00000000..95151fcf
--- /dev/null
+++ b/src-ui/windows/config_window/topbar/title_box/TitleBox.module.scss
@@ -0,0 +1,19 @@
+.container {
+ // flex: 0;
+ width: var(--config_window_sidebar_width);
+ height: 100%;
+ display: flex;
+ justify-content: left;
+ align-items: center;
+ padding-left: 2.6rem;
+ gap: 1.4rem;
+}
+
+.logo_chato {
+ width: 3.2rem;
+ padding-top: 0.6rem;
+}
+
+.title {
+ font-size: 2.2rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/MainWindow.jsx b/src-ui/windows/main_window/MainWindow.jsx
new file mode 100644
index 00000000..7e391cd5
--- /dev/null
+++ b/src-ui/windows/main_window/MainWindow.jsx
@@ -0,0 +1,52 @@
+import { useEffect, useRef } from "react";
+import styles from "./MainWindow.module.scss";
+import { SidebarSection } from "./sidebar_section/SidebarSection";
+import { MainSection } from "./main_section/MainSection";
+import { useStartPython } from "@logics/useStartPython";
+
+export const MainWindow = () => {
+ const { asyncStartPython } = useStartPython();
+ const hasRunRef = useRef(false);
+
+ useEffect(() => {
+ if (!hasRunRef.current) {
+ asyncStartPython();
+ }
+ return () => hasRunRef.current = true;
+ }, []);
+
+ return (
+
+
+
+
+
+ );
+};
+
+
+import { useTranslation } from "react-i18next";
+import { useIsOpenedConfigWindow } from "@store";
+import { useWindow } from "@utils/useWindow";
+
+export const MainWindowCover = () => {
+ const { t } = useTranslation();
+ const { currentIsOpenedConfigWindow } = useIsOpenedConfigWindow();
+ const { closeConfigWindow } = useWindow();
+ // console.log(currentIsOpenedConfigWindow);
+ if ( currentIsOpenedConfigWindow === false) return null;
+
+ const closeSettingsWindow = () => closeConfigWindow();
+
+ return (
+
+
{t("main_window.cover_message")}
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/MainWindow.module.scss b/src-ui/windows/main_window/MainWindow.module.scss
new file mode 100644
index 00000000..7a8b0027
--- /dev/null
+++ b/src-ui/windows/main_window/MainWindow.module.scss
@@ -0,0 +1,45 @@
+.container {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ background-color: var(--dark_888_color);
+ position: relative;
+}
+
+.main_window_cover {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: (#000000cc);
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+ justify-content: center;
+ align-items: center;
+ backdrop-filter: blur(0.8rem);
+ color: var(--dark_basic_text_color);
+}
+
+.cover_message {
+ font-size: 2rem;
+ font-weight: 300;
+}
+
+.close_settings_window_button {
+ font-size: 1.6rem;
+ font-weight: 300;
+ padding: 1rem 1.4rem;
+ border-radius: 0.4rem;
+ background-color: var(--dark_888_color);
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_825_color);
+ }
+ &:active {
+ background-color: var(--dark_925_color);
+ }
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/index.jsx b/src-ui/windows/main_window/index.jsx
new file mode 100644
index 00000000..07d4d1d2
--- /dev/null
+++ b/src-ui/windows/main_window/index.jsx
@@ -0,0 +1,11 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import "../../../locales/config.js";
+import "@utils/root.css";
+import { MainWindow } from "./MainWindow";
+
+ReactDOM.createRoot(document.getElementById("root")).render(
+
+
+ ,
+);
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/MainSection.jsx b/src-ui/windows/main_window/main_section/MainSection.jsx
new file mode 100644
index 00000000..2b62be6a
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/MainSection.jsx
@@ -0,0 +1,30 @@
+import styles from "./MainSection.module.scss";
+
+import { TopBar } from "./top_bar/TopBar";
+import { MessageContainer } from "./message_container/MessageContainer";
+import { LanguageSelector } from "./language_selector/LanguageSelector";
+
+import { useIsOpenedLanguageSelector } from "@store";
+
+export const MainSection = () => {
+
+ return (
+
+
+
+
+
+ );
+};
+
+const HandleLanguageSelector = () => {
+ const { currentIsOpenedLanguageSelector } = useIsOpenedLanguageSelector();
+
+ if (currentIsOpenedLanguageSelector.your_language === true) {
+ return ;
+ } else if (currentIsOpenedLanguageSelector.target_language === true) {
+ return ;
+ } else {
+ return null;
+ }
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/MainSection.module.scss b/src-ui/windows/main_window/main_section/MainSection.module.scss
new file mode 100644
index 00000000..29a7907a
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/MainSection.module.scss
@@ -0,0 +1,13 @@
+.container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.language_selector_container {
+ width: 100%;
+ height: 100%;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/language_selector/LanguageSelector.jsx b/src-ui/windows/main_window/main_section/language_selector/LanguageSelector.jsx
new file mode 100644
index 00000000..a23faee3
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/language_selector/LanguageSelector.jsx
@@ -0,0 +1,61 @@
+import { useTranslation } from "react-i18next";
+
+import { language_list } from "@data";
+import styles from "./LanguageSelector.module.scss";
+
+import { LanguageSelectorTopBar } from "./language_selector_top_bar/LanguageSelectorTopBar";
+export const LanguageSelector = ({ id }) => {
+ const { t } = useTranslation();
+
+ const languageTitles = {
+ "your_language": t("selectable_language_window.title_your_language"),
+ "target_language": t("selectable_language_window.title_target_language")
+ };
+
+ const language_selector_title = languageTitles[id] || "";
+
+ const groupLanguagesByFirstLetter = (languages) => {
+ return languages.reduce((acc, { language, country }) => {
+ const firstLetter = language[0].toUpperCase();
+ if (!acc[firstLetter]) {
+ acc[firstLetter] = [];
+ }
+ acc[firstLetter].push({ language, country });
+ return acc;
+ }, {});
+ };
+
+ const groupedLanguages = groupLanguagesByFirstLetter(language_list);
+
+ return (
+
+
+
+
+ {Object.entries(groupedLanguages).map(([letter, languages]) => (
+
+ ))}
+
+
+
+ );
+};
+
+const LanguageGroup = ({ letter, languages }) => {
+ return (
+
+
{letter}
+ {languages.map((languageData, index) => (
+
+ ))}
+
+ );
+};
+
+const LanguageButton = ({ languageData }) => {
+ return (
+
+
{languageData.language} ({languageData.country})
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/language_selector/LanguageSelector.module.scss b/src-ui/windows/main_window/main_section/language_selector/LanguageSelector.module.scss
new file mode 100644
index 00000000..17845deb
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/language_selector/LanguageSelector.module.scss
@@ -0,0 +1,50 @@
+.container {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: var(--dark_875_color);
+ flex: 1;
+ overflow-y: hidden;
+}
+
+.language_list_scroll_wrapper {
+ height: 100%;
+ overflow-y: auto;
+ padding: 1.4rem 1rem 8rem 1rem;
+}
+
+.language_list {
+ column-count: auto;
+ column-width: 16rem;
+}
+
+.language_each_letter_box {
+ break-inside: avoid-column;
+ margin-bottom: 1.4rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.1rem;
+}
+
+.language_latter {
+ font-size: 1.4rem;
+ color: var(--dark_500_color);
+}
+
+.language_button {
+ padding: 0.8rem 0.6rem;
+ cursor: pointer;
+ &:hover{
+ background-color: var(--dark_825_color);
+ }
+ &:active{
+ background-color: var(--dark_888_color);
+ }
+}
+
+.language_label {
+ font-size: 1.4rem;
+ color: var(--dark_basic_text_color);
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/language_selector/language_selector_top_bar/LanguageSelectorTopBar.jsx b/src-ui/windows/main_window/main_section/language_selector/language_selector_top_bar/LanguageSelectorTopBar.jsx
new file mode 100644
index 00000000..d1eecc73
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/language_selector/language_selector_top_bar/LanguageSelectorTopBar.jsx
@@ -0,0 +1,23 @@
+import styles from "./LanguageSelectorTopBar.module.scss";
+
+import { useIsOpenedLanguageSelector } from "@store";
+
+export const LanguageSelectorTopBar = (props) => {
+ const { updateIsOpenedLanguageSelector } = useIsOpenedLanguageSelector();
+
+ const closeLanguageSelector = () => {
+ updateIsOpenedLanguageSelector({
+ your_language: false,
+ target_language: false,
+ });
+ };
+
+ return (
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/language_selector/language_selector_top_bar/LanguageSelectorTopBar.module.scss b/src-ui/windows/main_window/main_section/language_selector/language_selector_top_bar/LanguageSelectorTopBar.module.scss
new file mode 100644
index 00000000..1dc95be7
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/language_selector/language_selector_top_bar/LanguageSelectorTopBar.module.scss
@@ -0,0 +1,32 @@
+.container {
+ height: var(--main_window_topbar_height);
+ background-color: var(--dark_850_color);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+}
+
+.title {
+ font-size: 2rem;
+ color: var(--dark_400_color);
+}
+
+.go_back_button_wrapper {
+ position: absolute;
+ left: 0;
+ background-color: var(--dark_800_color);
+ padding: 1.2rem;
+ cursor: pointer;
+ &:hover{
+ background-color: var(--dark_750_color);
+ }
+ &:active{
+ background-color: var(--dark_875_color);
+ }
+}
+
+.go_back_button_label {
+ font-size: 1.4rem;
+ color: var(--dark_400_color);
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/message_container/MessageContainer.jsx b/src-ui/windows/main_window/main_section/message_container/MessageContainer.jsx
new file mode 100644
index 00000000..68e8875f
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/message_container/MessageContainer.jsx
@@ -0,0 +1,34 @@
+import { useResizable } from "react-resizable-layout";
+
+import styles from "./MessageContainer.module.scss";
+
+import { LogBox } from "./log_box/LogBox";
+import { MessageInputBox } from "./message_input_box/MessageInputBox";
+
+export const MessageContainer = () => {
+ const { position, separatorProps } = useResizable({
+ axis: "y",
+ reverse: true
+ });
+
+ return (
+
+ );
+};
+
+const Separator = ({ ...props }) => {
+ return (
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/message_container/MessageContainer.module.scss b/src-ui/windows/main_window/main_section/message_container/MessageContainer.module.scss
new file mode 100644
index 00000000..2bd2288b
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/message_container/MessageContainer.module.scss
@@ -0,0 +1,36 @@
+.container {
+ height: 0%;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ padding: 0 1.6rem 1rem 1.6rem;
+}
+
+.separator {
+ position: relative;
+ width: 100%;
+ height: 0.8rem;
+ cursor: row-resize;
+ flex-shrink: 0;
+ &:hover {
+ & .separator_line {
+ background-color: var(--primary_300_color);
+ }
+ }
+}
+.separator_line {
+ position: absolute;
+ bottom: 0%;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ height: 50%;
+ width: 99%;
+ transition: background-color .15s ease-out;
+}
+
+.message_box_resize_wrapper {
+ height: 10rem;
+ min-height: 3.8rem;
+ max-height: 80%;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/message_container/log_box/LogBox.jsx b/src-ui/windows/main_window/main_section/message_container/log_box/LogBox.jsx
new file mode 100644
index 00000000..2dbeee71
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/message_container/log_box/LogBox.jsx
@@ -0,0 +1,47 @@
+import { useEffect, useLayoutEffect, useRef, useState } from "react";
+import styles from "./LogBox.module.scss";
+import { useMessageLogs, store } from "@store";
+import { MessageContainer } from "./message_container/MessageContainer";
+import { scrollToBottom } from "@logics/scrollToBottom";
+
+export const LogBox = () => {
+ const { currentMessageLogs } = useMessageLogs();
+ const log_container_ref = useRef(null);
+ const [is_scrolling, setIsScrolling] = useState(false);
+
+ useLayoutEffect(() => {
+ store.log_box_ref = log_container_ref;
+ if (!is_scrolling) {
+ scrollToBottom(store.log_box_ref, true);
+ }
+ }, [currentMessageLogs]);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ const element = log_container_ref.current;
+ const currentScrollTop = element.scrollTop;
+ const at_bottom = element.scrollHeight - currentScrollTop === element.clientHeight;
+
+ if (at_bottom) {
+ setIsScrolling(false);
+ } else {
+ setIsScrolling(true);
+ }
+ };
+
+ const element = log_container_ref.current;
+ element.addEventListener("scroll", handleScroll);
+
+ return () => {
+ element.removeEventListener("scroll", handleScroll);
+ };
+ }, []);
+
+ return (
+
+ {currentMessageLogs.map(message_data => (
+
+ ))}
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/message_container/log_box/LogBox.module.scss b/src-ui/windows/main_window/main_section/message_container/log_box/LogBox.module.scss
new file mode 100644
index 00000000..1a29c1dc
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/message_container/log_box/LogBox.module.scss
@@ -0,0 +1,13 @@
+.container {
+ height: 100%;
+ width: 100%;
+ flex: 1;
+ background-color: var(--dark_900_color);
+ overflow: auto;
+ border-radius: 0.8rem;
+ padding: 1rem;
+}
+
+.text {
+ overflow-wrap: break-word;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/message_container/log_box/message_container/MessageContainer.jsx b/src-ui/windows/main_window/main_section/message_container/log_box/message_container/MessageContainer.jsx
new file mode 100644
index 00000000..7ce032a7
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/message_container/log_box/message_container/MessageContainer.jsx
@@ -0,0 +1,44 @@
+import { useTranslation } from "react-i18next";
+import clsx from "clsx";
+import styles from "./MessageContainer.module.scss";
+
+export const MessageContainer = ({ messages, status, category, created_at }) => {
+ const { t } = useTranslation();
+
+ const is_translated_exist = messages.translated.length >= 1;
+ const is_pending = status === "pending";
+ const is_sent_message = category === "sent";
+ const category_text = is_sent_message ? t("main_window.textbox_tab_sent") : t("main_window.textbox_tab_received");
+
+ const message_type_class_name = clsx({
+ [styles.sent_message]: is_sent_message,
+ [styles.received_message]: !is_sent_message,
+ });
+
+ return (
+
+
+
{created_at}
+
{category_text}
+ {is_sent_message && is_pending &&
}
+
+
+ {is_translated_exist
+ ?
+ :
{messages.original}
+ }
+
+
+ );
+};
+
+const WithTranslatedMessages = ({ messages }) => {
+ return (
+ <>
+ {messages.original}
+ {messages.translated.map((message, index) => (
+ {message}
+ ))}
+ >
+ );
+};
diff --git a/src-ui/windows/main_window/main_section/message_container/log_box/message_container/MessageContainer.module.scss b/src-ui/windows/main_window/main_section/message_container/log_box/message_container/MessageContainer.module.scss
new file mode 100644
index 00000000..66bd5c92
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/message_container/log_box/message_container/MessageContainer.module.scss
@@ -0,0 +1,70 @@
+@import "@scss_mixins";
+
+.container {
+ margin-bottom: 1rem;
+ width: 100%;
+ flex-direction: column;
+ display: flex;
+ justify-content: center;
+ &.sent_message {
+ align-items: end;
+ }
+ &.received_message {
+ align-items: start;
+ }
+}
+
+.info_box {
+ position: relative;
+ display: flex;
+ gap: 0.8rem;
+ justify-content: center;
+ &.sent_message {
+ align-items: end;
+ }
+ &.received_message {
+ flex-flow: row-reverse;
+ align-items: start;
+ }
+}
+
+.loader {
+ @include loader(0.8rem, 0.1rem, left, -1rem);
+}
+
+.time {
+ font-size: 1rem;
+ color: var(--dark_600_color);
+}
+
+.category {
+ font-size: 1rem;
+ &.sent_message {
+ color: var(--sent_400_color);
+ }
+ &.received_message {
+ align-items: start;
+ color: var(--received_300_color);
+ }
+}
+
+.message_box {
+ display: flex;
+ flex-direction: column;
+ &.sent_message {
+ align-items: end;
+ }
+ &.received_message {
+ align-items: start;
+ }
+}
+
+.message_main {
+ color: var(--dark_basic_text_color);
+ font-size: 1.4rem;
+}
+
+.message_second {
+ color: var(--dark_450_color);
+ font-size: 1rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/message_container/message_input_box/MessageInputBox.jsx b/src-ui/windows/main_window/main_section/message_container/message_input_box/MessageInputBox.jsx
new file mode 100644
index 00000000..951ec4b8
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/message_container/message_input_box/MessageInputBox.jsx
@@ -0,0 +1,45 @@
+import { useState } from "react";
+import styles from "./MessageInputBox.module.scss";
+import SendMessageSvg from "@images/send_message.svg?react";
+import { useMessage } from "@logics/useMessage";
+import { store } from "@store";
+import { scrollToBottom } from "@logics/scrollToBottom";
+
+
+export const MessageInputBox = () => {
+ const [inputValue, setInputValue] = useState("");
+ const { sendMessage } = useMessage();
+
+ const onSubmitFunction = (e) => {
+ e.preventDefault();
+ sendMessage(inputValue);
+
+ setTimeout(() => {
+ scrollToBottom(store.log_box_ref);
+ }, 10);
+
+ };
+
+ const onChangeFunction = (e) => {
+ setInputValue(e.currentTarget.value);
+ };
+
+ return (
+
+ );
+};
diff --git a/src-ui/windows/main_window/main_section/message_container/message_input_box/MessageInputBox.module.scss b/src-ui/windows/main_window/main_section/message_container/message_input_box/MessageInputBox.module.scss
new file mode 100644
index 00000000..bb90bb3e
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/message_container/message_input_box/MessageInputBox.module.scss
@@ -0,0 +1,45 @@
+.container {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+}
+
+.message_box_wrapper {
+ width: 100%;
+ height: 100%;
+ margin-right: 1rem;
+ padding: 0.8rem;
+ background-color: var(--dark_875_color);
+ border: 0.1rem solid var(--dark_750_color);
+ border-radius: 0.4rem;
+}
+
+.message_box_input_area {
+ width: 100%;
+ height: 100%;
+ font-size: 1.6rem;
+ resize: none;
+}
+
+.message_send_button {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ max-width: 10rem;
+ height: 100%;
+ font-size: 1.2rem;
+ background-color: var(--dark_850_color);
+ border-radius: 0.4rem;
+ aspect-ratio: 1 / 1;
+ &:hover {
+ background-color: var(--dark_825_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color);
+ }
+}
+
+.message_send_icon {
+ width: 2rem;
+ color: var(--dark_400_color);
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/top_bar/TopBar.jsx b/src-ui/windows/main_window/main_section/top_bar/TopBar.jsx
new file mode 100644
index 00000000..8beac986
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/top_bar/TopBar.jsx
@@ -0,0 +1,13 @@
+import styles from "./TopBar.module.scss";
+
+import { SidebarCompactModeButton } from "./sidebar_compact_mode_button/SidebarCompactModeButton";
+import { RightSideComponents } from "./right_side_components/RightSideComponents";
+
+export const TopBar = () => {
+ return (
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/top_bar/TopBar.module.scss b/src-ui/windows/main_window/main_section/top_bar/TopBar.module.scss
new file mode 100644
index 00000000..0b6f0c09
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/top_bar/TopBar.module.scss
@@ -0,0 +1,7 @@
+.container {
+ height: var(--main_window_topbar_height);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-right: 1.6rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/top_bar/right_side_components/RightSideComponents.jsx b/src-ui/windows/main_window/main_section/top_bar/right_side_components/RightSideComponents.jsx
new file mode 100644
index 00000000..4ceb31f9
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/top_bar/right_side_components/RightSideComponents.jsx
@@ -0,0 +1,20 @@
+import styles from "./RightSideComponents.module.scss";
+
+import HelpSvg from "@images/help.svg?react";
+
+export const RightSideComponents = () => {
+ return (
+
+
VRC mic mute sync
+
Overlay(VR)
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/top_bar/right_side_components/RightSideComponents.module.scss b/src-ui/windows/main_window/main_section/top_bar/right_side_components/RightSideComponents.module.scss
new file mode 100644
index 00000000..d3c77d6d
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/top_bar/right_side_components/RightSideComponents.module.scss
@@ -0,0 +1,23 @@
+.container {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 1rem;
+}
+
+.help_and_info_button {
+ padding: 0.6rem;
+ border-radius: 0.6rem;
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_800_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color);
+ }
+}
+
+.help_svg {
+ width: 2.4rem;
+ color: var(--dark_400_color);
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/top_bar/sidebar_compact_mode_button/SidebarCompactModeButton.jsx b/src-ui/windows/main_window/main_section/top_bar/sidebar_compact_mode_button/SidebarCompactModeButton.jsx
new file mode 100644
index 00000000..ddcc859e
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/top_bar/sidebar_compact_mode_button/SidebarCompactModeButton.jsx
@@ -0,0 +1,23 @@
+import clsx from "clsx";
+import styles from "./SidebarCompactModeButton.module.scss";
+
+import { useIsCompactMode } from "@store";
+import ArrowLeftSvg from "@images/arrow_left.svg?react";
+
+export const SidebarCompactModeButton = () => {
+ const { updateIsCompactMode, currentIsCompactMode } = useIsCompactMode();
+
+ const toggleCompactMode = () => {
+ updateIsCompactMode(!currentIsCompactMode);
+ };
+
+ const class_names = clsx(styles["arrow_left_svg"], {
+ [styles["reverse"]]: currentIsCompactMode
+ });
+
+ return (
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/main_section/top_bar/sidebar_compact_mode_button/SidebarCompactModeButton.module.scss b/src-ui/windows/main_window/main_section/top_bar/sidebar_compact_mode_button/SidebarCompactModeButton.module.scss
new file mode 100644
index 00000000..b9107305
--- /dev/null
+++ b/src-ui/windows/main_window/main_section/top_bar/sidebar_compact_mode_button/SidebarCompactModeButton.module.scss
@@ -0,0 +1,22 @@
+.container {
+ height: 100%;
+ width: 2.2rem;
+ background-color: var(--dark_850_color);
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_800_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color);
+ }
+}
+
+.arrow_left_svg {
+ height: 100%;
+ width: 100%;
+ padding: 1.1rem 0rem;
+ color: var(--dark_400_color);
+ &.reverse {
+ transform: rotate(180deg);
+ }
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/SidebarSection.jsx b/src-ui/windows/main_window/sidebar_section/SidebarSection.jsx
new file mode 100644
index 00000000..86cc73e4
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/SidebarSection.jsx
@@ -0,0 +1,25 @@
+import clsx from "clsx";
+
+import styles from "./SidebarSection.module.scss";
+import { useIsCompactMode } from "@store";
+
+import { Logo } from "./logo/Logo";
+import { MainFunctionSwitch } from "./main_function_switch/MainFunctionSwitch";
+import { LanguageSettings } from "./language_settings/LanguageSettings";
+import { OpenSettings } from "./open_settings/OpenSettings";
+
+export const SidebarSection = () => {
+ const { currentIsCompactMode } = useIsCompactMode();
+ const container_class_name = clsx(styles["container"], {
+ [styles["is_compact_mode"]]: currentIsCompactMode
+ });
+
+ return (
+
+
+
+ {!currentIsCompactMode && }
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/SidebarSection.module.scss b/src-ui/windows/main_window/sidebar_section/SidebarSection.module.scss
new file mode 100644
index 00000000..de2f091a
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/SidebarSection.module.scss
@@ -0,0 +1,11 @@
+.container {
+ position: relative;
+ min-width: 23rem;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ background-color: var(--dark_850_color);
+ &.is_compact_mode {
+ min-width: auto;
+ }
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/LanguageSettings.jsx b/src-ui/windows/main_window/sidebar_section/language_settings/LanguageSettings.jsx
new file mode 100644
index 00000000..cac910dc
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/LanguageSettings.jsx
@@ -0,0 +1,101 @@
+import { useTranslation } from "react-i18next";
+
+import styles from "./LanguageSettings.module.scss";
+
+import { PresetSelectTabs } from "./preset_select_tabs/PresetSelectTabs";
+import { LanguageSelectorOpenButton } from "./language_selector_open_button/LanguageSelectorOpenButton";
+import { LanguageSwapButton } from "./language_swap_button/LanguageSwapButton";
+import { TranslatorSelectorOpenButton } from "./translator_selector_open_button/TranslatorSelectorOpenButton";
+import { useOpenedTranslatorSelector } from "@store";
+
+export const LanguageSettings = () => {
+ const { updateOpenedTranslatorSelector} = useOpenedTranslatorSelector();
+ const closeTranslatorSelector = () => updateOpenedTranslatorSelector(false);
+
+ return (
+
+
Language Settings
+
+
+
+ );
+};
+
+
+import MicSvg from "@images/mic.svg?react";
+import HeadphonesSvg from "@images/headphones.svg?react";
+import { useIsOpenedLanguageSelector } from "@store";
+import { useMainFunction } from "@logics/useMainFunction";
+
+const PresetContainer = () => {
+ const { t } = useTranslation();
+ const { updateIsOpenedLanguageSelector, currentIsOpenedLanguageSelector } = useIsOpenedLanguageSelector();
+
+ const {
+ currentState_TranscriptionSend,
+ currentState_TranscriptionReceive,
+ } = useMainFunction();
+
+
+ const closeLanguageSelector = () => {
+ updateIsOpenedLanguageSelector({
+ your_language: false,
+ target_language: false,
+ });
+ };
+
+ const toggleYourLanguageSelector = () => {
+ if (currentIsOpenedLanguageSelector.your_language === true) {
+ closeLanguageSelector();
+ } else {
+ updateIsOpenedLanguageSelector({
+ your_language: true,
+ target_language: false,
+ });
+ }
+ };
+
+ const toggleTargetLanguageSelector = () => {
+ if (currentIsOpenedLanguageSelector.target_language === true) {
+ closeLanguageSelector();
+ } else {
+ updateIsOpenedLanguageSelector({
+ your_language: false,
+ target_language: true,
+ });
+ }
+ };
+
+ const handleLanguageSelectorClick = (selector) => {
+ if (selector === "your_language") {
+ toggleYourLanguageSelector();
+ } else if (selector === "target_language") {
+ toggleTargetLanguageSelector();
+ }
+ };
+
+ const your_language_settings = {
+ title: t("main_window.your_language"),
+ is_opened: currentIsOpenedLanguageSelector.your_language,
+ onClickFunction: () => handleLanguageSelectorClick("your_language"),
+ TurnedOnSvgComponent: ,
+ is_turned_on: currentState_TranscriptionSend.data,
+ };
+
+ const target_language_settings = {
+ title: t("main_window.target_language"),
+ is_opened: currentIsOpenedLanguageSelector.target_language,
+ onClickFunction: () => handleLanguageSelectorClick("target_language"),
+ TurnedOnSvgComponent: ,
+ is_turned_on: currentState_TranscriptionReceive.data,
+ };
+
+ return (
+
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/LanguageSettings.module.scss b/src-ui/windows/main_window/sidebar_section/language_settings/LanguageSettings.module.scss
new file mode 100644
index 00000000..1c2b3a0e
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/LanguageSettings.module.scss
@@ -0,0 +1,21 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.title {
+ font-size: 1.4rem;
+ padding-top: 1rem;
+ padding-bottom: 0.8rem;
+ color: var(--dark_400_color);
+}
+
+.preset_container {
+ width: 100%;
+ padding-top: 0.8rem;
+ background-color: var(--dark_800_color);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/language_selector_open_button/LanguageSelectorOpenButton.jsx b/src-ui/windows/main_window/sidebar_section/language_settings/language_selector_open_button/LanguageSelectorOpenButton.jsx
new file mode 100644
index 00000000..9c269101
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/language_selector_open_button/LanguageSelectorOpenButton.jsx
@@ -0,0 +1,34 @@
+import clsx from "clsx";
+import styles from "./LanguageSelectorOpenButton.module.scss";
+import ArrowLeftSvg from "@images/arrow_left.svg?react";
+import { useSvg } from "@utils/useSvg";
+export const LanguageSelectorOpenButton = (props) => {
+
+ const toggleLanguageSelector = () => {
+ props.onClickFunction();
+ };
+
+ const class_names = clsx(styles["arrow_left_svg"], {
+ [styles["reverse"]]: props.is_opened
+ });
+
+ const SvgComponent = useSvg(props.TurnedOnSvgComponent,
+ {className: clsx(styles["category_svg"], {
+ [styles["is_turned_on"]]: props.is_turned_on
+ })}
+ );
+
+ return (
+
+
+ {SvgComponent}
+
{props.title}
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/language_selector_open_button/LanguageSelectorOpenButton.module.scss b/src-ui/windows/main_window/sidebar_section/language_settings/language_selector_open_button/LanguageSelectorOpenButton.module.scss
new file mode 100644
index 00000000..3bce23ac
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/language_selector_open_button/LanguageSelectorOpenButton.module.scss
@@ -0,0 +1,73 @@
+.container {
+ width: 100%;
+ background-color: var(--dark_825_color);
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ padding: 0.8rem;
+ gap: 0.8rem;
+}
+
+.title_container {
+ position: relative;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ text-align: center;
+}
+
+.category_svg {
+ position: absolute;
+ top: 50%;
+ left: 1.2rem;
+ transform: translate(-50%, -50%);
+ width: 1.4rem;
+ color: var(--dark_400_color);
+ display: none;
+ &.is_turned_on {
+ display: block;
+ }
+}
+
+.title {
+ font-size: 1.6rem;
+ color: var(--dark_400_color);
+}
+
+.dropdown_menu_container {
+ position: relative;
+ background-color: var(--dark_888_color);
+ width: 100%;
+ padding: 0.2rem 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ border-radius: 0.4rem;
+ gap: 0.2rem;
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_875_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color);
+ }
+}
+
+.selected_language {
+ font-size: 1.2rem;
+ color: var(--dark_basic_text_color);
+}
+
+.arrow_left_svg {
+ position: absolute;
+ right: 0;
+ margin: 0 0.2rem;
+ transform: rotate(180deg);
+ width: 1.6rem;
+ color: var(--dark_basic_text_color);
+ &.reverse {
+ transform: rotate(0deg);
+ }
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/language_swap_button/LanguageSwapButton.jsx b/src-ui/windows/main_window/sidebar_section/language_settings/language_swap_button/LanguageSwapButton.jsx
new file mode 100644
index 00000000..0f91b73e
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/language_swap_button/LanguageSwapButton.jsx
@@ -0,0 +1,37 @@
+import { useState } from "react";
+import clsx from "clsx";
+import { useTranslation } from "react-i18next";
+
+import styles from "./LanguageSwapButton.module.scss";
+
+import NarrowArrowDownSvg from "@images/narrow_arrow_down.svg?react";
+
+export const LanguageSwapButton = () => {
+ const [isHovered, setIsHovered] = useState(false);
+ const { t } = useTranslation();
+
+ const label = isHovered
+ ? t("main_window.swap_button_label")
+ : t("main_window.translate_each_other_label");
+
+ const labelClassName = clsx(styles["label"], {
+ [styles["is_hovered"]]: isHovered
+ });
+
+ const handleMouseEnter = () => setIsHovered(true);
+ const handleMouseLeave = () => setIsHovered(false);
+
+ return (
+
+ );
+};
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/language_swap_button/LanguageSwapButton.module.scss b/src-ui/windows/main_window/sidebar_section/language_settings/language_swap_button/LanguageSwapButton.module.scss
new file mode 100644
index 00000000..1badfdda
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/language_swap_button/LanguageSwapButton.module.scss
@@ -0,0 +1,36 @@
+.container {
+ width: 100%;
+}
+
+.swap_button_wrapper {
+ width: auto;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin: 0.8rem 2rem;
+ padding: 0.4rem 0.8rem;
+ border-radius: 0.6rem;
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_750_color);
+ }
+ &:active {
+ background-color: var(--dark_850_color);
+ }
+}
+
+.narrow_arrow_down_svg {
+ width: 1.6rem;
+ color: var(--dark_500_color);
+ &.reverse {
+ transform: rotate(180deg);
+ }
+}
+
+.label {
+ font-size: 1.2rem;
+ color: var(--dark_500_color);
+ &.is_hovered {
+ color: var(--dark_basic_text_color);
+ }
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/preset_select_tabs/PresetSelectTabs.jsx b/src-ui/windows/main_window/sidebar_section/language_settings/preset_select_tabs/PresetSelectTabs.jsx
new file mode 100644
index 00000000..62504caa
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/preset_select_tabs/PresetSelectTabs.jsx
@@ -0,0 +1,32 @@
+import styles from "./PresetSelectTabs.module.scss";
+
+export const PresetSelectTabs = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+import clsx from "clsx";
+
+import { useSelectedTab } from "@store";
+
+const Tab = (props) => {
+ const { updateSelectedTab, currentSelectedTab } = useSelectedTab();
+ const onclickFunction = () => {
+ updateSelectedTab(props.preset_number);
+ };
+
+ const class_names = clsx(styles["tab_container"], {
+ [styles["is_selected"]]: (currentSelectedTab === props.preset_number) ? true : false
+ });
+
+ return (
+
+
{props.preset_number}
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/preset_select_tabs/PresetSelectTabs.module.scss b/src-ui/windows/main_window/sidebar_section/language_settings/preset_select_tabs/PresetSelectTabs.module.scss
new file mode 100644
index 00000000..906bafd3
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/preset_select_tabs/PresetSelectTabs.module.scss
@@ -0,0 +1,32 @@
+.container {
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+}
+
+.tab_container {
+ height: 3rem;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 0.6rem 0.6rem 0 0;
+ color: var(--dark_600_color);
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_825_color);
+ }
+ &:active {
+ background-color: var(--dark_875_color);
+ }
+ &.is_selected {
+ background-color: var(--dark_800_color);
+ color: var(--dark_basic_text_color);
+ cursor: default;
+ pointer-events: none;
+ }
+}
+
+.tab_number {
+ font-size: 1.6rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/TranslatorSelectorOpenButton.jsx b/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/TranslatorSelectorOpenButton.jsx
new file mode 100644
index 00000000..9fa9d23c
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/TranslatorSelectorOpenButton.jsx
@@ -0,0 +1,28 @@
+import { useTranslation } from "react-i18next";
+
+import styles from "./TranslatorSelectorOpenButton.module.scss";
+import { TranslatorSelector } from "./translator_selector/TranslatorSelector";
+import { useTranslatorList, useSelectedTranslator, useOpenedTranslatorSelector } from "@store";
+
+export const TranslatorSelectorOpenButton = () => {
+ const { t } = useTranslation();
+ const { currentSelectedTranslator } = useSelectedTranslator();
+ const { currentTranslatorList } = useTranslatorList();
+ const currentTranslator = currentTranslatorList.find(
+ translator_data => translator_data.translator_key === currentSelectedTranslator
+ );
+
+ const { currentOpenedTranslatorSelector, updateOpenedTranslatorSelector} = useOpenedTranslatorSelector();
+
+ const openTranslatorSelector = () => updateOpenedTranslatorSelector(!currentOpenedTranslatorSelector);
+
+ return (
+
+
+
{t("main_window.translator")}
+
{currentTranslator?.translator_name}
+
+ {currentOpenedTranslatorSelector &&
}
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/TranslatorSelectorOpenButton.module.scss b/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/TranslatorSelectorOpenButton.module.scss
new file mode 100644
index 00000000..f32a232e
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/TranslatorSelectorOpenButton.module.scss
@@ -0,0 +1,27 @@
+.container {
+ position: relative;
+ width: 100%;
+}
+
+.translator_selector_button {
+ width: auto;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 0.2rem;
+ margin: 0.4rem;
+ padding: 0.6rem 0;
+ border-radius: 0.6rem;
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_875_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color);
+ }
+}
+
+.label {
+ font-size: 1.2rem;
+ color: var(--dark_basic_text_color);
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/translator_selector/TranslatorSelector.jsx b/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/translator_selector/TranslatorSelector.jsx
new file mode 100644
index 00000000..c0c1bf8f
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/translator_selector/TranslatorSelector.jsx
@@ -0,0 +1,49 @@
+import styles from "./TranslatorSelector.module.scss";
+import { chunkArray } from "@utils/chunkArray";
+
+import { useTranslatorList, useSelectedTranslator, useOpenedTranslatorSelector } from "@store";
+export const TranslatorSelector = () => {
+ const { currentTranslatorList } = useTranslatorList();
+ const columns = chunkArray(currentTranslatorList, 2);
+
+ return (
+
+
+ {columns.map((column, column_index) => (
+
+ {column.map(({ translator_key, translator_name, is_available }) => (
+
+ ))}
+
+ ))}
+
+
+ );
+};
+
+import clsx from "clsx";
+const TranslatorBox = (props) => {
+ const { currentSelectedTranslator, updateSelectedTranslator} = useSelectedTranslator();
+ const { updateOpenedTranslatorSelector} = useOpenedTranslatorSelector();
+
+ const box_class_name = clsx(
+ styles.box,
+ { [styles["is_selected"]]: (currentSelectedTranslator === props.translator_id) ? true : false },
+ { [styles["is_available"]]: (props.is_available === true) ? true : false }
+ );
+
+ const selectTranslator = () => {
+ updateSelectedTranslator(props.translator_id);
+ updateOpenedTranslatorSelector(false);
+ };
+ return (
+
+
{props.translator_name}
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/translator_selector/TranslatorSelector.module.scss b/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/translator_selector/TranslatorSelector.module.scss
new file mode 100644
index 00000000..09262137
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/language_settings/translator_selector_open_button/translator_selector/TranslatorSelector.module.scss
@@ -0,0 +1,63 @@
+.container {
+ position: absolute;
+ bottom: 100%;
+ width: 100%;
+ height: 26rem;
+ padding: 1rem;
+ background-color: (#000000dd);
+ // background-color: (var(--dark_875_color) + 80);
+ backdrop-filter: blur(0.1rem);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 1rem;
+}
+
+.column_wrapper {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 1rem;
+}
+
+$box_size: 6.8rem;
+.box {
+ width: $box_size;
+ height: $box_size;
+ background-color: var(--dark_875_color);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ white-space: pre-wrap;
+ text-align: center;
+ border-radius: 0.6rem;
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_825_color);
+ }
+ &:active {
+ background-color: var(--dark_900_color);
+ border: 0.1rem solid var(--primary_300_color);
+ }
+ &.is_selected {
+ border: 0.2rem solid var(--primary_300_color);
+ }
+ &:not(.is_available) {
+ pointer-events: none;
+ background-color: var(--dark_950_color);
+ & .translator_name {
+ color: var(--dark_600_color);
+ }
+ }
+}
+
+.translator_name {
+ font-size: 1.4rem;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/logo/Logo.jsx b/src-ui/windows/main_window/sidebar_section/logo/Logo.jsx
new file mode 100644
index 00000000..7ac3ca13
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/logo/Logo.jsx
@@ -0,0 +1,23 @@
+import styles from "./Logo.module.scss";
+
+export const Logo = () => {
+ return (
+
+
+
+ );
+};
+
+
+import vrct_logo from "@images/vrct_logo_for_dark_mode.png";
+import chato_img from "@images/chato_white.png";
+import { useIsCompactMode } from "@store";
+
+export const LogoBox = () => {
+ const { currentIsCompactMode } = useIsCompactMode();
+ if (currentIsCompactMode === true) {
+ return
;
+ } else {
+ return
;
+ }
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/logo/Logo.module.scss b/src-ui/windows/main_window/sidebar_section/logo/Logo.module.scss
new file mode 100644
index 00000000..74a57682
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/logo/Logo.module.scss
@@ -0,0 +1,18 @@
+.container {
+ height: var(--main_window_topbar_height);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.logo {
+ width: 12rem;
+ height: auto;
+ margin: auto;
+}
+
+.logo_chato {
+ width: 2rem;
+ height: auto;
+ margin: auto;
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/main_function_switch/MainFunctionSwitch.jsx b/src-ui/windows/main_window/sidebar_section/main_function_switch/MainFunctionSwitch.jsx
new file mode 100644
index 00000000..5a663f42
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/main_function_switch/MainFunctionSwitch.jsx
@@ -0,0 +1,117 @@
+import { useTranslation } from "react-i18next";
+import clsx from "clsx";
+import styles from "./MainFunctionSwitch.module.scss";
+import TranslationSvg from "@images/translation.svg?react";
+import MicSvg from "@images/mic.svg?react";
+import HeadphonesSvg from "@images/headphones.svg?react";
+import ForegroundSvg from "@images/foreground.svg?react";
+import { useIsCompactMode } from "@store";
+
+import { useMainFunction } from "@logics/useMainFunction";
+
+export const MainFunctionSwitch = () => {
+ const { t } = useTranslation();
+
+ const {
+ toggleTranslation, currentState_Translation,
+ toggleTranscriptionSend, currentState_TranscriptionSend,
+ toggleTranscriptionReceive, currentState_TranscriptionReceive,
+ toggleForeground, currentState_Foreground,
+ } = useMainFunction();
+
+
+ const switch_items = [
+ {
+ switch_id: "translation",
+ label: t("main_window.translation"),
+ SvgComponent: TranslationSvg,
+ currentState: currentState_Translation,
+ toggleFunction: toggleTranslation,
+ },
+ {
+ switch_id: "transcription_send",
+ label: t("main_window.transcription_send"),
+ SvgComponent: MicSvg,
+ currentState: currentState_TranscriptionSend,
+ toggleFunction: toggleTranscriptionSend,
+ },
+ {
+ switch_id: "transcription_receive",
+ label: t("main_window.transcription_receive"),
+ SvgComponent: HeadphonesSvg,
+ currentState: currentState_TranscriptionReceive,
+ toggleFunction: toggleTranscriptionReceive,
+ },
+ {
+ switch_id: "foreground",
+ label: t("main_window.foreground"),
+ SvgComponent: ForegroundSvg,
+ currentState: currentState_Foreground,
+ toggleFunction: toggleForeground,
+ },
+ ];
+
+ return (
+
+ {switch_items.map(item => (
+
+
+ ))}
+
+ );
+};
+
+import { useState } from "react";
+
+export const SwitchContainer = ({ switchLabel, switch_id, children, currentState, toggleFunction, SvgComponent }) => {
+ const [is_hovered, setIsHovered] = useState(false);
+ const [is_mouse_down, setIsMouseDown] = useState(false);
+
+ const { currentIsCompactMode } = useIsCompactMode();
+
+ const getClassNames = (baseClass) => clsx(baseClass, {
+ [styles.is_compact_mode]: currentIsCompactMode,
+ [styles.is_active]: (currentState.data === true),
+ [styles.is_loading]: (currentState.state === "loading"),
+ [styles.is_hovered]: is_hovered,
+ [styles.is_mouse_down]: is_mouse_down,
+ });
+
+ const onMouseEnter = () => setIsHovered(true);
+ const onMouseLeave = () => setIsHovered(false);
+ const onMouseDown = () => setIsMouseDown(true);
+ const onMouseUp = () => setIsMouseDown(false);
+
+ return (
+
+
+
+
{switchLabel}
+ {children}
+
+
+
+
+
+
+
+ {(currentState.state === "loading")
+ ?
+ : null
+ }
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/main_function_switch/MainFunctionSwitch.module.scss b/src-ui/windows/main_window/sidebar_section/main_function_switch/MainFunctionSwitch.module.scss
new file mode 100644
index 00000000..1164c2b1
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/main_function_switch/MainFunctionSwitch.module.scss
@@ -0,0 +1,88 @@
+@import "@scss_mixins";
+.container {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ gap: 0.1rem;
+}
+
+.switch_container {
+ position: relative;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 1.6rem 1.4rem;
+ background-color: var(--dark_825_color);
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_800_color);
+ }
+ &:active {
+ background-color: var(--dark_875_color);
+ }
+ &.is_compact_mode {
+ padding: 1.5rem;
+ }
+ &.is_loading {
+ pointer-events: none;
+ }
+}
+
+.label_wrapper {
+ width: 100%;
+ display: flex;
+ justify-content: left;
+ align-items: center;
+ gap: 0.8rem;
+}
+
+$basic_label_color: var(--dark_basic_text_color);
+$loading_label_color: var(--dark_500_color);
+.switch_label {
+ font-size: 1.4rem;
+ color: $basic_label_color;
+ &.is_compact_mode {
+ display: none;
+ }
+ &.is_loading {
+ color: $loading_label_color;
+ }
+}
+
+.switch_svg {
+ width: 1.8rem;
+ color: $basic_label_color;
+ &.is_loading {
+ color: $loading_label_color;
+ }
+ &:not(.is_compact_mode) {
+ width: 1.6rem;
+ color: var(--dark_350_color);
+ }
+}
+
+.switch_indicator {
+ position: absolute;
+ top: 50%;
+ right: 0.4rem;
+ transform: translate(-50%, -50%);
+ width: 0.2rem;
+ height: 2.6rem;
+ border-radius: 0.1rem;
+ background-color: var(--primary_300_color);
+ display: none;
+ &.is_compact_mode.is_active {
+ display: block;
+ }
+}
+
+.loader {
+ @include loader(2rem, 0.2rem, left, 50%);
+}
+
+.toggle_control {
+ @include toggle_control_styles;
+ &.is_compact_mode {
+ display: none;
+ }
+}
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/open_settings/OpenSettings.jsx b/src-ui/windows/main_window/sidebar_section/open_settings/OpenSettings.jsx
new file mode 100644
index 00000000..2bcbeb54
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/open_settings/OpenSettings.jsx
@@ -0,0 +1,20 @@
+import styles from "./OpenSettings.module.scss";
+import ConfigurationSvg from "@images/configuration.svg?react";
+
+import { useWindow } from "@utils/useWindow";
+
+export const OpenSettings = () => {
+ const { createConfigWindow } = useWindow();
+
+ const openConfigWindow = () => {
+ createConfigWindow();
+ };
+
+ return (
+
+ );
+};
\ No newline at end of file
diff --git a/src-ui/windows/main_window/sidebar_section/open_settings/OpenSettings.module.scss b/src-ui/windows/main_window/sidebar_section/open_settings/OpenSettings.module.scss
new file mode 100644
index 00000000..04871748
--- /dev/null
+++ b/src-ui/windows/main_window/sidebar_section/open_settings/OpenSettings.module.scss
@@ -0,0 +1,28 @@
+.container {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ background-color: var(--dark_850_color);
+}
+
+.open_config_window_button {
+ width: auto;
+ margin: 1rem;
+ padding: 0.8rem 0;
+ display: flex;
+ justify-content: center;
+ border-radius: 0.6rem;
+ cursor: pointer;
+ &:hover {
+ background-color: var(--dark_800_color);
+ }
+ &:active {
+ background-color: var(--dark_875_color);
+ }
+}
+
+.configuration_svg {
+ width: 2rem;
+ color: var(--dark_500_color);
+}
\ No newline at end of file
diff --git a/view.py b/view.py
deleted file mode 100644
index 73332775..00000000
--- a/view.py
+++ /dev/null
@@ -1,2470 +0,0 @@
-from typing import Union
-from os import path as os_path
-from types import SimpleNamespace
-from tkinter import font as tk_font
-import webbrowser
-import i18n
-
-from customtkinter import StringVar, IntVar, DoubleVar, BooleanVar, get_appearance_mode
-from vrct_gui.ui_managers import ColorThemeManager, UiScalingManager, AboutVrctManager
-from vrct_gui import vrct_gui
-from utils import callFunctionIfCallable, intToPctStr, floatToPctStr
-
-from config import config
-
-class View():
- def __init__(self):
- # Localization
- i18n.load_path.append(os_path.join(os_path.dirname(__file__), "locales"))
- i18n.set("fallback", "en") # The fallback language is English.
- i18n.set("skip_locale_root_data", True)
- i18n.set("filename_format", "{locale}.{format}")
- i18n.set("enable_memoization", True)
- i18n.set("locale", config.UI_LANGUAGE)
-
- # Save settings at startup for items that require a restart VRCT for the changes to apply
- self.restart_required_configs_pre_data = SimpleNamespace(
- appearance_theme=config.APPEARANCE_THEME,
- ui_scaling=config.UI_SCALING,
- font_family=config.FONT_FAMILY,
- ui_language=config.UI_LANGUAGE,
- is_reset_button_displayed_for_translation=config.IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION,
- is_reset_button_displayed_for_whisper=config.IS_RESET_BUTTON_DISPLAYED_FOR_WHISPER,
- )
-
- if config.ENABLE_SPEAKER2CHATBOX is False:
- VERSION_TEXT=i18n.t("config_window.version", version=config.VERSION)
- else:
- VERSION_TEXT=i18n.t("config_window.version", version=config.VERSION) + " (Speaker2Chatbox)"
-
- self.TEXT_TRANSLATOR_CTRANSLATE2=i18n.t("main_window.translator") + ": " + i18n.t("main_window.translator_ctranslate2")
-
- self.settings = SimpleNamespace()
- theme = get_appearance_mode() if config.APPEARANCE_THEME == "System" else config.APPEARANCE_THEME
- all_ctm = ColorThemeManager(theme)
- all_uism = UiScalingManager(config.UI_SCALING)
-
- common_args = {
- "image_file": all_ctm.image_file,
- "FONT_FAMILY": config.FONT_FAMILY,
- }
-
- self.settings.main = SimpleNamespace(
- ctm=all_ctm.main,
- uism=all_uism.main,
- geometry=SimpleNamespace(
- width=config.MAIN_WINDOW_GEOMETRY["width"],
- height=config.MAIN_WINDOW_GEOMETRY["height"],
- x_pos=config.MAIN_WINDOW_GEOMETRY["x_pos"],
- y_pos=config.MAIN_WINDOW_GEOMETRY["y_pos"],
- ),
- to_restore_main_window_geometry=config.ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY,
- **common_args
- )
-
- about_vrct = AboutVrctManager(config.UI_SCALING, config.UI_LANGUAGE, all_ctm.config_window)
- self.settings.config_window = SimpleNamespace(
- ctm=all_ctm.config_window,
- uism=all_uism.config_window,
- about_vrct=about_vrct,
- **common_args
- )
-
- self.settings.selectable_language_window = SimpleNamespace(
- ctm=all_ctm.selectable_language_window,
- uism=all_uism.selectable_language_window,
- **common_args
- )
-
- self.settings.main_window_cover = SimpleNamespace(
- ctm=all_ctm.main_window_cover,
- uism=all_uism.main_window_cover,
- **common_args
- )
-
- self.settings.notification_message_window = SimpleNamespace(
- uism=all_uism.notification_message_window,
- **common_args
- )
-
- self.settings.confirmation_modal = SimpleNamespace(
- ctm=all_ctm.confirmation_modal,
- uism=all_uism.confirmation_modal,
- **common_args
- )
-
- self.settings.dropdown_menu_window = SimpleNamespace(
- # ctm=all_ctm.dropdown_menu_window,
- uism=all_uism.dropdown_menu_window,
- **common_args
- )
-
- self.view_variable = SimpleNamespace(
- # Common
- CALLBACK_ENABLE_EASTER_EGG=None,
-
- CALLBACK_RESTART_SOFTWARE=None,
- CALLBACK_UPDATE_SOFTWARE=None,
- CALLBACK_OPEN_FILEPATH_LOGS=None,
- CALLBACK_OPEN_FILEPATH_CONFIG_FILE=None,
- CALLBACK_OPEN_WEBPAGE_DEEPL_AUTH_KEY=self.openWebPage_DeepL_Auth_Key,
-
- CALLBACK_DELETE_MAIN_WINDOW=self.quitVRCT,
- CALLBACK_QUIT_VRCT=None,
-
- CALLBACK_WHEN_DETECT_WINDOW_OVERED_SIZE=self._showDisplayOverUiSizeConfirmationModal,
-
- IS_ENTRY_MESSAGE_BOX_DISABLED=False,
-
- # Confirmation Modal
- CALLBACK_HIDE_CONFIRMATION_MODAL=None,
- CALLBACK_ACCEPTED_CONFIRMATION_MODAL=None,
- CALLBACK_DENIED_CONFIRMATION_MODAL=None,
- VAR_MESSAGE_CONFIRMATION_MODAL=StringVar(value=""),
- VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON=StringVar(value=""),
- VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON=StringVar(value=""),
-
- # Window Control (Config Window)
- CALLBACK_CLICKED_OPEN_CONFIG_WINDOW_BUTTON=self._openConfigWindow,
- CALLBACK_CLICKED_CLOSE_CONFIG_WINDOW_BUTTON=self._closeConfigWindow,
- CALLBACK_OPEN_CONFIG_WINDOW=None,
- CALLBACK_CLOSE_CONFIG_WINDOW=None,
-
- # Open Help and Information Page
- CALLBACK_CLICKED_HELP_AND_INFO=self.openWebPage_VrctDocuments,
-
- # Open Update Confirmation Modal
- CALLBACK_CLICKED_UPDATE_AVAILABLE=self._showUpdateSoftwareConfirmationModal,
-
-
-
-
- # Overlay Settings
- VAR_OVERLAY_SETTINGS=StringVar(value="Overlay (VR)"),
- CALLBACK_SET_OPEN_OVERLAY_SETTINGS_WINDOW=self._openVrSettingsWindow,
- VAR_TO_DEFAULT_OVERLAY_SETTINGS=StringVar(value=i18n.t("overlay_settings.restore_default_settings")),
- CALLBACK_SET_TO_DEFAULT_OVERLAY_SETTINGS=self._toDefaultOverlaySettings,
- VAR_OVERLAY_SMALL_LOG_STATE=StringVar(value=""),
-
-
- CALLBACK_SET_OPEN_VRC_MIC_MUTE_SYNC_SETTINGS_WINDOW=self._openVrcMicMuteSyncSettingsWindow,
- VAR_VRC_MIC_MUTE_SYNC_SETTINGS=StringVar(value=i18n.t("config_window.vrc_mic_mute_sync.label")),
- VAR_VRC_MIC_MUTE_SYNC_STATE=StringVar(value=""),
-
-
- VAR_LABEL_OVERLAY_OPACITY=StringVar(value=i18n.t("overlay_settings.opacity")),
- SLIDER_RANGE_OVERLAY_OPACITY=(0.1, 1.0),
- NUMBER_OF_STEPS_OVERLAY_OPACITY=18,
- VAR_OVERLAY_OPACITY=DoubleVar(value=config.OVERLAY_SETTINGS["opacity"]),
- VAR_CURRENT_VALUE_OVERLAY_OPACITY=StringVar(value=floatToPctStr(config.OVERLAY_SETTINGS["opacity"])),
-
- VAR_LABEL_OVERLAY_UI_SCALING=StringVar(value=i18n.t("overlay_settings.ui_scaling")),
- SLIDER_RANGE_OVERLAY_UI_SCALING=(0.4, 2.0),
- NUMBER_OF_STEPS_OVERLAY_UI_SCALING=16,
- VAR_OVERLAY_UI_SCALING=DoubleVar(value=config.OVERLAY_SETTINGS["ui_scaling"]),
- VAR_CURRENT_VALUE_OVERLAY_UI_SCALING=StringVar(value=floatToPctStr(config.OVERLAY_SETTINGS["ui_scaling"])),
-
-
-
- CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS=None,
-
- VAR_LABEL_OVERLAY_SMALL_LOG_X_POS=StringVar(value=i18n.t("overlay_settings.x_position")),
- # SLIDER_RANGE_OVERLAY_SMALL_LOG_X_POS=(-5, 5),
- # NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_X_POS=10000,
- SLIDER_RANGE_OVERLAY_SMALL_LOG_X_POS=(-0.5, 0.5),
- NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_X_POS=100,
- VAR_OVERLAY_SMALL_LOG_X_POS=DoubleVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["x_pos"]),
- VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_POS=StringVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["x_pos"]),
-
- VAR_LABEL_OVERLAY_SMALL_LOG_Y_POS=StringVar(value=i18n.t("overlay_settings.y_position")),
- # SLIDER_RANGE_OVERLAY_SMALL_LOG_Y_POS=(-5, 5),
- # NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Y_POS=10000,
- SLIDER_RANGE_OVERLAY_SMALL_LOG_Y_POS=(-0.8, 0.8),
- NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Y_POS=160,
- VAR_OVERLAY_SMALL_LOG_Y_POS=DoubleVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["y_pos"]),
- VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_POS=StringVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["y_pos"]),
-
- VAR_LABEL_OVERLAY_SMALL_LOG_Z_POS=StringVar(value=i18n.t("overlay_settings.z_position")),
- # SLIDER_RANGE_OVERLAY_SMALL_LOG_Z_POS=(-5, 5),
- # NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Z_POS=10000,
- SLIDER_RANGE_OVERLAY_SMALL_LOG_Z_POS=(-0.5, 1.5),
- NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Z_POS=100,
- VAR_OVERLAY_SMALL_LOG_Z_POS=DoubleVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["z_pos"]),
- VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Z_POS=StringVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["z_pos"]),
-
- VAR_LABEL_OVERLAY_SMALL_LOG_X_ROTATION=StringVar(value=i18n.t("overlay_settings.x_rotation")),
- SLIDER_RANGE_OVERLAY_SMALL_LOG_X_ROTATION=(-180, 180),
- NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_X_ROTATION=360,
- VAR_OVERLAY_SMALL_LOG_X_ROTATION=DoubleVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["x_rotation"]),
- VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_ROTATION=StringVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["x_rotation"]),
-
- VAR_LABEL_OVERLAY_SMALL_LOG_Y_ROTATION=StringVar(value=i18n.t("overlay_settings.y_rotation")),
- SLIDER_RANGE_OVERLAY_SMALL_LOG_Y_ROTATION=(-180, 180),
- NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Y_ROTATION=360,
- VAR_OVERLAY_SMALL_LOG_Y_ROTATION=DoubleVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["y_rotation"]),
- VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_ROTATION=StringVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["y_rotation"]),
-
- VAR_LABEL_OVERLAY_SMALL_LOG_Z_ROTATION=StringVar(value=i18n.t("overlay_settings.z_rotation")),
- SLIDER_RANGE_OVERLAY_SMALL_LOG_Z_ROTATION=(-180, 180),
- NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Z_ROTATION=360,
- VAR_OVERLAY_SMALL_LOG_Z_ROTATION=DoubleVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["z_rotation"]),
- VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Z_ROTATION=StringVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["z_rotation"]),
-
-
- VAR_LABEL_OVERLAY_SMALL_LOG_DISPLAY_DURATION=StringVar(value=i18n.t("overlay_settings.display_duration")),
- SLIDER_RANGE_OVERLAY_SMALL_LOG_DISPLAY_DURATION=(1, 60),
- NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_DISPLAY_DURATION=59,
- VAR_OVERLAY_SMALL_LOG_DISPLAY_DURATION=IntVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["display_duration"]),
- VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DISPLAY_DURATION=StringVar(value=f"{config.OVERLAY_SMALL_LOG_SETTINGS['display_duration']} second(s)"),
-
- VAR_LABEL_OVERLAY_SMALL_LOG_FADEOUT_DURATION=StringVar(value=i18n.t("overlay_settings.fadeout_duration")),
- SLIDER_RANGE_OVERLAY_SMALL_LOG_FADEOUT_DURATION=(0, 5),
- NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_FADEOUT_DURATION=5,
- VAR_OVERLAY_SMALL_LOG_FADEOUT_DURATION=IntVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["fadeout_duration"]),
- VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_FADEOUT_DURATION=StringVar(value=f"{config.OVERLAY_SMALL_LOG_SETTINGS['fadeout_duration']} second(s)"),
-
-
-
-
-
-
-
-
- # Main Window
- # Sidebar
- # Sidebar Compact Mode
- IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE=config.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE,
- CALLBACK_TOGGLE_MAIN_WINDOW_SIDEBAR_COMPACT_MODE=None,
-
- # Sidebar Features
- VAR_LABEL_TRANSLATION=StringVar(value=i18n.t("main_window.translation")),
- CALLBACK_TOGGLE_TRANSLATION=None,
-
- VAR_LABEL_TRANSCRIPTION_SEND=StringVar(value=i18n.t("main_window.transcription_send")),
- CALLBACK_TOGGLE_TRANSCRIPTION_SEND=None,
-
- VAR_LABEL_TRANSCRIPTION_RECEIVE=StringVar(value=i18n.t("main_window.transcription_receive")),
- CALLBACK_TOGGLE_TRANSCRIPTION_RECEIVE=None,
-
- VAR_LABEL_FOREGROUND=StringVar(value=i18n.t("main_window.foreground")),
- CALLBACK_TOGGLE_FOREGROUND=None,
-
- # Sidebar Language Settings
- VAR_LABEL_LANGUAGE_SETTINGS=StringVar(value=i18n.t("main_window.language_settings")),
- LIST_SELECTABLE_LANGUAGES=[],
- CALLBACK_SELECTED_LANGUAGE_PRESET_TAB=None,
-
- VAR_LABEL_YOUR_LANGUAGE=StringVar(value=i18n.t("main_window.your_language")),
- VAR_YOUR_LANGUAGE=StringVar(value=f"{config.SOURCE_LANGUAGE}\n({config.SOURCE_COUNTRY})"),
- CALLBACK_OPEN_SELECTABLE_YOUR_LANGUAGE_WINDOW=None,
- IS_OPENED_SELECTABLE_YOUR_LANGUAGE_WINDOW=False,
- CALLBACK_SELECTED_YOUR_LANGUAGE=None,
-
- VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON=StringVar(value=""),
- CALLBACK_SWAP_LANGUAGES=None,
- CALLBACK_ENTERED_SWAP_LANGUAGES_BUTTON=self._enteredSwapLanguagesButton,
- CALLBACK_LEAVED_SWAP_LANGUAGES_BUTTON=self._leavedSwapLanguagesButton,
-
- VAR_LABEL_TARGET_LANGUAGE=StringVar(value=i18n.t("main_window.target_language")),
- VAR_TARGET_LANGUAGE=StringVar(value=f"{config.TARGET_LANGUAGE}\n({config.TARGET_COUNTRY})"),
- CALLBACK_OPEN_SELECTABLE_TARGET_LANGUAGE_WINDOW=None,
- IS_OPENED_SELECTABLE_TARGET_LANGUAGE_WINDOW=False,
- CALLBACK_SELECTED_TARGET_LANGUAGE=None,
-
- VAR_SELECTED_TRANSLATION_ENGINE=StringVar(value="Translator: INIT"),
- CALLBACK_SELECTED_TRANSLATION_ENGINE=None,
-
- VAR_LABEL_TEXTBOX_ALL=StringVar(value=i18n.t("main_window.textbox_tab_all")),
- VAR_LABEL_TEXTBOX_SENT=StringVar(value=i18n.t("main_window.textbox_tab_sent")),
- VAR_LABEL_TEXTBOX_RECEIVED=StringVar(value=i18n.t("main_window.textbox_tab_received")),
- VAR_LABEL_TEXTBOX_SYSTEM=StringVar(value=i18n.t("main_window.textbox_tab_system")),
-
- VAR_UPDATE_AVAILABLE=StringVar(value=i18n.t("main_window.update_available")),
-
-
- CALLBACK_MESSAGE_BOX_BIND_KEYSYM__UP=None,
- CALLBACK_MESSAGE_BOX_BIND_KEYSYM__DOWN=None,
- # Main Window Cover
- VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE=StringVar(value=""),
-
- # Selectable Language Window
- VAR_TITLE_LABEL_SELECTABLE_LANGUAGE=StringVar(value=""),
- VAR_GO_BACK_LABEL_SELECTABLE_LANGUAGE=StringVar(value=i18n.t("selectable_language_window.go_back_button")),
-
-
-
- # Config Window
- ACTIVE_SETTING_BOX_TAB_ATTR_NAME="side_menu_tab_appearance",
- CALLBACK_SELECTED_SETTING_BOX_TAB=None,
- VAR_ERROR_MESSAGE=StringVar(value=""),
- VAR_VERSION=StringVar(value=VERSION_TEXT),
- VAR_CONFIG_WINDOW_TITLE=StringVar(value=i18n.t("config_window.config_title")),
- VAR_CONFIG_WINDOW_COMPACT_MODE_LABEL=StringVar(value=i18n.t("config_window.compact_mode")),
- VAR_CONFIG_WINDOW_RESTART_BUTTON_LABEL=StringVar(value=i18n.t("config_window.restart_message")),
-
- CALLBACK_SLIDER_TOOLTIP_PERCENTAGE_FORMATTER=intToPctStr,
-
-
- # Side Menu Labels
- VAR_SIDE_MENU_LABEL_APPEARANCE=StringVar(value=i18n.t("config_window.side_menu_labels.appearance")),
- VAR_SIDE_MENU_LABEL_TRANSLATION=StringVar(value=i18n.t("config_window.side_menu_labels.translation")),
- VAR_SIDE_MENU_LABEL_TRANSCRIPTION=StringVar(value=i18n.t("config_window.side_menu_labels.transcription")),
- VAR_SECOND_TITLE_TRANSCRIPTION_MIC=StringVar(value=i18n.t("config_window.side_menu_labels.transcription_mic")),
- VAR_SECOND_TITLE_TRANSCRIPTION_SPEAKER=StringVar(value=i18n.t("config_window.side_menu_labels.transcription_speaker")),
- VAR_SECOND_TITLE_TRANSCRIPTION_INTERNAL_MODEL=StringVar(value=i18n.t("config_window.side_menu_labels.transcription_internal_model")),
- VAR_SIDE_MENU_LABEL_VR=StringVar(value=i18n.t("config_window.side_menu_labels.vr")),
- VAR_SIDE_MENU_LABEL_OTHERS=StringVar(value=i18n.t("config_window.side_menu_labels.others")),
- VAR_SIDE_MENU_LABEL_ADVANCED_SETTINGS=StringVar(value=i18n.t("config_window.side_menu_labels.advanced_settings")),
-
- VAR_SIDE_MENU_LABEL_ABOUT_VRCT=StringVar(value="About VRCT"),
- # VAR_SIDE_MENU_LABEL_ABOUT_VRCT=StringVar(value=i18n.t("config_window.side_menu_labels.advanced_settings")),
-
- VAR_CURRENT_ACTIVE_CONFIG_TITLE=StringVar(value=""),
-
- # Appearance Tab
- VAR_LABEL_TRANSPARENCY=StringVar(value=i18n.t("config_window.transparency.label")),
- VAR_DESC_TRANSPARENCY=StringVar(value=i18n.t("config_window.transparency.desc")),
- SLIDER_RANGE_TRANSPARENCY=config.TRANSPARENCY_RANGE,
- CALLBACK_SET_TRANSPARENCY=None,
- VAR_TRANSPARENCY=IntVar(value=config.TRANSPARENCY),
- CALLBACK_BUTTON_PRESS_TRANSPARENCY=self._closeTheCoverOfMainWindow,
- CALLBACK_BUTTON_RELEASE_TRANSPARENCY=self._openTheCoverOfMainWindow,
-
- VAR_LABEL_APPEARANCE_THEME=StringVar(value=i18n.t("config_window.appearance_theme.label")),
- VAR_DESC_APPEARANCE_THEME=StringVar(value=i18n.t("config_window.appearance_theme.desc")),
- LIST_APPEARANCE_THEME=config.APPEARANCE_THEME_LIST,
- CALLBACK_SET_APPEARANCE_THEME=None,
- VAR_APPEARANCE_THEME=StringVar(value=config.APPEARANCE_THEME),
-
- VAR_LABEL_UI_SCALING=StringVar(value=i18n.t("config_window.ui_size.label")),
- VAR_DESC_UI_SCALING=None,
- LIST_UI_SCALING=config.UI_SCALING_LIST,
- CALLBACK_SET_UI_SCALING=None,
- VAR_UI_SCALING=StringVar(value=config.UI_SCALING),
-
- VAR_LABEL_TEXTBOX_UI_SCALING=StringVar(value=i18n.t("config_window.textbox_ui_size.label")),
- VAR_DESC_TEXTBOX_UI_SCALING=StringVar(value=i18n.t("config_window.textbox_ui_size.desc")),
- SLIDER_RANGE_TEXTBOX_UI_SCALING=config.TEXTBOX_UI_SCALING_RANGE,
- CALLBACK_SET_TEXTBOX_UI_SCALING=None,
- VAR_TEXTBOX_UI_SCALING=IntVar(value=config.TEXTBOX_UI_SCALING),
- CALLBACK_BUTTON_PRESS_TEXTBOX_UI_SCALING=self._closeTheCoverOfMainWindow,
- CALLBACK_BUTTON_RELEASE_TEXTBOX_UI_SCALING=self._openTheCoverOfMainWindow,
-
- VAR_LABEL_MESSAGE_BOX_RATIO=StringVar(value=i18n.t("config_window.message_box_ratio.label")),
- VAR_DESC_MESSAGE_BOX_RATIO=StringVar(value=i18n.t("config_window.message_box_ratio.desc")),
- SLIDER_RANGE_MESSAGE_BOX_RATIO=config.MESSAGE_BOX_RATIO_RANGE,
- CALLBACK_SET_MESSAGE_BOX_RATIO=None,
- VAR_MESSAGE_BOX_RATIO=IntVar(value=config.MESSAGE_BOX_RATIO),
- CALLBACK_BUTTON_PRESS_MESSAGE_BOX_RATIO=self._closeTheCoverOfMainWindow,
- CALLBACK_BUTTON_RELEASE_MESSAGE_BOX_RATIO=self._openTheCoverOfMainWindow,
-
- VAR_LABEL_FONT_FAMILY=StringVar(value=i18n.t("config_window.font_family.label")),
- VAR_DESC_FONT_FAMILY=None,
- LIST_FONT_FAMILY=self.getAvailableFonts(),
- CALLBACK_SET_FONT_FAMILY=None,
- VAR_FONT_FAMILY=StringVar(value=config.FONT_FAMILY),
-
- VAR_LABEL_UI_LANGUAGE=StringVar(value=i18n.t("config_window.ui_language.label")),
- VAR_DESC_UI_LANGUAGE=None,
- LIST_UI_LANGUAGE=list(config.SELECTABLE_UI_LANGUAGES_DICT.values()),
- CALLBACK_SET_UI_LANGUAGE=None,
- VAR_UI_LANGUAGE=StringVar(value=config.SELECTABLE_UI_LANGUAGES_DICT[config.UI_LANGUAGE]),
-
- VAR_LABEL_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY=StringVar(value=i18n.t("config_window.to_restore_main_window_geometry.label")),
- VAR_DESC_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY=StringVar(value=i18n.t("config_window.to_restore_main_window_geometry.desc")),
- CALLBACK_SET_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY=None,
- VAR_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY=BooleanVar(value=config.ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY),
-
- # Translation Tab
- VAR_LABEL_USE_TRANSLATION_FEATURE=StringVar(value=i18n.t("config_window.use_translation_feature.label")),
- VAR_DESC_USE_TRANSLATION_FEATURE=StringVar(value=i18n.t("config_window.use_translation_feature.desc")),
- CALLBACK_SET_USE_TRANSLATION_FEATURE=None,
- VAR_USE_TRANSLATION_FEATURE=BooleanVar(value=config.USE_TRANSLATION_FEATURE),
-
- VAR_LABEL_CTRANSLATE2_WEIGHT_TYPE=StringVar(value=i18n.t("config_window.ctranslate2_weight_type.label")),
- VAR_DESC_CTRANSLATE2_WEIGHT_TYPE=StringVar(value=i18n.t("config_window.ctranslate2_weight_type.desc")),
- DICT_CTRANSLATE2_WEIGHT_TYPE=self.getSelectableCtranslate2WeightTypeDict(),
- CALLBACK_SET_CTRANSLATE2_WEIGHT_TYPE=None,
- VAR_CTRANSLATE2_WEIGHT_TYPE=StringVar(value=self.getSelectableCtranslate2WeightTypeDict()[config.CTRANSLATE2_WEIGHT_TYPE]),
-
- VAR_LABEL_DEEPL_AUTH_KEY=StringVar(value=i18n.t( "config_window.deepl_auth_key.label")),
- VAR_DESC_DEEPL_AUTH_KEY=StringVar(
- value=i18n.t(
- "config_window.deepl_auth_key.desc",
- translator=i18n.t("main_window.translator")
- )
- ),
- CALLBACK_SET_DEEPL_AUTH_KEY=None,
- VAR_DEEPL_AUTH_KEY=StringVar(value=config.AUTH_KEYS["DeepL_API"]),
- VAR_OPEN_DEEPL_WEB_PAGE=StringVar(value=i18n.t( "config_window.deepl_auth_key.open_auth_key_webpage")),
- CALLBACK_FOCUS_OUT_DEEPL_AUTH_KEY=self.callbackBindFocusOut_DeeplAuthKey,
-
-
-
- # Transcription Tab (Mic)
- VAR_TAB_SECOND_LABEL_TRANSCRIPTION_MIC=StringVar(value=i18n.t("config_window.tab_transcription.label")),
- VAR_LABEL_MIC_HOST=StringVar(value=i18n.t("config_window.mic_host.label")),
- VAR_DESC_MIC_HOST=None,
- LIST_MIC_HOST=[],
- CALLBACK_SET_MIC_HOST=None,
- VAR_MIC_HOST=StringVar(value=config.CHOICE_MIC_HOST),
-
- VAR_LABEL_MIC_DEVICE=StringVar(value=i18n.t("config_window.mic_device.label")),
- VAR_DESC_MIC_DEVICE=None,
- LIST_MIC_DEVICE=[],
- CALLBACK_SET_MIC_DEVICE=None,
- VAR_MIC_DEVICE=StringVar(value=config.CHOICE_MIC_DEVICE),
-
-
- VAR_LABEL_MIC_DYNAMIC_ENERGY_THRESHOLD=StringVar(value=""),
- VAR_DESC_MIC_DYNAMIC_ENERGY_THRESHOLD=StringVar(value=""),
- CALLBACK_SET_MIC_DYNAMIC_ENERGY_THRESHOLD=None,
- VAR_MIC_DYNAMIC_ENERGY_THRESHOLD=BooleanVar(value=config.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD),
-
- SLIDER_RANGE_MIC_ENERGY_THRESHOLD=(0, config.MAX_MIC_ENERGY_THRESHOLD),
- CALLBACK_CHECK_MIC_THRESHOLD=None,
- VAR_MIC_ENERGY_THRESHOLD__SLIDER=IntVar(value=config.INPUT_MIC_ENERGY_THRESHOLD),
- VAR_MIC_ENERGY_THRESHOLD__ENTRY=StringVar(value=config.INPUT_MIC_ENERGY_THRESHOLD),
- CALLBACK_FOCUS_OUT_MIC_ENERGY_THRESHOLD=self.callbackBindFocusOut_MicEnergyThreshold,
-
-
- VAR_LABEL_MIC_RECORD_TIMEOUT=StringVar(value=i18n.t("config_window.mic_record_timeout.label")),
- VAR_DESC_MIC_RECORD_TIMEOUT=StringVar(value=i18n.t("config_window.mic_record_timeout.desc")),
- CALLBACK_SET_MIC_RECORD_TIMEOUT=None,
- VAR_MIC_RECORD_TIMEOUT=StringVar(value=config.INPUT_MIC_RECORD_TIMEOUT),
- CALLBACK_FOCUS_OUT_MIC_RECORD_TIMEOUT=self.callbackBindFocusOut_MicRecordTimeout,
-
- VAR_LABEL_MIC_PHRASE_TIMEOUT=StringVar(value=i18n.t("config_window.mic_phrase_timeout.label")),
- VAR_DESC_MIC_PHRASE_TIMEOUT=StringVar(value=i18n.t("config_window.mic_phrase_timeout.desc")),
- CALLBACK_SET_MIC_PHRASE_TIMEOUT=None,
- VAR_MIC_PHRASE_TIMEOUT=StringVar(value=config.INPUT_MIC_PHRASE_TIMEOUT),
- CALLBACK_FOCUS_OUT_MIC_PHRASE_TIMEOUT=self.callbackBindFocusOut_MicPhraseTimeout,
-
- VAR_LABEL_MIC_MAX_PHRASES=StringVar(value=i18n.t("config_window.mic_max_phrase.label")),
- VAR_DESC_MIC_MAX_PHRASES=StringVar(value=i18n.t("config_window.mic_max_phrase.desc")),
- CALLBACK_SET_MIC_MAX_PHRASES=None,
- VAR_MIC_MAX_PHRASES=StringVar(value=config.INPUT_MIC_MAX_PHRASES),
- CALLBACK_FOCUS_OUT_MIC_MAX_PHRASES=self.callbackBindFocusOut_MicMaxPhrases,
-
- CALLBACK_ARROW_SWITCH_MIC_WORD_FILTER_LIST_OPEN=self._openMicWordFilterList,
- CALLBACK_ARROW_SWITCH_MIC_WORD_FILTER_LIST_CLOSE=self._closeMicWordFilterList,
-
- VAR_LABEL_MIC_WORD_FILTER=StringVar(value=i18n.t("config_window.mic_word_filter.label")),
- VAR_DESC_MIC_WORD_FILTER=StringVar(value=i18n.t("config_window.mic_word_filter.desc")),
- VAR_SWITCH_DESC_MIC_WORD_FILTER=StringVar(value=i18n.t("config_window.mic_word_filter.count_desc", count=len(config.INPUT_MIC_WORD_FILTER))),
- VAR_LABEL_MIC_WORD_FILTER_ADD_BUTTON=StringVar(value=i18n.t("config_window.mic_word_filter.add_button_label")),
- CALLBACK_SET_MIC_WORD_FILTER=None,
- MIC_WORD_FILTER_LIST=config.INPUT_MIC_WORD_FILTER,
-
-
- # Transcription Tab (Speaker)
- VAR_LABEL_SPEAKER_DEVICE=StringVar(value=i18n.t("config_window.speaker_device.label")),
- VAR_DESC_SPEAKER_DEVICE=None,
- LIST_SPEAKER_DEVICE=[],
- CALLBACK_SET_SPEAKER_DEVICE=None,
- VAR_SPEAKER_DEVICE=StringVar(value=config.CHOICE_SPEAKER_DEVICE),
-
-
- VAR_LABEL_SPEAKER_DYNAMIC_ENERGY_THRESHOLD=StringVar(value=""),
- VAR_DESC_SPEAKER_DYNAMIC_ENERGY_THRESHOLD=StringVar(value=""),
- CALLBACK_SET_SPEAKER_DYNAMIC_ENERGY_THRESHOLD=None,
- VAR_SPEAKER_DYNAMIC_ENERGY_THRESHOLD=BooleanVar(value=config.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD),
-
- SLIDER_RANGE_SPEAKER_ENERGY_THRESHOLD=(0, config.MAX_SPEAKER_ENERGY_THRESHOLD),
- CALLBACK_CHECK_SPEAKER_THRESHOLD=None,
- VAR_SPEAKER_ENERGY_THRESHOLD__SLIDER=IntVar(value=config.INPUT_SPEAKER_ENERGY_THRESHOLD),
- VAR_SPEAKER_ENERGY_THRESHOLD__ENTRY=StringVar(value=config.INPUT_SPEAKER_ENERGY_THRESHOLD),
- CALLBACK_FOCUS_OUT_SPEAKER_ENERGY_THRESHOLD=self.callbackBindFocusOut_SpeakerEnergyThreshold,
-
-
- VAR_LABEL_SPEAKER_RECORD_TIMEOUT=StringVar(value=i18n.t("config_window.speaker_record_timeout.label")),
- VAR_DESC_SPEAKER_RECORD_TIMEOUT=StringVar(value=i18n.t("config_window.speaker_record_timeout.desc")),
- CALLBACK_SET_SPEAKER_RECORD_TIMEOUT=None,
- VAR_SPEAKER_RECORD_TIMEOUT=StringVar(value=config.INPUT_SPEAKER_RECORD_TIMEOUT),
- CALLBACK_FOCUS_OUT_SPEAKER_RECORD_TIMEOUT=self.callbackBindFocusOut_SpeakerRecordTimeout,
-
- VAR_LABEL_SPEAKER_PHRASE_TIMEOUT=StringVar(value=i18n.t("config_window.speaker_phrase_timeout.label")),
- VAR_DESC_SPEAKER_PHRASE_TIMEOUT=StringVar(value=i18n.t("config_window.speaker_phrase_timeout.desc")),
- CALLBACK_SET_SPEAKER_PHRASE_TIMEOUT=None,
- VAR_SPEAKER_PHRASE_TIMEOUT=StringVar(value=config.INPUT_SPEAKER_PHRASE_TIMEOUT),
- CALLBACK_FOCUS_OUT_SPEAKER_PHRASE_TIMEOUT=self.callbackBindFocusOut_SpeakerPhraseTimeout,
-
- VAR_LABEL_SPEAKER_MAX_PHRASES=StringVar(value=i18n.t("config_window.speaker_max_phrase.label")),
- VAR_DESC_SPEAKER_MAX_PHRASES=StringVar(value=i18n.t("config_window.speaker_max_phrase.desc")),
- CALLBACK_SET_SPEAKER_MAX_PHRASES=None,
- VAR_SPEAKER_MAX_PHRASES=StringVar(value=config.INPUT_SPEAKER_MAX_PHRASES),
- CALLBACK_FOCUS_OUT_SPEAKER_MAX_PHRASES=self.callbackBindFocusOut_SpeakerMaxPhrases,
-
-
- # Transcription Tab (Whisper Internal AI Model)
- VAR_LABEL_USE_WHISPER_FEATURE=StringVar(value=i18n.t("config_window.use_whisper_feature.label")),
- VAR_DESC_USE_WHISPER_FEATURE=StringVar(value=i18n.t("config_window.use_whisper_feature.desc")),
- CALLBACK_SET_USE_WHISPER_FEATURE=None,
- VAR_USE_WHISPER_FEATURE=BooleanVar(value=config.USE_WHISPER_FEATURE),
-
- VAR_LABEL_WHISPER_WEIGHT_TYPE=StringVar(value=i18n.t("config_window.whisper_weight_type.label")),
- VAR_DESC_WHISPER_WEIGHT_TYPE=StringVar(value=i18n.t("config_window.whisper_weight_type.desc")),
- DICT_WHISPER_WEIGHT_TYPE=self.getSelectableWhisperWeightTypeDict(),
- CALLBACK_SET_WHISPER_WEIGHT_TYPE=None,
- VAR_WHISPER_WEIGHT_TYPE=StringVar(value=self.getSelectableWhisperWeightTypeDict()[config.WHISPER_WEIGHT_TYPE]),
-
-
- # VR Tab
- VAR_LABEL_ENABLE_OVERLAY_SMALL_LOG=StringVar(value=i18n.t("config_window.enable_overlay_small_log.label")),
- VAR_DESC_ENABLE_OVERLAY_SMALL_LOG=None,
- # VAR_DESC_ENABLE_OVERLAY_SMALL_LOG=StringVar(value=i18n.t("config_window.enable_overlay_small_log.desc")),
- CALLBACK_SET_ENABLE_OVERLAY_SMALL_LOG=None,
- VAR_ENABLE_OVERLAY_SMALL_LOG=BooleanVar(value=config.ENABLE_OVERLAY_SMALL_LOG),
- VAR_OPEN_OVERLAY_SETTINGS_BUTTON=StringVar(value=i18n.t("config_window.enable_overlay_small_log.open_overlay_settings")),
-
-
- # Others Tab
- VAR_LABEL_ENABLE_AUTO_CLEAR_MESSAGE_BOX=StringVar(value=i18n.t("config_window.auto_clear_the_message_box.label")),
- VAR_DESC_ENABLE_AUTO_CLEAR_MESSAGE_BOX=None,
- CALLBACK_SET_ENABLE_AUTO_CLEAR_MESSAGE_BOX=None,
- VAR_ENABLE_AUTO_CLEAR_MESSAGE_BOX=BooleanVar(value=config.ENABLE_AUTO_CLEAR_MESSAGE_BOX),
-
- VAR_LABEL_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES=StringVar(value=i18n.t("config_window.send_only_translated_messages.label")),
- VAR_DESC_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES=None,
- CALLBACK_SET_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES=None,
- VAR_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES=BooleanVar(value=config.ENABLE_SEND_ONLY_TRANSLATED_MESSAGES),
-
- VAR_LABEL_SEND_MESSAGE_BUTTON_TYPE=StringVar(value=i18n.t("config_window.send_message_button_type.label")),
- VAR_DESC_SEND_MESSAGE_BUTTON_TYPE=None,
- CALLBACK_SET_SEND_MESSAGE_BUTTON_TYPE=None,
- VAR_SEND_MESSAGE_BUTTON_TYPE=StringVar(value=config.SEND_MESSAGE_BUTTON_TYPE),
- KEYS_VALUES_SEND_MESSAGE_BUTTON_TYPE={
- "hide": StringVar(value=i18n.t("config_window.send_message_button_type.hide")),
- "show": StringVar(value=i18n.t("config_window.send_message_button_type.show")),
- "show_and_disable_enter_key": StringVar(value=i18n.t("config_window.send_message_button_type.show_and_disable_enter_key")),
- },
-
- VAR_LABEL_ENABLE_NOTICE_XSOVERLAY=StringVar(value=i18n.t("config_window.notice_xsoverlay.label")),
- VAR_DESC_ENABLE_NOTICE_XSOVERLAY=StringVar(value=i18n.t("config_window.notice_xsoverlay.desc")),
- CALLBACK_SET_ENABLE_NOTICE_XSOVERLAY=None,
- VAR_ENABLE_NOTICE_XSOVERLAY=BooleanVar(value=config.ENABLE_NOTICE_XSOVERLAY),
-
- VAR_LABEL_ENABLE_AUTO_EXPORT_MESSAGE_LOGS=StringVar(value=i18n.t("config_window.auto_export_message_logs.label")),
- VAR_DESC_ENABLE_AUTO_EXPORT_MESSAGE_LOGS=StringVar(value=i18n.t("config_window.auto_export_message_logs.desc")),
- CALLBACK_SET_ENABLE_AUTO_EXPORT_MESSAGE_LOGS=None,
- VAR_ENABLE_AUTO_EXPORT_MESSAGE_LOGS=BooleanVar(value=config.ENABLE_LOGGER),
-
-
- VAR_LABEL_ENABLE_VRC_MIC_MUTE_SYNC=StringVar(value=i18n.t("config_window.vrc_mic_mute_sync.label")),
- VAR_DESC_ENABLE_VRC_MIC_MUTE_SYNC=StringVar(value=i18n.t("config_window.vrc_mic_mute_sync.desc")),
- CALLBACK_SET_ENABLE_VRC_MIC_MUTE_SYNC=None,
- VAR_ENABLE_VRC_MIC_MUTE_SYNC=BooleanVar(value=config.ENABLE_VRC_MIC_MUTE_SYNC),
-
-
- VAR_LABEL_ENABLE_SEND_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_message_to_vrc.label")),
- VAR_DESC_ENABLE_SEND_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_message_to_vrc.desc")),
- CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC=None,
- VAR_ENABLE_SEND_MESSAGE_TO_VRC=BooleanVar(value=config.ENABLE_SEND_MESSAGE_TO_VRC),
-
-
-
- VAR_SECOND_TITLE_OTHERS_SEND_MESSAGE_FORMATS=StringVar(value=i18n.t("config_window.side_menu_labels.others_send_message_formats")),
-
-
- VAR_LABEL_SEND_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.send_message_format.label")),
- VAR_DESC_SEND_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.send_message_format.desc")),
- CALLBACK_SET_SEND_MESSAGE_FORMAT=None,
- VAR_SEND_MESSAGE_FORMAT=StringVar(value=config.SEND_MESSAGE_FORMAT),
- VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT=StringVar(value=""),
- VAR_ENTRY_0_SEND_MESSAGE_FORMAT=StringVar(value=""),
- VAR_ENTRY_1_SEND_MESSAGE_FORMAT=StringVar(value=""),
- VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT=StringVar(value="[message]"),
- CALLBACK_FOCUS_OUT_SEND_MESSAGE_FORMAT=self.callbackBindFocusOut_SendMessageFormat,
-
-
- VAR_LABEL_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=i18n.t("config_window.send_message_format_with_t.label")),
- VAR_DESC_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=i18n.t("config_window.send_message_format_with_t.desc")),
- CALLBACK_SET_SEND_MESSAGE_FORMAT_WITH_T=None,
- CALLBACK_SWAP_SEND_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT=self._swapSendMessageFormatWithT_RequiredText,
- VAR_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=config.SEND_MESSAGE_FORMAT_WITH_T),
- VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
- VAR_ENTRY_0_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
- VAR_ENTRY_1_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
- VAR_ENTRY_2_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
- VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value="[message]"),
- VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value="[translation]"),
- CALLBACK_FOCUS_OUT_SEND_MESSAGE_FORMAT_WITH_T=self.callbackBindFocusOut_SendMessageFormatWithT,
-
-
-
- VAR_LABEL_RECEIVED_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.received_message_format.label")),
- VAR_DESC_RECEIVED_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.received_message_format.desc")),
- CALLBACK_SET_RECEIVED_MESSAGE_FORMAT=None,
- VAR_RECEIVED_MESSAGE_FORMAT=StringVar(value=config.RECEIVED_MESSAGE_FORMAT),
- VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT=StringVar(value=""),
- VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT=StringVar(value=""),
- VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT=StringVar(value=""),
- VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT=StringVar(value="[message]"),
- CALLBACK_FOCUS_OUT_RECEIVED_MESSAGE_FORMAT=self.callbackBindFocusOut_ReceivedMessageFormat,
-
-
- VAR_SECOND_TITLE_OTHERS_RECEIVED_MESSAGE_FORMATS=StringVar(value=i18n.t("config_window.side_menu_labels.others_received_message_formats")),
-
- VAR_LABEL_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=i18n.t("config_window.received_message_format_with_t.label")),
- VAR_DESC_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=i18n.t("config_window.received_message_format_with_t.desc")),
- CALLBACK_SET_RECEIVED_MESSAGE_FORMAT_WITH_T=None,
- CALLBACK_SWAP_RECEIVED_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT=self._swapReceivedMessageFormatWithT_RequiredText,
- VAR_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=config.RECEIVED_MESSAGE_FORMAT_WITH_T),
- VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
- VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
- VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
- VAR_ENTRY_2_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
- VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value="[message]"),
- VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value="[translation]"),
- CALLBACK_FOCUS_OUT_RECEIVED_MESSAGE_FORMAT_WITH_T=self.callbackBindFocusOut_ReceivedMessageFormatWithT,
-
-
- # -------------------Speaker2Chatbox-----------
- VAR_SECOND_TITLE_OTHERS_SPEAKER2CHATBOX=StringVar(value=i18n.t("config_window.side_menu_labels.others_speaker2chatbox")),
-
- VAR_LABEL_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_received_message_to_vrc.label")),
- VAR_DESC_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_received_message_to_vrc.desc")),
- CALLBACK_SET_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC=None,
- VAR_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC=BooleanVar(value=config.ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC),
- # -------------------Speaker2Chatbox-----------
-
-
-
- # Advanced Settings Tab
- VAR_LABEL_OSC_IP_ADDRESS=StringVar(value=i18n.t("config_window.osc_ip_address.label")),
- VAR_DESC_OSC_IP_ADDRESS=None,
- CALLBACK_SET_OSC_IP_ADDRESS=None,
- VAR_OSC_IP_ADDRESS=StringVar(value=config.OSC_IP_ADDRESS),
-
- VAR_LABEL_OSC_PORT=StringVar(value=i18n.t("config_window.osc_port.label")),
- VAR_DESC_OSC_PORT=None,
- CALLBACK_SET_OSC_PORT=None,
- VAR_OSC_PORT=StringVar(value=config.OSC_PORT),
-
- VAR_LABEL_OPEN_CONFIG_FILEPATH=StringVar(value=i18n.t("config_window.open_config_filepath.label")),
- VAR_DESC_OPEN_CONFIG_FILEPATH=None,
-
-
- # About VRCT Tab
- CALLBACK_OPEN_WEBPAGE_ABOUT_VRCT=self.openWebPage_AboutVrct,
-
- CALLBACK_ABOUT_VRCT_POSTER_NEXT_BUTTON=None,
- CALLBACK_ABOUT_VRCT_POSTER_PREV_BUTTON=None,
- CALLBACK_ABOUT_VRCT_POSTER_IMAGE_CURRENT_PAGE_NUM=0,
-
- CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_WORLD_LIST=None,
- CALLBACK_ABOUT_VRCT_POSTER_SHOWCASE_CURRENT_PAGE_NUM=0,
- )
-
-
-
- def register(
- self,
- common_registers=None,
- window_action_registers=None,
- main_window_registers=None,
- config_window_registers=None
- ):
-
-
- if common_registers is not None:
- self.view_variable.CALLBACK_ENABLE_EASTER_EGG=common_registers.get("callback_enable_easter_egg", None)
-
- self.view_variable.CALLBACK_UPDATE_SOFTWARE=common_registers.get("callback_update_software", None)
- self.view_variable.CALLBACK_RESTART_SOFTWARE=common_registers.get("callback_restart_software", None)
- self.view_variable.CALLBACK_OPEN_FILEPATH_LOGS=common_registers.get("callback_filepath_logs", None)
- self.view_variable.CALLBACK_OPEN_FILEPATH_CONFIG_FILE=common_registers.get("callback_filepath_config_file", None)
- self.view_variable.CALLBACK_QUIT_VRCT=common_registers.get("callback_quit_vrct", None)
-
-
- if window_action_registers is not None:
- self.view_variable.CALLBACK_OPEN_CONFIG_WINDOW=window_action_registers.get("callback_open_config_window", None)
- self.view_variable.CALLBACK_CLOSE_CONFIG_WINDOW=window_action_registers.get("callback_close_config_window", None)
-
-
- if main_window_registers is not None:
- self.view_variable.CALLBACK_ENABLE_MAIN_WINDOW_SIDEBAR_COMPACT_MODE=main_window_registers.get("callback_enable_main_window_sidebar_compact_mode", None)
- self.view_variable.CALLBACK_DISABLE_MAIN_WINDOW_SIDEBAR_COMPACT_MODE=main_window_registers.get("callback_disable_main_window_sidebar_compact_mode", None)
-
-
- self.view_variable.CALLBACK_TOGGLE_TRANSLATION=main_window_registers.get("callback_toggle_translation", None)
- self.view_variable.CALLBACK_TOGGLE_TRANSCRIPTION_SEND=main_window_registers.get("callback_toggle_transcription_send", None)
- self.view_variable.CALLBACK_TOGGLE_TRANSCRIPTION_RECEIVE=main_window_registers.get("callback_toggle_transcription_receive", None)
- self.view_variable.CALLBACK_TOGGLE_FOREGROUND=main_window_registers.get("callback_toggle_foreground", None)
-
- self.view_variable.CALLBACK_SELECTED_YOUR_LANGUAGE=main_window_registers.get("callback_your_language", None)
- self.view_variable.CALLBACK_SELECTED_TARGET_LANGUAGE=main_window_registers.get("callback_target_language", None)
- main_window_registers.get("values", None) and self.updateList_selectableLanguages(main_window_registers["values"])
- self.view_variable.CALLBACK_SWAP_LANGUAGES=main_window_registers.get("callback_swap_languages", None)
-
- self.view_variable.CALLBACK_SELECTED_LANGUAGE_PRESET_TAB=main_window_registers.get("callback_selected_language_preset_tab", None)
-
- self.view_variable.CALLBACK_SELECTED_TRANSLATION_ENGINE=main_window_registers.get("callback_selected_translation_engine", None)
-
- def adjustedMessageBoxReturnFunction(_e):
- if self.view_variable.IS_ENTRY_MESSAGE_BOX_DISABLED is True:
- return
- if config.SEND_MESSAGE_BUTTON_TYPE != "show_and_disable_enter_key":
- main_window_registers.get("message_box_bind_Return")()
- return "break" # For deleting the next line that will be inserted when the Enter key is pressed.
- def pressedSendMessageButtonFunction(_e):
- main_window_registers.get("message_box_bind_Return")()
- vrct_gui.entry_message_box.focus()
-
- entry_message_box=getattr(vrct_gui, "entry_message_box")
- entry_message_box.bind("", lambda _e: None) # This is to prevent message sending on Shift + Enter key press and just add a new line.
- entry_message_box.bind("", adjustedMessageBoxReturnFunction)
- entry_message_box.bind("", main_window_registers.get("message_box_bind_Any_KeyPress"))
- self.view_variable.CALLBACK_CLICKED_SEND_MESSAGE_BUTTON=pressedSendMessageButtonFunction
-
-
- self.view_variable.CALLBACK_MESSAGE_BOX_BIND_KEYSYM__UP=main_window_registers.get("message_box_bind_Up_KeyPress")
- self.view_variable.CALLBACK_MESSAGE_BOX_BIND_KEYSYM__DOWN=main_window_registers.get("message_box_bind_Down_KeyPress")
-
-
- entry_message_box.bind("", main_window_registers.get("message_box_bind_FocusIn"))
- entry_message_box.bind("", main_window_registers.get("message_box_bind_FocusOut"))
-
-
- self.updateGuiVariableByPresetTabNo(config.SELECTED_TAB_NO)
- vrct_gui._setDefaultActiveLanguagePresetTab(tab_no=config.SELECTED_TAB_NO)
-
- self.view_variable.CALLBACK_OPEN_SELECTABLE_YOUR_LANGUAGE_WINDOW=self.openSelectableLanguagesWindow_YourLanguage
- self.view_variable.CALLBACK_OPEN_SELECTABLE_TARGET_LANGUAGE_WINDOW=self.openSelectableLanguagesWindow_TargetLanguage
-
-
- # Config Window
- self.view_variable.CALLBACK_SELECTED_SETTING_BOX_TAB=self._updateActiveSettingBoxTabNo
-
-
- if config_window_registers is not None:
- # Compact Mode Switch
- self.view_variable.CALLBACK_ENABLE_CONFIG_WINDOW_COMPACT_MODE=config_window_registers.get("callback_disable_config_window_compact_mode", None)
- self.view_variable.CALLBACK_DISABLE_CONFIG_WINDOW_COMPACT_MODE=config_window_registers.get("callback_enable_config_window_compact_mode", None)
-
-
- # Appearance Tab
- self.view_variable.CALLBACK_SET_TRANSPARENCY=config_window_registers.get("callback_set_transparency", None)
-
- self.view_variable.CALLBACK_SET_APPEARANCE=config_window_registers.get("callback_set_appearance", None)
- self.view_variable.CALLBACK_SET_UI_SCALING=config_window_registers.get("callback_set_ui_scaling", None)
- self.view_variable.CALLBACK_SET_TEXTBOX_UI_SCALING=config_window_registers.get("callback_set_textbox_ui_scaling", None)
- self.view_variable.CALLBACK_SET_MESSAGE_BOX_RATIO=config_window_registers.get("callback_set_message_box_ratio", None)
- self.view_variable.CALLBACK_SET_FONT_FAMILY=config_window_registers.get("callback_set_font_family", None)
- self.view_variable.CALLBACK_SET_UI_LANGUAGE=config_window_registers.get("callback_set_ui_language", None)
- self.view_variable.CALLBACK_SET_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY=config_window_registers.get("callback_set_enable_restore_main_window_geometry", None)
-
-
- # Translation Tab
- self.view_variable.CALLBACK_SET_USE_TRANSLATION_FEATURE=config_window_registers.get("callback_set_use_translation_feature", None)
- self.view_variable.CALLBACK_SET_CTRANSLATE2_WEIGHT_TYPE=config_window_registers.get("callback_set_ctranslate2_weight_type", None)
- self.view_variable.CALLBACK_SET_DEEPL_AUTH_KEY=config_window_registers.get("callback_set_deepl_auth_key", None)
-
- # Transcription Tab (Mic)
- self.view_variable.CALLBACK_SET_MIC_HOST=config_window_registers.get("callback_set_mic_host", None)
- config_window_registers.get("list_mic_host", None) and self.updateList_MicHost(config_window_registers["list_mic_host"])
-
- self.view_variable.CALLBACK_SET_MIC_DEVICE=config_window_registers.get("callback_set_mic_device", None)
- config_window_registers.get("list_mic_device", None) and self.updateList_MicDevice(config_window_registers["list_mic_device"])
-
- self.view_variable.CALLBACK_SET_MIC_ENERGY_THRESHOLD=config_window_registers.get("callback_set_mic_energy_threshold", None)
- self.view_variable.CALLBACK_SET_MIC_DYNAMIC_ENERGY_THRESHOLD=config_window_registers.get("callback_set_mic_dynamic_energy_threshold", None)
- self.view_variable.CALLBACK_CHECK_MIC_THRESHOLD=config_window_registers.get("callback_check_mic_threshold", None)
- self.view_variable.CALLBACK_SET_MIC_RECORD_TIMEOUT=config_window_registers.get("callback_set_mic_record_timeout", None)
- self.view_variable.CALLBACK_SET_MIC_PHRASE_TIMEOUT=config_window_registers.get("callback_set_mic_phrase_timeout", None)
- self.view_variable.CALLBACK_SET_MIC_MAX_PHRASES=config_window_registers.get("callback_set_mic_max_phrases", None)
- self.view_variable.CALLBACK_SET_MIC_WORD_FILTER=config_window_registers.get("callback_set_mic_word_filter", None)
- self.view_variable.CALLBACK_DELETE_MIC_WORD_FILTER=config_window_registers.get("callback_delete_mic_word_filter", None)
-
- # Transcription Tab (Speaker)
- self.view_variable.CALLBACK_SET_SPEAKER_DEVICE = config_window_registers.get("callback_set_speaker_device", None)
- config_window_registers.get("list_speaker_device", None) and self.updateList_SpeakerDevice(config_window_registers["list_speaker_device"])
-
- self.view_variable.CALLBACK_SET_SPEAKER_ENERGY_THRESHOLD=config_window_registers.get("callback_set_speaker_energy_threshold", None)
- self.view_variable.CALLBACK_SET_SPEAKER_DYNAMIC_ENERGY_THRESHOLD=config_window_registers.get("callback_set_speaker_dynamic_energy_threshold", None)
- self.view_variable.CALLBACK_CHECK_SPEAKER_THRESHOLD=config_window_registers.get("callback_check_speaker_threshold", None)
- self.view_variable.CALLBACK_SET_SPEAKER_RECORD_TIMEOUT=config_window_registers.get("callback_set_speaker_record_timeout", None)
- self.view_variable.CALLBACK_SET_SPEAKER_PHRASE_TIMEOUT=config_window_registers.get("callback_set_speaker_phrase_timeout", None)
- self.view_variable.CALLBACK_SET_SPEAKER_MAX_PHRASES=config_window_registers.get("callback_set_speaker_max_phrases", None)
-
- # Transcription Tab (Internal AI Model)
- self.view_variable.CALLBACK_SET_USE_WHISPER_FEATURE=config_window_registers.get("callback_set_use_whisper_feature", None)
- self.view_variable.CALLBACK_SET_WHISPER_WEIGHT_TYPE=config_window_registers.get("callback_set_whisper_weight_type", None)
-
- # VR Tab
- # VR Tab (Quick Settings)
- self.view_variable.CALLBACK_SET_OVERLAY_SETTINGS=config_window_registers.get("callback_set_overlay_settings", None)
-
- self.view_variable.CALLBACK_SET_ENABLE_OVERLAY_SMALL_LOG=config_window_registers.get("callback_set_enable_overlay_small_log", None)
- # VR Tab (Quick Settings)
- self.view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS=config_window_registers.get("callback_set_overlay_small_log_settings", None)
-
-
- # Others Tab
- self.view_variable.CALLBACK_SET_ENABLE_AUTO_CLEAR_MESSAGE_BOX=config_window_registers.get("callback_set_enable_auto_clear_chatbox", None)
- self.view_variable.CALLBACK_SET_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES=config_window_registers.get("callback_set_send_only_translated_messages", None)
- self.view_variable.CALLBACK_SET_SEND_MESSAGE_BUTTON_TYPE=config_window_registers.get("callback_set_send_message_button_type", None)
- self.view_variable.CALLBACK_SET_ENABLE_NOTICE_XSOVERLAY=config_window_registers.get("callback_set_enable_notice_xsoverlay", None)
- self.view_variable.CALLBACK_SET_ENABLE_AUTO_EXPORT_MESSAGE_LOGS=config_window_registers.get("callback_set_enable_auto_export_message_logs", None)
-
- self.view_variable.CALLBACK_SET_ENABLE_VRC_MIC_MUTE_SYNC=config_window_registers.get("callback_set_enable_vrc_mic_mute_sync", None)
- self.view_variable.CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC=config_window_registers.get("callback_set_enable_send_message_to_vrc", None)
-
- self.view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT=config_window_registers.get("callback_set_send_message_format", None)
- self.view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT_WITH_T=config_window_registers.get("callback_set_send_message_format_with_t", None)
- self.view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT=config_window_registers.get("callback_set_received_message_format", None)
- self.view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT_WITH_T=config_window_registers.get("callback_set_received_message_format_with_t", None)
-
- # Speaker2Chatbox----------------
- self.view_variable.CALLBACK_SET_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC=config_window_registers.get("callback_set_enable_send_received_message_to_vrc", None)
- # Speaker2Chatbox----------------
-
-
-
- # Advanced Settings Tab
- self.view_variable.CALLBACK_SET_OSC_IP_ADDRESS=config_window_registers.get("callback_set_osc_ip_address", None)
- self.view_variable.CALLBACK_SET_OSC_PORT=config_window_registers.get("callback_set_osc_port", None)
-
- # The initial processing after registration.
- if config.IS_CONFIG_WINDOW_COMPACT_MODE is True:
- self.enableConfigWindowCompactMode()
- vrct_gui.config_window.setting_box_compact_mode_switch_box.select()
-
- self.setMainWindowMessageBoxRatio(config.MESSAGE_BOX_RATIO)
-
- if config.USE_TRANSLATION_FEATURE is True:
- self.useTranslationFeatureProcess("Normal")
- self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.translate_each_other_label"))
- else:
- self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.swap_button_label"))
- self.useTranslationFeatureProcess("Disable")
-
-
- if config.ENABLE_VRC_MIC_MUTE_SYNC is True:
- self.setStateVrcMicMuteSync("enabled")
- elif config.ENABLE_VRC_MIC_MUTE_SYNC is False:
- self.setStateVrcMicMuteSync("disabled")
-
- if config.ENABLE_OVERLAY_SMALL_LOG is True:
- self.setStateOverlaySmallLog("enabled")
- elif config.ENABLE_OVERLAY_SMALL_LOG is False:
- self.setStateOverlaySmallLog("disabled")
-
-
- if config.CHOICE_MIC_HOST == "NoHost":
- self.view_variable.VAR_MIC_HOST.set("No Mic Host Detected")
-
- if config.CHOICE_MIC_DEVICE == "NoDevice":
- self.view_variable.VAR_MIC_DEVICE.set("No Mic Device Detected")
-
- if config.CHOICE_MIC_HOST == "NoHost" or config.CHOICE_MIC_DEVICE == "NoDevice":
- vrct_gui._changeConfigWindowWidgetsStatus(
- status="disabled",
- target_names=[
- "sb__optionmenu_mic_host",
- "sb__optionmenu_mic_device",
- ]
- )
- self.replaceMicThresholdCheckButton_Disabled()
-
- if config.CHOICE_SPEAKER_DEVICE == "NoDevice":
- self.view_variable.VAR_SPEAKER_DEVICE.set("No Speaker Device Detected")
- vrct_gui._changeConfigWindowWidgetsStatus(
- status="disabled",
- target_names=[
- "sb__optionmenu_speaker_device",
- ]
- )
- self.replaceSpeakerThresholdCheckButton_Disabled()
-
- if config.USE_WHISPER_FEATURE is True:
- self.openWhisperWeightTypeWidget()
- else:
- self.closeWhisperWeightTypeWidget()
-
- if config.ENABLE_SPEAKER2CHATBOX is False:
- vrct_gui._changeConfigWindowWidgetsStatus(
- status="disabled",
- target_names=[
- "sb__checkbox_enable_send_received_message_to_vrc",
- ]
- )
-
- if config.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD is True:
- self.closeMicEnergyThresholdWidget()
- else:
- self.openMicEnergyThresholdWidget()
-
- if config.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD is True:
- self.closeSpeakerEnergyThresholdWidget()
- else:
- self.openSpeakerEnergyThresholdWidget()
-
-
- self.setSendMessageFormat_EntryWidgets(config.SEND_MESSAGE_FORMAT)
- self.setSendMessageFormatWithT_EntryWidgets(config.SEND_MESSAGE_FORMAT_WITH_T)
- self.setReceivedMessageFormat_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT)
- self.setReceivedMessageFormatWithT_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT_WITH_T)
-
-
- # Set Easter Egg
- self.count = 0
- def clickedCounter(_e):
- if self.count < 2:
- self.count+=1
- print("Easter egg count:", self.count)
- else:
- print("Easter egg count:", self.count, "Easter egg has enabled.")
- callFunctionIfCallable(self.view_variable.CALLBACK_ENABLE_EASTER_EGG)
- print(config.OVERLAY_UI_TYPE)
-
- vrct_gui.sidebar_logo.bind(
- "",
- clickedCounter,
- "+"
- )
-
-
- # Insert sample conversation for testing.
- # self._insertSampleConversationToTextbox()
-
- # vrct_gui.updating_window.showUpdatingWindow()
-
-# Send Message Format
- def setSendMessageFormat_EntryWidgets(self, message_format:str):
- result = self.extractMessageFormat(message_format)
-
- self.view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT.set(result.before)
- self.view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT.set(result.after)
- self.updateSendMessageFormat_ExampleTextWidget()
-
- def updateSendMessageFormat_ExampleTextWidget(self):
- message = i18n.t("config_window.send_message_format.example_text")
- example_message = config.SEND_MESSAGE_FORMAT.replace("[message]", message)
-
- self.view_variable.VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT.set(example_message)
-
-
-# Send Message Format With Translation
- def setSendMessageFormatWithT_EntryWidgets(self, message_format:str):
- result = self.extractMessageFormatWithT(message_format)
-
- if result.is_message_first is True:
- self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.set("[message]")
- self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.set("[translation]")
- else:
- self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.set("[translation]")
- self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.set("[message]")
-
- self.view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT_WITH_T.set(result.before)
- self.view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT_WITH_T.set(result.between)
- self.view_variable.VAR_ENTRY_2_SEND_MESSAGE_FORMAT_WITH_T.set(result.after)
- self.updateSendMessageFormatWithT_ExampleTextWidget()
-
- def _swapSendMessageFormatWithT_RequiredText(self):
- text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.get()
- text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.get()
- self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.set(text_1)
- self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.set(text_0)
- self.updateSendMessageFormatWithT_ExampleTextWidget()
-
- new_message_format = self.getLatestMessageFormatWithT_FromWidget()
- callFunctionIfCallable(self.view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT_WITH_T, new_message_format)
-
-
- def getLatestMessageFormatWithT_FromWidget(self):
- text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.get()
- text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.get()
- entry_0 = self.view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT_WITH_T.get()
- entry_1 = self.view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT_WITH_T.get()
- entry_2 = self.view_variable.VAR_ENTRY_2_SEND_MESSAGE_FORMAT_WITH_T.get()
- return entry_0+text_0+entry_1+text_1+entry_2
-
- def updateSendMessageFormatWithT_ExampleTextWidget(self):
- message = i18n.t("config_window.send_message_format_with_t.example_text", locale=config.UI_LANGUAGE)
- translation_locale = "ja" if config.UI_LANGUAGE == "en" else "en"
- translation = i18n.t("config_window.send_message_format_with_t.example_text", locale=translation_locale)
-
- example_message = config.SEND_MESSAGE_FORMAT_WITH_T.replace("[message]", message)
- example_message = example_message.replace("[translation]", translation)
-
- self.view_variable.VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT_WITH_T.set(example_message)
-
-
-# Received Message Format
- def setReceivedMessageFormat_EntryWidgets(self, message_format:str):
- result = self.extractMessageFormat(message_format)
-
- self.view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT.set(result.before)
- self.view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT.set(result.after)
- self.updateReceivedMessageFormat_ExampleTextWidget()
-
- def updateReceivedMessageFormat_ExampleTextWidget(self):
- message = i18n.t("config_window.received_message_format.example_text")
- example_message = config.RECEIVED_MESSAGE_FORMAT.replace("[message]", message)
-
- self.view_variable.VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT.set(example_message)
-
-
-# Received Message Format With Translation
- def setReceivedMessageFormatWithT_EntryWidgets(self, message_format:str):
- result = self.extractMessageFormatWithT(message_format)
-
- if result.is_message_first is True:
- self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.set("[message]")
- self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.set("[translation]")
- else:
- self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.set("[translation]")
- self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.set("[message]")
-
- self.view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT_WITH_T.set(result.before)
- self.view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT_WITH_T.set(result.between)
- self.view_variable.VAR_ENTRY_2_RECEIVED_MESSAGE_FORMAT_WITH_T.set(result.after)
- self.updateReceivedMessageFormatWithT_ExampleTextWidget()
-
- def _swapReceivedMessageFormatWithT_RequiredText(self):
- text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
- text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
- self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.set(text_1)
- self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.set(text_0)
- self.updateReceivedMessageFormatWithT_ExampleTextWidget()
-
- new_message_format = self.getLatestReceivedMessageFormatWithT_FromWidget()
- callFunctionIfCallable(self.view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT_WITH_T, new_message_format)
-
-
- def getLatestReceivedMessageFormatWithT_FromWidget(self):
- text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
- text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
- entry_0 = self.view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
- entry_1 = self.view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
- entry_2 = self.view_variable.VAR_ENTRY_2_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
- return entry_0+text_0+entry_1+text_1+entry_2
-
- def updateReceivedMessageFormatWithT_ExampleTextWidget(self):
- message = i18n.t("config_window.received_message_format_with_t.example_text", locale=config.UI_LANGUAGE)
- translation_locale = "ja" if config.UI_LANGUAGE == "en" else "en"
- translation = i18n.t("config_window.received_message_format_with_t.example_text", locale=translation_locale)
-
- example_message = config.RECEIVED_MESSAGE_FORMAT_WITH_T.replace("[message]", message)
- example_message = example_message.replace("[translation]", translation)
-
- self.view_variable.VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT_WITH_T.set(example_message)
-
-
-
-
-
-# GUI process
- def createGUI(self):
- vrct_gui._createGUI(settings=self.settings, view_variable=self.view_variable)
-
- @staticmethod
- def showGUI():
- vrct_gui._showGUI()
-
- @staticmethod
- def startMainLoop():
- vrct_gui._showGUI()
- vrct_gui._startMainLoop()
-
- def quitVRCT(self):
- callFunctionIfCallable(self.view_variable.CALLBACK_QUIT_VRCT)
- vrct_gui._quitVRCT()
-
-# Common
- @staticmethod
- def getAvailableFonts():
- available_fonts = list(tk_font.families())
- available_fonts.sort()
- filtered_available_fonts = list(filter(lambda x: x.startswith("@") is False, available_fonts))
- return filtered_available_fonts
-
- @staticmethod
- def openWebPage(url:str):
- webbrowser.open_new_tab(url)
-
- @staticmethod
- def getMainWindowGeometry(return_int:bool=False):
- if return_int is True:
- return {
- "width": vrct_gui.winfo_toplevel().winfo_width(),
- "height": vrct_gui.winfo_toplevel().winfo_height(),
- "x_pos": vrct_gui.winfo_toplevel().winfo_x(),
- "y_pos": vrct_gui.winfo_toplevel().winfo_y(),
- }
-
- return {
- "width": str(vrct_gui.winfo_toplevel().winfo_width()),
- "height": str(vrct_gui.winfo_toplevel().winfo_height()),
- "x_pos": str(vrct_gui.winfo_toplevel().winfo_x()),
- "y_pos": str(vrct_gui.winfo_toplevel().winfo_y()),
- }
-
- def getPreUiScaling(self):
- return self.restart_required_configs_pre_data.ui_scaling
-
- @staticmethod
- def getSelectableCtranslate2WeightTypeDict():
- return {
- config.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT["Small"]: i18n.t("config_window.ctranslate2_weight_type.small", capacity="418MB"),
- config.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT["Large"]: i18n.t("config_window.ctranslate2_weight_type.large", capacity="1.2GB"),
- }
-
- def useTranslationFeatureProcess(self, state:str):
- def changeWidget_UseTranslationFeature():
- vrct_gui.sls__box_translation_optionmenu_wrapper.grid()
- vrct_gui.compact_mode_translation_frame.grid()
- vrct_gui.translation_frame.grid()
- self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.translate_each_other_label"))
-
- def changeWidget_DontUseTranslationFeature():
- vrct_gui.sls__box_translation_optionmenu_wrapper.grid_remove()
- vrct_gui.compact_mode_translation_frame.grid_remove()
- vrct_gui.translation_frame.grid_remove()
- self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.swap_button_label"))
-
-
- if state == "Normal":
- self.setLatestCTranslate2WeightType()
- self.openCtranslate2WeightTypeWidget()
- self.setTranslationSwitchStatus("normal", release_locked_state=True)
- changeWidget_UseTranslationFeature()
-
- elif state == "Disable":
- view.closeCtranslate2WeightTypeWidget()
- view.setTranslationSwitchStatus("disabled", to_lock_state=True)
- changeWidget_DontUseTranslationFeature()
-
- elif state == "Restart":
- view.setLatestCTranslate2WeightType()
- view.setTranslationSwitchStatus("disabled", to_lock_state=True)
- changeWidget_UseTranslationFeature()
-
- vrct_gui.update()
- vrct_gui.config_window.lift()
-
- @staticmethod
- def getSelectableWhisperWeightTypeDict():
- def callI18n(model_name, capacity, is_recommended=False):
- if is_recommended is True:
- return i18n.t("config_window.whisper_weight_type.recommended_model_template", model_name=model_name, capacity=capacity)
- else:
- return i18n.t("config_window.whisper_weight_type.model_template", model_name=model_name, capacity=capacity)
-
- DICT_DATA = config.SELECTABLE_WHISPER_WEIGHT_TYPE_DICT
- return {
- DICT_DATA["tiny"]: callI18n("tiny", "74.5MB"),
- DICT_DATA["base"]: callI18n("base", "141MB", True),
- DICT_DATA["small"]: callI18n("small", "463MB"),
- DICT_DATA["medium"]: callI18n("medium", "1.42GB"),
- DICT_DATA["large-v1"]: callI18n("large-v1", "2.87GB"),
- DICT_DATA["large-v2"]: callI18n("large-v2", "2.87GB"),
- DICT_DATA["large-v3"]: callI18n("large-v3", "2.87GB"),
- }
-
-
- def _toDefaultOverlaySettings(self):
- INIT_OVERLAY_SETTINGS = {
- "opacity": 1.0,
- "ui_scaling": 1.0,
- }
- INIT_OVERLAY_SMALL_LOG_SETTINGS = {
- "x_pos": 0.0,
- "y_pos": 0.0,
- "z_pos": 0.0,
- "x_rotation": 0.0,
- "y_rotation": 0.0,
- "z_rotation": 0.0,
- "display_duration": 5,
- "fadeout_duration": 2,
- }
- for key in INIT_OVERLAY_SETTINGS.keys():
- callFunctionIfCallable(self.view_variable.CALLBACK_SET_OVERLAY_SETTINGS, INIT_OVERLAY_SETTINGS[key], key)
-
- for key in INIT_OVERLAY_SMALL_LOG_SETTINGS.keys():
- callFunctionIfCallable(self.view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, INIT_OVERLAY_SMALL_LOG_SETTINGS[key], key)
-
- self.setLatestConfigVariable("OverlayOpacity")
- self.setLatestConfigVariable("OverlayUiScaling")
-
- self.setLatestConfigVariable("OverlaySmallLogXPos")
- self.setLatestConfigVariable("OverlaySmallLogYPos")
- self.setLatestConfigVariable("OverlaySmallLogZPos")
- self.setLatestConfigVariable("OverlaySmallLogXRotation")
- self.setLatestConfigVariable("OverlaySmallLogYRotation")
- self.setLatestConfigVariable("OverlaySmallLogZRotation")
- self.setLatestConfigVariable("OverlaySmallLogDisplayDuration")
- self.setLatestConfigVariable("OverlaySmallLogFadeoutDuration")
-
-# Open Webpage Functions
- def openWebPage_Booth(self):
- self.openWebPage(config.BOOTH_URL)
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.opened_web_page_booth"))
-
- def openWebPage_VrctDocuments(self):
- self.openWebPage(config.DOCUMENTS_URL)
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.opened_web_page_vrct_documents"))
-
- def openWebPage_DeepL_Auth_Key(self):
- self.openWebPage(config.DEEPL_AUTH_KEY_PAGE_URL)
-
- def openWebPage_AboutVrct(self, target_type:str, arg=None):
- url = ""
- match (target_type):
- case ("X_MISYA"):
- url = "https://twitter.com/misya_ai"
- case ("GITHUB_MISYA"):
- url = "https://github.com/misyaguziya"
-
- case ("X_SHIINA"):
- url = "https://twitter.com/Shiina_12siy"
-
- case ("X_DONE_SAN"):
- url = "https://twitter.com/done_vrc"
-
- case ("X_IYA"):
- url = "https://twitter.com/IYAA_HHHH"
-
- case ("X_RERA"):
- url = "https://twitter.com/rerassi"
- case ("GITHUB_RERA"):
- url = "https://github.com/soumt-r"
-
- case ("X_POPOSUKE"):
- url = "https://twitter.com/sig_popo"
-
- case ("X_KUMAGUMA"):
- url = "https://twitter.com/K_kumaguma_A"
-
-
- case ("BOOTH"):
- url = "https://misyaguziya.booth.pm/items/5155325"
- case ("VRCT_DOCUMENTS"):
- url = config.DOCUMENTS_URL
- case ("VRCT_GITHUB"):
- url = "https://github.com/misyaguziya/VRCT"
- case ("CONTACT_US"):
- url = "https://docs.google.com/forms/d/e/1FAIpQLSei-xoydOY60ivXqhOjaTzNN8PiBQIDcNhzfy6cw2sjYkcg_g/viewform"
-
- case ("SUPPORTER_REGISTRATION"):
- url = "https://docs.google.com/forms/d/e/1FAIpQLSepLzdEOTJQFVHdOOxAA0dix3zCmnNBlmH4XWon5FldXkIiqw/viewform"
-
- case ("POSTER_CONTACT_US"):
- url = "https://docs.google.com/forms/d/e/1FAIpQLScwt19eX4Lkj_4w9J5H_3a-bkzXs6rkOc0B-0ZTVVfHKyiU7g/viewform"
-
-
- case ("X_SHIINA_POSTER_SHOWCASE_POST"):
- if arg is None:
- print("arg that received is None. it mus be something number")
- return
- url = "https://twitter.com/Shiina_12siy/status/" + arg
-
-
- case "TEMP":
- print("here is still under construction.")
- return
- case (_):
- raise ValueError(f"No matching case for target_type: {target_type}")
-
- self.openWebPage(url)
-
-# Widget Control
- # Common
-
- # Note: The difference between _clearEntryBox and _clearTextBox
- # idk why, but in CTkEntry and CTkTextbox, the first argument for the delete function is different. Otherwise, it throws an error.
- @staticmethod
- def _clearEntryBox(entry_widget):
- entry_widget.delete(0, "end")
-
- @staticmethod
- def _clearTextBox(entry_widget):
- entry_widget.delete("1.0", "end")
-
- def clearNotificationMessage(self):
- vrct_gui._clearNotificationMessage()
-
-
- @staticmethod
- def showUpdateAvailableButton():
- vrct_gui.update_available_container.grid()
-
- @staticmethod
- def setMainWindowAllWidgetsStatusToNormal():
- vrct_gui._changeMainWindowWidgetsStatus("normal", "All")
-
- @staticmethod
- def setMainWindowAllWidgetsStatusToDisabled():
- vrct_gui._changeMainWindowWidgetsStatus("disabled", "All")
-
- @staticmethod
- def setTranslationSwitchStatus(status:str, to_lock_state:bool=False, release_locked_state:bool=False):
- vrct_gui._changeMainWindowWidgetsStatus(status, ["translation_switch"], to_lock_state, release_locked_state)
-
- def enableMainWindowSidebarCompactMode(self):
- self.view_variable.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE = True
- vrct_gui._enableMainWindowSidebarCompactMode()
-
- def disableMainWindowSidebarCompactMode(self):
- self.view_variable.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE = False
- vrct_gui._disableMainWindowSidebarCompactMode()
-
- def changeTranscriptionDisplayStatus(self, status):
- match (status):
- case "MIC_ON":
- vrct_gui.sls__box_your_language_mic_status__enabled.place(relx=0.1, rely=0.2, anchor="center")
- case "MIC_OFF":
- vrct_gui.sls__box_your_language_mic_status__enabled.place_forget()
- case "SPEAKER_ON":
- vrct_gui.sls__box_target_language_speaker_status__enabled.place(relx=0.1, rely=0.2, anchor="center")
- case "SPEAKER_OFF":
- vrct_gui.sls__box_target_language_speaker_status__enabled.place_forget()
-
- def updateSelectableTranslationEngineList(self, selectable_translation_engines_list):
- translation_dict = {item: item for item in selectable_translation_engines_list}
- translation_dict["CTranslate2"] = i18n.t("main_window.translator_ctranslate2")
-
- vrct_gui.translation_engine_dropdown_menu_window.updateDropdownMenuValues(
- dropdown_menu_widget_id="translation_engine_dropdown_menu",
- dropdown_menu_values=translation_dict,
- )
-
- def setStateVrcMicMuteSync(self, state:str):
- if state == "enabled":
- self.view_variable.VAR_VRC_MIC_MUTE_SYNC_STATE.set(i18n.t("main_window.state_text_enabled"))
- vrct_gui.vrc_mic_mute_sync_settings_state_label.configure(text_color=self.settings.main.ctm.TOP_BAR_BUTTON_STATE_TEXT_ENABLED_COLOR)
- elif state == "disabled":
- self.view_variable.VAR_VRC_MIC_MUTE_SYNC_STATE.set(i18n.t("main_window.state_text_disabled"))
- vrct_gui.vrc_mic_mute_sync_settings_state_label.configure(text_color=self.settings.main.ctm.TOP_BAR_BUTTON_STATE_TEXT_DISABLED_COLOR)
-
- vrct_gui.config_window.after(200, vrct_gui.config_window.lift)
-
- def setStateOverlaySmallLog(self, state:str):
- if state == "enabled":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_STATE.set(i18n.t("main_window.state_text_enabled"))
- vrct_gui.overlay_settings_state_label.configure(text_color=self.settings.main.ctm.TOP_BAR_BUTTON_STATE_TEXT_ENABLED_COLOR)
- elif state == "disabled":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_STATE.set(i18n.t("main_window.state_text_disabled"))
- vrct_gui.overlay_settings_state_label.configure(text_color=self.settings.main.ctm.TOP_BAR_BUTTON_STATE_TEXT_DISABLED_COLOR)
-
- vrct_gui.config_window.after(200, vrct_gui.config_window.lift)
-
-
- # Config Window
- def enableConfigWindowCompactMode(self):
- for additional_widget in vrct_gui.config_window.additional_widgets:
- additional_widget.grid_remove()
- self._closeMicWordFilterList()
-
- def disableConfigWindowCompactMode(self):
- for additional_widget in vrct_gui.config_window.additional_widgets:
- additional_widget.grid()
- self._closeMicWordFilterList()
-
- def showRestartButton(self):
- self._showRestartButton()
-
- def hideRestartButton(self):
- self._hideRestartButton()
-
- def showRestartButtonIfRequired(self, locale:Union[None,str]=None):
- is_restart_required = not (
- self.restart_required_configs_pre_data.appearance_theme == config.APPEARANCE_THEME and
- self.restart_required_configs_pre_data.ui_scaling == config.UI_SCALING and
- self.restart_required_configs_pre_data.font_family == config.FONT_FAMILY and
- self.restart_required_configs_pre_data.ui_language == config.UI_LANGUAGE and
- self.restart_required_configs_pre_data.is_reset_button_displayed_for_translation == config.IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION and
- self.restart_required_configs_pre_data.is_reset_button_displayed_for_whisper == config.IS_RESET_BUTTON_DISPLAYED_FOR_WHISPER
- )
-
- if locale is None:
- locale = config.UI_LANGUAGE
-
- if is_restart_required is True:
- self._showRestartButton(locale)
- else:
- self._hideRestartButton()
-
-
- def _showRestartButton(self, locale:Union[None,str]=None):
- self.view_variable.VAR_CONFIG_WINDOW_RESTART_BUTTON_LABEL.set(i18n.t("config_window.restart_message", locale=locale))
- vrct_gui.config_window.restart_button_container.grid()
- def _hideRestartButton(self):
- vrct_gui.config_window.restart_button_container.grid_remove()
-
-
-
- @staticmethod
- def setWidgetsStatus_ConfigWindowCompactModeSwitch_Disabled():
- vrct_gui.config_window.setting_box_compact_mode_switch_box.configure(state="disabled")
-
- @staticmethod
- def setWidgetsStatus_ConfigWindowCompactModeSwitch_Normal():
- vrct_gui.config_window.setting_box_compact_mode_switch_box.configure(state="normal")
-
-
- @staticmethod
- def setWidgetsStatus_changeWeightType_Pending():
- vrct_gui.config_window.sb__switch_use_translation_feature.configure(state="disabled")
- vrct_gui._changeConfigWindowWidgetsStatus(
- status="disabled",
- target_names=[
- "sb__switch_use_translation_feature",
- "sb__optionmenu_ctranslate2_weight_type",
- ]
- )
- @staticmethod
- def setWidgetsStatus_changeWeightType_Done():
- vrct_gui.config_window.sb__switch_use_translation_feature.configure(state="normal")
- vrct_gui._changeConfigWindowWidgetsStatus(
- status="normal",
- target_names=[
- "sb__switch_use_translation_feature",
- "sb__optionmenu_ctranslate2_weight_type",
- ]
- )
-
-
- def updateSelectedCtranslate2WeightType(self, selected_weight_type:str):
- self.view_variable.VAR_CTRANSLATE2_WEIGHT_TYPE.set(self.getSelectableCtranslate2WeightTypeDict()[selected_weight_type])
-
- def setLatestCTranslate2WeightType(self):
- selected_weight_type = self.getSelectableCtranslate2WeightTypeDict()[config.CTRANSLATE2_WEIGHT_TYPE]
- self.view_variable.VAR_CTRANSLATE2_WEIGHT_TYPE.set(selected_weight_type)
-
-
- def openCtranslate2WeightTypeWidget(self):
- vrct_gui.config_window.sb__use_translation_feature.grid(pady=0)
- vrct_gui.config_window.sb__ctranslate2_weight_type.grid()
-
- def closeCtranslate2WeightTypeWidget(self):
- vrct_gui.config_window.sb__use_translation_feature.grid(pady=(0,1))
- vrct_gui.config_window.sb__ctranslate2_weight_type.grid_remove()
-
-
- def openWhisperWeightTypeWidget(self):
- vrct_gui.config_window.sb__use_whisper_feature.grid()
- vrct_gui.config_window.sb__whisper_weight_type.grid()
-
- def closeWhisperWeightTypeWidget(self):
- vrct_gui.config_window.sb__use_whisper_feature.grid()
- vrct_gui.config_window.sb__whisper_weight_type.grid_remove()
-
-
- def updateSelectedWhisperWeightType(self, selected_weight_type:str):
- self.view_variable.VAR_WHISPER_WEIGHT_TYPE.set(self.getSelectableWhisperWeightTypeDict()[selected_weight_type])
-
- def setLatestCTranslate2WeightType(self):
- selected_weight_type = self.getSelectableWhisperWeightTypeDict()[config.WHISPER_WEIGHT_TYPE]
- self.view_variable.VAR_WHISPER_WEIGHT_TYPE.set(selected_weight_type)
-
-
- def openMicEnergyThresholdWidget(self):
- self.view_variable.VAR_LABEL_MIC_DYNAMIC_ENERGY_THRESHOLD.set(i18n.t("config_window.mic_dynamic_energy_threshold.label_for_manual"))
- self.view_variable.VAR_DESC_MIC_DYNAMIC_ENERGY_THRESHOLD.set(i18n.t("config_window.mic_dynamic_energy_threshold.desc_for_manual"))
- vrct_gui.config_window.sb__mic_dynamic_energy_threshold.grid(pady=0)
- vrct_gui.config_window.sb__mic_energy_threshold.grid()
-
- def closeMicEnergyThresholdWidget(self):
- self.view_variable.VAR_LABEL_MIC_DYNAMIC_ENERGY_THRESHOLD.set(i18n.t("config_window.mic_dynamic_energy_threshold.label_for_automatic"))
- self.view_variable.VAR_DESC_MIC_DYNAMIC_ENERGY_THRESHOLD.set(i18n.t("config_window.mic_dynamic_energy_threshold.desc_for_automatic"))
- vrct_gui.config_window.sb__mic_dynamic_energy_threshold.grid(pady=(0,1))
- vrct_gui.config_window.sb__mic_energy_threshold.grid_remove()
-
- def openSpeakerEnergyThresholdWidget(self):
- self.view_variable.VAR_LABEL_SPEAKER_DYNAMIC_ENERGY_THRESHOLD.set(i18n.t("config_window.speaker_dynamic_energy_threshold.label_for_manual"))
- self.view_variable.VAR_DESC_SPEAKER_DYNAMIC_ENERGY_THRESHOLD.set(i18n.t("config_window.speaker_dynamic_energy_threshold.desc_for_manual"))
- vrct_gui.config_window.sb__speaker_dynamic_energy_threshold.grid(pady=0)
- vrct_gui.config_window.sb__speaker_energy_threshold.grid()
-
- def closeSpeakerEnergyThresholdWidget(self):
- self.view_variable.VAR_LABEL_SPEAKER_DYNAMIC_ENERGY_THRESHOLD.set(i18n.t("config_window.speaker_dynamic_energy_threshold.label_for_automatic"))
- self.view_variable.VAR_DESC_SPEAKER_DYNAMIC_ENERGY_THRESHOLD.set(i18n.t("config_window.speaker_dynamic_energy_threshold.desc_for_automatic"))
- vrct_gui.config_window.sb__speaker_dynamic_energy_threshold.grid(pady=(0,1))
- vrct_gui.config_window.sb__speaker_energy_threshold.grid_remove()
-
-
-
- def initMicThresholdCheckButton(self):
- if config.CHOICE_MIC_HOST == "NoHost" or config.CHOICE_MIC_DEVICE == "NoDevice":
- self.replaceMicThresholdCheckButton_Disabled()
- else:
- self.replaceMicThresholdCheckButton_Passive()
-
- @staticmethod
- def replaceMicThresholdCheckButton_Active():
- vrct_gui.config_window.sb__progressbar_x_slider__passive_button_mic_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__disabled_button_mic_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__active_button_mic_energy_threshold.grid()
-
- @staticmethod
- def replaceMicThresholdCheckButton_Disabled():
- vrct_gui.config_window.sb__progressbar_x_slider__passive_button_mic_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__active_button_mic_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__disabled_button_mic_energy_threshold.grid()
-
- @staticmethod
- def replaceMicThresholdCheckButton_Passive():
- vrct_gui.config_window.sb__progressbar_x_slider__active_button_mic_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__disabled_button_mic_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__passive_button_mic_energy_threshold.grid()
-
-
-
- def initSpeakerThresholdCheckButton(self):
- if config.CHOICE_SPEAKER_DEVICE == "NoDevice":
- self.replaceSpeakerThresholdCheckButton_Disabled()
- else:
- self.replaceSpeakerThresholdCheckButton_Passive()
-
- @staticmethod
- def replaceSpeakerThresholdCheckButton_Active():
- vrct_gui.config_window.sb__progressbar_x_slider__passive_button_speaker_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__disabled_button_speaker_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__active_button_speaker_energy_threshold.grid()
-
- @staticmethod
- def replaceSpeakerThresholdCheckButton_Disabled():
- vrct_gui.config_window.sb__progressbar_x_slider__passive_button_speaker_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__active_button_speaker_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__disabled_button_speaker_energy_threshold.grid()
-
- @staticmethod
- def replaceSpeakerThresholdCheckButton_Passive():
- vrct_gui.config_window.sb__progressbar_x_slider__active_button_speaker_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__disabled_button_speaker_energy_threshold.grid_remove()
- vrct_gui.config_window.sb__progressbar_x_slider__passive_button_speaker_energy_threshold.grid()
-
-
-
-
- def updateList_MicHost(self, new_mic_host_list:list):
- self.view_variable.LIST_MIC_HOST = new_mic_host_list
- vrct_gui.dropdown_menu_window.updateDropdownMenuValues(
- dropdown_menu_widget_id="sb__optionmenu_mic_host",
- dropdown_menu_values=new_mic_host_list,
- )
-
- def updateSelected_MicHost(self, selected_mic_host_name:str):
- self.view_variable.VAR_MIC_HOST.set(selected_mic_host_name)
-
- def updateList_MicDevice(self, new_mic_device_list:list):
- self.view_variable.LIST_MIC_DEVICE = new_mic_device_list
- vrct_gui.dropdown_menu_window.updateDropdownMenuValues(
- dropdown_menu_widget_id="sb__optionmenu_mic_device",
- dropdown_menu_values=new_mic_device_list,
- )
-
- def updateSelected_MicDevice(self, default_selected_mic_device_name:str):
- self.view_variable.VAR_MIC_DEVICE.set(default_selected_mic_device_name)
-
-
- def updateSetProgressBar_MicEnergy(self, new_mic_energy):
- self.updateProgressBar(
- target_progressbar_widget=vrct_gui.config_window.sb__progressbar_x_slider__progressbar_mic_energy_threshold,
- new_energy=new_mic_energy,
- max_energy=config.MAX_MIC_ENERGY_THRESHOLD,
- energy_threshold=config.INPUT_MIC_ENERGY_THRESHOLD,
- )
-
-
- @staticmethod
- def initProgressBar_MicEnergy():
- vrct_gui.config_window.sb__progressbar_x_slider__progressbar_mic_energy_threshold.set(0)
-
-
- def updateList_SpeakerDevice(self, new_speaker_device_list:list):
- self.view_variable.LIST_SPEAKER_DEVICE = new_speaker_device_list
- vrct_gui.dropdown_menu_window.updateDropdownMenuValues(
- dropdown_menu_widget_id="sb__optionmenu_speaker_device",
- dropdown_menu_values=new_speaker_device_list,
- )
-
- def updateSetProgressBar_SpeakerEnergy(self, new_speaker_energy):
- self.updateProgressBar(
- target_progressbar_widget=vrct_gui.config_window.sb__progressbar_x_slider__progressbar_speaker_energy_threshold,
- new_energy=new_speaker_energy,
- max_energy=config.MAX_SPEAKER_ENERGY_THRESHOLD,
- energy_threshold=config.INPUT_SPEAKER_ENERGY_THRESHOLD,
- )
-
- @staticmethod
- def initProgressBar_SpeakerEnergy():
- vrct_gui.config_window.sb__progressbar_x_slider__progressbar_speaker_energy_threshold.set(0)
-
-
- def updateProgressBar(
- self,
- target_progressbar_widget,
- new_energy,
- max_energy,
- energy_threshold,
- ):
- target_progressbar_widget.set(new_energy/max_energy)
- if new_energy >= energy_threshold:
- target_progressbar_widget.configure(progress_color=self.settings.config_window.ctm.SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_PROGRESS_EXCEED_THRESHOLD_BG_COLOR)
- else:
- target_progressbar_widget.configure(progress_color=self.settings.config_window.ctm.SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_PROGRESS_BG_COLOR)
-
-
-
- def _openMicWordFilterList(self):
- target_widget = vrct_gui.config_window.sb__widgets["sb__arrow_switch_mic_word_filter"]
- target_widget.arrow_switch_open.grid_remove()
- target_widget.arrow_switch_close.grid()
-
- vrct_gui.config_window.sb__mic_word_filter_list.grid()
-
- def _closeMicWordFilterList(self):
- target_widget = vrct_gui.config_window.sb__widgets["sb__arrow_switch_mic_word_filter"]
- target_widget.arrow_switch_close.grid_remove()
- target_widget.arrow_switch_open.grid()
-
- vrct_gui.config_window.sb__mic_word_filter_list.grid_remove()
-
-
- def addValueToList_WordFilter(self, values:list):
- target_widget = vrct_gui.config_window.sb__widgets["sb__add_and_delete_able_list_mic_word_filter_list"]
- for t_item in target_widget.items:
- if t_item.label in values:
- values.remove(t_item.label)
- t_item.redoFunction()
- mic_word_filter_item_row_wrapper, accumulated_labels_width, last_row, last_column = target_widget.addValues(
- values,
- target_widget.mic_word_filter_item_row_wrapper,
- target_widget.accumulated_labels_width,
- target_widget.last_row,
- target_widget.last_column
- )
- target_widget.mic_word_filter_item_row_wrapper = mic_word_filter_item_row_wrapper
- target_widget.accumulated_labels_width = accumulated_labels_width
- target_widget.last_row = last_row
- target_widget.last_column = last_column
-
- def clearEntryBox_WordFilter(self):
- self._clearEntryBox(vrct_gui.config_window.sb__entry_mic_word_filter_list)
-
-
-# Widget Control
- def foregroundOnIfForegroundEnabled(self):
- if config.ENABLE_FOREGROUND:
- self.foregroundOn()
-
- def foregroundOffIfForegroundEnabled(self):
- if config.ENABLE_FOREGROUND:
- self.foregroundOff()
-
-
- @staticmethod
- def foregroundOn():
- vrct_gui.attributes("-topmost", True)
-
- @staticmethod
- def foregroundOff():
- vrct_gui.attributes("-topmost", False)
-
-
- @staticmethod
- def setMainWindowTransparency(transparency:float):
- vrct_gui.wm_attributes("-alpha", transparency)
-
- @staticmethod
- def setMainWindowTextboxUiSize(custom_font_size_scale:float):
- vrct_gui.print_to_textbox.setTagsSettings(custom_font_size_scale=custom_font_size_scale)
-
- def setMainWindowMessageBoxRatio(self, message_box_ratio:int):
- if message_box_ratio < config.MESSAGE_BOX_RATIO_RANGE[0] or message_box_ratio > config.MESSAGE_BOX_RATIO_RANGE[1]:
- raise ValueError(f"Input must be between {config.MESSAGE_BOX_RATIO_RANGE[0]} and {config.MESSAGE_BOX_RATIO_RANGE[1]} (inclusive)")
-
- vrct_gui.main_bg_container.grid_rowconfigure(tuple(range(config.MESSAGE_BOX_RATIO_RANGE[0], config.MESSAGE_BOX_RATIO_RANGE[1]+2)), weight=1)
- textbox_ratio = int((config.MESSAGE_BOX_RATIO_RANGE[1]+1) - message_box_ratio)
- message_box_row = int(textbox_ratio + 1)
- message_box_rowwpan = int((config.MESSAGE_BOX_RATIO_RANGE[1]+1) - textbox_ratio)
- vrct_gui.main_textbox_container.grid(row=1, rowspan=textbox_ratio, column=0, sticky="nsew")
- vrct_gui.main_entry_message_container.grid(row=message_box_row, rowspan=message_box_rowwpan, column=0, sticky="nsew")
-
- new_send_message_button_width = int(self.settings.main.uism.SEND_MESSAGE_BUTTON_RATE_WIDTH * message_box_ratio)
-
- if new_send_message_button_width > self.settings.main.uism.SEND_MESSAGE_BUTTON_MAX_WIDTH:
- new_send_message_button_width = self.settings.main.uism.SEND_MESSAGE_BUTTON_MAX_WIDTH
-
- if new_send_message_button_width < self.settings.main.uism.SEND_MESSAGE_BUTTON_MIN_WIDTH:
- new_send_message_button_width = self.settings.main.uism.SEND_MESSAGE_BUTTON_MIN_WIDTH
-
- vrct_gui.main_send_message_button_container.grid_columnconfigure(0, weight=0, minsize=new_send_message_button_width)
-
- @staticmethod
- def changeMainWindowSendMessageButton(status:str):
- match (status):
- case "hide":
- vrct_gui.main_send_message_button_container.grid_remove()
- vrct_gui.config_window.after(200, vrct_gui.config_window.lift)
- case "show" | "show_and_disable_enter_key":
- vrct_gui.main_send_message_button_container.grid()
- vrct_gui.config_window.after(200, vrct_gui.config_window.lift)
-
- def _enteredSwapLanguagesButton(self):
- self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.swap_button_label"))
- vrct_gui.sls__both_direction_desc.configure(
- text_color=self.settings.main.ctm.SLS__BOX_ARROWS_SWAP_BUTTON_TEXT_COLOR,
- )
-
- def _leavedSwapLanguagesButton(self):
- if config.USE_TRANSLATION_FEATURE is True:
- self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.translate_each_other_label"))
- vrct_gui.sls__both_direction_desc.configure(
- text_color=self.settings.main.ctm.SLS__BOX_ARROWS_TEXT_COLOR,
- )
-
-# Function
- def _adjustUiSizeAndRestart(self):
- current_percentage = int(config.UI_SCALING.replace("%",""))
- target_percentage = current_percentage - 20
- if target_percentage >= 40 and str(target_percentage) + "%" in self.view_variable.LIST_UI_SCALING:
- index = self.view_variable.LIST_UI_SCALING.index(str(target_percentage) + "%")
- callFunctionIfCallable(self.view_variable.CALLBACK_SET_UI_SCALING, self.view_variable.LIST_UI_SCALING[index])
- callFunctionIfCallable(self.view_variable.CALLBACK_RESTART_SOFTWARE)
- else:
- self._hideConfirmationModal()
- # ※Below 40% of the UI size is not supported, and we cannot handle it at this time.
-
-
-
-# Show Modal
- def _showDisplayOverUiSizeConfirmationModal(self):
- self.foregroundOffIfForegroundEnabled()
-
- self.view_variable.VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE.set("")
- vrct_gui.main_window_cover.show()
-
- self.view_variable.CALLBACK_HIDE_CONFIRMATION_MODAL=self._hideConfirmationModal
- self.view_variable.CALLBACK_ACCEPTED_CONFIRMATION_MODAL=self._adjustUiSizeAndRestart
- self.view_variable.CALLBACK_DENIED_CONFIRMATION_MODAL=self._hideConfirmationModal
-
- self.view_variable.VAR_MESSAGE_CONFIRMATION_MODAL.set(i18n.t("main_window.confirmation_message.detected_over_ui_size", current_ui_size=config.UI_SCALING))
- self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON.set(i18n.t("main_window.confirmation_message.deny_adjust_ui_size"))
- self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON.set(i18n.t("main_window.confirmation_message.accept_adjust_ui_size"))
-
- vrct_gui.confirmation_modal.show(hide_title_bar=False, close_when_focusout=False)
-
-
-
- def _showUpdateSoftwareConfirmationModal(self):
- self.foregroundOffIfForegroundEnabled()
-
- self.view_variable.VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE.set("")
- vrct_gui.main_window_cover.show()
-
- self.view_variable.CALLBACK_HIDE_CONFIRMATION_MODAL=self._hideConfirmationModal
- self.view_variable.CALLBACK_ACCEPTED_CONFIRMATION_MODAL=self._startUpdateSoftware
- self.view_variable.CALLBACK_DENIED_CONFIRMATION_MODAL=self._hideConfirmationModal
-
- self.view_variable.VAR_MESSAGE_CONFIRMATION_MODAL.set(i18n.t("main_window.confirmation_message.update_software"))
- self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON.set(i18n.t("main_window.confirmation_message.deny_update_software"))
- self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON.set(i18n.t("main_window.confirmation_message.accept_update_software"))
- vrct_gui.confirmation_modal.show()
-
-
-
-
-# Hide Modal
- def _hideInformationModal(self):
- vrct_gui.information_modal.hide()
- vrct_gui.main_window_cover.hide()
- self.foregroundOnIfForegroundEnabled()
-
-
- def _hideConfirmationModal(self):
- vrct_gui.confirmation_modal.hide()
- vrct_gui.main_window_cover.hide()
- self.foregroundOnIfForegroundEnabled()
-
-
-# Process
- def _startUpdateSoftware(self):
- self.view_variable.VAR_MESSAGE_CONFIRMATION_MODAL.set(i18n.t("main_window.confirmation_message.updating"))
- vrct_gui.confirmation_modal.hide_buttons()
- vrct_gui.update()
- vrct_gui.confirmation_modal.update()
-
- self._hideConfirmationModal()
- vrct_gui.withdraw()
- vrct_gui.updating_window.showUpdatingWindow()
-
- def func(**kwargs):
- vrct_gui.updating_window.updateDownloadProgress(**kwargs)
- callFunctionIfCallable(self.view_variable.CALLBACK_UPDATE_SOFTWARE, func)
-
-
-
-# Window Control
- def _openConfigWindow(self):
- self.view_variable.VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE.set(i18n.t("main_window.cover_message"))
- callFunctionIfCallable(self.view_variable.CALLBACK_OPEN_CONFIG_WINDOW)
- vrct_gui._openConfigWindow()
-
- def _closeConfigWindow(self):
- callFunctionIfCallable(self.view_variable.CALLBACK_CLOSE_CONFIG_WINDOW)
- self._closeMicWordFilterList()
- vrct_gui._closeConfigWindow()
-
- def _openVrSettingsWindow(self):
- vrct_gui.quick_settings_window.show(target="overlay")
-
- def _openVrcMicMuteSyncSettingsWindow(self):
- vrct_gui.quick_settings_window.show(target="vrc_mic_mute_sync")
-
-# Window Control (Main Window Cover)
- def _openTheCoverOfMainWindow(self):
- vrct_gui.main_window_cover.show()
- vrct_gui.config_window.lift()
-
- @staticmethod
- def _closeTheCoverOfMainWindow():
- vrct_gui.main_window_cover.withdraw()
-
-# Window Control (Selectable Languages Window)
- def openSelectableLanguagesWindow_YourLanguage(self, _e):
- self.view_variable.VAR_TITLE_LABEL_SELECTABLE_LANGUAGE.set(i18n.t("selectable_language_window.title_your_language"))
- vrct_gui._openSelectableLanguagesWindow("your_language")
-
- def openSelectableLanguagesWindow_TargetLanguage(self, _e):
- self.view_variable.VAR_TITLE_LABEL_SELECTABLE_LANGUAGE.set(i18n.t("selectable_language_window.title_target_language"))
- vrct_gui._openSelectableLanguagesWindow("target_language")
-
-
-# Update GuiVariable (view_variable)
- def updateGuiVariableByPresetTabNo(self, tab_no:str):
- select = config.SELECTED_TAB_YOUR_LANGUAGES[tab_no]
- your_language = select["language"]
- your_country = select["country"]
- self.view_variable.VAR_YOUR_LANGUAGE.set(f"{your_language}\n({your_country})")
- select = config.SELECTED_TAB_TARGET_LANGUAGES[tab_no]
- target_language = select["language"]
- target_country = select["country"]
- self.view_variable.VAR_TARGET_LANGUAGE.set(f"{target_language}\n({target_country})")
-
-
- def updateList_selectableLanguages(self, new_selectable_language_list:list):
- self.view_variable.LIST_SELECTABLE_LANGUAGES = new_selectable_language_list
-
- # (Config Window Setting Box Tab)
- def _updateActiveSettingBoxTabNo(self, active_setting_box_tab_attr_name:str):
- self.view_variable.ACTIVE_SETTING_BOX_TAB_ATTR_NAME = active_setting_box_tab_attr_name
-
-
-# Set GuiVariable (view_variable)
- def setGuiVariable_SelectedTranslationEngine(self, value):
- if value == "CTranslate2":
- self.view_variable.VAR_SELECTED_TRANSLATION_ENGINE.set(self.TEXT_TRANSLATOR_CTRANSLATE2)
- value = self.TEXT_TRANSLATOR_CTRANSLATE2
- else:
- self.view_variable.VAR_SELECTED_TRANSLATION_ENGINE.set(i18n.t("main_window.translator") + ": " + value)
-
- def setGuiVariable_MicEnergyThreshold(self, value):
- self.view_variable.VAR_MIC_ENERGY_THRESHOLD__SLIDER.set(int(value))
- self.view_variable.VAR_MIC_ENERGY_THRESHOLD__ENTRY.set(str(value))
-
-
- def setGuiVariable_SpeakerEnergyThreshold(self, value):
- self.view_variable.VAR_SPEAKER_ENERGY_THRESHOLD__SLIDER.set(int(value))
- self.view_variable.VAR_SPEAKER_ENERGY_THRESHOLD__ENTRY.set(str(value))
-
-
- def setGuiVariable_MicRecordTimeout(self, value):
- self.view_variable.VAR_MIC_RECORD_TIMEOUT.set(str(value))
-
-
- def setGuiVariable_MicPhraseTimeout(self, value):
- self.view_variable.VAR_MIC_PHRASE_TIMEOUT.set(str(value))
-
-
- def setGuiVariable_MicMaxPhrases(self, value):
- self.view_variable.VAR_MIC_MAX_PHRASES.set(str(value))
-
- def setGuiVariable_MicWordFilter_Length(self, value):
- self.view_variable.VAR_SWITCH_DESC_MIC_WORD_FILTER.set(i18n.t("config_window.mic_word_filter.count_desc", count=value))
-
- def setGuiVariable_SpeakerRecordTimeout(self, value):
- self.view_variable.VAR_SPEAKER_RECORD_TIMEOUT.set(str(value))
-
-
- def setGuiVariable_SpeakerPhraseTimeout(self, value):
- self.view_variable.VAR_SPEAKER_PHRASE_TIMEOUT.set(str(value))
-
-
- def setGuiVariable_SpeakerMaxPhrases(self, value):
- self.view_variable.VAR_SPEAKER_MAX_PHRASES.set(str(value))
-
-
- def setGuiVariable_OscIpAddress(self, value):
- self.view_variable.VAR_OSC_IP_ADDRESS.set(str(value))
-
- def setGuiVariable_OscPort(self, value):
- self.view_variable.VAR_OSC_PORT.set(int(value))
-
-
-
- def setLatestConfigVariable(self, target_name:str):
- match (target_name):
- case "MicEnergyThreshold":
- self.setGuiVariable_MicEnergyThreshold(config.INPUT_MIC_ENERGY_THRESHOLD)
- case "SpeakerEnergyThreshold":
- self.setGuiVariable_SpeakerEnergyThreshold(config.INPUT_SPEAKER_ENERGY_THRESHOLD)
- case "MicRecordTimeout":
- self.setGuiVariable_MicRecordTimeout(config.INPUT_MIC_RECORD_TIMEOUT)
- case "MicPhraseTimeout":
- self.setGuiVariable_MicPhraseTimeout(config.INPUT_MIC_PHRASE_TIMEOUT)
- case "MicMaxPhrases":
- self.setGuiVariable_MicMaxPhrases(config.INPUT_MIC_MAX_PHRASES)
- case "MicMicWordFilter":
- self.setGuiVariable_MicWordFilter_Length(len(config.INPUT_MIC_WORD_FILTER))
-
- case "SpeakerRecordTimeout":
- self.setGuiVariable_SpeakerRecordTimeout(config.INPUT_SPEAKER_RECORD_TIMEOUT)
- case "SpeakerPhraseTimeout":
- self.setGuiVariable_SpeakerPhraseTimeout(config.INPUT_SPEAKER_PHRASE_TIMEOUT)
- case "SpeakerMaxPhrases":
- self.setGuiVariable_SpeakerMaxPhrases(config.INPUT_SPEAKER_MAX_PHRASES)
-
- case "SendMessageFormat":
- self.setSendMessageFormat_EntryWidgets(config.SEND_MESSAGE_FORMAT)
- case "SendMessageFormatWithT":
- self.setSendMessageFormatWithT_EntryWidgets(config.SEND_MESSAGE_FORMAT_WITH_T)
- case "ReceivedMessageFormat":
- self.setReceivedMessageFormat_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT)
- case "ReceivedMessageFormatWithT":
- self.setReceivedMessageFormatWithT_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT_WITH_T)
-
-
-
- case "OverlayOpacity":
- self.view_variable.VAR_OVERLAY_OPACITY.set(config.OVERLAY_SETTINGS["opacity"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_OPACITY.set(floatToPctStr(config.OVERLAY_SETTINGS["opacity"]))
-
- case "OverlayUiScaling":
- self.view_variable.VAR_OVERLAY_UI_SCALING.set(config.OVERLAY_SETTINGS["ui_scaling"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_UI_SCALING.set(floatToPctStr(config.OVERLAY_SETTINGS["ui_scaling"]))
-
-
- case "OverlaySmallLogXPos":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_X_POS.set(config.OVERLAY_SMALL_LOG_SETTINGS["x_pos"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_POS.set(config.OVERLAY_SMALL_LOG_SETTINGS["x_pos"])
-
- case "OverlaySmallLogYPos":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_Y_POS.set(config.OVERLAY_SMALL_LOG_SETTINGS["y_pos"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_POS.set(config.OVERLAY_SMALL_LOG_SETTINGS["y_pos"])
-
- case "OverlaySmallLogZPos":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_Z_POS.set(config.OVERLAY_SMALL_LOG_SETTINGS["z_pos"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Z_POS.set(config.OVERLAY_SMALL_LOG_SETTINGS["z_pos"])
-
- case "OverlaySmallLogXRotation":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_X_ROTATION.set(config.OVERLAY_SMALL_LOG_SETTINGS["x_rotation"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_ROTATION.set(config.OVERLAY_SMALL_LOG_SETTINGS["x_rotation"])
-
- case "OverlaySmallLogYRotation":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_Y_ROTATION.set(config.OVERLAY_SMALL_LOG_SETTINGS["y_rotation"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_ROTATION.set(config.OVERLAY_SMALL_LOG_SETTINGS["y_rotation"])
-
- case "OverlaySmallLogZRotation":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_Z_ROTATION.set(config.OVERLAY_SMALL_LOG_SETTINGS["z_rotation"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Z_ROTATION.set(config.OVERLAY_SMALL_LOG_SETTINGS["z_rotation"])
-
- case "OverlaySmallLogDisplayDuration":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_DISPLAY_DURATION.set(config.OVERLAY_SMALL_LOG_SETTINGS["display_duration"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DISPLAY_DURATION.set(f"{config.OVERLAY_SMALL_LOG_SETTINGS['display_duration']} second(s)")
-
- case "OverlaySmallLogFadeoutDuration":
- self.view_variable.VAR_OVERLAY_SMALL_LOG_FADEOUT_DURATION.set(config.OVERLAY_SMALL_LOG_SETTINGS["fadeout_duration"])
- self.view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_FADEOUT_DURATION.set(f"{config.OVERLAY_SMALL_LOG_SETTINGS['fadeout_duration']} second(s)")
-
- case _:
- raise ValueError(f"No matching case for target_name: {target_name}")
-
-
-# Print To Textbox.
- def printToTextbox_enableEasterEgg(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.enabled_easter_egg"))
-
- def printToTextbox_enableTranslation(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.enabled_translation"))
- def printToTextbox_disableTranslation(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.disabled_translation"))
-
- def printToTextbox_enableTranscriptionSend(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.enabled_voice2chatbox"))
- def printToTextbox_disableTranscriptionSend(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.disabled_voice2chatbox"))
-
- def printToTextbox_enableTranscriptionReceive(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.enabled_speaker2log"))
- def printToTextbox_disableTranscriptionReceive(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.disabled_speaker2log"))
-
- def printToTextbox_enableForeground(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.enabled_foreground"))
- def printToTextbox_disableForeground(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.disabled_foreground"))
-
- def printToTextbox_AuthenticationSuccess(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.auth_key_success"))
- def printToTextbox_AuthenticationError(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.auth_key_error"))
-
-
- def printToTextbox_TranscriptionSendNoDeviceError(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.no_mic_device_detected_error"))
-
- def printToTextbox_TranscriptionReceiveNoDeviceError(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.no_speaker_device_detected_error"))
-
-
- def printToTextbox_TranslationEngineLimitError(self):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.translation_engine_limit_error"))
-
-
- def printToTextbox_DetectedByWordFilter(self, detected_message):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.detected_by_word_filter", detected_message=detected_message))
-
-
-
- def printToTextbox_selectedYourLanguages(self, selected_your_language):
- language = selected_your_language["language"]
- country = selected_your_language["country"]
- your_language = f"{language} ({country})"
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.selected_your_language", your_language=your_language))
-
- def printToTextbox_selectedTargetLanguages(self, selected_target_language):
- language = selected_target_language["language"]
- country = selected_target_language["country"]
- target_language = f"{language} ({country})"
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.selected_target_language", target_language=target_language))
-
- def printToTextbox_changedLanguagePresetTab(self, tab_no:str):
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.switched_language_preset_tab", tab_no=tab_no))
- self.printToTextbox_latestSelectedLanguages()
-
- def printToTextbox_latestSelectedLanguages(self):
- your_language = self.view_variable.VAR_YOUR_LANGUAGE.get().replace("\n", " ")
- target_language = self.view_variable.VAR_TARGET_LANGUAGE.get().replace("\n", " ")
- self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.latest_language_setting", your_language=your_language, target_language=target_language))
-
-
- @staticmethod
- def _printToTextbox_Info(info_message, **kwargs):
- vrct_gui._printToTextbox(
- target_type="SYSTEM",
- original_message=info_message,
- **kwargs,
- )
-
-
-
- def printToTextbox_SentMessage(self, original_message, translated_message):
- self._printToTextbox_Sent(original_message, translated_message)
-
- @staticmethod
- def _printToTextbox_Sent(original_message, translated_message):
- vrct_gui._printToTextbox(
- target_type="SENT",
- original_message=original_message,
- translated_message=translated_message,
- )
-
-
- def printToTextbox_ReceivedMessage(self, original_message, translated_message):
- self._printToTextbox_Received(original_message, translated_message)
-
- @staticmethod
- def _printToTextbox_Received(original_message, translated_message):
- vrct_gui._printToTextbox(
- target_type="RECEIVED",
- original_message=original_message,
- translated_message=translated_message,
- )
-
-
-# Message Box
- @staticmethod
- def getTextFromMessageBox():
- return vrct_gui.entry_message_box.get('1.0', "end-1c")
-
- def clearMessageBox(self):
- self._clearTextBox(vrct_gui.entry_message_box)
-
- @staticmethod
- def insertMessageBox(text):
- vrct_gui.entry_message_box.insert("end", text)
-
- def replaceMessageBox(self, text):
- self.clearMessageBox()
- self.insertMessageBox(text)
-
-
-
-# Callback Bind FocusOut
- def callbackBindFocusOut_DeeplAuthKey(self, _e=None):
- self.clearNotificationMessage()
-
- def callbackBindFocusOut_MicEnergyThreshold(self, _e=None):
- self.setLatestConfigVariable("MicEnergyThreshold")
- self.clearNotificationMessage()
-
- def callbackBindFocusOut_SpeakerEnergyThreshold(self, _e=None):
- self.setLatestConfigVariable("SpeakerEnergyThreshold")
- self.clearNotificationMessage()
-
-
- def callbackBindFocusOut_MicRecordTimeout(self, _e=None):
- self.setLatestConfigVariable("MicRecordTimeout")
- self.clearNotificationMessage()
-
- def callbackBindFocusOut_MicPhraseTimeout(self, _e=None):
- self.setLatestConfigVariable("MicPhraseTimeout")
- self.clearNotificationMessage()
-
- def callbackBindFocusOut_MicMaxPhrases(self, _e=None):
- self.setLatestConfigVariable("MicMaxPhrases")
- self.clearNotificationMessage()
-
-
- def callbackBindFocusOut_SpeakerRecordTimeout(self, _e=None):
- self.setLatestConfigVariable("SpeakerRecordTimeout")
- self.clearNotificationMessage()
-
- def callbackBindFocusOut_SpeakerPhraseTimeout(self, _e=None):
- self.setLatestConfigVariable("SpeakerPhraseTimeout")
- self.clearNotificationMessage()
-
- def callbackBindFocusOut_SpeakerMaxPhrases(self, _e=None):
- self.setLatestConfigVariable("SpeakerMaxPhrases")
- self.clearNotificationMessage()
-
-
- def callbackBindFocusOut_SendMessageFormat(self, _e=None):
- self.setLatestConfigVariable("SendMessageFormat")
- self.clearNotificationMessage()
-
- def callbackBindFocusOut_SendMessageFormatWithT(self, _e=None):
- self.setLatestConfigVariable("SendMessageFormatWithT")
- self.clearNotificationMessage()
-
- def callbackBindFocusOut_ReceivedMessageFormat(self, _e=None):
- self.setLatestConfigVariable("ReceivedMessageFormat")
- self.clearNotificationMessage()
-
- def callbackBindFocusOut_ReceivedMessageFormatWithT(self, _e=None):
- self.setLatestConfigVariable("ReceivedMessageFormatWithT")
- self.clearNotificationMessage()
-
-
-
-# Show Notification Message (Config Window)
- def showSuccessMessage_DeeplAuthKey(self):
- self._showSuccessMessage(
- vrct_gui.config_window.sb__entry_deepl_auth_key,
- i18n.t("config_window.deepl_auth_key.auth_key_success")
- )
- def showErrorMessage_DeeplAuthKey(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_deepl_auth_key,
- i18n.t("config_window.deepl_auth_key.auth_key_error")
- )
-
- def showErrorMessage_MicEnergyThreshold(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__progressbar_x_slider__entry_mic_energy_threshold,
- self._makeInvalidValueErrorMessage(i18n.t("config_window.mic_dynamic_energy_threshold.error_message", max=config.MAX_MIC_ENERGY_THRESHOLD))
- )
-
- def showErrorMessage_MicRecordTimeout(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_mic_record_timeout,
- self._makeInvalidValueErrorMessage(
- i18n.t(
- "config_window.mic_record_timeout.error_message",
- mic_phrase_timeout_label=i18n.t("config_window.mic_phrase_timeout.label")
- )
- )
- )
-
- def showErrorMessage_MicPhraseTimeout(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_mic_phrase_timeout,
- self._makeInvalidValueErrorMessage(
- i18n.t(
- "config_window.mic_phrase_timeout.error_message",
- mic_record_timeout_label=i18n.t("config_window.mic_record_timeout.label")
- )
- )
- )
-
- def showErrorMessage_MicMaxPhrases(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_mic_max_phrases,
- self._makeInvalidValueErrorMessage(i18n.t("config_window.mic_max_phrase.error_message"))
- )
-
-
- def showErrorMessage_SpeakerEnergyThreshold(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__progressbar_x_slider__entry_speaker_energy_threshold,
- self._makeInvalidValueErrorMessage(i18n.t("config_window.speaker_dynamic_energy_threshold.error_message", max=config.MAX_SPEAKER_ENERGY_THRESHOLD))
- )
-
- def showErrorMessage_SpeakerRecordTimeout(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_speaker_record_timeout,
- self._makeInvalidValueErrorMessage(
- i18n.t(
- "config_window.speaker_record_timeout.error_message",
- speaker_phrase_timeout_label=i18n.t("config_window.speaker_phrase_timeout.label")
- )
- )
- )
-
- def showErrorMessage_SpeakerPhraseTimeout(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_speaker_phrase_timeout,
- self._makeInvalidValueErrorMessage(
- i18n.t(
- "config_window.speaker_phrase_timeout.error_message",
- speaker_record_timeout_label=i18n.t("config_window.speaker_record_timeout.label")
- )
- )
- )
-
- def showErrorMessage_SpeakerMaxPhrases(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_speaker_max_phrases,
- self._makeInvalidValueErrorMessage(i18n.t("config_window.speaker_max_phrase.error_message"))
- )
-
-
- def showErrorMessage_CheckSpeakerThreshold_NoDevice(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__progressbar_x_slider__active_button_speaker_energy_threshold,
- self._makeInvalidValueErrorMessage(i18n.t("config_window.speaker_dynamic_energy_threshold.no_device_error_message"))
- )
-
-
- def showErrorMessage_SendMessageFormat(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_send_message_format_1,
- self._makeInvalidValueErrorMessage(i18n.t("config_window.send_message_format.error_message"))
- )
-
- def showErrorMessage_SendMessageFormatWithT(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_send_message_format_with_t_2,
- self._makeInvalidValueErrorMessage(i18n.t("config_window.send_message_format_with_t.error_message"))
- )
-
- def showErrorMessage_ReceivedMessageFormat(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_received_message_format_1,
- self._makeInvalidValueErrorMessage(i18n.t("config_window.received_message_format.error_message"))
- )
-
- def showErrorMessage_ReceivedMessageFormatWithT(self):
- self._showErrorMessage(
- vrct_gui.config_window.sb__entry_received_message_format_with_t_2,
- self._makeInvalidValueErrorMessage(i18n.t("config_window.received_message_format_with_t.error_message"))
- )
-
-
- @staticmethod
- def _makeInvalidValueErrorMessage(error_message):
- return i18n.t("config_window.common_error_message.invalid_value") + "\n" + error_message
-
- def _showSuccessMessage(self, target_widget, message):
- self.view_variable.VAR_ERROR_MESSAGE.set(message)
- vrct_gui._showSuccessMessage(target_widget=target_widget)
-
- def _showErrorMessage(self, target_widget, message):
- self.view_variable.VAR_ERROR_MESSAGE.set(message)
- vrct_gui._showErrorMessage(target_widget=target_widget)
-
- @staticmethod
- def extractMessageFormat(text):
- split_result = text.split("[message]")
- result_data = SimpleNamespace(
- before = split_result[0],
- after = split_result[1],
- )
- return result_data
-
- @staticmethod
- def extractMessageFormatWithT(text):
- import re
- message_index = text.find("[message]")
- translation_index = text.find("[translation]")
-
- result_data = SimpleNamespace(
- is_message_first = True,
- before = "",
- between = "",
- after = "",
- )
-
- if message_index < translation_index:
- text_before_message = text[:message_index]
- result_data.before = text_before_message
-
- match = re.search(r"\[message\](.*?)\[translation\]", text)
- if match:
- extracted_text = match.group(1)
- result_data.between = extracted_text
-
- else:
- raise ValueError("Invalid Message Format")
-
- text_after_translation = text[translation_index + len("[translation]"):]
- result_data.after = text_after_translation
-
-
-
-
- elif translation_index < message_index:
- result_data.is_message_first = False
- text_before_translation = text[:translation_index]
- result_data.before = text_before_translation
-
- match = re.search(r"\[translation\](.*?)\[message\]", text)
- if match:
- extracted_text = match.group(1)
- result_data.between = extracted_text
- else:
- raise ValueError("Invalid Message Format")
-
- text_after_message = text[message_index + len("[message]"):]
- result_data.after = text_after_message
-
- else:
- raise ValueError("Invalid Message Format")
-
- return result_data
-
-
-
-
-
-
- # These conversations are generated by ChatGPT
- def _insertSampleConversationToTextbox(self):
-
- self.printToTextbox_enableTranscriptionSend()
- self.printToTextbox_enableTranscriptionReceive()
-
- conversation_data_without_translation = [
- {
- "me": "おはよう。",
- },
- {
- "me": "おはよう。",
- "target": "やぁ。",
- },
- {
- "me": "今日の天気はどうかな?",
- "target": "天気予報を見てないけど、晴れるといいね。",
- },
- {
- "me": "そうだね。昨日は雨だったから。",
- "target": "それで、今日の予定は?",
- },
- ]
-
- for data in conversation_data_without_translation:
- if data.get("me", None) is not None:
- self.printToTextbox_SentMessage(data.get("me", None), data.get("me_t", None))
- if data.get("target", None) is not None:
- self.printToTextbox_ReceivedMessage(data.get("target", None), data.get("target_t", None))
-
- self.printToTextbox_enableTranslation()
-
- conversation_data = [
- {
- "me": "I have work in the morning, but I'm meeting friends for dinner in the evening.",
- "me_t": "아침에 일이 있지만 저녁에 친구들과 만나 저녁 식사할 예정이에요.",
- "target": "재미있어 보여요! 무엇을 먹을 예정이에요?",
- "target_t": "Sounds fun! What are you planning to eat?"
- },
- {
- "me": "We're going to an Italian restaurant, and I'm going to have pizza.",
- "me_t": "우리는 이탈리안 레스토랑에 가서 피자를 먹을 거에요.",
- "target": "그걸 듣자마자 배가 고파져요. 언젠가 함께하고 싶어요.",
- "target_t": "Just hearing that makes me hungry. I'd love to join you sometime."
- },
- {
- "me": "Let's plan it for next time!",
- "me_t": "다음 번에 계획해 봐요!",
- "target": "그래요!",
- "target_t": "Sure!"
- },
- {
- "me": "When would be a good time for you?",
- "me_t": "너에게 언제가 좋을까?",
- "target": "나는 주말이 가장 좋을 것 같아요. 토요일은 어때요?",
- "target_t": "I think the weekend works best for me. How about Saturday?"
- },
- {
- "me": "Saturday sounds perfect. What time would be convenient?",
- "me_t": "토요일이 완벽해 보여. 편한 시간은 언제인가요?",
- "target": "저는 저녁이 괜찮아요. 7시쯤 괜찮을까요?",
- "target_t": "Evening works for me. Is around 7 PM okay?"
- },
- {
- "me": "7 PM works great. Do you have any preferences for food other than Italian?",
- "me_t": "7시가 아주 적당해. 이탈리안 음식 이외에 어떤 음식을 좋아하세요?",
- "target": "특별한 선호도는 없어요. 무엇이든 괜찮아요. 추천 디저트가 있다면 알려주세요.",
- "target_t": "I don't have any particular preferences, so anything is fine. If there's a recommended dessert, let me know."
- },
-
-
- {
- "me": "朝は仕事があるけど、夜は友達と食事に行く予定だよ。",
- "me_t": "I have work in the morning, but I'm meeting friends for dinner in the evening.",
- "target": "Sounds fun! What are you planning to eat?",
- "target_t": "楽しそう!何を食べる予定?",
- },
- {
- "me": "イタリアンレストランに行って、ピザを食べるつもりだよ。",
- "me_t": "We're going to an Italian restaurant, and I'm going to have pizza.",
- "target": "Just hearing that makes me hungry. I'd love to join you sometime.",
- "target_t": "それ聞いただけでおなかすいたよ。私も一緒に行きたいな。",
- },
- {
- "me": "次回にぜひ一緒に行こう!",
- "me_t": "Let's plan it for next time!",
- "target": "Sure!",
- "target_t": "そうだね!",
- },
- {
- "me": "次回はいつがいいかな?",
- "me_t": "When would be a good time for you?",
- "target": "I think the weekend works best for me. How about Saturday?",
- "target_t": "私は週末が一番いいかな。土曜日はどう?"
- },
- {
- "me": "土曜日はちょうどいいね。何時ごろが良いかな?",
- "me_t": "Saturday sounds perfect. What time would be convenient?",
- "target": "Evening works for me. Is around 7 PM okay?",
- "target_t": "夜がいいかな。7時くらいからがちょうど良いかな。"
- },
- {
- "me": "7時からはちょうどいいよ。イタリアン以外の食べ物について何か好みがある?",
- "me_t": "7 PM works great. Do you have any preferences for food other than Italian?",
- "target": "I don't have any particular preferences, so anything is fine. If there's a recommended dessert, let me know.",
- "target_t": "特に好みはないから、何でも大丈夫。おすすめのデザートがあれば教えてね。"
- },
- ]
- for data in conversation_data:
- if data.get("me", None) is not None:
- self.printToTextbox_SentMessage(data.get("me", None), data.get("me_t", None))
- if data.get("target", None) is not None:
- self.printToTextbox_ReceivedMessage(data.get("target", None), data.get("target_t", None))
-
-
-view = View()
\ No newline at end of file
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 00000000..284d9450
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,48 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import svgr from "vite-plugin-svgr";
+import path from "path";
+
+// https://vitejs.dev/config/
+export default defineConfig(async () => ({
+ plugins: [react(), svgr()],
+
+ // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
+ //
+ // 1. prevent vite from obscuring rust errors
+ clearScreen: false,
+ // 2. tauri expects a fixed port, fail if that port is not available
+ server: {
+ port: 1420,
+ strictPort: true,
+ watch: {
+ // 3. tell vite to ignore watching `src-tauri`
+ ignored: ["**/src-tauri/**"],
+ },
+ },
+
+ build: {
+ outDir: path.resolve(__dirname, "dist"),
+ rollupOptions: {
+ input: {
+ main: path.resolve(__dirname, "index.html"),
+ second: path.resolve(__dirname, "./src-ui/windows/config_window/index.html"),
+ },
+ },
+ },
+
+ resolve: {
+ alias: {
+ "@data": path.resolve(__dirname, "./data.js"),
+
+ "@scss_mixins": path.resolve(__dirname, "src-ui/utils/mixins.scss"),
+ "@store": path.resolve(__dirname, "src-ui/store.js"),
+ "@logic": path.resolve(__dirname, "src-ui/logic.js"),
+ "@images": path.resolve(__dirname, "src-ui/assets"),
+ "@utils": path.resolve(__dirname, "src-ui/utils"),
+ "@logics": path.resolve(__dirname, "src-ui/utils/logics"),
+ },
+ },
+
+
+}));
diff --git a/vrct_gui/_CreateConfirmationModal.py b/vrct_gui/_CreateConfirmationModal.py
deleted file mode 100644
index 898e9c84..00000000
--- a/vrct_gui/_CreateConfirmationModal.py
+++ /dev/null
@@ -1,270 +0,0 @@
-from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont, CTkProgressBar
-
-from .ui_utils import fadeInAnimation, setGeometryToCenterOfTheWidget, bindButtonFunctionAndColor, generateGradientColor
-
-from utils import callFunctionIfCallable
-
-class _CreateConfirmationModal(CTkToplevel):
- def __init__(self, attach_window, settings, view_variable, modal_type=None):
- super().__init__()
- self.withdraw()
-
- self.attach_window = attach_window
- self.settings = settings
- self._view_variable = view_variable
-
- self.is_showed_progressbar = False
-
- self.title("")
- self.overrideredirect(True)
- self.wm_attributes("-toolwindow", True)
-
- self.BIND_FOCUS_OUT_FUNC_ID=None
-
-
-
- self.configure(fg_color=self.settings.ctm.FAKE_BORDER_COLOR)
- self.protocol("WM_DELETE_WINDOW", lambda: callFunctionIfCallable(self._view_variable.CALLBACK_HIDE_CONFIRMATION_MODAL))
-
-
-
- self.grid_rowconfigure(0,weight=1)
- self.grid_columnconfigure(0,weight=1)
- self.modal_container = CTkFrame(self, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR)
- self.modal_container.grid(row=0, column=0, padx=self.settings.uism.FAKE_BORDER_SIZE, pady=self.settings.uism.FAKE_BORDER_SIZE)
-
-
- self.modal_contents_wrapper = CTkFrame(self.modal_container, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR)
- self.modal_contents_wrapper.grid(row=0, column=0, padx=self.settings.uism.CONTENTS_WRAPPER, pady=self.settings.uism.CONTENTS_WRAPPER)
-
-
-
- self.modal_contents_wrapper.grid_rowconfigure(1, minsize=self.settings.uism.MARGIN_BETWEEN_MESSAGE_AND_BUTTONS)
-
- self.modal_message_label_wrapper = CTkFrame(self.modal_contents_wrapper, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR)
- self.modal_message_label_wrapper.grid(row=0, column=0)
-
- self.modal_message_label_wrapper.grid_rowconfigure((0,2),weight=1)
- self.modal_message_label_wrapper.grid_columnconfigure((0,2),weight=1)
-
- self.modal_message_label = CTkLabel(
- self.modal_message_label_wrapper,
- textvariable=self._view_variable.VAR_MESSAGE_CONFIRMATION_MODAL,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.MESSAGE_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.MESSAGE_TEXT_COLOR,
- )
- self.modal_message_label.grid(row=1, column=1)
-
-
-
- self.modal_buttons_container = CTkFrame(self.modal_contents_wrapper, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR)
- self.modal_buttons_container.grid(row=2, column=0, sticky="nsew")
-
- self.modal_buttons_container.grid_rowconfigure((0,2),weight=1)
- self.modal_buttons_container.grid_columnconfigure(0,weight=1)
-
- self.modal_buttons_wrapper = CTkFrame(self.modal_buttons_container, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR)
- self.modal_buttons_wrapper.grid(row=1, column=0, sticky="ew")
-
-
- # Progress bar
- self.progressbar_widget = CTkProgressBar(
- self.modal_contents_wrapper,
- height=8,
- corner_radius=0,
- fg_color="black",
- # fg_color="#4b4c4f",
- progress_color="gray",
- )
- self.progressbar_widget.set(0)
-
-
- if modal_type == "information":
- self.modal_buttons_wrapper.grid_columnconfigure((0,2), weight=1)
-
-
- self.accept_button = CTkFrame(self.modal_buttons_wrapper, corner_radius=self.settings.uism.BUTTONS_CORNER_RADIUS, fg_color=self.settings.ctm.ACCEPT_BUTTON_BG_COLOR, cursor="hand2")
- self.accept_button.grid(row=0, column=1, sticky="ew")
-
-
- self.accept_button.grid_columnconfigure(0, weight=1)
- self.accept_button_label_wrapper = CTkFrame(self.accept_button, corner_radius=0, fg_color=self.settings.ctm.ACCEPT_BUTTON_BG_COLOR)
- self.accept_button_label_wrapper.grid(row=0, column=0, padx=self.settings.uism.BUTTONS_IPADX, pady=self.settings.uism.BUTTONS_IPADY, sticky="ew")
-
- self.accept_button_label_wrapper.grid_columnconfigure((0,2), weight=1)
- self.accept_button_label = CTkLabel(
- self.accept_button_label_wrapper,
- textvariable=self._view_variable.VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.CONFIRMATION_BUTTONS_TEXT_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.CONFIRMATION_BUTTONS_TEXT_COLOR,
- )
- self.accept_button_label.grid(row=0, column=1)
-
-
-
- bindButtonFunctionAndColor(
- target_widgets=[
- self.accept_button,
- self.accept_button_label_wrapper,
- self.accept_button_label,
- ],
- enter_color=settings.ctm.ACCEPT_BUTTON_HOVERED_BG_COLOR,
- leave_color=settings.ctm.ACCEPT_BUTTON_BG_COLOR,
- clicked_color=settings.ctm.ACCEPT_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=lambda _e: callFunctionIfCallable(self._view_variable.CALLBACK_ACCEPTED_CONFIRMATION_MODAL),
- )
-
-
-
-
-
-
- else:
- self.modal_buttons_wrapper.grid_columnconfigure(1, weight=1, minsize=self.settings.uism.BUTTONS_BETWEEN_PADDING)
- self.modal_buttons_wrapper.grid_columnconfigure((0,2), weight=0, uniform="button_wrapper")
-
-
-
-
-
- self.deny_button = CTkFrame(self.modal_buttons_wrapper, corner_radius=self.settings.uism.BUTTONS_CORNER_RADIUS, fg_color=self.settings.ctm.DENY_BUTTON_BG_COLOR, cursor="hand2")
- self.deny_button.grid(row=0, column=0, sticky="ew")
-
-
- self.deny_button.grid_columnconfigure(0, weight=1)
- self.deny_button_label_wrapper = CTkFrame(self.deny_button, corner_radius=0, fg_color=self.settings.ctm.DENY_BUTTON_BG_COLOR)
- self.deny_button_label_wrapper.grid(row=0, column=0, padx=self.settings.uism.BUTTONS_IPADX, pady=self.settings.uism.BUTTONS_IPADY, sticky="ew")
-
- self.deny_button_label_wrapper.grid_columnconfigure((0,2), weight=1)
-
-
- self.deny_button_label_wrapper.grid_columnconfigure(0, weight=1)
- self.deny_button_label = CTkLabel(
- self.deny_button_label_wrapper,
- textvariable=self._view_variable.VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.CONFIRMATION_BUTTONS_TEXT_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.CONFIRMATION_BUTTONS_TEXT_COLOR,
- )
- self.deny_button_label.grid(row=0, column=1)
-
-
-
- bindButtonFunctionAndColor(
- target_widgets=[
- self.deny_button,
- self.deny_button_label_wrapper,
- self.deny_button_label,
- ],
- enter_color=settings.ctm.DENY_BUTTON_HOVERED_BG_COLOR,
- leave_color=settings.ctm.DENY_BUTTON_BG_COLOR,
- clicked_color=settings.ctm.DENY_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=lambda _e: callFunctionIfCallable(self._view_variable.CALLBACK_DENIED_CONFIRMATION_MODAL),
- )
-
-
-
- self.accept_button = CTkFrame(self.modal_buttons_wrapper, corner_radius=self.settings.uism.BUTTONS_CORNER_RADIUS, fg_color=self.settings.ctm.ACCEPT_BUTTON_BG_COLOR, cursor="hand2")
- self.accept_button.grid(row=0, column=2, sticky="ew")
-
-
- self.accept_button.grid_columnconfigure(0, weight=1)
- self.accept_button_label_wrapper = CTkFrame(self.accept_button, corner_radius=0, fg_color=self.settings.ctm.ACCEPT_BUTTON_BG_COLOR)
- self.accept_button_label_wrapper.grid(row=0, column=0, padx=self.settings.uism.BUTTONS_IPADX, pady=self.settings.uism.BUTTONS_IPADY, sticky="ew")
-
- self.accept_button_label_wrapper.grid_columnconfigure((0,2), weight=1)
- self.accept_button_label = CTkLabel(
- self.accept_button_label_wrapper,
- textvariable=self._view_variable.VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.CONFIRMATION_BUTTONS_TEXT_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.CONFIRMATION_BUTTONS_TEXT_COLOR,
- )
- self.accept_button_label.grid(row=0, column=1)
-
-
-
- bindButtonFunctionAndColor(
- target_widgets=[
- self.accept_button,
- self.accept_button_label_wrapper,
- self.accept_button_label,
- ],
- enter_color=settings.ctm.ACCEPT_BUTTON_HOVERED_BG_COLOR,
- leave_color=settings.ctm.ACCEPT_BUTTON_BG_COLOR,
- clicked_color=settings.ctm.ACCEPT_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=lambda _e: callFunctionIfCallable(self._view_variable.CALLBACK_ACCEPTED_CONFIRMATION_MODAL),
- )
-
-
-
- def hide_buttons(self):
- self.modal_buttons_wrapper.grid_remove()
-
-
- def show(self, hide_title_bar:bool=True, close_when_focusout:bool=True):
- self.modal_buttons_wrapper.grid()
-
- if hide_title_bar is False:
- self.overrideredirect(False)
- else:
- self.overrideredirect(True)
-
- self.close_when_focusout = close_when_focusout
- if self.close_when_focusout is True:
- self.BIND_FOCUS_OUT_FUNC_ID = self.bind("", self.focusOutFunction, "+")
- else:
- self._grab_set()
-
-
- self.attributes("-alpha", 0)
- self.deiconify()
- setGeometryToCenterOfTheWidget(
- attach_widget=self.attach_window,
- target_widget=self
- )
- fadeInAnimation(self, steps=5, interval=0.005, max_alpha=1)
- self.lift()
- self.focus_set()
-
-
- def hide(self):
- if self.BIND_FOCUS_OUT_FUNC_ID is not None:
- self.unbind("", self.BIND_FOCUS_OUT_FUNC_ID)
-
- self.withdraw()
- self.grab_release()
-
- def focusOutFunction(self, e):
- if str(e.widget) != ".!_createconfirmationmodal":
- return
- callFunctionIfCallable(self._view_variable.CALLBACK_HIDE_CONFIRMATION_MODAL)
-
-
- def updateDownloadProgress(self, progress:float):
- if self.is_showed_progressbar is False:
- self.progressbar_widget.place(relwidth=0.9, relx=0.5, rely=0.84, anchor="s")
- self.is_showed_progressbar = True
- self.update()
-
- progress_color = generateGradientColor(
- value=progress,
- color_start=[242, 242, 242], # RGB values for #f2f2f2
- color_end=[72, 164, 149], # RGB values for #48a495
- )
- self.progressbar_widget.configure(progress_color=progress_color)
- self.progressbar_widget.set(progress)
- self.update_idletasks()
-
- def _grab_set(self):
- self.grab_set()
diff --git a/vrct_gui/_CreateDropdownMenuWindow.py b/vrct_gui/_CreateDropdownMenuWindow.py
deleted file mode 100644
index d6853b35..00000000
--- a/vrct_gui/_CreateDropdownMenuWindow.py
+++ /dev/null
@@ -1,386 +0,0 @@
-from typing import Union
-from types import SimpleNamespace
-
-from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont
-from time import sleep
-
-from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, getLatestHeight, applyUiScalingAndFixTheBugScrollBar, getLatestWidth, getLongestText, getLongestText_Dict, CustomizedCTkScrollableFrame
-from functools import partial
-
-from utils import isEven, makeEven
-
-class _CreateDropdownMenuWindow(CTkToplevel):
- def __init__(
- self,
- settings,
- view_variable,
-
- window_additional_y_pos,
- window_border_width,
- scrollbar_ipadx,
- scrollbar_width,
- value_ipadx,
- value_ipady,
- value_pady,
- value_font_size,
- dropdown_menu_default_min_width,
-
- window_bg_color,
- window_border_color,
- values_bg_color,
- values_hovered_bg_color,
- values_clicked_bg_color,
- values_text_color,
- ):
-
- super().__init__()
- self.withdraw()
- self.hide = True
-
- self.window_additional_y_pos=window_additional_y_pos
- self.window_border_width=window_border_width
- self.scrollbar_ipadx=scrollbar_ipadx
- self.scrollbar_width=scrollbar_width
- self.value_ipadx=value_ipadx
- self.value_ipady=value_ipady
- self.value_pady=value_pady
- self.value_font_size=value_font_size
- self.dropdown_menu_default_min_width=dropdown_menu_default_min_width
-
- self.window_bg_color=window_bg_color
- self.window_border_color=window_border_color
- self.values_bg_color=values_bg_color
- self.values_hovered_bg_color=values_hovered_bg_color
- self.values_clicked_bg_color=values_clicked_bg_color
- self.values_text_color=values_text_color
-
-
- self.settings = settings
- self.attach_widget = None
- self._view_variable = view_variable
- self.wrapper_widget = None
-
- self.dropdown_menu_widgets = {}
- self.active_dropdown_menu_widget = None
-
-
-
- self.attach_widget_width = None
- self.attach_widget_height = None
- self.attach_widget_x_pos = None
- self.attach_widget_y_pos = None
- self.x_pos = None
- self.y_pos = None
-
- self.init_height = 200
- self.new_height = self.init_height
- self.init_width = 200
- self.new_width = self.init_width
-
- self.init_max_display_length = 8
- self.max_display_length = self.init_max_display_length
-
- self.title("")
- self.overrideredirect(True)
-
- self.wm_attributes("-alpha", 0)
- self.wm_attributes("-toolwindow", True)
-
- self.configure(fg_color=self.window_bg_color)
- self.resizable(width=False, height=False)
-
-
-
- def updateDropdownMenuValues(self, dropdown_menu_widget_id, dropdown_menu_values:Union[dict, list],):
- self.dropdown_menu_widgets[dropdown_menu_widget_id].widget.destroy()
- self.createDropdownMenuBox(
- dropdown_menu_widget_id=dropdown_menu_widget_id,
- dropdown_menu_values=dropdown_menu_values,
- command=self.dropdown_menu_widgets[dropdown_menu_widget_id].command,
- wrapper_widget=self.dropdown_menu_widgets[dropdown_menu_widget_id].wrapper_widget,
- attach_widget=self.dropdown_menu_widgets[dropdown_menu_widget_id].attach_widget,
-
- dropdown_menu_min_width=self.dropdown_menu_widgets[dropdown_menu_widget_id].dropdown_menu_settings.dropdown_menu_min_width,
- dropdown_menu_height=self.dropdown_menu_widgets[dropdown_menu_widget_id].dropdown_menu_settings.dropdown_menu_height,
- max_display_length=self.dropdown_menu_widgets[dropdown_menu_widget_id].dropdown_menu_settings.max_display_length,
- )
-
-
- def createDropdownMenuBox(self, dropdown_menu_widget_id, dropdown_menu_values:Union[dict, list], command, wrapper_widget, attach_widget, dropdown_menu_min_width=None, dropdown_menu_height=None, max_display_length=None):
-
- self.attach_widget = attach_widget
- self.wrapper_widget = wrapper_widget
-
-
- self.new_width = dropdown_menu_min_width if dropdown_menu_min_width is not None else self.dropdown_menu_default_min_width
- self.new_height = dropdown_menu_height if dropdown_menu_height is not None else self.init_height
- self.max_display_length = max_display_length if max_display_length is not None else self.init_max_display_length
-
-
- self.dropdown_menu_container = CTkFrame(self, corner_radius=0, fg_color=self.window_border_color, width=0, height=0)
- self.dropdown_menu_container.grid(row=0, column=0, sticky="nsew")
-
-
- BORDER_WIDTH=self.window_border_width
- self.scroll_frame_container = CustomizedCTkScrollableFrame(
- self.dropdown_menu_container,
- corner_radius=0,
- fg_color=self.window_bg_color,
- width=0,
- height=0,
- border_width=0,
- )
- self.scroll_frame_container.grid(row=0, column=0, padx=BORDER_WIDTH, pady=BORDER_WIDTH, sticky="nsew")
- self.scroll_frame_container.grid_columnconfigure(0, weight=1)
-
-
-
- self._createDropdownMenuValues(dropdown_menu_widget_id, dropdown_menu_values, command)
-
- applyUiScalingAndFixTheBugScrollBar(
- scrollbar_widget=self.scroll_frame_container,
- padx=self.scrollbar_ipadx,
- width=self.scrollbar_width,
- )
-
- geometry_width = int(self.new_width + self.scroll_frame_container._scrollbar.winfo_width() + (BORDER_WIDTH*2) + (self.scrollbar_ipadx[0] + self.scrollbar_ipadx[1]))
- geometry_height = int(self.new_height + (BORDER_WIDTH*2))
-
- self.dropdown_menu_widgets[dropdown_menu_widget_id] = SimpleNamespace()
-
- self.dropdown_menu_widgets[dropdown_menu_widget_id] = SimpleNamespace(
- widget=self.dropdown_menu_container,
- command=command,
- wrapper_widget=wrapper_widget,
- attach_widget=attach_widget,
- dropdown_menu_settings=SimpleNamespace(
- dropdown_menu_min_width=dropdown_menu_min_width,
- dropdown_menu_height=dropdown_menu_height,
- max_display_length=max_display_length,
- ),
- _settings=SimpleNamespace(
- geometry_width=geometry_width,
- geometry_height=geometry_height,
- ),
- )
-
- self.dropdown_menu_container.grid_remove()
-
-
- def _createDropdownMenuValues(self, dropdown_menu_widget_id, dropdown_menu_values:Union[dict, list], command):
- if isinstance(dropdown_menu_values, list):
- longest_text = getLongestText(dropdown_menu_values)
- elif isinstance(dropdown_menu_values, dict):
- longest_text = getLongestText_Dict(dropdown_menu_values)
-
- self.dropdown_menu_values_wrapper = CTkFrame(self.scroll_frame_container, corner_radius=0, fg_color=self.window_bg_color)
- self.dropdown_menu_values_wrapper.grid(row=0, column=0, sticky="nsew")
- self.dropdown_menu_values_wrapper.grid_columnconfigure(0, weight=1)
-
- # for get to the height__________________
- __dropdown_menu_value_wrapper = CTkFrame(self.dropdown_menu_values_wrapper, corner_radius=0, fg_color=self.values_bg_color, width=0, height=0)
- __dropdown_menu_value_wrapper.grid(row=0, column=0, pady=self.value_pady, sticky="nsew")
- setattr(self, f"{dropdown_menu_widget_id}__{0}", __dropdown_menu_value_wrapper)
-
-
- __dropdown_menu_value_wrapper.grid_rowconfigure((0,2), weight=1)
- __label_widget = CTkLabel(
- __dropdown_menu_value_wrapper,
- text=longest_text,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.value_font_size, weight="normal"),
- anchor="w",
- text_color=self.values_text_color,
- )
-
- __label_widget.grid(row=1, column=0, padx=self.value_ipadx, pady=self.value_ipady, sticky="w")
-
- label_height = getLatestHeight(__dropdown_menu_value_wrapper)
- label_width = getLatestWidth(__label_widget)
- label_width += self.scroll_frame_container._scrollbar.winfo_width() + (self.window_border_width*2) + (self.scrollbar_ipadx[0] + self.scrollbar_ipadx[1])
- if label_width > self.new_width:
- additional_width = int(label_width - self.new_width + self.settings.uism.MARGIN_WIDTH)
- self.new_width += additional_width
-
- # for fixing 1px bug
- if isEven(label_height) is False:
- self.value_ipady = (self.value_ipady[0], self.value_ipady[1] - 1)
-
- __dropdown_menu_value_wrapper.destroy()
- # ______________________________________
-
- dropdown_menu_values_length = len(dropdown_menu_values)
- if dropdown_menu_values_length < self.max_display_length:
- self.new_height = int(dropdown_menu_values_length * label_height)
- else:
- self.new_height = int(self.max_display_length * label_height)
-
-
- # for fixing 1px bug
- self.new_height = makeEven(self.new_height)
- self.new_width = makeEven(self.new_width)
- self.scroll_frame_container.configure(width=self.new_width, height=self.new_height)
-
-
-
- IS_LIST_TYPE = False
- if isinstance(dropdown_menu_values, list):
- for_in_values = dropdown_menu_values
- IS_LIST_TYPE = True
- elif isinstance(dropdown_menu_values, dict):
- for_in_values = dropdown_menu_values.keys()
- IS_LIST_TYPE = False
-
- row=0
- for dropdown_menu_value in for_in_values:
- dropdown_menu_value_wrapper = CTkFrame(self.dropdown_menu_values_wrapper, corner_radius=0, fg_color=self.values_bg_color, width=0, height=0, cursor="hand2")
- dropdown_menu_value_wrapper.grid(row=row, column=0, pady=self.value_pady, sticky="nsew")
- setattr(self, f"{dropdown_menu_widget_id}__{row}", dropdown_menu_value_wrapper)
-
-
-
- if IS_LIST_TYPE is True:
- dropdown_menu_value_text = dropdown_menu_value
- else:
- dropdown_menu_value_text = dropdown_menu_values[dropdown_menu_value]
-
- dropdown_menu_value_wrapper.grid_rowconfigure((0,2), weight=1)
- label_widget = CTkLabel(
- dropdown_menu_value_wrapper,
- text=dropdown_menu_value_text,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.value_font_size, weight="normal"),
- anchor="w",
- text_color=self.values_text_color,
- )
-
- label_widget.grid(row=1, column=0, padx=self.value_ipadx, pady=self.value_ipady, sticky="w")
-
-
- bindEnterAndLeaveColor([dropdown_menu_value_wrapper, label_widget], self.values_hovered_bg_color, self.values_bg_color)
- bindButtonPressColor([dropdown_menu_value_wrapper, label_widget], self.values_clicked_bg_color, self.values_bg_color)
-
-
-
- def optimizedCommand(value, _e):
- command(value)
- self._withdraw()
-
- if IS_LIST_TYPE is True:
- callback = partial(optimizedCommand, dropdown_menu_value_text)
- else:
- callback = partial(optimizedCommand, dropdown_menu_value)
-
- bindButtonReleaseFunction([dropdown_menu_value_wrapper, label_widget], callback)
-
- row+=1
-
-
-
- def show(self, dropdown_menu_widget_id):
- if self.hide is False:
- return
- self.wm_attributes("-alpha", 0)
-
-
-
- if self.active_dropdown_menu_widget is not None:
- try:
- self.active_dropdown_menu_widget.grid_remove()
- except:
- pass
-
- target_data = self.dropdown_menu_widgets[dropdown_menu_widget_id]
- self.attach_widget = target_data.attach_widget
-
- target_data.widget.grid()
- self.active_dropdown_menu_widget = target_data.widget
-
- self.geometry("{}x{}".format(target_data._settings.geometry_width, target_data._settings.geometry_height))
-
-
- self.deiconify()
- self._adjustToTargetWidgetGeometry()
- self.BIND_CONFIGURE_FUNC_ID = self.attach_widget.winfo_toplevel().bind("", self._adjustToTargetWidgetGeometry, "+")
- self.BIND_UNMAP_FUNC_ID = self.attach_widget.bind("", self._withdraw, "+")
-
- self.BIND_BUTTON_1_FUNC_ID = self.attach_widget.winfo_toplevel().bind("", self._withdraw, "+")
-
-
- self.hide = False
-
-
-
- for i in range(0,91,10):
- if not self.winfo_exists():
- break
- self.attributes("-alpha", i/100)
- self.update()
- sleep(1/100)
- self.wm_attributes("-alpha", 1)
- self.update()
-
-
-
- def _withdraw(self, e=None):
- self.withdraw()
- try:
- self.attach_widget.winfo_toplevel().unbind("", self.BIND_CONFIGURE_FUNC_ID)
- except Exception:
- pass
- try:
- self.attach_widget.unbind("", self.BIND_UNMAP_FUNC_ID)
- except Exception:
- pass
- try:
- self.attach_widget.winfo_toplevel().unbind("", self.BIND_BUTTON_1_FUNC_ID)
- except Exception:
- pass
- self.hide = True
-
-
- def _adjustToTargetWidgetGeometry(self, e=None):
- if not self.attach_widget.winfo_exists():
- return
- self.attach_widget.update_idletasks()
-
-
-
- self.update()
- if self.attach_widget_x_pos == self.attach_widget.winfo_rootx() and self.attach_widget_y_pos == self.attach_widget.winfo_rooty():
- self.lift()
- return
-
- self.wrapper_widget_y_pos = self.wrapper_widget.winfo_rooty()
- self.wrapper_widget_bottom_y_pos = self.wrapper_widget_y_pos + self.wrapper_widget.winfo_height()
-
- self.attach_widget_width = self.attach_widget.winfo_width()
- self.attach_widget_height = self.attach_widget.winfo_height()
- self.attach_widget_x_pos = self.attach_widget.winfo_rootx()
- self.attach_widget_y_pos = self.attach_widget.winfo_rooty()
-
-
- self.y_pos = int(self.attach_widget_y_pos + self.attach_widget_height + self.window_additional_y_pos)
-
- if self.wrapper_widget_y_pos > self.y_pos or self.y_pos > self.wrapper_widget_bottom_y_pos:
- self.hideTemporarily()
- else:
- if self.winfo_exists():
- self.deiconify()
-
-
- if self.winfo_width() >= self.attach_widget_width:
- self.x_pos = int(self.attach_widget_x_pos - (self.winfo_width() - self.attach_widget_width))
- else:
- self.x_pos = self.attach_widget_x_pos
-
- self.geometry("+{}+{}".format(self.x_pos, self.y_pos))
-
- self.lift()
-
- def hideTemporarily(self):
- self.withdraw()
-
-
diff --git a/vrct_gui/_CreateNotificationWindow.py b/vrct_gui/_CreateNotificationWindow.py
deleted file mode 100644
index e7fa2226..00000000
--- a/vrct_gui/_CreateNotificationWindow.py
+++ /dev/null
@@ -1,186 +0,0 @@
-from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont
-from time import sleep
-
-from .ui_utils import getLatestWidth, getLatestHeight
-from utils import isEven
-
-
-class _CreateNotificationWindow(CTkToplevel):
- def __init__(
- self,
- settings,
- view_variable,
- wrapper_widget,
-
- message_ipadx,
- message_ipady,
- message_font_size,
-
- error_message_bg_color,
- success_message_bg_color,
- message_text_color,
- ):
-
- super().__init__()
- self.withdraw()
- self.hide = True
-
- self.settings = settings
- self.attach_widget = None
- self._view_variable = view_variable
- self.wrapper_widget = wrapper_widget
-
-
- self.message_ipadx = message_ipadx
- self.message_ipady = message_ipady
- self.message_font_size = message_font_size
-
- self.error_message_bg_color = error_message_bg_color
- self.success_message_bg_color = success_message_bg_color
- self.message_text_color = message_text_color
-
-
- self.attach_widget_width = None
- self.attach_widget_height = None
- self.attach_widget_x_pos = None
- self.attach_widget_y_pos = None
- self.x_pos = None
- self.y_pos = None
-
- self.title("")
- self.overrideredirect(True)
-
- self.wm_attributes("-alpha", 0)
- self.wm_attributes("-toolwindow", True)
-
-
- self.grid_rowconfigure(0,weight=1)
- self.grid_columnconfigure(0,weight=1)
-
- self.notification_message_container = CTkFrame(self, corner_radius=0, width=0, height=0)
- self.notification_message_container.grid(row=0, column=0, sticky="nsew")
-
-
- self.notification_message_container_label_wrapper = CTkLabel(
- self.notification_message_container,
- # text=message,
- textvariable=self._view_variable.VAR_ERROR_MESSAGE,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.message_font_size, weight="normal"),
- anchor="w",
- justify="left",
- text_color=self.message_text_color,
- )
- self.notification_message_container_label_wrapper.grid(row=0, column=0, padx=self.message_ipadx, pady=self.message_ipady, sticky="nsew")
-
-
-
-
- def show(self, target_widget, message_type):
- if message_type == "Error":
- self.notification_message_container.configure(fg_color=self.error_message_bg_color)
- elif message_type == "Success":
- self.notification_message_container.configure(fg_color=self.success_message_bg_color)
- else:
- raise ValueError("message_type is not selected")
-
- if self.hide is False:
- return
-
- self.attach_widget = target_widget
-
- self.deiconify()
- self._adjustToTargetWidgetGeometry()
- self.BIND_CONFIGURE_FUNC_ID = self.attach_widget.winfo_toplevel().bind("", self._adjustToTargetWidgetGeometry, "+")
- self.BIND_UNMAP_FUNC_ID = self.attach_widget.bind("", self._withdraw, "+")
-
- self.hide = False
-
- label_width = getLatestWidth(self.notification_message_container_label_wrapper)
- label_height = getLatestHeight(self.notification_message_container_label_wrapper)
-
- # for fixing 1px bug
- if isEven(label_width) is False:
- self.notification_message_container_label_wrapper.grid(padx=(self.message_ipadx[0], self.message_ipadx[1]-1))
- else:
- self.notification_message_container_label_wrapper.grid(padx=self.message_ipadx)
-
- # for fixing 1px bug
- if isEven(label_height) is False:
- self.notification_message_container_label_wrapper.grid(pady=(self.message_ipady[0], self.message_ipady[1]-1))
- else:
- self.notification_message_container_label_wrapper.grid(pady=self.message_ipady)
-
-
- # First show animation
- for i in range(0,101,20):
- if not self.winfo_exists():
- break
- self.attributes("-alpha", i/100)
- self.update()
- sleep(1/100)
-
- sleep(0.1)
-
- # Blink animation
- if message_type == "Error":
- for i in range(0,91,10):
- if not self.winfo_exists():
- break
- self.attributes("-alpha", i/100)
- self.update()
- sleep(1/80)
-
-
- def _withdraw(self, e=None):
- self.withdraw()
- self.attach_widget.winfo_toplevel().unbind("", self.BIND_CONFIGURE_FUNC_ID)
- self.attach_widget.unbind("", self.BIND_UNMAP_FUNC_ID)
- self.hide = True
-
-
-
- def _adjustToTargetWidgetGeometry(self, e=None):
- if not self.attach_widget.winfo_exists():
- return
- self.attach_widget.update_idletasks()
-
-
-
- self.update()
- if self.attach_widget_x_pos == self.attach_widget.winfo_rootx() and self.attach_widget_y_pos == self.attach_widget.winfo_rooty():
- self.lift()
- return
-
- self.wrapper_widget_y_pos = self.wrapper_widget.winfo_rooty()
- self.wrapper_widget_bottom_y_pos = self.wrapper_widget_y_pos + self.wrapper_widget.winfo_height()
-
- self.attach_widget_width = self.attach_widget.winfo_width()
- self.attach_widget_height = self.attach_widget.winfo_height()
- self.attach_widget_x_pos = self.attach_widget.winfo_rootx()
- self.attach_widget_y_pos = self.attach_widget.winfo_rooty()
-
-
- self.y_pos = int(self.attach_widget_y_pos + self.attach_widget_height + 4)
-
- if self.wrapper_widget_y_pos > self.y_pos or self.y_pos > self.wrapper_widget_bottom_y_pos:
- self.hideTemporarily()
- else:
- if self.winfo_exists():
- self.deiconify()
-
-
- if self.winfo_width() >= self.attach_widget_width:
- self.x_pos = int(self.attach_widget_x_pos - (self.winfo_width() - self.attach_widget_width))
- else:
- self.x_pos = self.attach_widget_x_pos
-
- self.geometry("+{}+{}".format(self.x_pos, self.y_pos))
-
- self.lift()
-
- def hideTemporarily(self):
- self.withdraw()
-
-
diff --git a/vrct_gui/_CreateSelectableLanguagesWindow.py b/vrct_gui/_CreateSelectableLanguagesWindow.py
deleted file mode 100644
index 4c5482cd..00000000
--- a/vrct_gui/_CreateSelectableLanguagesWindow.py
+++ /dev/null
@@ -1,190 +0,0 @@
-from functools import partial
-
-from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, applyUiScalingAndFixTheBugScrollBar, CustomizedCTkScrollableFrame
-from utils import callFunctionIfCallable, makeEven
-
-from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont
-
-class _CreateSelectableLanguagesWindow(CTkToplevel):
- def __init__(self, vrct_gui, settings, view_variable):
- super().__init__()
- self.withdraw()
-
- self.attach = vrct_gui.main_bg_container
- self.vrct_gui = vrct_gui
- self.settings = settings
- self._view_variable = view_variable
-
- self.is_created = False
- self.selectable_language_window_type = None
-
-
- self.title("_CreateSelectableLanguagesWindow")
- self.overrideredirect(True)
- self.configure(fg_color=self.settings.ctm.TOP_BG_COLOR)
- self.protocol("WM_DELETE_WINDOW", vrct_gui._closeSelectableLanguagesWindow)
- self.bind("", self.focusOutFunction)
-
-
-
-
- def createContainer(self, selectable_language_window_type):
- self.selectable_language_window_type = selectable_language_window_type
-
- self.attach.update_idletasks()
- self.x_pos = self.attach.winfo_rootx()
- self.y_pos = self.attach.winfo_rooty()
- self.width_new = makeEven(self.attach.winfo_width())
- self.height_new = makeEven(self.attach.winfo_height())
-
-
- self.geometry("{}x{}+{}+{}".format(self.width_new, self.height_new, self.x_pos, self.y_pos))
-
-
-
- if self.is_created is True:
- pass
- else:
- self._createContainer()
-
-
- def callbackSelectableLanguages(self, value, _e):
- language = value["language"]
- country = value["country"]
- callback_value = {
- "language" : language,
- "country" : country,
- }
- set_value = f"{language}\n({country})"
-
- if self.selectable_language_window_type == "your_language":
- callback = self._view_variable.CALLBACK_SELECTED_YOUR_LANGUAGE
- target_variable = self._view_variable.VAR_YOUR_LANGUAGE
- elif self.selectable_language_window_type == "target_language":
- callback = self._view_variable.CALLBACK_SELECTED_TARGET_LANGUAGE
- target_variable = self._view_variable.VAR_TARGET_LANGUAGE
-
- target_variable.set(set_value)
- callFunctionIfCallable(callback, callback_value)
- self.vrct_gui._closeSelectableLanguagesWindow()
-
-
-
-
-
- def _createContainer(self):
- self.grid_rowconfigure(0, minsize=self.settings.uism.TOP_BAR_MIN_HEIGHT)
- self.grid_rowconfigure(1, weight=1)
- self.grid_columnconfigure(0, weight=1)
- self.top_container = CTkFrame(self, corner_radius=0, fg_color=self.settings.ctm.TOP_BG_COLOR, width=0, height=0)
- self.top_container.grid(row=0, column=0, sticky="nsew")
-
-
- self.top_container.grid_rowconfigure((0,2), weight=1)
- self.top_container.grid_columnconfigure(1, weight=1)
- self.go_back_button_container = CTkFrame(self.top_container, corner_radius=0, fg_color=self.settings.ctm.GO_BACK_BUTTON_BG_COLOR, width=0, height=0, cursor="hand2")
- self.go_back_button_container.grid(row=1, column=0)
-
- self.go_back_button_label = CTkLabel(
- self.go_back_button_container,
- textvariable=self._view_variable.VAR_GO_BACK_LABEL_SELECTABLE_LANGUAGE,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.GO_BACK_BUTTON_LABEL_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.BASIC_TEXT_COLOR,
- )
- self.go_back_button_label.grid(row=0, column=0, padx=self.settings.uism.GO_BACK_BUTTON_IPADX, pady=self.settings.uism.GO_BACK_BUTTON_IPADY)
-
-
- bindEnterAndLeaveColor([self.go_back_button_container, self.go_back_button_label], self.settings.ctm.GO_BACK_BUTTON_BG_HOVERED_COLOR, self.settings.ctm.GO_BACK_BUTTON_BG_COLOR)
- bindButtonPressColor([self.go_back_button_container, self.go_back_button_label], self.settings.ctm.GO_BACK_BUTTON_BG_CLICKED_COLOR, self.settings.ctm.GO_BACK_BUTTON_BG_COLOR)
-
-
- bindButtonReleaseFunction([self.go_back_button_container, self.go_back_button_label], lambda _e: self.vrct_gui._closeSelectableLanguagesWindow())
-
-
-
- self.title_container = CTkFrame(self.top_container, corner_radius=0, fg_color=self.settings.ctm.TOP_BG_COLOR, width=0, height=0)
- self.title_container.grid(row=1, column=1, sticky="nsew")
-
- self.title_container.grid_columnconfigure((0,2), weight=1)
- self.title_container.grid_rowconfigure((0,2), weight=1)
- self.title_label = CTkLabel(
- self.title_container,
- textvariable=self._view_variable.VAR_TITLE_LABEL_SELECTABLE_LANGUAGE,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.TITLE_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.TITLE_TEXT_COLOR,
- )
- self.title_label.grid(row=1, column=1)
-
-
-
-
- self.scroll_frame_container = CustomizedCTkScrollableFrame(self, corner_radius=0, fg_color=self.settings.ctm.MAIN_BG_COLOR, width=self.width_new, height=self.height_new)
- self.scroll_frame_container.grid(row=1, column=0, sticky="nsew")
-
- applyUiScalingAndFixTheBugScrollBar(
- scrollbar_widget=self.scroll_frame_container,
- padx=self.settings.uism.SCROLLBAR_IPADX,
- width=self.settings.uism.SCROLLBAR_WIDTH,
- )
-
-
- self.container = CTkFrame(self.scroll_frame_container, corner_radius=0, fg_color=self.settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- self.container.grid(row=0, column=0, sticky="nsew")
-
-
-
- max_row = int(len(self._view_variable.LIST_SELECTABLE_LANGUAGES)/3) + 1
- max_row+=1
- row=0
- column=0
- for selectable_language_dict in self._view_variable.LIST_SELECTABLE_LANGUAGES:
-
- self.wrapper = CTkFrame(self.container, corner_radius=0, fg_color=self.settings.ctm.LANGUAGE_BUTTON_BG_COLOR, width=0, height=0, cursor="hand2")
- self.wrapper.grid(row=row, column=column, sticky="nsew")
- setattr(self, f"{row}_{column}", self.wrapper)
-
-
-
- self.wrapper.grid_rowconfigure((0,2), weight=1)
- label_widget = CTkLabel(
- self.wrapper,
- text=f"{selectable_language_dict['language']} ({selectable_language_dict['country']})",
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.VALUES_TEXT_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.BASIC_TEXT_COLOR,
- )
-
- label_widget.grid(row=1, column=0, padx=self.settings.uism.VALUES_TEXT_IPADX, pady=self.settings.uism.VALUES_TEXT_IPADY)
-
-
-
- bindEnterAndLeaveColor([self.wrapper, label_widget], self.settings.ctm.LANGUAGE_BUTTON_BG_HOVERED_COLOR, self.settings.ctm.LANGUAGE_BUTTON_BG_COLOR)
- bindButtonPressColor([self.wrapper, label_widget], self.settings.ctm.LANGUAGE_BUTTON_BG_CLICKED_COLOR, self.settings.ctm.LANGUAGE_BUTTON_BG_COLOR)
-
-
-
- callback = partial(self.callbackSelectableLanguages, selectable_language_dict)
- bindButtonReleaseFunction([self.wrapper, label_widget], callback)
-
- if row == max_row:
- row=0
- column+=1
- else:
- row+=1
-
-
- self.is_created = True
-
-
- def focusOutFunction(self, e):
- if str(e.widget) != ".!_createselectablelanguageswindow":
- return
- self.vrct_gui._closeSelectableLanguagesWindow()
\ No newline at end of file
diff --git a/vrct_gui/_CreateWindowCover.py b/vrct_gui/_CreateWindowCover.py
deleted file mode 100644
index 2b88a3d8..00000000
--- a/vrct_gui/_CreateWindowCover.py
+++ /dev/null
@@ -1,80 +0,0 @@
-from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont
-
-from .ui_utils import fadeInAnimation
-from utils import makeEven
-
-class _CreateWindowCover(CTkToplevel):
- def __init__(self, attach_window, settings, view_variable):
- super().__init__()
- self.withdraw()
-
- self.BIND_CONFIGURE_ADJUSTED_GEOMETRY_FUNC_ID=None
- self.BIND_FOCUS_IN_FUNC_ID=None
-
- self.attach_window = attach_window
- self.settings = settings
- self._view_variable = view_variable
-
- self.title("")
- self.overrideredirect(True)
- self.wm_attributes("-toolwindow", True)
- self.configure(fg_color=self.settings.ctm.BG_COLOR)
- self.protocol("WM_DELETE_WINDOW", lambda: self.withdraw())
-
-
- self.grid_rowconfigure(0,weight=1)
- self.grid_columnconfigure(0,weight=1)
- self.cover_container = CTkFrame(self, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR, width=0, height=0)
- self.cover_container.grid(row=0, column=0, sticky="nsew")
-
-
- self.cover_container_label_wrapper = CTkLabel(
- self.cover_container,
- textvariable=self._view_variable.VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.TEXT_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.TEXT_COLOR,
- )
- self.cover_container_label_wrapper.place(relx=0.5, rely=0.5, anchor="center")
-
-
- def show(self, bind_focusin=None):
- self.BIND_CONFIGURE_ADJUSTED_GEOMETRY_FUNC_ID = self.attach_window.bind("", self._adjustToMainWindowGeometry, "+")
- if bind_focusin is not None:
- self.BIND_FOCUS_IN_FUNC_ID = self.bind("", lambda _e: bind_focusin(), "+")
- else:
- self.BIND_FOCUS_IN_FUNC_ID = None
-
-
- self.attributes("-alpha", 0)
- self.deiconify()
- self.attach_window.update_idletasks()
- self.x_pos = self.attach_window.winfo_rootx()
- self.y_pos = self.attach_window.winfo_rooty()
- self.width_new = self.attach_window.winfo_width()
- self.height_new = self.attach_window.winfo_height()
- self.geometry("{}x{}+{}+{}".format(self.width_new, self.height_new, self.x_pos, self.y_pos))
- fadeInAnimation(self, steps=5, interval=0.005, max_alpha=0.8)
-
-
-
- def hide(self):
- self.attach_window.unbind("", self.BIND_CONFIGURE_ADJUSTED_GEOMETRY_FUNC_ID)
- if self.BIND_FOCUS_IN_FUNC_ID is not None:
- self.unbind("", self.BIND_FOCUS_IN_FUNC_ID)
-
- self.withdraw()
-
-
-
- def _adjustToMainWindowGeometry(self, e=None):
- self.attach_window.update_idletasks()
- x_pos = self.attach_window.winfo_rootx()
- y_pos = self.attach_window.winfo_rooty()
- width_new = makeEven(self.attach_window.winfo_width())
- height_new = makeEven(self.attach_window.winfo_height())
- self.geometry("{}x{}+{}+{}".format(width_new, height_new, x_pos, y_pos))
-
- self.lift()
\ No newline at end of file
diff --git a/vrct_gui/_PrintToTextbox.py b/vrct_gui/_PrintToTextbox.py
deleted file mode 100644
index 0c8597c3..00000000
--- a/vrct_gui/_PrintToTextbox.py
+++ /dev/null
@@ -1,170 +0,0 @@
-from datetime import datetime
-from customtkinter import CTkFont
-from .ui_utils import calculateUiSize
-
-class _PrintToTextbox():
- def __init__(
- self,
- vrct_gui,
- settings,
- init_scaling:float,
- ):
-
- self.vrct_gui = vrct_gui
- self.settings = settings
- self.init_scaling = init_scaling
-
- self._DEFAULT_TEXTBOX_FIRST_INSERT_SPACING = self.settings.uism.TEXTBOX_FIRST_INSERT_SPACING
- self._DEFAULT_TEXTBOX_FONT_SIZE__LABEL = self.settings.uism.TEXTBOX_FONT_SIZE__LABEL
- self._DEFAULT_TEXTBOX_FONT_SIZE__TIMESTAMP = self.settings.uism.TEXTBOX_FONT_SIZE__TIMESTAMP
- self._DEFAULT_TEXTBOX_FONT_SIZE__SYSTEM_TEXT_FONT = self.settings.uism.TEXTBOX_FONT_SIZE__SYSTEM_TEXT_FONT
- self._DEFAULT_TEXTBOX_FONT_SIZE__SECONDARY_TEXT_FONT = self.settings.uism.TEXTBOX_FONT_SIZE__SECONDARY_TEXT_FONT
- self._DEFAULT_TEXTBOX_FONT_SIZE__MAIN_TEXT_FONT = self.settings.uism.TEXTBOX_FONT_SIZE__MAIN_TEXT_FONT
-
-
-
- self.textbox_first_insert_spacing = None
- self.textbox_font_size__label = None
- self.textbox_font_size__timestamp = None
- self.textbox_font_size__system_text_font = None
- self.textbox_font_size__secondary_text_font = None
- self.textbox_font_size__main_text_font = None
-
-
- # self.all_textbox_widgets = [self.vrct_gui.textbox_all, self.vrct_gui.textbox_system, self.vrct_gui.textbox_sent, self.vrct_gui.textbox_received]
- self.all_textbox_widgets = [self.vrct_gui.textbox_all]
-
-
- self.setTagsSettings(self.init_scaling)
-
-
- def printToTextbox(self, target_type, original_message=None, translated_message=None, to_print_to_textbox_all:bool=True):
- # [Deprecated] Print to textbox to only all-tab. sent received system tabs are deprecated.
- # self._printEachTextbox(
- # target_textbox=self._getTargetTextboxWidget(target_type),
- # print_type=target_type,
- # original_message=original_message,
- # translated_message=translated_message,
- # )
-
- # To automatically print the same log to the textbox_all widget as well.
- # if to_print_to_textbox_all is True:
- self._printEachTextbox(
- target_textbox=self._getTargetTextboxWidget("ALL"),
- print_type=target_type,
- original_message=original_message,
- translated_message=translated_message,
- )
-
- def setTagsSettings(self, custom_font_size_scale:float=1.0):
- # Calculate Textbox's ui size by default size * textbox_ui_scale
- self.textbox_first_insert_spacing = calculateUiSize(self._DEFAULT_TEXTBOX_FIRST_INSERT_SPACING, custom_font_size_scale)
- self.textbox_font_size__label = calculateUiSize(self._DEFAULT_TEXTBOX_FONT_SIZE__LABEL, custom_font_size_scale)
- self.textbox_font_size__timestamp = calculateUiSize(self._DEFAULT_TEXTBOX_FONT_SIZE__TIMESTAMP, custom_font_size_scale)
- self.textbox_font_size__system_text_font = calculateUiSize(self._DEFAULT_TEXTBOX_FONT_SIZE__SYSTEM_TEXT_FONT, custom_font_size_scale)
- self.textbox_font_size__secondary_text_font = calculateUiSize(self._DEFAULT_TEXTBOX_FONT_SIZE__SECONDARY_TEXT_FONT, custom_font_size_scale)
- self.textbox_font_size__main_text_font = calculateUiSize(self._DEFAULT_TEXTBOX_FONT_SIZE__MAIN_TEXT_FONT, custom_font_size_scale)
-
- for each_textbox_widget in self.all_textbox_widgets:
- self._setTagsSettings(target_textbox=each_textbox_widget)
- each_textbox_widget.see("end")
-
-
-
- def _setTagsSettings(self, target_textbox):
- target_textbox.tag_config("JUSTIFY_CENTER", justify="center")
- target_textbox.tag_config("JUSTIFY_RIGHT", justify="right")
- target_textbox.tag_config("JUSTIFY_LEFT", justify="left")
-
- # common tag settings
- # target_textbox._textbox.tag_configure("START", spacing1=16)
- target_textbox.tag_config("FIRST_INSERT_SPACING", spacing1=self.textbox_first_insert_spacing)
- target_textbox._textbox.tag_configure("LABEL", font=CTkFont(family=self.settings.FONT_FAMILY, size=self.textbox_font_size__label, weight="normal"))
- target_textbox._textbox.tag_configure("TIMESTAMP", font=CTkFont(family=self.settings.FONT_FAMILY, size=self.textbox_font_size__timestamp, weight="normal"), foreground=self.settings.ctm.TEXTBOX_TIMESTAMP_TEXT_COLOR)
- target_textbox._textbox.tag_configure("SECONDARY_TEXT_FONT", font=CTkFont(family=self.settings.FONT_FAMILY, size=self.textbox_font_size__secondary_text_font, weight="normal"))
- target_textbox._textbox.tag_configure("MAIN_TEXT_FONT", font=CTkFont(family=self.settings.FONT_FAMILY, size=self.textbox_font_size__main_text_font, weight="normal"))
-
- # System Tag Settings
- target_textbox.tag_config("SYSTEM_TAG", foreground=self.settings.ctm.TEXTBOX_SYSTEM_TAG_TEXT_COLOR)
- target_textbox.tag_config("SYSTEM_TEXT", foreground=self.settings.ctm.TEXTBOX_TEXT_SUB_COLOR)
- target_textbox._textbox.tag_configure("SYSTEM_TEXT_FONT", font=CTkFont(family=self.settings.FONT_FAMILY, size=self.textbox_font_size__system_text_font, weight="normal"))
-
- # Sent Tag Settings
- target_textbox.tag_config("SENT_TAG", foreground=self.settings.ctm.TEXTBOX_SENT_TAG_TEXT_COLOR)
- target_textbox.tag_config("SENT_TEXT", foreground=self.settings.ctm.TEXTBOX_TEXT_COLOR)
- target_textbox.tag_config("SENT_SUB_TEXT", foreground=self.settings.ctm.TEXTBOX_TEXT_SUB_COLOR)
-
- # Received Tag Settings
- target_textbox.tag_config("RECEIVED_TAG", foreground=self.settings.ctm.TEXTBOX_RECEIVED_TAG_TEXT_COLOR)
- target_textbox.tag_config("RECEIVED_TEXT", foreground=self.settings.ctm.TEXTBOX_TEXT_COLOR)
- target_textbox.tag_config("RECEIVED_SUB_TEXT", foreground=self.settings.ctm.TEXTBOX_TEXT_SUB_COLOR)
-
-
- def _printEachTextbox(
- self,
- target_textbox,
- print_type,
- original_message,
- translated_message,
- ):
- now_raw_data = datetime.now()
- now_hm = now_raw_data.strftime("%H:%M")
-
- is_only_one_message = True if original_message is None or translated_message is None or translated_message == "" else False
-
- FAKE_MARGIN = " "
- # insert
- target_textbox.configure(state="normal")
- target_textbox.insert("end", "\n")
- match (print_type):
- case "SYSTEM":
- target_textbox.insert("end", "System", ("SYSTEM_TAG", "FIRST_INSERT_SPACING", "JUSTIFY_CENTER", "LABEL"))
- target_textbox.insert("end", FAKE_MARGIN+original_message+FAKE_MARGIN, ("SYSTEM_TEXT", "SYSTEM_TEXT_FONT", "JUSTIFY_CENTER"))
- target_textbox.insert("end", now_hm, ("TIMESTAMP", "JUSTIFY_CENTER"))
-
- case "SENT":
- target_textbox.insert("end", now_hm, ("TIMESTAMP", "FIRST_INSERT_SPACING", "JUSTIFY_RIGHT"))
- target_textbox.insert("end", FAKE_MARGIN+"Sent", ("SENT_TAG", "LABEL"))
- target_textbox.insert("end", "\n")
- if is_only_one_message is False:
- target_textbox.insert("end", original_message, ("SENT_SUB_TEXT", "SECONDARY_TEXT_FONT", "JUSTIFY_RIGHT"))
- target_textbox.insert("end", "\n")
- target_textbox.insert("end", translated_message, ("SENT_TEXT", "MAIN_TEXT_FONT", "JUSTIFY_RIGHT"))
- else:
- target_textbox.insert("end", original_message, ("SENT_TEXT", "MAIN_TEXT_FONT", "JUSTIFY_RIGHT"))
-
- case "RECEIVED":
- target_textbox.insert("end", "Received", ("RECEIVED_TAG", "FIRST_INSERT_SPACING", "JUSTIFY_LEFT", "LABEL"))
- target_textbox.insert("end", FAKE_MARGIN+now_hm, ("TIMESTAMP"))
- if is_only_one_message is False:
- target_textbox.insert("end", "\n")
- target_textbox.insert("end", original_message, ("RECEIVED_SUB_TEXT", "SECONDARY_TEXT_FONT"))
- target_textbox.insert("end", "\n")
- target_textbox.insert("end", translated_message, ("RECEIVED_TEXT", "MAIN_TEXT_FONT", "JUSTIFY_LEFT"))
- else:
- target_textbox.insert("end", "\n")
- target_textbox.insert("end", original_message, ("RECEIVED_TEXT", "MAIN_TEXT_FONT", "JUSTIFY_LEFT"))
-
- target_textbox.configure(state="disabled")
- target_textbox.see("end")
-
-
-
-
-
-
-
- def _getTargetTextboxWidget(self, target_type):
- match (target_type):
- case "ALL":
- target_textbox = self.vrct_gui.textbox_all
- # case "SYSTEM":
- # target_textbox = self.vrct_gui.textbox_system
- # case "SENT":
- # target_textbox = self.vrct_gui.textbox_sent
- # case "RECEIVED":
- # target_textbox = self.vrct_gui.textbox_received
- case (_):
- raise ValueError(f"No matching case for target_type: {target_type}")
-
- return target_textbox
\ No newline at end of file
diff --git a/vrct_gui/__init__.py b/vrct_gui/__init__.py
deleted file mode 100644
index 5c2e8cca..00000000
--- a/vrct_gui/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .vrct_gui import vrct_gui
\ No newline at end of file
diff --git a/vrct_gui/_changeConfigWindowWidgetsStatus.py b/vrct_gui/_changeConfigWindowWidgetsStatus.py
deleted file mode 100644
index 8f3b6b80..00000000
--- a/vrct_gui/_changeConfigWindowWidgetsStatus.py
+++ /dev/null
@@ -1,97 +0,0 @@
-from customtkinter import CTkImage
-
-def _changeConfigWindowWidgetsStatus(config_window, settings, view_variable, status, target_names):
- # if target_names == "All":
- # target_names = []
-
-
- def disableLabelsWidgets(target_widget):
- target_widget.label_widget.configure(text_color=settings.ctm.LABELS_TEXT_DISABLED_COLOR)
- if target_widget.desc_widget is not None:
- target_widget.desc_widget.configure(text_color=settings.ctm.LABELS_TEXT_DISABLED_COLOR)
-
- def normalLabelsWidgets(target_widget):
- target_widget.label_widget.configure(text_color=settings.ctm.LABELS_TEXT_COLOR)
- if target_widget.desc_widget is not None:
- target_widget.desc_widget.configure(text_color=settings.ctm.LABELS_DESC_TEXT_COLOR)
-
-
- def disableOptionmenuWidget(target_widget):
- target_widget.optionmenu_label_widget.configure(text_color=settings.ctm.LABELS_TEXT_DISABLED_COLOR)
- target_widget.optionmenu_img_widget.configure(image=CTkImage(settings.image_file.ARROW_LEFT_DISABLED.rotate(90), size=settings.uism.SB__OPTIONMENU_IMG_SIZE))
- target_widget.optionmenu_box.unbindFunction()
- target_widget.optionmenu_box.configure(cursor="")
-
- def normalOptionmenuWidget(target_widget):
- target_widget.optionmenu_label_widget.configure(text_color=settings.ctm.LABELS_TEXT_COLOR)
- target_widget.optionmenu_img_widget.configure(image=CTkImage(settings.image_file.ARROW_LEFT.rotate(90), size=settings.uism.SB__OPTIONMENU_IMG_SIZE))
- target_widget.optionmenu_box.bindFunction()
- target_widget.optionmenu_box.configure(cursor="hand2")
-
-
- for target_name in target_names:
- match target_name:
- case "sb__optionmenu_mic_host":
- if status == "disabled":
- target_widget = config_window.sb__widgets["sb__optionmenu_mic_host"]
- disableLabelsWidgets(target_widget)
- disableOptionmenuWidget(target_widget)
-
- case "sb__optionmenu_mic_device":
- if status == "disabled":
- target_widget = config_window.sb__widgets["sb__optionmenu_mic_device"]
- disableLabelsWidgets(target_widget)
- disableOptionmenuWidget(target_widget)
-
- case "sb__optionmenu_speaker_device":
- if status == "disabled":
- target_widget = config_window.sb__widgets["sb__optionmenu_speaker_device"]
- disableLabelsWidgets(target_widget)
- disableOptionmenuWidget(target_widget)
-
- case "sb__optionmenu_appearance_theme":
- if status == "disabled":
- target_widget = config_window.sb__widgets["sb__optionmenu_appearance_theme"]
- disableLabelsWidgets(target_widget)
- disableOptionmenuWidget(target_widget)
-
- case "sb__optionmenu_ctranslate2_weight_type":
- target_widget = config_window.sb__widgets["sb__optionmenu_ctranslate2_weight_type"]
- if status == "disabled":
- disableOptionmenuWidget(target_widget)
- elif status == "normal":
- normalOptionmenuWidget(target_widget)
-
-
- case "sb__switch_use_translation_feature":
- target_widget = config_window.sb__widgets["sb__switch_use_translation_feature"]
- if status == "disabled":
- target_widget.switch_box.configure(
- state="disabled",
- fg_color=settings.ctm.SB__SWITCH_BOX_BG_DISABLED_COLOR,
- progress_color=settings.ctm.SB__SWITCH_BOX_ACTIVE_BG_DISABLED_COLOR,
- button_color=settings.ctm.SB__SWITCH_BOX_BUTTON_DISABLED_COLOR,
- )
- elif status == "normal":
- target_widget.switch_box.configure(
- state="normal",
- fg_color=settings.ctm.SB__SWITCH_BOX_BG_COLOR,
- progress_color=settings.ctm.SB__SWITCH_BOX_ACTIVE_BG_COLOR,
- button_color=settings.ctm.SB__SWITCH_BOX_BUTTON_COLOR,
- )
-
- case "sb__checkbox_enable_send_received_message_to_vrc":
- if status == "disabled":
- target_widget = config_window.sb__widgets["sb__checkbox_enable_send_received_message_to_vrc"]
- disableLabelsWidgets(target_widget)
- target_widget.checkbox.configure(
- state="disabled",
- border_color=settings.ctm.SB__CHECKBOX_BORDER_DISABLED_COLOR
- )
-
- case _:
- raise ValueError(f"No matching case for target_name: {target_name}")
-
-
-
- config_window.update()
\ No newline at end of file
diff --git a/vrct_gui/_changeMainWindowWidgetsStatus.py b/vrct_gui/_changeMainWindowWidgetsStatus.py
deleted file mode 100644
index 3b6eaf74..00000000
--- a/vrct_gui/_changeMainWindowWidgetsStatus.py
+++ /dev/null
@@ -1,170 +0,0 @@
-from customtkinter import CTkImage
-lock_state_list=[]
-def _changeMainWindowWidgetsStatus(vrct_gui, settings, view_variable, status, target_names:list, to_lock_state:bool=False, release_locked_state:bool=False):
- global lock_state_list
- if target_names == "All":
- target_names = ["translation_switch", "transcription_send_switch", "transcription_receive_switch", "foreground_switch", "quick_language_settings", "config_button", "minimize_sidebar_button", "entry_message_box", "send_message_button"]
-
- if release_locked_state is True:
- for item in target_names:
- if item in lock_state_list:
- lock_state_list.remove(item)
-
- for item in lock_state_list:
- if item in target_names:
- target_names.remove(item)
-
-
- def update_switch_status(
- widget_frame,
- widget_label,
- widget_switch_box,
- widget_selected_mark,
- widget_compact_mode_icon,
- icon_name,
- disabled_icon_name,
- ):
-
- if status == "disabled":
- widget_frame.configure(cursor="")
- widget_label.configure(text_color=settings.ctm.SF__TEXT_DISABLED_COLOR)
- widget_switch_box.configure(state="disabled", progress_color=settings.ctm.SF__SWITCH_BOX_DISABLE_BG_COLOR, button_color=settings.ctm.SF__SWITCH_BOX_BUTTON_DISABLED_COLOR)
- widget_selected_mark.configure(fg_color=settings.ctm.SF__SELECTED_MARK_DISABLE_BG_COLOR)
- icon_file = disabled_icon_name
- elif status == "normal":
- widget_frame.configure(cursor="hand2")
- widget_label.configure(text_color=settings.ctm.LABELS_TEXT_COLOR)
- widget_switch_box.configure(state="normal", progress_color=settings.ctm.SF__SWITCH_BOX_ACTIVE_BG_COLOR, button_color=settings.ctm.SF__SWITCH_BOX_BUTTON_COLOR)
- widget_selected_mark.configure(fg_color=settings.ctm.SF__SELECTED_MARK_ACTIVE_BG_COLOR)
- icon_file = icon_name
-
- image = CTkImage(icon_file, size=settings.uism.SF__COMPACT_MODE_IMAGE_SIZE)
- widget_compact_mode_icon.configure(image=image)
-
-
-
-
- for target_name in target_names:
- match target_name:
- case "translation_switch":
- update_switch_status(
- widget_frame=vrct_gui.translation_frame,
- widget_label=vrct_gui.label_translation,
- widget_switch_box=vrct_gui.translation_switch_box,
- widget_selected_mark=vrct_gui.translation_selected_mark,
- widget_compact_mode_icon=vrct_gui.translation_compact_mode_icon,
- icon_name=settings.image_file.TRANSLATION_ICON,
- disabled_icon_name=settings.image_file.TRANSLATION_ICON_DISABLED
- )
- case "transcription_send_switch":
- update_switch_status(
- widget_frame=vrct_gui.transcription_send_frame,
- widget_label=vrct_gui.label_transcription_send,
- widget_switch_box=vrct_gui.transcription_send_switch_box,
- widget_selected_mark=vrct_gui.transcription_send_selected_mark,
- widget_compact_mode_icon=vrct_gui.transcription_send_compact_mode_icon,
- icon_name=settings.image_file.MIC_ICON,
- disabled_icon_name=settings.image_file.MIC_ICON_DISABLED
- )
- case "transcription_receive_switch":
- update_switch_status(
- widget_frame=vrct_gui.transcription_receive_frame,
- widget_label=vrct_gui.label_transcription_receive,
- widget_switch_box=vrct_gui.transcription_receive_switch_box,
- widget_selected_mark=vrct_gui.transcription_receive_selected_mark,
- widget_compact_mode_icon=vrct_gui.transcription_receive_compact_mode_icon,
- icon_name=settings.image_file.HEADPHONES_ICON,
- disabled_icon_name=settings.image_file.HEADPHONES_ICON_DISABLED
- )
- case "foreground_switch":
- update_switch_status(
- widget_frame=vrct_gui.foreground_frame,
- widget_label=vrct_gui.label_foreground,
- widget_switch_box=vrct_gui.foreground_switch_box,
- widget_selected_mark=vrct_gui.foreground_selected_mark,
- widget_compact_mode_icon=vrct_gui.foreground_compact_mode_icon,
- icon_name=settings.image_file.FOREGROUND_ICON,
- disabled_icon_name=settings.image_file.FOREGROUND_ICON_DISABLED
- )
-
-
-
-
-
-
- case "quick_language_settings":
- if status == "disabled":
- vrct_gui.sls__container_title.configure(text_color=settings.ctm.SF__TEXT_DISABLED_COLOR)
- vrct_gui.sls__title_text_your_language.configure(text_color=settings.ctm.SF__TEXT_DISABLED_COLOR)
- vrct_gui.sls__title_text_target_language.configure(text_color=settings.ctm.SF__TEXT_DISABLED_COLOR)
- if view_variable.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE is False:
- vrct_gui.current_active_preset_tab.children["!ctklabel"].configure(text_color=settings.ctm.SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR_PASSIVE)
-
-
- elif status == "normal":
- vrct_gui.sls__container_title.configure(text_color=settings.ctm.LABELS_TEXT_COLOR)
- vrct_gui.sls__title_text_your_language.configure(text_color=settings.ctm.LABELS_TEXT_COLOR)
- vrct_gui.sls__title_text_target_language.configure(text_color=settings.ctm.LABELS_TEXT_COLOR)
- if view_variable.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE is False:
- vrct_gui.current_active_preset_tab.children["!ctklabel"].configure(text_color=settings.ctm.SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR)
- vrct_gui.current_active_preset_tab.children["!ctklabel"].configure(text_color=settings.ctm.SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR)
-
-
-
- case "config_button":
- if status == "disabled":
- vrct_gui.sidebar_config_button_wrapper.configure(cursor="")
- vrct_gui.sidebar_config_button.configure(
- image=CTkImage(settings.image_file.CONFIGURATION_ICON_DISABLED, size=settings.uism.SF__COMPACT_MODE_IMAGE_SIZE),
- )
- elif status == "normal":
- vrct_gui.sidebar_config_button_wrapper.configure(cursor="hand2")
- vrct_gui.sidebar_config_button.configure(
- image=CTkImage(settings.image_file.CONFIGURATION_ICON, size=settings.uism.SF__COMPACT_MODE_IMAGE_SIZE),
- )
-
-
- case "minimize_sidebar_button":
- MINIMIZE_SIDEBAR_IMAGE_SIZE = vrct_gui.minimize_sidebar_button__for_opening.cget("image").cget("size")
- if status == "disabled":
- vrct_gui.minimize_sidebar_button_container__for_opening.configure(cursor="")
- vrct_gui.minimize_sidebar_button_container__for_closing.configure(cursor="")
-
- image_file__for_opening = CTkImage((settings.image_file.ARROW_LEFT_DISABLED).rotate(180), size=MINIMIZE_SIDEBAR_IMAGE_SIZE)
- image_file__for_closing = CTkImage((settings.image_file.ARROW_LEFT_DISABLED), size=MINIMIZE_SIDEBAR_IMAGE_SIZE)
-
- elif status == "normal":
- vrct_gui.minimize_sidebar_button_container__for_opening.configure(cursor="hand2")
- vrct_gui.minimize_sidebar_button_container__for_closing.configure(cursor="hand2")
-
- image_file__for_opening = CTkImage((settings.image_file.ARROW_LEFT).rotate(180), size=MINIMIZE_SIDEBAR_IMAGE_SIZE)
- image_file__for_closing = CTkImage((settings.image_file.ARROW_LEFT), size=MINIMIZE_SIDEBAR_IMAGE_SIZE)
- vrct_gui.minimize_sidebar_button__for_opening.configure(image=image_file__for_opening)
- vrct_gui.minimize_sidebar_button__for_closing.configure(image=image_file__for_closing)
-
-
- case "entry_message_box":
- if status == "disabled":
- vrct_gui.entry_message_box.configure(state="disabled", text_color=settings.ctm.TEXTBOX_ENTRY_TEXT_DISABLED_COLOR)
- view_variable.IS_ENTRY_MESSAGE_BOX_DISABLED = True
- elif status == "normal":
- vrct_gui.entry_message_box.configure(state="normal", text_color=settings.ctm.TEXTBOX_ENTRY_TEXT_COLOR)
- view_variable.IS_ENTRY_MESSAGE_BOX_DISABLED = False
-
-
- case "send_message_button":
- if status == "disabled":
- vrct_gui.main_send_message_button__disabled.grid()
- elif status == "normal":
- vrct_gui.main_send_message_button__disabled.grid_remove()
-
- case _:
- raise ValueError(f"No matching case for target_name: {target_name}")
-
-
- if to_lock_state is True:
- for item in target_names:
- if item not in lock_state_list:
- lock_state_list.append(item)
-
- vrct_gui.update()
\ No newline at end of file
diff --git a/vrct_gui/config_window/ConfigWindow.py b/vrct_gui/config_window/ConfigWindow.py
deleted file mode 100644
index 42272110..00000000
--- a/vrct_gui/config_window/ConfigWindow.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from .widgets import createConfigWindowTitle, createSideMenuAndSettingsBoxContainers, createSettingBoxTopBar
-
-
-from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont
-
-from ..ui_utils import getImagePath, getLatestWidth
-from utils import isEven
-
-class ConfigWindow(CTkToplevel):
- def __init__(self, vrct_gui, settings, view_variable):
- super().__init__()
- self.withdraw()
-
- self.settings = settings
- self._view_variable = view_variable
-
- # configure window
- self.after(200, lambda: self.iconbitmap(getImagePath("vrct_logo_mark_black.ico")))
- self.geometry(f"{self.settings.uism.DEFAULT_WIDTH}x{self.settings.uism.DEFAULT_HEIGHT}")
-
-
- self.configure(fg_color=self.settings.ctm.MAIN_BG_COLOR)
- self.protocol("WM_DELETE_WINDOW", self._view_variable.CALLBACK_CLICKED_CLOSE_CONFIG_WINDOW_BUTTON)
-
-
- self.title(self._view_variable.VAR_CONFIG_WINDOW_TITLE.get())
- # When the configuration window's compact mode is turned on, it will call `grid_remove()` on each widget appended to this array. In the opposite case, `grid()` will be called.
- self.additional_widgets = []
-
- self.sb__widgets = {}
-
- createConfigWindowTitle(config_window=self, settings=self.settings, view_variable=self._view_variable)
-
- createSettingBoxTopBar(config_window=self, settings=self.settings, view_variable=self._view_variable)
-
- createSideMenuAndSettingsBoxContainers(config_window=self, settings=self.settings, view_variable=self._view_variable)
-
- # for fixing 1px bug
- l_width = getLatestWidth(self.side_menu_bg_container)
- if isEven(l_width) is False:
- self.side_menu_bg_container.grid_columnconfigure(0, weight=0, minsize=l_width+1)
-
- # for fixing 1px bug
- # self.side_menu_bg_container.grid_rowconfigure(2, weight=1)
- # sls__box_optionmenu_wrapper_fix_1px_bug = CTkFrame(self.side_menu_bg_container, corner_radius=0, width=0, height=0)
- # sls__box_optionmenu_wrapper_fix_1px_bug.grid(row=3, column=0, sticky="sew")
-
- # for fixing 1px bug
- l_width = getLatestWidth(self.side_menu_bg_container)
-
-
-
- # VRCT Now Version Label(Tmp)
- version_label = CTkLabel(
- self.side_menu_bg_container,
- textvariable=self._view_variable.VAR_VERSION,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.NOW_VERSION_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.NOW_VERSION_TEXT_COLOR,
- )
- version_label.place(relx=0.05, rely=0.99, anchor="sw")
-
-
- self.bind_all("", lambda event: event.widget.focus_set(), "+")
\ No newline at end of file
diff --git a/vrct_gui/config_window/__init__.py b/vrct_gui/config_window/__init__.py
deleted file mode 100644
index c6dbe941..00000000
--- a/vrct_gui/config_window/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .ConfigWindow import ConfigWindow
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/__init__.py b/vrct_gui/config_window/widgets/__init__.py
deleted file mode 100644
index e3651955..00000000
--- a/vrct_gui/config_window/widgets/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from .createConfigWindowTitle import createConfigWindowTitle
-from .createSettingBoxTopBar import createSettingBoxTopBar
-
-from .createSideMenuAndSettingsBoxContainers import createSideMenuAndSettingsBoxContainers
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createConfigWindowTitle.py b/vrct_gui/config_window/widgets/createConfigWindowTitle.py
deleted file mode 100644
index 4db6b4f4..00000000
--- a/vrct_gui/config_window/widgets/createConfigWindowTitle.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from customtkinter import CTkFont, CTkFrame, CTkLabel, CTkImage
-
-def createConfigWindowTitle(config_window, settings, view_variable):
-
- config_window.grid_columnconfigure(0, weight=0, minsize=settings.uism.TOP_BAR_SIDE_AREA_MIN_WIDTH)
- config_window.grid_rowconfigure(0, weight=0, minsize=settings.uism.TOP_BAR__MIN_HEIGHT)
- config_window.side_menu_config_window_title_logo_frame = CTkFrame(config_window, corner_radius=0, fg_color=settings.ctm.TOP_BAR_BG_COLOR, width=0, height=0)
- config_window.side_menu_config_window_title_logo_frame.grid(row=0, column=0, sticky="nsew")
-
- config_window.side_menu_config_window_title_logo_frame.grid_rowconfigure(0,weight=1)
- config_window.side_menu_config_window_title_logo_frame.grid_columnconfigure(0,weight=1)
- config_window.side_menu_config_window_title_logo_wrapper = CTkFrame(config_window.side_menu_config_window_title_logo_frame, corner_radius=0, fg_color=settings.ctm.TOP_BAR_BG_COLOR, width=0, height=0)
- config_window.side_menu_config_window_title_logo_wrapper.grid(row=0, column=0, padx=settings.uism.TOP_BAR_SIDE__TITLE_PADX, pady=settings.uism.TOP_BAR__IPADY, sticky="nsew")
-
-
-
-
- config_window.side_menu_config_window_title_logo_wrapper.grid_rowconfigure(0,weight=1)
- config_window.side_menu_config_window_title = CTkLabel(
- config_window.side_menu_config_window_title_logo_frame,
- textvariable=view_variable.VAR_CONFIG_WINDOW_TITLE,
- height=0,
- anchor="w",
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.TOP_BAR_SIDE__CONFIG_TITLE_FONT_SIZE, weight="bold"),
- text_color=settings.ctm.LABELS_TEXT_COLOR,
- )
- config_window.side_menu_config_window_title.place(relx=0.255, rely=0.5, anchor="w")
-
- config_window.side_menu_config_window_title_logo = CTkLabel(
- config_window.side_menu_config_window_title_logo_frame,
- text=None,
- height=0,
- anchor="w",
- image=CTkImage(settings.image_file.VRCT_LOGO_MARK, size=settings.uism.TOP_BAR_SIDE__CONFIG_LOGO_MARK_SIZE),
- )
- config_window.side_menu_config_window_title_logo.place(relx=0.08, rely=0.58, anchor="w")
diff --git a/vrct_gui/config_window/widgets/createSettingBoxTopBar/__init__.py b/vrct_gui/config_window/widgets/createSettingBoxTopBar/__init__.py
deleted file mode 100644
index b5be1139..00000000
--- a/vrct_gui/config_window/widgets/createSettingBoxTopBar/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .createSettingBoxTopBar import createSettingBoxTopBar
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSettingBoxTopBar/_createRestartButton.py b/vrct_gui/config_window/widgets/createSettingBoxTopBar/_createRestartButton.py
deleted file mode 100644
index 91e08761..00000000
--- a/vrct_gui/config_window/widgets/createSettingBoxTopBar/_createRestartButton.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from customtkinter import CTkFont, CTkFrame, CTkLabel
-from utils import callFunctionIfCallable
-from ....ui_utils import bindButtonFunctionAndColor
-
-def _createRestartButton(parent_widget, config_window, settings, view_variable, column_num):
-
- parent_widget.grid_columnconfigure(0, weight=1)
- config_window.restart_button_container = CTkFrame(parent_widget, corner_radius=settings.uism.RESTART_BUTTON_CORNER_RADIUS, fg_color=settings.ctm.RESTART_BUTTON_BG_COLOR, width=0, height=0, cursor="hand2")
- config_window.restart_button_container.grid(row=0, column=column_num, padx=settings.uism.RESTART_BUTTON_PADX, sticky="ew")
-
-
- config_window.restart_button_container.grid_rowconfigure(0, weight=1)
- config_window.restart_button_label = CTkLabel(
- config_window.restart_button_container,
- height=0,
- textvariable=view_variable.VAR_CONFIG_WINDOW_RESTART_BUTTON_LABEL,
- anchor="w",
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.RESTART_BUTTON_LABEL_FONT_SIZE, weight="normal"),
- text_color=settings.ctm.LABELS_TEXT_COLOR
- )
- config_window.restart_button_label.grid(row=0, column=0, padx=settings.uism.RESTART_BUTTON_IPADX, pady=settings.uism.RESTART_BUTTON_IPADY)
-
-
-
- bindButtonFunctionAndColor(
- target_widgets=[
- config_window.restart_button_container,
- config_window.restart_button_label,
- ],
- enter_color=settings.ctm.RESTART_BUTTON_HOVERED_BG_COLOR,
- leave_color=settings.ctm.RESTART_BUTTON_BG_COLOR,
- clicked_color=settings.ctm.RESTART_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_RESTART_SOFTWARE),
- )
-
-
- config_window.restart_button_container.grid_remove()
diff --git a/vrct_gui/config_window/widgets/createSettingBoxTopBar/_createSettingBoxCompactModeButton.py b/vrct_gui/config_window/widgets/createSettingBoxTopBar/_createSettingBoxCompactModeButton.py
deleted file mode 100644
index 80a5d152..00000000
--- a/vrct_gui/config_window/widgets/createSettingBoxTopBar/_createSettingBoxCompactModeButton.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from customtkinter import CTkFont, CTkFrame, CTkLabel, CTkSwitch
-
-def _createSettingBoxCompactModeButton(parent_widget, config_window, settings, view_variable, column_num):
-
- def switchConfigWindowCompactMode():
- if config_window.setting_box_compact_mode_switch_box.get() is True:
- if callable(view_variable.CALLBACK_ENABLE_CONFIG_WINDOW_COMPACT_MODE) is True:
- view_variable.CALLBACK_ENABLE_CONFIG_WINDOW_COMPACT_MODE()
- else:
- if callable(view_variable.CALLBACK_DISABLE_CONFIG_WINDOW_COMPACT_MODE) is True:
- view_variable.CALLBACK_DISABLE_CONFIG_WINDOW_COMPACT_MODE()
-
-
-
- config_window.setting_box_compact_mode_button_container = CTkFrame(parent_widget, corner_radius=0, fg_color=settings.ctm.TOP_BAR_BG_COLOR, width=0, height=0)
- config_window.setting_box_compact_mode_button_container.grid(row=0, column=column_num, padx=settings.uism.COMPACT_MODE_PADX, sticky="nse")
-
-
-
- config_window.setting_box_compact_mode_button_container.grid_rowconfigure((0,2), weight=1)
- config_window.setting_box_compact_mode_button_container = CTkFrame(config_window.setting_box_compact_mode_button_container, corner_radius=0, fg_color=settings.ctm.TOP_BAR_BG_COLOR, width=0, height=0)
- config_window.setting_box_compact_mode_button_container.grid(row=1, column=0, sticky="nsew")
-
-
- config_window.setting_box_compact_mode_button_container.grid_rowconfigure(0, weight=1)
- config_window.setting_box_compact_mode_label = CTkLabel(
- config_window.setting_box_compact_mode_button_container,
- height=0,
- # text="Compact Mode",
- textvariable=view_variable.VAR_CONFIG_WINDOW_COMPACT_MODE_LABEL,
- anchor="w",
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.COMPACT_MODE_LABEL_FONT_SIZE, weight="normal"),
- text_color=settings.ctm.LABELS_TEXT_COLOR
- )
- config_window.setting_box_compact_mode_label.grid(row=0, column=0, padx=settings.uism.COMPACT_MODE_LABEL_PADX)
-
-
-
-
-
-
-
-
- config_window.setting_box_compact_mode_switch_frame = CTkFrame(config_window.setting_box_compact_mode_button_container, corner_radius=0, width=0, height=0, fg_color=settings.ctm.TOP_BAR_BG_COLOR)
- config_window.setting_box_compact_mode_switch_frame.grid(row=0, column=1, padx=0, sticky="e")
-
- config_window.setting_box_compact_mode_switch_box = CTkSwitch(
- config_window.setting_box_compact_mode_switch_frame,
- text=None,
- height=0,
- width=0,
- # corner_radius=0,
- border_width=0,
- switch_width=settings.uism.COMPACT_MODE_SWITCH_WIDTH,
- switch_height=settings.uism.COMPACT_MODE_SWITCH_HEIGHT,
- onvalue=True,
- offvalue=False,
- command=switchConfigWindowCompactMode,
- fg_color=settings.ctm.COMPACT_MODE_SWITCH_BOX_BG_COLOR,
- # bg_color="red",
- progress_color=settings.ctm.COMPACT_MODE_SWITCH_BOX_ACTIVE_BG_COLOR,
- button_color=settings.ctm.COMPACT_MODE_SWITCH_BOX_BUTTON_COLOR,
- button_hover_color=settings.ctm.COMPACT_MODE_SWITCH_BOX_BUTTON_HOVERED_COLOR,
- )
-
- config_window.setting_box_compact_mode_switch_box.grid(row=0, column=0)
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSettingBoxTopBar/_createSettingBoxTitle.py b/vrct_gui/config_window/widgets/createSettingBoxTopBar/_createSettingBoxTitle.py
deleted file mode 100644
index 199a12fb..00000000
--- a/vrct_gui/config_window/widgets/createSettingBoxTopBar/_createSettingBoxTitle.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from customtkinter import CTkFont, CTkFrame, CTkLabel
-
-def _createSettingBoxTitle(parent_widget, config_window, settings, view_variable, column_num):
-
- parent_widget.grid_columnconfigure(0, weight=1)
- config_window.main_current_active_config_title_container = CTkFrame(parent_widget, corner_radius=0, fg_color=settings.ctm.TOP_BAR_BG_COLOR, width=0, height=0)
- config_window.main_current_active_config_title_container.grid(row=0, column=column_num, sticky="nsew")
-
-
- config_window.main_current_active_config_title_container.grid_rowconfigure(0, weight=1)
- config_window.main_current_active_config_title = CTkLabel(
- config_window.main_current_active_config_title_container,
- height=0,
- textvariable=view_variable.VAR_CURRENT_ACTIVE_CONFIG_TITLE,
- anchor="w",
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.TOP_BAR_MAIN__TITLE_FONT_SIZE, weight="bold"),
- text_color=settings.ctm.LABELS_TEXT_COLOR
- )
- config_window.main_current_active_config_title.grid(row=0, column=0, padx=0, pady=settings.uism.TOP_BAR__IPADY)
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSettingBoxTopBar/createSettingBoxTopBar.py b/vrct_gui/config_window/widgets/createSettingBoxTopBar/createSettingBoxTopBar.py
deleted file mode 100644
index 12a0403c..00000000
--- a/vrct_gui/config_window/widgets/createSettingBoxTopBar/createSettingBoxTopBar.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from customtkinter import CTkFrame
-
-from ._createSettingBoxTitle import _createSettingBoxTitle
-from ._createRestartButton import _createRestartButton
-from ._createSettingBoxCompactModeButton import _createSettingBoxCompactModeButton
-
-from ....ui_utils import getLatestHeight
-from utils import isEven
-
-def createSettingBoxTopBar(config_window, settings, view_variable):
-
- config_window.grid_columnconfigure(1, weight=1)
- config_window.setting_box_top_bar = CTkFrame(config_window, corner_radius=0, fg_color=settings.ctm.TOP_BAR_BG_COLOR, width=0, height=0)
- config_window.setting_box_top_bar.grid(row=0, column=1, sticky="nsew")
-
-
- config_window.setting_box_top_bar.grid_rowconfigure(0, weight=1)
-
- column_num=0
- _createSettingBoxTitle(parent_widget=config_window.setting_box_top_bar, config_window=config_window, settings=settings, view_variable=view_variable, column_num=column_num)
- column_num+=1
-
- config_window.setting_box_top_bar.grid_columnconfigure(column_num, weight=1)
- column_num+=1
-
- # Restart Button(Tmp)
- _createRestartButton(parent_widget=config_window.setting_box_top_bar, config_window=config_window, settings=settings, view_variable=view_variable, column_num=column_num)
- column_num+=1
-
- _createSettingBoxCompactModeButton(parent_widget=config_window.setting_box_top_bar, config_window=config_window, settings=settings, view_variable=view_variable, column_num=column_num)
- column_num+=1
-
-
- l_height = getLatestHeight(config_window.side_menu_config_window_title_logo_frame)
- if isEven(l_height) is False:
- config_window.grid_rowconfigure(0, weight=0, minsize=l_height+1)
-
- # for fixing 1px bug
- setting_box_top_bar_fix_1px_bug = CTkFrame(config_window.setting_box_top_bar, corner_radius=0, width=0, height=0)
- setting_box_top_bar_fix_1px_bug.grid(row=0, column=column_num, sticky="nse")
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/__init__.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/__init__.py
deleted file mode 100644
index 245472c9..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .createSideMenuAndSettingsBoxContainers import createSideMenuAndSettingsBoxContainers
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/_addConfigSideMenuItem.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/_addConfigSideMenuItem.py
deleted file mode 100644
index 39d83009..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/_addConfigSideMenuItem.py
+++ /dev/null
@@ -1,107 +0,0 @@
-from customtkinter import CTkFont, CTkFrame, CTkLabel
-
-from ....ui_utils import bindEnterAndLeaveColor, bindButtonPressColor, bindButtonReleaseFunction, switchActiveTabAndPassiveTab, switchTabsColor
-
-from utils import callFunctionIfCallable
-
-
-def _addConfigSideMenuItem(config_window, settings, view_variable, side_menu_settings, side_menu_row, all_side_menu_tab_attr_name):
-
-
- def switchActiveAndPassiveSettingBoxContainerTabsColor(target_active_widget):
-
- setting_box_container_tabs = []
- for tab_attr_name in all_side_menu_tab_attr_name:
- tab_attr = getattr(config_window, tab_attr_name)
- setting_box_container_tabs.append(tab_attr)
-
- switchTabsColor(
- target_widget=target_active_widget,
- tab_buttons=setting_box_container_tabs,
- active_bg_color=settings.ctm.SIDE_MENU_LABELS_BG_COLOR,
- active_text_color=settings.ctm.SIDE_MENU_LABELS_SELECTED_TEXT_COLOR,
- passive_bg_color=settings.ctm.SIDE_MENU_LABELS_BG_COLOR,
- passive_text_color=settings.ctm.LABELS_TEXT_COLOR
- )
-
- for setting_box_container_tab in setting_box_container_tabs:
- setting_box_container_tab.children["!ctkframe"].place(relx=-1)
-
- target_active_widget.children["!ctkframe"].place(relx=0)
-
-
-
-
- def switchSettingBoxContainerTabFunction(target_active_widget):
- switchActiveAndPassiveSettingBoxContainerTabsColor(target_active_widget)
- switchActiveTabAndPassiveTab(target_active_widget, config_window.current_active_side_menu_tab, config_window.current_active_side_menu_tab.passive_function, settings.ctm.SIDE_MENU_LABELS_HOVERED_BG_COLOR, settings.ctm.SIDE_MENU_LABELS_CLICKED_BG_COLOR, settings.ctm.SIDE_MENU_LABELS_BG_COLOR)
- config_window.current_active_side_menu_tab = target_active_widget
-
-
-
-
-
-
- def switchSettingBoxContainer(target_setting_box_container_attr_name):
- config_window.current_active_setting_box_container.grid_remove()
- config_window.current_active_setting_box_container = getattr(config_window, target_setting_box_container_attr_name)
- config_window.current_active_setting_box_container.grid()
-
- # Move to the top position when the setting box is switched.
- config_window.main_setting_box_scrollable_container._parent_canvas.yview_moveto("0")
-
-
- def switchToTargetSettingBoxContainer(textvariable, target_active_tab_widget_attr_name, target_setting_box_container_attr_name):
- view_variable.VAR_CURRENT_ACTIVE_CONFIG_TITLE.set(textvariable.get())
- target_active_tab_widget = getattr(config_window, target_active_tab_widget_attr_name)
- switchSettingBoxContainerTabFunction(target_active_tab_widget)
- switchSettingBoxContainer(target_setting_box_container_attr_name)
- callFunctionIfCallable(view_variable.CALLBACK_SELECTED_SETTING_BOX_TAB, target_active_tab_widget_attr_name)
-
-
-
-
-
- side_menu_tab_attr_name = side_menu_settings["side_menu_tab_attr_name"]
- label_attr_name = side_menu_settings["label_attr_name"]
- selected_mark_attr_name = side_menu_settings["selected_mark_attr_name"]
- textvariable = side_menu_settings["textvariable"]
- setting_box_container_attr_name = side_menu_settings["setting_box_container_settings"]["setting_box_container_attr_name"]
- command = lambda _e: switchToTargetSettingBoxContainer(
- textvariable=textvariable,
- target_active_tab_widget_attr_name=side_menu_tab_attr_name,
- target_setting_box_container_attr_name=setting_box_container_attr_name,
- )
-
-
- # Side menu
- frame_widget = CTkFrame(config_window.side_menu_container, corner_radius=0, fg_color=settings.ctm.SIDE_MENU_LABELS_BG_COLOR, cursor="hand2", width=0, height=0)
- setattr(config_window, side_menu_tab_attr_name, frame_widget)
-
- frame_widget.grid(row=side_menu_row, column=0, pady=(0,1), sticky="ew")
- frame_widget.grid_columnconfigure(0, weight=1)
-
- label_widget = CTkLabel(
- frame_widget,
- textvariable=textvariable,
- height=0,
- corner_radius=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.SIDE_MENU_LABELS_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=settings.ctm.LABELS_TEXT_COLOR,
- )
- setattr(config_window, label_attr_name, label_widget)
-
- selected_mark_widget = CTkFrame(frame_widget, corner_radius=0, fg_color=settings.ctm.SIDE_MENU_SELECTED_MARK_ACTIVE_BG_COLOR, width=3, height=0)
- setattr(config_window, selected_mark_attr_name, selected_mark_widget)
-
-
- # Arrange
- selected_mark_widget.place(relx=-1, rely=0.5, relheight=1, anchor="w")
- label_widget.grid(row=0, column=0, padx=settings.uism.SIDE_MENU_LABELS_IPADX, pady=settings.uism.SIDE_MENU_LABELS_IPADY, sticky="ew")
-
- bindEnterAndLeaveColor([frame_widget, label_widget], settings.ctm.SIDE_MENU_LABELS_HOVERED_BG_COLOR, settings.ctm.SIDE_MENU_LABELS_BG_COLOR)
- bindButtonPressColor([frame_widget, label_widget], settings.ctm.SIDE_MENU_LABELS_CLICKED_BG_COLOR, settings.ctm.SIDE_MENU_LABELS_BG_COLOR)
-
- frame_widget.passive_function = command
- bindButtonReleaseFunction([frame_widget, label_widget], command)
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/_createSettingBoxContainer.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/_createSettingBoxContainer.py
deleted file mode 100644
index a140ecc3..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/_createSettingBoxContainer.py
+++ /dev/null
@@ -1,68 +0,0 @@
-from customtkinter import CTkFont, CTkFrame, CTkLabel
-
-
-def _createSettingBoxContainer(config_window, settings, view_variable, setting_box_container_settings, bottom_margin):
-
-
- def createSectionTitle(container_widget, var_section_title):
-
- setting_box_wrapper_section_title = CTkLabel(
- container_widget,
- textvariable=var_section_title,
- anchor="w",
- height=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.SB__SECTION_TITLE_FONT_SIZE, weight="normal"),
- text_color=settings.ctm.LABELS_TEXT_COLOR
- )
- setting_box_wrapper_section_title.place(relx=0, rely=0)
-
- return container_widget
-
-
- # Setting box container
- setting_box_container_widget = CTkFrame(config_window.main_setting_box_bg_wrapper, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- setattr(config_window, setting_box_container_settings["setting_box_container_attr_name"], setting_box_container_widget)
- setting_box_container_widget.grid(row=0, pady=bottom_margin)
- setting_box_container_widget.grid_remove()
-
-
-
- setting_box_row=0
- for setting_box_setting in setting_box_container_settings["setting_boxes"]:
- # Top-Padding that can be container the section title
- if setting_box_setting.get("about_vrct", False) is True:
- setting_box_top_padding = CTkFrame(setting_box_container_widget, corner_radius=0, fg_color=settings.ctm.ABOUT_VRCT_BG, width=0, height=settings.uism.ABOUT_VRCT_SB__TOP_PADY)
- setting_box_wrapper = CTkFrame(setting_box_container_widget, fg_color=settings.ctm.MAIN_BG_COLOR, corner_radius=0, width=0, height=0)
- else:
- setting_box_top_padding = CTkFrame(setting_box_container_widget, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=settings.uism.SB__TOP_PADY)
- setting_box_wrapper = CTkFrame(setting_box_container_widget, fg_color=settings.ctm.SB__WRAPPER_BG_COLOR, corner_radius=0, width=0, height=0)
-
- setting_box_top_padding.grid(row=setting_box_row, column=0, sticky="ew", padx=0, pady=0)
- setting_box_top_padding.grid_columnconfigure(0, weight=1)
- setting_box_row+=1
-
- if setting_box_setting["var_section_title"] is not None:
- setting_box_wrapper_section_title = CTkLabel(
- setting_box_top_padding,
- textvariable=setting_box_setting["var_section_title"],
- anchor="w",
- height=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.SB__SECTION_TITLE_FONT_SIZE, weight="normal"),
- text_color=settings.ctm.LABELS_TEXT_COLOR
- )
- setting_box_wrapper_section_title.place(relx=0, rely=0.4, anchor="nw")
-
-
- setting_box_wrapper.grid(row=setting_box_row, column=0, sticky="ew")
- setting_box_wrapper.grid_columnconfigure(0, weight=1)
- setting_box_row+=1
-
-
- if setting_box_setting["setting_box"] is not None:
- setting_box_setting["setting_box"](
- setting_box_wrapper=setting_box_wrapper,
- config_window=config_window,
- settings=settings,
- view_variable=view_variable,
- )
-
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/createSideMenuAndSettingsBoxContainers.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/createSideMenuAndSettingsBoxContainers.py
deleted file mode 100644
index 85e2d20e..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/createSideMenuAndSettingsBoxContainers.py
+++ /dev/null
@@ -1,213 +0,0 @@
-from customtkinter import CTkFrame
-
-from ....ui_utils import setDefaultActiveTab, applyUiScalingAndFixTheBugScrollBar, CustomizedCTkScrollableFrame
-
-from ._addConfigSideMenuItem import _addConfigSideMenuItem
-from ._createSettingBoxContainer import _createSettingBoxContainer
-
-
-from .setting_box_containers.setting_box_appearance import createSettingBox_Appearance
-from .setting_box_containers.setting_box_transcription import createSettingBox_Mic, createSettingBox_Speaker, createSettingBox_InternalModel
-from .setting_box_containers.setting_box_others import createSettingBox_Others, createSettingBox_Others_SendMessageFormats, createSettingBox_Others_ReceivedMessageFormats, createSettingBox_Others_Additional
-from .setting_box_containers.setting_box_advanced_settings import createSettingBox_AdvancedSettings
-from .setting_box_containers.setting_box_translation import createSettingBox_Translation
-from .setting_box_containers.setting_box_vr import createSettingBox_Vr
-
-from .setting_box_containers.setting_box_about_vrct import createSettingBox_AboutVrct
-
-
-def createSideMenuAndSettingsBoxContainers(config_window, settings, view_variable):
-
- # Main container
- config_window.main_bg_container = CTkFrame(config_window, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- config_window.main_bg_container.grid(row=1, column=1, sticky="nsew")
-
- config_window.main_bg_container.grid_columnconfigure(0, weight=1)
- config_window.main_bg_container.grid_rowconfigure(0, weight=0)
-
-
-
-
- # Side menu Base
- config_window.grid_rowconfigure(1, weight=1)
- config_window.side_menu_bg_container = CTkFrame(config_window, corner_radius=0, fg_color=settings.ctm.SIDE_MENU_BG_COLOR, width=0, height=0)
- config_window.side_menu_bg_container.grid(row=1, column=0, sticky="nsew")
- config_window.side_menu_bg_container.grid_columnconfigure(0, weight=1)
- config_window.side_menu_bg_container.grid_rowconfigure(0, weight=1)
- config_window.side_menu_container = CTkFrame(config_window.side_menu_bg_container, corner_radius=0, fg_color=settings.ctm.SIDE_MENU_LABELS_BG_FOR_FAKE_BORDER_COLOR, width=0, height=0)
- config_window.side_menu_container.grid(row=0, column=0, padx=settings.uism.TOP_BAR_SIDE__TITLE_PADX, pady=settings.uism.SIDE_MENU_PADY, sticky="nsew")
-
-
-
- # Setting box container
- config_window.main_bg_container.grid_rowconfigure(1, weight=1)
- config_window.main_setting_box_scrollable_container = CustomizedCTkScrollableFrame(config_window.main_bg_container, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR)
- config_window.main_setting_box_scrollable_container.grid(row=1, column=0, sticky="nsew")
-
- applyUiScalingAndFixTheBugScrollBar(
- scrollbar_widget=config_window.main_setting_box_scrollable_container,
- padx=settings.uism.SCROLLBAR_IPADX,
- width=settings.uism.SCROLLBAR_WIDTH,
- )
-
-
- config_window.main_setting_box_bg_wrapper = CTkFrame(config_window.main_setting_box_scrollable_container, corner_radius=0, width=0, height=0, fg_color=settings.ctm.MAIN_BG_COLOR)
- config_window.main_setting_box_bg_wrapper.grid(row=0, column=0, pady=0, sticky="n")
-
-
-
- side_menu_and_setting_box_containers_settings = [
- {
- "side_menu_tab_attr_name": "side_menu_tab_appearance",
- "label_attr_name": "label_appearance",
- "selected_mark_attr_name": "selected_mark_appearance",
- "textvariable": view_variable.VAR_SIDE_MENU_LABEL_APPEARANCE,
- "setting_box_container_settings": {
- "setting_box_container_attr_name": "setting_box_container_appearance",
- "setting_boxes": [
- { "var_section_title": None, "setting_box": createSettingBox_Appearance },
- ]
- },
- },
- {
- "side_menu_tab_attr_name": "side_menu_tab_translation",
- "label_attr_name": "label_translation",
- "selected_mark_attr_name": "selected_mark_translation",
- "textvariable": view_variable.VAR_SIDE_MENU_LABEL_TRANSLATION,
- "setting_box_container_settings": {
- "setting_box_container_attr_name": "setting_box_container_translation",
- "setting_boxes": [
- { "var_section_title": None, "setting_box": createSettingBox_Translation },
- ]
- },
- },
- {
- "side_menu_tab_attr_name": "side_menu_tab_transcription",
- "label_attr_name": "label_transcription",
- "selected_mark_attr_name": "selected_mark_transcription",
- "textvariable": view_variable.VAR_SIDE_MENU_LABEL_TRANSCRIPTION,
- "setting_box_container_settings": {
- "setting_box_container_attr_name": "setting_box_container_transcription",
- "setting_boxes": [
- {
- "var_section_title": view_variable.VAR_SECOND_TITLE_TRANSCRIPTION_MIC,
- "setting_box": createSettingBox_Mic
- },
- {
- "var_section_title": view_variable.VAR_SECOND_TITLE_TRANSCRIPTION_SPEAKER,
- "setting_box": createSettingBox_Speaker
- },
- {
- "var_section_title": view_variable.VAR_SECOND_TITLE_TRANSCRIPTION_INTERNAL_MODEL,
- "setting_box": createSettingBox_InternalModel
- },
- ]
- },
- },
- {
- "side_menu_tab_attr_name": "side_menu_tab_vr",
- "label_attr_name": "label_vr",
- "selected_mark_attr_name": "selected_mark_vr",
- "textvariable": view_variable.VAR_SIDE_MENU_LABEL_VR,
- "setting_box_container_settings": {
- "setting_box_container_attr_name": "setting_box_container_vr",
- "setting_boxes": [
- {
- "var_section_title": None,
- "setting_box": createSettingBox_Vr
- }
- ]
- },
- },
- {
- "side_menu_tab_attr_name": "side_menu_tab_others",
- "label_attr_name": "label_others",
- "selected_mark_attr_name": "selected_mark_others",
- "textvariable": view_variable.VAR_SIDE_MENU_LABEL_OTHERS,
- "setting_box_container_settings": {
- "setting_box_container_attr_name": "setting_box_container_others",
- "setting_boxes": [
- { "var_section_title": None, "setting_box": createSettingBox_Others },
- { "var_section_title": view_variable.VAR_SECOND_TITLE_OTHERS_SEND_MESSAGE_FORMATS, "setting_box": createSettingBox_Others_SendMessageFormats },
- { "var_section_title": view_variable.VAR_SECOND_TITLE_OTHERS_RECEIVED_MESSAGE_FORMATS, "setting_box": createSettingBox_Others_ReceivedMessageFormats },
- { "var_section_title": view_variable.VAR_SECOND_TITLE_OTHERS_SPEAKER2CHATBOX, "setting_box": createSettingBox_Others_Additional },
- ]
- },
- },
- {
- "side_menu_tab_attr_name": "side_menu_tab_advanced",
- "label_attr_name": "label_advanced",
- "selected_mark_attr_name": "selected_mark_advanced",
- "textvariable": view_variable.VAR_SIDE_MENU_LABEL_ADVANCED_SETTINGS,
- "setting_box_container_settings": {
- "setting_box_container_attr_name": "setting_box_container_advanced",
- "setting_boxes": [
- { "var_section_title": None, "setting_box": createSettingBox_AdvancedSettings },
- ]
- },
- },
-
- # About VRCT. It is separated from the others.
- {
- "side_menu_tab_attr_name": "side_menu_tab_about_vrct",
- "label_attr_name": "label_about_vrct",
- "selected_mark_attr_name": "selected_mark_about_vrct",
- "textvariable": view_variable.VAR_SIDE_MENU_LABEL_ABOUT_VRCT,
- "setting_box_container_settings": {
- "setting_box_container_attr_name": "setting_box_container_about_vrct",
- "setting_boxes": [
- { "var_section_title": None, "setting_box": createSettingBox_AboutVrct, "about_vrct": True },
- ]
- },
- },
- ]
- SEPARATE_ROW_COUNT=1 # It's just count the row and separate from below.
- SEPARATE_ROW_NUMBER = len(side_menu_and_setting_box_containers_settings) - SEPARATE_ROW_COUNT
-
- all_side_menu_tab_attr_name = [item["side_menu_tab_attr_name"] for item in side_menu_and_setting_box_containers_settings]
-
- side_menu_row=0
- for sm_and_sbc_setting in side_menu_and_setting_box_containers_settings:
-
- if side_menu_row == SEPARATE_ROW_NUMBER:
- side_menu_separator = CTkFrame(config_window.side_menu_container, corner_radius=0, fg_color=settings.ctm.SIDE_MENU_LABELS_BG_COLOR, width=0, height=0)
- config_window.side_menu_container.grid_rowconfigure(side_menu_row, weight=1, minsize=settings.uism.SIDE_MENU_LABELS_SEPARATE_MIN_HEIGHT)
- side_menu_separator.grid(row=side_menu_row, column=0, sticky="nsew")
- side_menu_row+=1
-
-
- _addConfigSideMenuItem(
- config_window=config_window,
- settings=settings,
- view_variable=view_variable,
- side_menu_settings=sm_and_sbc_setting,
- side_menu_row=side_menu_row,
- all_side_menu_tab_attr_name=all_side_menu_tab_attr_name,
- )
- side_menu_row+=1
-
-
- bottom_margin = 0 if sm_and_sbc_setting["setting_box_container_settings"]["setting_box_container_attr_name"] == "setting_box_container_about_vrct" else settings.uism.SB__BOTTOM_MARGIN
- _createSettingBoxContainer(
- config_window=config_window,
- settings=settings,
- view_variable=view_variable,
- setting_box_container_settings=sm_and_sbc_setting["setting_box_container_settings"],
- bottom_margin=bottom_margin,
- )
-
-
- if sm_and_sbc_setting["side_menu_tab_attr_name"] == view_variable.ACTIVE_SETTING_BOX_TAB_ATTR_NAME:
- # Set default active side menu tab
- view_variable.VAR_CURRENT_ACTIVE_CONFIG_TITLE.set(sm_and_sbc_setting["textvariable"].get())
- config_window.current_active_side_menu_tab = getattr(config_window, sm_and_sbc_setting["side_menu_tab_attr_name"])
- setDefaultActiveTab(
- active_tab_widget=config_window.current_active_side_menu_tab,
- active_bg_color=settings.ctm.SIDE_MENU_LABELS_BG_COLOR,
- active_text_color=settings.ctm.SIDE_MENU_LABELS_SELECTED_TEXT_COLOR
- )
- config_window.current_active_side_menu_tab.children["!ctkframe"].place(relx=0)
-
- # Set default active setting box container
- config_window.current_active_setting_box_container = getattr(config_window, sm_and_sbc_setting["setting_box_container_settings"]["setting_box_container_attr_name"])
- config_window.current_active_setting_box_container.grid()
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/_SettingBoxGenerator.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/_SettingBoxGenerator.py
deleted file mode 100644
index 751211fc..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/_SettingBoxGenerator.py
+++ /dev/null
@@ -1,1448 +0,0 @@
-from functools import partial
-from types import SimpleNamespace
-from typing import Union
-
-from customtkinter import CTkFont, CTkFrame, CTkLabel, CTkEntry, CTkSlider, CTkSwitch, CTkCheckBox, CTkProgressBar, CTkImage, CTkRadioButton
-from CTkToolTip import *
-
-from vrct_gui.ui_utils import createButtonWithImage, getLatestWidth, createOptionMenuBox, getLatestHeight, bindButtonFunctionAndColor, bindEnterAndLeaveFunction, bindButtonReleaseFunction, bindButtonPressFunction, createLabelButton
-from vrct_gui import vrct_gui
-from utils import isEven, callFunctionIfCallable
-
-SETTING_BOX_COLUMN = 1
-
-class _SettingBoxGenerator():
- def __init__(self, parent_widget, config_window, settings, view_variable):
- self.view_variable = view_variable
- self.config_window = config_window
- self.parent_widget = parent_widget
- self.settings = settings
-
- self.MAIN_INNER_AREA_MIN_WIDTH = int(self.settings.uism.MAIN_AREA_MIN_WIDTH - self.settings.uism.SB__IPADX)
-
- self.dropdown_menu_window = vrct_gui.vrct_gui.dropdown_menu_window
-
- def _createSettingBoxFrame(self, sb__attr_name, for_var_label_text=None, for_var_desc_text=None, expand_label_frame:bool=False):
- self.config_window.sb__widgets[sb__attr_name] = SimpleNamespace()
-
- setting_box_frame = CTkFrame(self.parent_widget, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
-
- # "pady=(0,1)" is for bottom padding. It can be removed(override) when you do like "self.attr_name.grid(row=row, pady=0)"
- setting_box_frame.grid(column=0, padx=0, pady=self.settings.uism.SB__FAKE_BOTTOM_BORDER_SIZE, sticky="ew")
- setting_box_frame.grid_columnconfigure(0, weight=1)
-
-
- setting_box_frame_wrapper = CTkFrame(setting_box_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- setting_box_frame_wrapper.grid(row=0, column=0, padx=self.settings.uism.SB__IPADX, pady=self.settings.uism.SB__IPADY, sticky="ew")
-
-
- setting_box_frame_wrapper_fix_border = CTkFrame(setting_box_frame, corner_radius=0, width=0, height=0)
- setting_box_frame_wrapper_fix_border.grid(row=1, column=0, sticky="ew")
-
- setting_box_frame_wrapper_fix_border2 = CTkFrame(setting_box_frame, corner_radius=0, width=0, height=0)
- setting_box_frame_wrapper_fix_border2.grid(row=0, column=1, sticky="ns")
-
-
-
- if for_var_label_text is not None:
- self._setSettingBoxLabels(sb__attr_name, setting_box_frame_wrapper, for_var_label_text, for_var_desc_text, expand_label_frame)
- if expand_label_frame is True:
- setting_box_frame_wrapper.grid_columnconfigure(0, weight=1, minsize=int(self.settings.uism.MAIN_AREA_MIN_WIDTH))
- setting_box_frame_wrapper.grid(columnspan=3)
- return setting_box_frame
-
-
- setting_box_frame_wrapper.grid_columnconfigure(0, weight=0, minsize=int(self.settings.uism.MAIN_AREA_MIN_WIDTH / 2))
- setting_box_frame_wrapper.grid_columnconfigure(2, weight=1, minsize=int(self.settings.uism.MAIN_AREA_MIN_WIDTH / 2))
-
-
-
-
- setting_box_item_frame = CTkFrame(setting_box_frame_wrapper, corner_radius=0, width=0, height=0, fg_color=self.settings.ctm.SB__BG_COLOR)
- if for_var_label_text is not None:
- setting_box_item_frame.grid(row=0, column=2, padx=0, sticky="nsew")
- else:
- setting_box_item_frame.grid(row=0, columnspan=3, padx=0, sticky="nsew")
- setting_box_item_frame.grid_rowconfigure((0,2), weight=1)
- setting_box_item_frame.grid_columnconfigure(0, weight=1)
-
- return (setting_box_frame, setting_box_item_frame)
-
- def _setSettingBoxLabels(self, sb__attr_name, setting_box_frame_wrapper, for_var_label_text, for_var_desc_text=None, expand_label_frame:bool=False):
-
- setting_box_labels_frame = CTkFrame(setting_box_frame_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- setting_box_labels_frame.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
-
- setting_box_labels_frame.grid_rowconfigure((0,3), weight=1)
- setting_box_label = CTkLabel(
- setting_box_labels_frame,
- textvariable=for_var_label_text,
- anchor="w",
- height=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__LABEL_FONT_SIZE, weight="normal"),
- text_color=self.settings.ctm.LABELS_TEXT_COLOR
- )
- setting_box_label.grid(row=1, column=0, padx=0, pady=0, sticky="ew")
- self.config_window.sb__widgets[sb__attr_name].label_widget = setting_box_label
-
-
- if for_var_desc_text is not None:
- setting_box_desc = CTkLabel(
- setting_box_labels_frame,
- textvariable=for_var_desc_text,
- anchor="w",
- justify="left",
- height=0,
- wraplength=int(self.settings.uism.MAIN_AREA_MIN_WIDTH / 2),
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__DESC_FONT_SIZE, weight="normal"),
- text_color=self.settings.ctm.LABELS_DESC_TEXT_COLOR
- )
- if expand_label_frame is True:
- setting_box_desc.configure(wraplength=self.settings.uism.MAIN_AREA_MIN_WIDTH)
-
- setting_box_desc.grid(row=2, column=0, padx=0, pady=(self.settings.uism.SB__DESC_TOP_PADY,0), sticky="ew")
- self.config_window.additional_widgets.append(setting_box_desc)
- self.config_window.sb__widgets[sb__attr_name].desc_widget=setting_box_desc
- else:
- self.config_window.sb__widgets[sb__attr_name].desc_widget=None
-
-
- def createSettingBox_Labels(
- self,
- for_var_label_text,
- labels_attr_name,
- for_var_desc_text=None,
- ):
-
- setting_box_frame= self._createSettingBoxFrame(labels_attr_name, for_var_label_text, for_var_desc_text, expand_label_frame=True)
-
- return setting_box_frame
-
-
-
- def createSettingBoxDropdownMenu(
- self,
- for_var_label_text, for_var_desc_text,
- optionmenu_attr_name,
- command,
- dropdown_menu_min_width=None,
- dropdown_menu_values=None,
- variable=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(optionmenu_attr_name, for_var_label_text, for_var_desc_text)
-
- def adjustedCommand(value):
- variable.set(value)
- command(value)
-
-
- (option_menu_widget, optionmenu_label_widget, optionmenu_img_widget) = createOptionMenuBox(
- parent_widget=setting_box_item_frame,
- optionmenu_bg_color=self.settings.ctm.SB__OPTIONMENU_BG_COLOR,
- optionmenu_hovered_bg_color=self.settings.ctm.SB__OPTIONMENU_HOVERED_BG_COLOR,
- optionmenu_clicked_bg_color=self.settings.ctm.SB__OPTIONMENU_CLICKED_BG_COLOR,
- optionmenu_ipadx=self.settings.uism.SB__OPTIONMENU_IPADX,
- optionmenu_ipady=self.settings.uism.SB__OPTIONMENU_IPADY,
- optionmenu_padx_between_img=self.settings.uism.SB__OPTIONMENU_IPADX_BETWEEN_IMG,
- optionmenu_min_height=self.settings.uism.SB__OPTIONMENU_MIN_HEIGHT,
- optionmenu_min_width=self.settings.uism.SB__OPTIONMENU_MIN_WIDTH,
- variable=variable,
- font_family=self.settings.FONT_FAMILY,
- font_size=self.settings.uism.SB__OPTION_MENU_FONT_SIZE,
- text_color=self.settings.ctm.LABELS_TEXT_COLOR,
- image_file=self.settings.image_file.ARROW_LEFT.rotate(90),
- image_size=self.settings.uism.SB__OPTIONMENU_IMG_SIZE,
- optionmenu_clicked_command=lambda _e: self.dropdown_menu_window.show(
- dropdown_menu_widget_id=optionmenu_attr_name,
- ),
- )
-
-
- self.config_window.sb__widgets[optionmenu_attr_name].optionmenu_box = option_menu_widget
- self.config_window.sb__widgets[optionmenu_attr_name].optionmenu_label_widget = optionmenu_label_widget
- self.config_window.sb__widgets[optionmenu_attr_name].optionmenu_img_widget = optionmenu_img_widget
-
-
- option_menu_widget.grid(row=1, column=SETTING_BOX_COLUMN, sticky="e")
- setattr(self.config_window, optionmenu_attr_name, option_menu_widget)
-
- self.dropdown_menu_window.createDropdownMenuBox(
- dropdown_menu_widget_id=optionmenu_attr_name,
- dropdown_menu_values=dropdown_menu_values,
- command=adjustedCommand,
- wrapper_widget=self.config_window.main_bg_container,
- attach_widget=option_menu_widget,
- dropdown_menu_min_width=dropdown_menu_min_width,
- )
-
- return setting_box_frame
-
-
-
-
- def createSettingBoxSwitch(self,
- for_var_label_text, for_var_desc_text,
- switch_attr_name,
- variable,
- command,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(switch_attr_name, for_var_label_text, for_var_desc_text)
-
- switch_widget = CTkSwitch(
- setting_box_item_frame,
- text=None,
- height=0,
- width=0,
- corner_radius=int(self.settings.uism.SB__SWITCH_BOX_HEIGHT/2),
- border_width=0,
- switch_height=self.settings.uism.SB__SWITCH_BOX_HEIGHT,
- switch_width=self.settings.uism.SB__SWITCH_BOX_WIDTH,
- onvalue=True,
- offvalue=False,
- variable=variable,
- command=command,
- fg_color=self.settings.ctm.SB__SWITCH_BOX_BG_COLOR,
- progress_color=self.settings.ctm.SB__SWITCH_BOX_ACTIVE_BG_COLOR,
- button_color=self.settings.ctm.SB__SWITCH_BOX_BUTTON_COLOR,
- button_hover_color=self.settings.ctm.SB__SWITCH_BOX_BUTTON_HOVERED_COLOR,
- )
- setattr(self.config_window, switch_attr_name, switch_widget)
-
- self.config_window.sb__widgets[switch_attr_name].switch_box = switch_widget
-
- switch_widget.grid(row=1, column=SETTING_BOX_COLUMN, sticky="e")
-
- return setting_box_frame
-
-
-
- def createSettingBoxCheckbox(self,
- for_var_label_text,
- checkbox_attr_name,
- command,
- variable,
- for_var_desc_text=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(checkbox_attr_name, for_var_label_text, for_var_desc_text)
-
- checkbox_widget = CTkCheckBox(
- setting_box_item_frame,
- text=None,
- width=0,
- checkbox_width=self.settings.uism.SB__CHECKBOX_SIZE,
- checkbox_height=self.settings.uism.SB__CHECKBOX_SIZE,
- onvalue=True,
- offvalue=False,
- variable=variable,
- command=command,
- corner_radius=self.settings.uism.SB__CHECKBOX_CORNER_RADIUS,
- border_width=self.settings.uism.SB__CHECKBOX_BORDER_WIDTH,
- border_color=self.settings.ctm.SB__CHECKBOX_BORDER_COLOR,
- hover_color=self.settings.ctm.SB__CHECKBOX_HOVER_COLOR,
- checkmark_color=self.settings.ctm.SB__CHECKBOX_CHECKMARK_COLOR,
- fg_color=self.settings.ctm.SB__CHECKBOX_CHECKED_COLOR,
- )
- setattr(self.config_window, checkbox_attr_name, checkbox_widget)
-
- self.config_window.sb__widgets[checkbox_attr_name].checkbox = checkbox_widget
-
- checkbox_widget.grid(row=1, column=SETTING_BOX_COLUMN, sticky="e")
-
- return setting_box_frame
-
-
-
- # 3 Options
- def createSettingBoxRadioButtons(
- self,
- for_var_label_text, for_var_desc_text,
- radio_button_attr_name,
- variable,
- command,
- radiobutton_keys_values=dict,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(radio_button_attr_name, for_var_label_text, for_var_desc_text)
-
- row=0
- for key, value in radiobutton_keys_values.items():
- radiobutton_wrapper = CTkFrame(setting_box_item_frame, corner_radius=6, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0, cursor="hand2")
- radiobutton_wrapper.grid(row=row, column=0, sticky="ew")
- row+=1
-
- radiobutton_wrapper.grid_rowconfigure((0,2), weight=1)
- setting_box_radio_button = CTkRadioButton(
- radiobutton_wrapper,
- textvariable=value,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__RADIO_BUTTON_FONT_SIZE, weight="normal"),
- variable=variable,
- value=key,
- text_color=self.settings.ctm.SB__RADIOBUTTON_TEXT_COLOR,
- fg_color=self.settings.ctm.SB__RADIOBUTTON_SELECTED_COLOR,
- border_color=self.settings.ctm.SB__RADIOBUTTON_BORDER_COLOR,
- hover=False
- )
- setting_box_radio_button.grid(row=1, column=0, padx=10, pady=10, sticky="ew")
-
- if key == variable.get():
- setting_box_radio_button.select()
-
- setting_box_radio_button._canvas.unbind("")
- setting_box_radio_button._text_label.unbind("")
- setting_box_radio_button._text_label.grid(padx=(10,0))
-
-
- def buttonPressedFunction(radiobutton_wrapper, radiobutton_widget, _e):
- radiobutton_wrapper.configure(fg_color=self.settings.ctm.SB__RADIOBUTTON_BG_CLICKED_COLOR)
-
- def buttonReleasedFunction(radiobutton_wrapper, radiobutton_widget, _e):
- radiobutton_wrapper.configure(fg_color=self.settings.ctm.SB__RADIOBUTTON_BG_HOVERED_COLOR)
- radiobutton_widget.select()
- command()
-
- def enterFunction(radiobutton_wrapper, _e):
- radiobutton_wrapper.configure(fg_color=self.settings.ctm.SB__RADIOBUTTON_BG_HOVERED_COLOR)
-
- def leaveFunction(radiobutton_wrapper, _e):
- radiobutton_wrapper.configure(fg_color=self.settings.ctm.SB__BG_COLOR)
-
-
- bindEnterAndLeaveFunction(
- target_widgets=[radiobutton_wrapper, setting_box_radio_button, setting_box_radio_button._bg_canvas],
- enterFunction=partial(enterFunction, radiobutton_wrapper),
- leaveFunction=partial(leaveFunction, radiobutton_wrapper)
- )
-
- bindButtonPressFunction(
- target_widgets=[radiobutton_wrapper, setting_box_radio_button, setting_box_radio_button._bg_canvas],
- buttonPressedFunction=partial(buttonPressedFunction, radiobutton_wrapper, setting_box_radio_button)
- )
-
- bindButtonReleaseFunction(
- target_widgets=[radiobutton_wrapper, setting_box_radio_button, setting_box_radio_button._bg_canvas],
- buttonReleasedFunction=partial(buttonReleasedFunction, radiobutton_wrapper, setting_box_radio_button)
- )
-
-
- return setting_box_frame
-
-
-
- def createSettingBoxAutoExportMessageLogs(
- self,
- for_var_label_text, for_var_desc_text,
- checkbox_attr_name,
- checkbox_command,
- button_command,
- variable,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(checkbox_attr_name, for_var_label_text, for_var_desc_text)
-
-
-
- all_wrapper = CTkFrame(setting_box_item_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- all_wrapper.grid(row=1, column=0, sticky="ew")
-
- all_wrapper.grid_columnconfigure(1, weight=1)
-
-
-
-
- button_widget = createButtonWithImage(
- parent_widget=all_wrapper,
- button_fg_color=self.settings.ctm.SB__BUTTON_COLOR,
- button_enter_color=self.settings.ctm.SB__BUTTON_HOVERED_COLOR,
- button_clicked_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
- button_image_file=self.settings.image_file.FOLDER_OPEN_ICON,
- button_image_size=self.settings.uism.SB__BUTTON_ICON_SIZE,
- corner_radius=self.settings.uism.SB__BUTTON_CORNER_RADIUS,
- button_ipadxy=self.settings.uism.SB__BUTTON_IPADXY,
- button_command=button_command,
- )
- button_widget.grid(row=0, column=0, padx=0, sticky="w")
-
-
-
- checkbox_widget = CTkCheckBox(
- all_wrapper,
- text=None,
- width=0,
- checkbox_width=self.settings.uism.SB__CHECKBOX_SIZE,
- checkbox_height=self.settings.uism.SB__CHECKBOX_SIZE,
- onvalue=True,
- offvalue=False,
- variable=variable,
- command=checkbox_command,
- corner_radius=self.settings.uism.SB__CHECKBOX_CORNER_RADIUS,
- border_width=self.settings.uism.SB__CHECKBOX_BORDER_WIDTH,
- border_color=self.settings.ctm.SB__CHECKBOX_BORDER_COLOR,
- hover_color=self.settings.ctm.SB__CHECKBOX_HOVER_COLOR,
- checkmark_color=self.settings.ctm.SB__CHECKBOX_CHECKMARK_COLOR,
- fg_color=self.settings.ctm.SB__CHECKBOX_CHECKED_COLOR,
- )
- setattr(self.config_window, checkbox_attr_name, checkbox_widget)
-
- checkbox_widget.grid(row=0, column=2, sticky="e")
-
- return setting_box_frame
-
-
-
-
-
-
- def createSettingBoxSlider(
- self,
- for_var_label_text, for_var_desc_text,
- slider_attr_name,
- slider_range,
- command,
- variable,
- slider_number_of_steps: Union[int,
- None] = None,
- slider_bind__ButtonPress=None,
- slider_bind__ButtonRelease=None,
- sliderTooltipFormatter=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(slider_attr_name, for_var_label_text, for_var_desc_text)
-
- if slider_number_of_steps is None:
- slider_number_of_steps = int(slider_range[1] - slider_range[0])
-
- slider_widget = CTkSlider(
- setting_box_item_frame,
- width=self.settings.uism.SB__SLIDER_WIDTH,
- height=self.settings.uism.SB__SLIDER_HEIGHT,
- from_=slider_range[0],
- to=slider_range[1],
- number_of_steps=slider_number_of_steps,
- fg_color=self.settings.ctm.SB__SLIDER_BG_COLOR,
- progress_color=self.settings.ctm.SB__SLIDER_PROGRESS_BG_COLOR,
- button_color=self.settings.ctm.SB__SLIDER_BUTTON_COLOR,
- button_hover_color=self.settings.ctm.SB__SLIDER_BUTTON_HOVERED_COLOR,
- command=command,
- variable=variable,
- )
- setattr(self.config_window, slider_attr_name, slider_widget)
-
- def getSliderValueWAfterFormatting():
- return sliderTooltipFormatter(variable.get()) if sliderTooltipFormatter else variable.get()
-
-
-
- slider_tooltip = CTkToolTip(
- slider_widget,
- message=getSliderValueWAfterFormatting(),
- delay=0,
- bg_color=self.settings.ctm.SB__SLIDER_TOOLTIP_BG_COLOR,
- corner_radius=0,
- text_color=self.settings.ctm.SB__SLIDER_TOOLTIP_TEXT_COLOR,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__SLIDER_TOOLTIP_FONT_SIZE, weight="normal"),
- )
-
- slider_widget.grid(row=1, column=SETTING_BOX_COLUMN, sticky="e")
-
- if slider_bind__ButtonPress is not None:
- def adjusted_slider_bind__ButtonPress(_e):
- command(_e)
- slider_tooltip.configure(message=getSliderValueWAfterFormatting())
- slider_bind__ButtonPress()
- slider_widget.configure(command=adjusted_slider_bind__ButtonPress)
-
- if slider_bind__ButtonRelease is not None:
- def adjusted_slider_bind__ButtonRelease(_e):
- slider_bind__ButtonRelease()
- slider_widget.bind("", adjusted_slider_bind__ButtonRelease, "+")
-
- return setting_box_frame
-
-
-
-
- def createSettingBoxProgressbarXSlider(
- self,
- command, progressbar_x_slider_attr_name,
- entry_attr_name, entry_bind__FocusOut,
- slider_attr_name, slider_range,
- progressbar_attr_name,
- passive_button_attr_name, passive_button_command,
- active_button_attr_name, active_button_command,
- disabled_button_attr_name, disabled_button_image_file,
- button_image_file,
-
- entry_variable,
- slider_variable,
-
- slider_number_of_steps: Union[int, None] = None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(progressbar_x_slider_attr_name)
-
- def adjusted_command__for_entry_bind__Any_KeyRelease(e):
- command(e.widget.get())
- def adjusted_command__for_slider(value):
- command(value)
-
- setting_box_item_frame.grid_columnconfigure((0,2), weight=0)
- setting_box_item_frame.grid_columnconfigure(1, weight=1)
- entry_widget = CTkEntry(
- setting_box_item_frame,
- text_color=self.settings.ctm.SB__ENTRY_TEXT_COLOR,
- fg_color=self.settings.ctm.SB__ENTRY_BG_COLOR,
- border_color=self.settings.ctm.SB__ENTRY_BORDER_COLOR,
- width=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__ENTRY_WIDTH,
- height=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__ENTRY_HEIGHT,
- textvariable=entry_variable,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__ENTRY_FONT_SIZE, weight="normal"),
- )
-
- entry_widget.bind("", adjusted_command__for_entry_bind__Any_KeyRelease)
- if entry_bind__FocusOut is not None:
- entry_widget.bind("", entry_bind__FocusOut, "+")
-
- entry_widget.grid(row=1, column=2, padx=0, pady=0, sticky="e")
- setattr(self.config_window, entry_attr_name, entry_widget)
-
-
-
- # at least 2px is needed otherwise the slider button is gonna broken.
- SLIDER_BORDER_WIDTH = max(2,self.settings.uism.SB__PROGRESSBAR_X_SLIDER__SLIDER_BUTTON_LENGTH)
- SLIDER_BUTTON_LENGTH = int(SLIDER_BORDER_WIDTH/2)
- slider_widget = CTkSlider(
- setting_box_item_frame,
- from_=slider_range[0],
- to=slider_range[1],
- number_of_steps=slider_number_of_steps,
- command=adjusted_command__for_slider,
- variable=slider_variable,
- height=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__SLIDER_HEIGHT,
- border_width=0,
- button_length=SLIDER_BORDER_WIDTH,
- button_corner_radius=SLIDER_BUTTON_LENGTH,
- corner_radius=0,
- button_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__SLIDER_BUTTON_COLOR,
- button_hover_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__SLIDER_BUTTON_HOVERED_COLOR,
- fg_color=self.settings.ctm.SB__BG_COLOR,
- progress_color=self.settings.ctm.SB__BG_COLOR,
- border_color=self.settings.ctm.SB__BG_COLOR,
- )
- slider_widget.grid(row=1, column=1, padx=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__BAR_PADX, sticky="ew")
- setattr(self.config_window, slider_attr_name, slider_widget)
-
-
-
-
- progressbar_widget = CTkProgressBar(
- setting_box_item_frame,
- height=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_HEIGHT,
- corner_radius=0,
- fg_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_BG_COLOR,
- progress_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_PROGRESS_BG_COLOR,
- )
- setattr(self.config_window, progressbar_attr_name, progressbar_widget)
- progressbar_widget.grid(row=1, column=1, padx=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__BAR_PADX, sticky="ew")
- progressbar_widget.set(0)
-
-
-
-
- passive_button_wrapper = self._createPassiveButtonForProgressbarXSlider(setting_box_item_frame, passive_button_command, button_image_file)
- setattr(self.config_window, passive_button_attr_name, passive_button_wrapper)
-
- disabled_button_wrapper = self._createDisabledButtonForProgressbarXSlider(setting_box_item_frame, disabled_button_image_file)
- setattr(self.config_window, disabled_button_attr_name, disabled_button_wrapper)
-
- active_button_wrapper = self._createActiveButtonForProgressbarXSlider(setting_box_item_frame, active_button_command, button_image_file)
- setattr(self.config_window, active_button_attr_name, active_button_wrapper)
-
- passive_button_wrapper.grid(row=1, column=0, padx=0, sticky="w")
- passive_button_wrapper.configure(corner_radius=int(getLatestWidth(passive_button_wrapper)/2))
-
- disabled_button_wrapper.grid(row=1, column=0, padx=0, sticky="w")
- disabled_button_wrapper.configure(corner_radius=int(getLatestWidth(passive_button_wrapper)/2))
-
- active_button_wrapper.grid(row=1, column=0, padx=0, sticky="w")
- active_button_wrapper.configure(corner_radius=int(getLatestWidth(passive_button_wrapper)/2))
-
- passive_button_wrapper.grid_remove()
- disabled_button_wrapper.grid_remove()
- active_button_wrapper.grid_remove()
-
- passive_button_wrapper.grid()
- return setting_box_frame
-
-
-
-
- def createSettingBoxEntry(self,
- for_var_label_text, for_var_desc_text,
- entry_attr_name,
- entry_width,
- entry_textvariable,
- entry_bind__Any_KeyRelease,
- entry_bind__FocusOut=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(entry_attr_name, for_var_label_text, for_var_desc_text)
-
- def adjusted_command__for_entry_bind__Any_KeyRelease(e):
- entry_bind__Any_KeyRelease(e.widget.get())
-
- entry_widget = CTkEntry(
- setting_box_item_frame,
- text_color=self.settings.ctm.SB__ENTRY_TEXT_COLOR,
- fg_color=self.settings.ctm.SB__ENTRY_BG_COLOR,
- border_color=self.settings.ctm.SB__ENTRY_BORDER_COLOR,
- width=entry_width,
- height=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__ENTRY_HEIGHT,
- textvariable=entry_textvariable,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__ENTRY_FONT_SIZE, weight="normal"),
- )
- entry_widget.bind("", adjusted_command__for_entry_bind__Any_KeyRelease)
- setattr(self.config_window, entry_attr_name, entry_widget)
-
-
- entry_widget.grid(row=1, column=SETTING_BOX_COLUMN, sticky="e")
-
- if entry_bind__FocusOut is not None:
- entry_widget.bind("", entry_bind__FocusOut, "+")
-
- return setting_box_frame
-
-
- def createSettingBoxEntry_AuthKey(self,
- for_var_label_text, for_var_desc_text,
- entry_attr_name,
- entry_width,
- entry_textvariable,
- entry_bind__Any_KeyRelease,
- entry_bind__FocusOut=None,
- open_authkey_page_command=None,
- open_authkey_text_variable=None,
- image_file=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(entry_attr_name, for_var_label_text, for_var_desc_text)
-
-
- all_wrapper = CTkFrame(setting_box_item_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- all_wrapper.grid(row=1, column=0, sticky="ew")
-
- all_wrapper.grid_columnconfigure(0, weight=1)
-
-
- def adjusted_command__for_entry_bind__Any_KeyRelease(e):
- entry_bind__Any_KeyRelease(e.widget.get())
-
- entry_widget = CTkEntry(
- all_wrapper,
- text_color=self.settings.ctm.SB__ENTRY_TEXT_COLOR,
- fg_color=self.settings.ctm.SB__ENTRY_BG_COLOR,
- border_color=self.settings.ctm.SB__ENTRY_BORDER_COLOR,
- width=entry_width,
- height=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__ENTRY_HEIGHT,
- textvariable=entry_textvariable,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__ENTRY_FONT_SIZE, weight="normal"),
- )
- entry_widget.bind("", adjusted_command__for_entry_bind__Any_KeyRelease)
- setattr(self.config_window, entry_attr_name, entry_widget)
-
-
- entry_widget.grid(row=0, column=SETTING_BOX_COLUMN, sticky="e")
-
- if entry_bind__FocusOut is not None:
- entry_widget.bind("", entry_bind__FocusOut, "+")
-
-
-
- (open_page_button, label_button_label_widget, label_button_img_widget) = createLabelButton(
- parent_widget=all_wrapper,
- label_button_bg_color=self.settings.ctm.SB__BUTTON_COLOR,
- label_button_hovered_bg_color=self.settings.ctm.SB__BUTTON_HOVERED_COLOR,
- label_button_clicked_bg_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
- label_button_ipadx=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_IPADX,
- label_button_ipady=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_IPADY,
- variable=open_authkey_text_variable,
- font_family=self.settings.FONT_FAMILY,
- font_size=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_LABEL_FONT_SIZE,
- text_color=self.settings.ctm.LABELS_TEXT_COLOR,
- label_button_clicked_command=open_authkey_page_command,
-
- label_button_position="center",
-
- image_file=image_file,
- image_size=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_IMG_SIZE,
- label_button_padx_between_img=self.settings.uism.SB__AUTHKEY_WEBPAGE_PADX_BETWEEN_LABEL_AND_ICON,
- )
- open_page_button.grid(row=1, column=SETTING_BOX_COLUMN, pady=(self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_TOP_PADY,0))
-
-
- return setting_box_frame
-
-
-
-
- def createSettingBoxMessageFormatEntries_WithTranslation(self,
- base_entry_attr_name,
- entry_textvariable_0,
- entry_textvariable_1,
- entry_textvariable_2,
- textvariable_0,
- textvariable_1,
- example_label_textvariable,
- swap_button_command,
- entry_bind__Any_KeyRelease,
- entry_bind__FocusOut=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(base_entry_attr_name)
-
-
- all_wrapper = CTkFrame(setting_box_item_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- all_wrapper.grid(row=1, column=0, sticky="ew")
-
- all_wrapper.grid_columnconfigure(0, weight=1)
-
-
- example_box_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- example_box_wrapper.grid(row=0, column=0, pady=self.settings.uism.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY, sticky="ew")
-
- entries_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- entries_wrapper.grid(row=1, column=0, pady=self.settings.uism.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY, sticky="ew")
-
- swap_button_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- swap_button_wrapper.grid(row=2, column=0, sticky="e")
-
-
-
-
-
- example_box_wrapper.grid_columnconfigure((0,2), weight=1)
- example_frame_widget = CTkFrame(example_box_wrapper, corner_radius=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_CORNER_RADIUS, fg_color=self.settings.ctm.SB__MESSAGE_FORMAT__EXAMPLE_BG_COLOR, width=0, height=0)
- example_frame_widget.grid(row=0, column=1)
-
- example_frame_widget.grid_rowconfigure((0,2), weight=1)
- example_frame_widget.grid_columnconfigure((0,2), weight=1)
- example_label_widget = CTkLabel(
- example_frame_widget,
- textvariable=example_label_textvariable,
- anchor="center",
- justify="center",
- wraplength=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_WRAP_LENGTH,
- height=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
- text_color=self.settings.ctm.SB__MESSAGE_FORMAT__EXAMPLE_TEXT_COLOR,
- )
- example_label_widget.grid(row=1, column=1, padx=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY, pady=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY, sticky="ew")
-
- self.config_window.additional_widgets.append(example_box_wrapper)
-
-
-
-
- entry_textvariables = [entry_textvariable_0, entry_textvariable_1, entry_textvariable_2]
- for i in range(3):
- entry_widget = CTkEntry(
- entries_wrapper,
- text_color=self.settings.ctm.SB__ENTRY_TEXT_COLOR,
- fg_color=self.settings.ctm.SB__ENTRY_BG_COLOR,
- border_color=self.settings.ctm.SB__ENTRY_BORDER_COLOR,
- height=self.settings.uism.SB__MESSAGE_FORMAT__ENTRY_HEIGHT,
- textvariable=entry_textvariables[i],
- justify="center",
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__ENTRY_FONT_SIZE, weight="normal"),
- )
- setattr(self.config_window, base_entry_attr_name + "_" + str(i), entry_widget)
-
-
-
- if entry_bind__FocusOut is not None:
- entry_widget.bind("", entry_bind__FocusOut, "+")
-
-
- label_frame_widget_0 = CTkFrame(entries_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
-
- label_frame_widget_0.grid_rowconfigure((0,2), weight=1)
- label_frame_widget_0.grid_columnconfigure(0, weight=1)
- label_widget_0 = CTkLabel(
- label_frame_widget_0,
- textvariable=textvariable_0,
- anchor="center",
- height=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
- text_color=self.settings.ctm.LABELS_TEXT_COLOR
- )
- label_widget_0.grid(row=1, column=0, padx=0, pady=0, sticky="ew")
-
-
- label_frame_widget_1 = CTkFrame(entries_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
-
- label_frame_widget_1.grid_rowconfigure((0,2), weight=1)
- label_frame_widget_1.grid_columnconfigure(0, weight=1)
- label_widget_1 = CTkLabel(
- label_frame_widget_1,
- textvariable=textvariable_1,
- anchor="center",
- height=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
- text_color=self.settings.ctm.LABELS_TEXT_COLOR
- )
- label_widget_1.grid(row=1, column=0, padx=0, pady=0, sticky="ew")
-
-
- entries_wrapper.grid_columnconfigure((0,2,4), weight=1)
- entries_wrapper.grid_columnconfigure((1,3), weight=0, uniform="message_format_fixed_labels")
-
- entry_widget_0 = getattr(self.config_window, base_entry_attr_name+"_0")
- entry_widget_1 = getattr(self.config_window, base_entry_attr_name+"_1")
- entry_widget_2 = getattr(self.config_window, base_entry_attr_name+"_2")
- entry_widget_0.grid(row=0, column=0, sticky="ew")
- entry_widget_1.grid(row=0, column=2, sticky="ew")
- entry_widget_2.grid(row=0, column=4, sticky="ew")
- label_frame_widget_0.grid(row=0, column=1, padx=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_PADX, sticky="ew")
- label_frame_widget_1.grid(row=0, column=3, padx=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_PADX, sticky="ew")
-
- def adjusted_command__for_entry_bind__Any_KeyRelease(_e):
- message_format = entry_widget_0.get() + textvariable_0.get() + entry_widget_1.get() + textvariable_1.get() + entry_widget_2.get()
- entry_bind__Any_KeyRelease(message_format)
-
-
- entry_widget_0.bind("", adjusted_command__for_entry_bind__Any_KeyRelease)
- entry_widget_1.bind("", adjusted_command__for_entry_bind__Any_KeyRelease)
- entry_widget_2.bind("", adjusted_command__for_entry_bind__Any_KeyRelease)
-
-
-
-
-
-
- swap_button = CTkFrame(swap_button_wrapper, corner_radius=self.settings.uism.BUTTONS_CORNER_RADIUS, fg_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR, cursor="hand2")
- swap_button.grid(row=0, column=2, sticky="ew")
-
-
- swap_button.grid_columnconfigure(0, weight=1)
- swap_button_label_wrapper = CTkFrame(swap_button, corner_radius=0, fg_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR)
- swap_button_label_wrapper.grid(row=0, column=0, padx=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_IPADX, pady=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_IPADY, sticky="ew")
-
-
- swap_button_label_wrapper.grid_columnconfigure((0,4), weight=1)
- swap_button_label_wrapper.grid_rowconfigure((0,2), weight=1)
-
- swap_button_label_0 = CTkLabel(
- swap_button_label_wrapper,
- textvariable=textvariable_0,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.LABELS_TEXT_COLOR,
- )
- swap_button_label_0.grid(row=1, column=1)
-
- swap_button_both_direction_arrow_img = CTkLabel(
- swap_button_label_wrapper,
- text=None,
- height=0,
- corner_radius=0,
- image=CTkImage((self.settings.image_file.SWAP_ICON), size=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_ARROWS_IMG_SIZE),
- anchor="w",
- text_color=self.settings.ctm.LABELS_TEXT_COLOR,
- )
- swap_button_both_direction_arrow_img.grid(row=1, column=2, padx=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_TEXT_PADX)
-
- swap_button_label_1 = CTkLabel(
- swap_button_label_wrapper,
- textvariable=textvariable_1,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.LABELS_TEXT_COLOR,
- )
- swap_button_label_1.grid(row=1, column=3)
-
- bindButtonFunctionAndColor(
- target_widgets=[
- swap_button,
- swap_button_label_wrapper,
- swap_button_label_0,
- swap_button_both_direction_arrow_img,
- swap_button_label_1,
- ],
- enter_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_HOVERED_COLOR,
- leave_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR,
- clicked_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_CLICKED_COLOR,
- buttonReleasedFunction=swap_button_command,
- )
-
-
- return setting_box_frame
-
-
-
-
- def createSettingBoxMessageFormatEntries(self,
- base_entry_attr_name,
- entry_textvariable_0,
- entry_textvariable_1,
- textvariable_0,
- example_label_textvariable,
- entry_bind__Any_KeyRelease,
- entry_bind__FocusOut=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(base_entry_attr_name)
-
-
- all_wrapper = CTkFrame(setting_box_item_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- all_wrapper.grid(row=1, column=0, sticky="ew")
-
- all_wrapper.grid_columnconfigure(0, weight=1)
-
-
- example_box_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- example_box_wrapper.grid(row=0, column=0, pady=self.settings.uism.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY, sticky="ew")
-
- entries_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- entries_wrapper.grid(row=1, column=0, pady=self.settings.uism.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY, sticky="ew")
-
-
-
-
- example_box_wrapper.grid_columnconfigure((0,2), weight=1)
- example_frame_widget = CTkFrame(example_box_wrapper, corner_radius=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_CORNER_RADIUS, fg_color=self.settings.ctm.SB__MESSAGE_FORMAT__EXAMPLE_BG_COLOR, width=0, height=0)
- example_frame_widget.grid(row=0, column=1)
-
- example_frame_widget.grid_rowconfigure((0,2), weight=1)
- example_frame_widget.grid_columnconfigure((0,2), weight=1)
- example_label_widget = CTkLabel(
- example_frame_widget,
- textvariable=example_label_textvariable,
- anchor="center",
- justify="center",
- wraplength=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_WRAP_LENGTH,
- height=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
- text_color=self.settings.ctm.SB__MESSAGE_FORMAT__EXAMPLE_TEXT_COLOR,
- )
- example_label_widget.grid(row=1, column=1, padx=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY, pady=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY, sticky="ew")
-
- self.config_window.additional_widgets.append(example_box_wrapper)
-
-
-
-
- entry_textvariables = [entry_textvariable_0, entry_textvariable_1]
- for i in range(2):
- entry_widget = CTkEntry(
- entries_wrapper,
- text_color=self.settings.ctm.SB__ENTRY_TEXT_COLOR,
- fg_color=self.settings.ctm.SB__ENTRY_BG_COLOR,
- border_color=self.settings.ctm.SB__ENTRY_BORDER_COLOR,
- height=self.settings.uism.SB__MESSAGE_FORMAT__ENTRY_HEIGHT,
- textvariable=entry_textvariables[i],
- justify="center",
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__ENTRY_FONT_SIZE, weight="normal"),
- )
- setattr(self.config_window, base_entry_attr_name + "_" + str(i), entry_widget)
-
-
-
- if entry_bind__FocusOut is not None:
- entry_widget.bind("", entry_bind__FocusOut, "+")
-
-
- label_frame_widget_0 = CTkFrame(entries_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
-
- label_frame_widget_0.grid_rowconfigure((0,2), weight=1)
- label_frame_widget_0.grid_columnconfigure(0, weight=1)
- label_widget_0 = CTkLabel(
- label_frame_widget_0,
- textvariable=textvariable_0,
- anchor="center",
- height=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
- text_color=self.settings.ctm.LABELS_TEXT_COLOR
- )
- label_widget_0.grid(row=1, column=0, padx=0, pady=0, sticky="ew")
-
-
-
-
-
- entries_wrapper.grid_columnconfigure((0,2), weight=1)
- entries_wrapper.grid_columnconfigure(1, weight=0)
-
- entry_widget_0 = getattr(self.config_window, base_entry_attr_name+"_0")
- entry_widget_1 = getattr(self.config_window, base_entry_attr_name+"_1")
- entry_widget_0.grid(row=0, column=0, sticky="ew")
- entry_widget_1.grid(row=0, column=2, sticky="ew")
- label_frame_widget_0.grid(row=0, column=1, padx=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_PADX, sticky="ew")
-
- def adjusted_command__for_entry_bind__Any_KeyRelease(_e):
- message_format = entry_widget_0.get() + textvariable_0.get() + entry_widget_1.get()
- entry_bind__Any_KeyRelease(message_format)
-
-
- entry_widget_0.bind("", adjusted_command__for_entry_bind__Any_KeyRelease)
- entry_widget_1.bind("", adjusted_command__for_entry_bind__Any_KeyRelease)
-
-
-
- return setting_box_frame
-
-
-
- def createSettingBox_Overlay(self,
- for_var_label_text, for_var_desc_text,
- switch_attr_name,
- variable,
- command,
- for_var_button_label,
- label_button_clicked_command,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(switch_attr_name, for_var_label_text, for_var_desc_text)
-
-
- all_wrapper = CTkFrame(setting_box_item_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- all_wrapper.grid(row=1, column=0, sticky="ew")
-
- all_wrapper.grid_columnconfigure(1, weight=1)
-
-
-
-
- switch_widget = CTkSwitch(
- all_wrapper,
- text=None,
- height=0,
- width=0,
- corner_radius=int(self.settings.uism.SB__SWITCH_BOX_HEIGHT/2),
- border_width=0,
- switch_height=self.settings.uism.SB__SWITCH_BOX_HEIGHT,
- switch_width=self.settings.uism.SB__SWITCH_BOX_WIDTH,
- onvalue=True,
- offvalue=False,
- variable=variable,
- command=command,
- fg_color=self.settings.ctm.SB__SWITCH_BOX_BG_COLOR,
- progress_color=self.settings.ctm.SB__SWITCH_BOX_ACTIVE_BG_COLOR,
- button_color=self.settings.ctm.SB__SWITCH_BOX_BUTTON_COLOR,
- button_hover_color=self.settings.ctm.SB__SWITCH_BOX_BUTTON_HOVERED_COLOR,
- )
- setattr(self.config_window, switch_attr_name, switch_widget)
-
- self.config_window.sb__widgets[switch_attr_name].switch_box = switch_widget
-
- switch_widget.grid(row=0, pady=20, column=SETTING_BOX_COLUMN)
-
-
- (open_page_button, label_button_label_widget) = createLabelButton(
- parent_widget=all_wrapper,
- label_button_bg_color=self.settings.ctm.SB__BUTTON_COLOR,
- label_button_hovered_bg_color=self.settings.ctm.SB__BUTTON_HOVERED_COLOR,
- label_button_clicked_bg_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
- label_button_ipadx=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_IPADX,
- label_button_ipady=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_IPADY,
- variable=for_var_button_label,
- font_family=self.settings.FONT_FAMILY,
- font_size=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_LABEL_FONT_SIZE,
- text_color=self.settings.ctm.LABELS_TEXT_COLOR,
- label_button_clicked_command=label_button_clicked_command,
-
- label_button_position="center",
- )
- open_page_button.grid(row=1, column=SETTING_BOX_COLUMN, pady=(self.settings.uism.SB__OPEN_OVERLAY_SETTINGS_WINDOW,0))
-
-
- return setting_box_frame
-
-
- def createSettingBoxButtonWithImage(
- self,
- for_var_label_text, for_var_desc_text,
- button_attr_name,
- button_image,
- button_command,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(button_attr_name, for_var_label_text, for_var_desc_text)
-
-
- button_with_image_widget = createButtonWithImage(
- parent_widget=setting_box_item_frame,
- button_fg_color=self.settings.ctm.SB__BUTTON_COLOR,
- button_enter_color=self.settings.ctm.SB__BUTTON_HOVERED_COLOR,
- button_clicked_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
- button_image_file=button_image,
- button_image_size=self.settings.uism.SB__BUTTON_ICON_SIZE,
- corner_radius=self.settings.uism.SB__BUTTON_CORNER_RADIUS,
- button_ipadxy=self.settings.uism.SB__OPEN_CONFIG_FILE_BUTTON_IPADXY,
- button_command=button_command,
- )
- button_with_image_widget.grid(row=1, column=SETTING_BOX_COLUMN, sticky="e")
-
- return setting_box_frame
-
-
-
-
- def createSettingBoxArrowSwitch(
- self,
- for_var_label_text, for_var_desc_text,
- arrow_switch_attr_name,
- open_command,
- close_command,
- var_switch_desc=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(arrow_switch_attr_name, for_var_label_text, for_var_desc_text)
-
- ARROW_BUTTON_COLUMN = SETTING_BOX_COLUMN
-
- if var_switch_desc is not None:
- label_widget = CTkLabel(
- setting_box_item_frame,
- textvariable=var_switch_desc,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__ARROW_SWITCH_DESC_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.LABELS_DESC_TEXT_COLOR,
- )
-
- label_widget.grid(row=1, column=SETTING_BOX_COLUMN)
- ARROW_BUTTON_COLUMN = SETTING_BOX_COLUMN + 1
-
-
- for_opening_button_wrapper = createButtonWithImage(
- parent_widget=setting_box_item_frame,
- button_fg_color=self.settings.ctm.SB__BUTTON_COLOR,
- button_enter_color=self.settings.ctm.SB__BUTTON_HOVERED_COLOR,
- button_clicked_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
- button_image_file=self.settings.image_file.ARROW_LEFT.rotate(270),
- button_image_size=self.settings.uism.SB__BUTTON_ICON_SIZE,
- corner_radius=self.settings.uism.SB__BUTTON_CORNER_RADIUS,
- button_ipadxy=self.settings.uism.SB__BUTTON_IPADXY,
- button_command=open_command,
- )
- for_opening_button_wrapper.grid(row=1, column=ARROW_BUTTON_COLUMN, padx=self.settings.uism.SB__ARROW_SWITCH_LEFT_PADX, sticky="e")
-
- self.config_window.sb__widgets[arrow_switch_attr_name].arrow_switch_open = for_opening_button_wrapper
-
- for_closing_button_wrapper = createButtonWithImage(
- parent_widget=setting_box_item_frame,
- button_fg_color=self.settings.ctm.SB__BUTTON_COLOR,
- button_enter_color=self.settings.ctm.SB__BUTTON_HOVERED_COLOR,
- button_clicked_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
- button_image_file=self.settings.image_file.ARROW_LEFT.rotate(90),
- button_image_size=self.settings.uism.SB__BUTTON_ICON_SIZE,
- corner_radius=self.settings.uism.SB__BUTTON_CORNER_RADIUS,
- button_ipadxy=self.settings.uism.SB__BUTTON_IPADXY,
- button_command=close_command,
- )
- for_closing_button_wrapper.grid(row=1, column=ARROW_BUTTON_COLUMN, padx=self.settings.uism.SB__ARROW_SWITCH_LEFT_PADX, sticky="e")
- for_closing_button_wrapper.grid_remove()
-
- self.config_window.sb__widgets[arrow_switch_attr_name].arrow_switch_close = for_closing_button_wrapper
-
-
- return setting_box_frame
-
-
-
- # I've added it for the word filter, but it's not currently generalized. If you want to use it in the same way elsewhere, it will require refactoring.
- def createSettingBoxAddAndDeleteAbleList(
- self,
- add_and_delete_able_list_attr_name,
- entry_attr_name,
- entry_width,
- mic_word_filter_list,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(add_and_delete_able_list_attr_name)
-
- self.config_window.sb__widgets[add_and_delete_able_list_attr_name].items = []
-
-
- list_container = CTkFrame(setting_box_item_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- list_container.grid(row=1, column=0, sticky="nsew")
-
-
- max_width = int(self.MAIN_INNER_AREA_MIN_WIDTH - (self.settings.uism.SB__IPADX*2))
-
- def addValues(mic_word_filter_list, mic_word_filter_item_row_wrapper, accumulated_labels_width, row, column):
- for mic_word_filter_item in mic_word_filter_list:
- mic_word_filter_item_wrapper = self._createValue(add_and_delete_able_list_attr_name, mic_word_filter_item_row_wrapper, row, column, mic_word_filter_item)
-
- if int(accumulated_labels_width + getLatestWidth(mic_word_filter_item_wrapper) + self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_LEFT_PADX[1]) >= max_width:
- accumulated_labels_width = 0
- column = 0
- row += 1
- mic_word_filter_item_wrapper.destroy()
- mic_word_filter_item_row_wrapper = self._createRowFrame(list_container, row)
- mic_word_filter_item_wrapper = self._createValue(add_and_delete_able_list_attr_name, mic_word_filter_item_row_wrapper, row, column, mic_word_filter_item)
- column += 1
- else:
- column += 1
-
- accumulated_labels_width += int(getLatestWidth(mic_word_filter_item_wrapper) + self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_LEFT_PADX[1])
-
-
-
- return mic_word_filter_item_row_wrapper, accumulated_labels_width, row, column
-
- accumulated_labels_width = 0
- row=0
- column=0
- mic_word_filter_item_row_wrapper = self._createRowFrame(list_container, row)
-
-
- mic_word_filter_list = self.view_variable.MIC_WORD_FILTER_LIST
-
- mic_word_filter_item_row_wrapper, accumulated_labels_width, row, column = addValues(mic_word_filter_list, mic_word_filter_item_row_wrapper, accumulated_labels_width, row, column)
-
-
- self.config_window.sb__widgets[add_and_delete_able_list_attr_name].mic_word_filter_item_row_wrapper = mic_word_filter_item_row_wrapper
- self.config_window.sb__widgets[add_and_delete_able_list_attr_name].accumulated_labels_width = accumulated_labels_width
- self.config_window.sb__widgets[add_and_delete_able_list_attr_name].last_row = row
- self.config_window.sb__widgets[add_and_delete_able_list_attr_name].last_column = column
- self.config_window.sb__widgets[add_and_delete_able_list_attr_name].addValues = lambda values, mic_word_filter_item_row_wrapper, accumulated_labels_width, last_row, last_column: addValues(values, mic_word_filter_item_row_wrapper, accumulated_labels_width, last_row, last_column)
-
-
- entry_and_add_button_wrapper = CTkFrame(setting_box_item_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR)
- entry_and_add_button_wrapper.grid(row=2, column=0, pady=(self.settings.uism.SB__IPADY, 0), sticky="ew")
-
- entry_and_add_button_wrapper.grid_columnconfigure((0,3), weight=1)
-
-
-
- entry_widget = CTkEntry(
- entry_and_add_button_wrapper,
- text_color=self.settings.ctm.SB__ENTRY_TEXT_COLOR,
- fg_color=self.settings.ctm.SB__ENTRY_BG_COLOR,
- border_color=self.settings.ctm.SB__ENTRY_BORDER_COLOR,
- width=entry_width,
- placeholder_text="AAA or AAA,BBB,CCC",
- height=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__ENTRY_HEIGHT,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__ENTRY_FONT_SIZE, weight="normal"),
- )
- setattr(self.config_window, entry_attr_name, entry_widget)
-
- entry_widget.grid(row=0, column=1, sticky="ew")
-
-
-
- add_button = CTkFrame(entry_and_add_button_wrapper, corner_radius=self.settings.uism.BUTTONS_CORNER_RADIUS, fg_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_COLOR, cursor="hand2")
- add_button.grid(row=0, column=2, padx=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_LEFT_PADX, sticky="ew")
-
-
- add_button.grid_columnconfigure(0, weight=1)
- add_button_label_wrapper = CTkFrame(add_button, corner_radius=0, fg_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_COLOR)
- add_button_label_wrapper.grid(row=0, column=0, padx=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_IPADX, pady=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_IPADY, sticky="ew")
-
- add_button_label_wrapper.grid_columnconfigure((0,2), weight=1)
- add_button_label = CTkLabel(
- add_button_label_wrapper,
- textvariable=self.view_variable.VAR_LABEL_MIC_WORD_FILTER_ADD_BUTTON,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.LABELS_TEXT_COLOR,
- )
- add_button_label.grid(row=0, column=1)
-
-
- def adjustedCommand():
- callFunctionIfCallable(self.view_variable.CALLBACK_SET_MIC_WORD_FILTER, entry_widget.get())
- entry_widget.focus_set()
-
- bindButtonFunctionAndColor(
- target_widgets=[
- add_button,
- add_button_label_wrapper,
- add_button_label,
- ],
- enter_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_HOVERED_COLOR,
- leave_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_COLOR,
- clicked_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_CLICKED_COLOR,
- buttonReleasedFunction=lambda _e: adjustedCommand(),
- )
-
-
- return setting_box_frame
-
-
- def _createRowFrame(self, parent_widget, row):
- mic_word_filter_item_row_wrapper = CTkFrame(parent_widget, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- mic_word_filter_item_row_wrapper.grid(row=row, column=0, pady=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_BOTTOM_PADY, sticky="nsew")
-
- return mic_word_filter_item_row_wrapper
-
-
-
- def _createValue(self, add_and_delete_able_list_attr_name, parent_row_frame, row, column, mic_word_filter_item):
- mic_word_filter_item_wrapper = CTkFrame(parent_row_frame, corner_radius=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_CORNER_RADIUS, fg_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST_BG_COLOR, width=0, height=0)
- mic_word_filter_item_wrapper.grid(row=0, column=column, padx=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_LEFT_PADX, sticky="nsew")
- setattr(self, f"{row}_{column}", mic_word_filter_item_wrapper)
-
-
-
- mic_word_filter_item_wrapper.grid_rowconfigure((0,2), weight=1)
- label_widget = CTkLabel(
- mic_word_filter_item_wrapper,
- text=mic_word_filter_item,
- height=0,
- corner_radius=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=self.settings.ctm.BASIC_TEXT_COLOR,
- )
-
- label_widget.grid(row=1, column=0, padx=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADX, pady=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADY)
-
-
- if isEven(getLatestHeight(label_widget)) is False:
- label_widget.grid(
- pady=(
- self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADY,
- self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADY + 1
- )
- )
-
-
- if isEven(getLatestWidth(label_widget)) is False:
- label_widget.grid(
- padx=(
- self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADX[0],
- self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADX[1] + 1
- )
- )
-
-
-
- def pressedDeleteButtonCommand(_e, delete_button, redo_button):
- # overstrike true
- label_widget.configure(font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_FONT_SIZE, weight="normal", overstrike=True))
- # change fg_color
- mic_word_filter_item_wrapper.configure(fg_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST_DELETED_BG_COLOR)
- # change button img to redo button
- delete_button.grid_remove()
- redo_button.grid()
- # callback delete function
- callFunctionIfCallable(self.view_variable.CALLBACK_DELETE_MIC_WORD_FILTER, mic_word_filter_item)
-
- def pressedRedoButtonCommand(_e, delete_button, redo_button):
- # overstrike false
- label_widget.configure(font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_FONT_SIZE, weight="normal", overstrike=False))
- # change fg_color
- mic_word_filter_item_wrapper.configure(fg_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST_BG_COLOR)
- # change button img to delete button
- redo_button.grid_remove()
- delete_button.grid()
- # callback add function
- callFunctionIfCallable(self.view_variable.CALLBACK_SET_MIC_WORD_FILTER, mic_word_filter_item)
-
-
-
- delete_button = createButtonWithImage(
- parent_widget=mic_word_filter_item_wrapper,
- button_fg_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST_BG_COLOR,
- button_enter_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_HOVERED_BG_COLOR,
- button_clicked_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CLICKED_BG_COLOR,
- button_image_file=self.settings.image_file.CANCEL_ICON,
- button_image_size=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IMG_SIZE,
- corner_radius=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CORNER_RADIUS,
- button_ipadxy=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IPADXY,
- button_command=lambda _e: pressedDeleteButtonCommand(_e, delete_button, redo_button),
- )
- delete_button.grid(row=1, column=1, padx=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_PADX, sticky="e")
-
- redo_button = createButtonWithImage(
- parent_widget=mic_word_filter_item_wrapper,
- button_fg_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST_DELETED_BG_COLOR,
- button_enter_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__VALUES_DELETED_BUTTON_HOVERED_BG_COLOR,
- button_clicked_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__VALUES_DELETED_BUTTON_CLICKED_BG_COLOR,
- button_image_file=self.settings.image_file.REDO_ICON,
- button_image_size=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IMG_SIZE,
- corner_radius=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CORNER_RADIUS,
- button_ipadxy=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IPADXY,
- button_command=lambda _e: pressedRedoButtonCommand(_e, delete_button, redo_button),
- )
- redo_button.grid(row=1, column=1, padx=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_PADX, sticky="e")
- redo_button.grid_remove()
-
-
- partial_pressedRedoButtonCommand = partial(pressedRedoButtonCommand, _e=None, delete_button=delete_button, redo_button=redo_button)
- item_data = SimpleNamespace(
- label = mic_word_filter_item,
- redoFunction = lambda: partial_pressedRedoButtonCommand(),
- )
-
-
- items = self.config_window.sb__widgets[add_and_delete_able_list_attr_name].items
- if len(items) == 0:
- items.append(item_data)
- else:
- is_replaced = False
- for i, item in enumerate(items):
- if item.label == mic_word_filter_item:
- items[i] = item_data
- is_replaced = True
- break
- if is_replaced is False:
- items.append(item_data)
-
-
- return mic_word_filter_item_wrapper
-
-
-
-
- def _createPassiveButtonForProgressbarXSlider(self, setting_box_progressbar_x_slider_frame, button_command, button_image_file):
- button_wrapper = createButtonWithImage(
- parent_widget=setting_box_progressbar_x_slider_frame,
- button_fg_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_COLOR,
- button_enter_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_HOVERED_COLOR,
- button_clicked_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_CLICKED_COLOR,
- button_image_file=button_image_file,
- button_image_size=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__BUTTON_ICON_SIZE,
- button_ipadxy=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__BUTTON_IPADXY,
- button_command=button_command,
- )
- return button_wrapper
-
-
-
- def _createActiveButtonForProgressbarXSlider(self, setting_box_progressbar_x_slider_frame, button_command, button_image_file):
- button_wrapper = createButtonWithImage(
- parent_widget=setting_box_progressbar_x_slider_frame,
- button_fg_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__ACTIVE_BUTTON_COLOR,
- button_enter_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__ACTIVE_BUTTON_HOVERED_COLOR,
- button_clicked_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__ACTIVE_BUTTON_CLICKED_COLOR,
- button_image_file=button_image_file,
- button_image_size=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__BUTTON_ICON_SIZE,
- button_ipadxy=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__BUTTON_IPADXY,
- button_command=button_command,
- )
- return button_wrapper
-
-
-
- def _createDisabledButtonForProgressbarXSlider(self, setting_box_progressbar_x_slider_frame, button_image_file):
- button_wrapper = createButtonWithImage(
- parent_widget=setting_box_progressbar_x_slider_frame,
- button_fg_color=self.settings.ctm.SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_DISABLED_COLOR,
- button_image_file=button_image_file,
- button_image_size=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__BUTTON_ICON_SIZE,
- button_ipadxy=self.settings.uism.SB__PROGRESSBAR_X_SLIDER__BUTTON_IPADXY,
- no_bind=True,
- )
- return button_wrapper
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_about_vrct/__init__.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_about_vrct/__init__.py
deleted file mode 100644
index 61b104ec..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_about_vrct/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .createSettingBox_AboutVrct import createSettingBox_AboutVrct
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_about_vrct/about_vrct_store.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_about_vrct/about_vrct_store.py
deleted file mode 100644
index bc015b17..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_about_vrct/about_vrct_store.py
+++ /dev/null
@@ -1,148 +0,0 @@
-poster_showcase_worlds_settings = [
- # トサカひよ
- {
- "author_name": "tosaka_hiyo",
- "data": [
- { "image_file_name": "kokekkopiyopiyo.png", "x_post_num": "1779076974369276014" },
- ]
- },
-
- # MiuJepang
- {
- "author_name": "miu_jepang",
- "data": [
- { "image_file_name": "ippaidou.png", "x_post_num": "1787801976354513319" },
- { "image_file_name": "nihongokurabu.png", "x_post_num": "1779004631936614893" },
- { "image_file_name": "language_exchange_tervern.png", "x_post_num": "1779749425923150317" },
- { "image_file_name": "japanese_culture_osenbeito.png", "x_post_num": "1788522972409721137" },
- { "image_file_name": "silakan_datang_ke_rumahku.png", "x_post_num": "1788522607631056941" },
- { "image_file_name": "uj_club.png", "x_post_num": "1780791654196388201" },
- { "image_file_name": "sushi_stand_guruguru.png", "x_post_num": "1788523302404952218" },
- { "image_file_name": "sushi_guru_annex.png", "x_post_num": None },
- ]
- },
-
- # poposuke_sig
- {
- "author_name": "poposuke_sig",
- "data": [
- { "image_file_name": "usanezumi_shrine2.png", "x_post_num": "1781224020383506649" },
- ]
- },
-
- # KUROINU_YOUHEI
- {
- "author_name": "kuroinu_youhei",
- "data": [
- { "image_file_name": "kuroinu_work_room.png", "x_post_num": "1779750007564112146" },
- ]
- },
-
- # いちや_ICHIYA
- {
- "author_name": "ichiya",
- "data": [
- { "image_file_name": "ehon_no_heikousekai_jimusho.png", "x_post_num": "1780792306976850285" },
- { "image_file_name": "ikoiba.png", "x_post_num": "1782723006923780580" },
- { "image_file_name": "kimodameshi.png", "x_post_num": "1781224391692714133" },
- { "image_file_name": "parallel_collar.png", "x_post_num": None },
- ]
- },
-
- # HayaTikaze
- {
- "author_name": "haya_tikaze",
- "data": [
- { "image_file_name": "study_japanese_world_japanichijou.png", "x_post_num": "1781539871829766550" },
- ]
- },
-
- # aji_3
- {
- "author_name": "aji_3",
- "data": [
- { "image_file_name": "yuttari_eikaiwa.png", "x_post_num": "1779002892999078046" },
- ]
- },
-
- # 八葉そるち
- {
- "author_name": "yatuha_soruti",
- "data": [
- { "image_file_name": "re_yatuha_room.png", "x_post_num": "1779830390435590196" },
- ]
- },
-
- # chakamoto
- {
- "author_name": "chakamoto",
- "data": [
- { "image_file_name": "chakachaka_multipurpose_room.png", "x_post_num": None },
- ]
- },
-
- # MloYolM (よるむ)
- {
- "author_name": "yolm",
- "data": [
- { "image_file_name": "cafe_cian.png", "x_post_num": "1787802552907739504" },
- ]
- },
-
- # ミラクル・オルカ
- {
- "author_name": "miracle_orca",
- "data": [
- { "image_file_name": "mamehinata_dogrun.png", "x_post_num": "1782723423179100471" },
- ]
- },
-
- # いんく(Eenkoo)
- {
- "author_name": "eenkoo",
- "data": [
- { "image_file_name": "tyuuniti_kouryuukai.png", "x_post_num": None },
- ]
- },
-
- # 1ban_meno
- {
- "author_name": "1ban_meno",
- "data": [
- { "image_file_name": "bar_asagao.png", "x_post_num": "1788523857642758370" },
- ]
- },
-
- # 沈黙静寂
- {
- "author_name": "sizudama_sizusabi",
- "data": [
- { "image_file_name": "monogatari_meetup.png", "x_post_num": "1781538415789674976" },
- ]
- },
-
-
- # tommie_500
- {
- "author_name": "tommie_500",
- "data": [
- { "image_file_name": "stretch_club_starting_from_minus.png", "x_post_num": None },
- ]
- },
-
- # MiMi_Sorahana # VRC日韓交流会 (KRJPEX.1355)
- {
- "author_name": "tommie_500",
- "data": [
- { "image_file_name": "kr_jp_exchange.png", "x_post_num": None },
- ]
- },
-
- # Ein(アイン)
- {
- "author_name": "ein",
- "data": [
- { "image_file_name": "smokerz_guild_v2.png", "x_post_num": None },
- ]
- },
-]
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_about_vrct/createSettingBox_AboutVrct.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_about_vrct/createSettingBox_AboutVrct.py
deleted file mode 100644
index 615f9107..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_about_vrct/createSettingBox_AboutVrct.py
+++ /dev/null
@@ -1,632 +0,0 @@
-from random import randint
-from types import SimpleNamespace
-from customtkinter import CTkFrame, CTkLabel, CTkImage, CTkFont
-
-from utils import callFunctionIfCallable, splitList
-from ......ui_utils import bindButtonFunctionAndColor, animateRotation, bindEnterAndLeaveFunction
-from .about_vrct_store import poster_showcase_worlds_settings
-
-def createSettingBox_AboutVrct(setting_box_wrapper, config_window, settings, view_variable):
- setting_box_wrapper.grid_columnconfigure(0, weight=1, minsize=settings.uism.MAIN_AREA_MIN_WIDTH)
- about_vrct_uism = settings.about_vrct.uism
- ABOUT_VRCT_BG = settings.ctm.ABOUT_VRCT_BG
-
-
- # For padding left. without this, setting_box_wrapper's bg shows...
- about_vrct_container_wrapper = CTkFrame(setting_box_wrapper, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- about_vrct_container_wrapper.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
- about_vrct_container_wrapper.grid_columnconfigure(0, weight=1)
-
-
- about_vrct_container = CTkFrame(about_vrct_container_wrapper, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- about_vrct_container.grid(column=0, row=0, padx=about_vrct_uism.ABOUT_VRCT_CONTAINER_LEFT_PADX, pady=0, sticky="nsew")
- about_vrct_container.grid_columnconfigure(0, weight=1)
-
-
- def createSectionContainer(section_row, section_title_image_file_name:str=None, section_bottom_padding:int=0, section_title_bottom_padding:int=0):
- section_container = CTkFrame(about_vrct_container, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- section_container.grid(column=0, row=section_row, padx=0, pady=(0, section_bottom_padding), sticky="nsew")
- section_container.grid_columnconfigure(0, weight=1)
-
- contents_row=0
- if section_title_image_file_name is not None:
- section_title_frame = settings.about_vrct.embedImageCTkLabel(section_container, section_title_image_file_name)
- section_title_frame.grid(column=0, row=contents_row, padx=0, pady=(0,section_title_bottom_padding), sticky="nw")
- contents_row = 1
-
-
-
- section_contents_wrapper = CTkFrame(section_container, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- section_contents_wrapper.grid(column=0, row=contents_row, padx=0, pady=0, sticky="nsew")
- section_contents_wrapper.grid_columnconfigure(0, weight=1)
-
- return (section_container, section_contents_wrapper)
-
-
-
- def createImageButtonRows(parent_frame, image_buttons_settings:list, bottom_pady, directly_type:str=None, corner_radius:int=0, ipadx:int=0, ipady:int=0):
- button_row=0
- setting_length = len(image_buttons_settings)
- for index, each_setting in enumerate(image_buttons_settings):
- each_button = settings.about_vrct.embedImageButtonCTkLabel(
- parent_frame=parent_frame,
- image_file_name=each_setting["image_file_name"],
- callback=each_setting.get("callback", None),
- directly_type=directly_type,
- corner_radius=corner_radius,
- no_bind=each_setting.get("no_bind", False),
- )
- each_button.grid(column=0, row=button_row, padx=0, pady=(0, bottom_pady), sticky="nsew")
- each_button.img_label.grid(padx=ipadx, pady=ipady, sticky="nsew")
- if index == setting_length-1:
- each_button.grid(pady=0)
- button_row+=1
-
- def createContactButton(parent_frame, image_file_name, callback_arg, fg_color=ABOUT_VRCT_BG):
- frame = settings.about_vrct.embedImageButtonCTkLabel(
- parent_frame=parent_frame,
- image_file_name=image_file_name,
- callback=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_OPEN_WEBPAGE_ABOUT_VRCT, callback_arg),
- fg_color=fg_color,
- hovered_color=fg_color,
- clicked_color=fg_color,
- )
- return frame
-
- def createTellUsButton(parent_frame, image_file_name, callback):
- tell_us_button_frame = settings.about_vrct.embedImageButtonCTkLabel(
- parent_frame=parent_frame,
- image_file_name=image_file_name,
- callback=callback,
- corner_radius=about_vrct_uism.TELL_US_BUTTON_CORNER_RADIUS,
- )
- tell_us_button_frame.img_label.grid(padx=about_vrct_uism.TELL_US_BUTTON_PADX, pady=about_vrct_uism.TELL_US_BUTTON_PADY, sticky="nsew")
-
- tell_us_button_frame.configure(border_width=about_vrct_uism.TELL_US_BUTTON_BORDER_WIDTH, border_color=settings.ctm.ABOUT_VRCT_TELL_US_BUTTON_BORDER_COLOR)
-
- return tell_us_button_frame
-
-
-
-
- section_row=0
- # The Developers ----------------------------------
- _the_developers, the_developers_contents_wrapper = createSectionContainer(
- section_row=section_row,
- section_title_image_file_name="dev_section_title.png",
- section_bottom_padding=about_vrct_uism.SECTION_BOTTOM_PADY,
- section_title_bottom_padding=about_vrct_uism.THE_DEVELOPERS_SECTION_TITLE_BOTTOM_PADY
- )
-
- dev_misya_label = settings.about_vrct.embedImageCTkLabel(the_developers_contents_wrapper, "dev_misya.png")
- dev_misya_label.grid(column=0, row=0, padx=0, pady=0, sticky="nsw")
-
- dev_misya_x = createContactButton(
- parent_frame=dev_misya_label,
- image_file_name="dev_x_icon.png",
- callback_arg="X_MISYA",
- fg_color=settings.ctm.ABOUT_VRCT_DEV_BG
- )
- dev_misya_x.place(x=about_vrct_uism.DEVS_MISYA_X_X, y=about_vrct_uism.DEVS_CONTACTS_Y1, anchor="nw")
-
- dev_misya_github = createContactButton(
- parent_frame=dev_misya_label,
- image_file_name="dev_github_icon.png",
- callback_arg="GITHUB_MISYA",
- fg_color=settings.ctm.ABOUT_VRCT_DEV_BG
- )
- dev_misya_github.place(x=about_vrct_uism.DEVS_MISYA_GITHUB_X, y=about_vrct_uism.DEVS_CONTACTS_Y1, anchor="nw")
-
-
-
- dev_shiina_label = settings.about_vrct.embedImageCTkLabel(the_developers_contents_wrapper, "dev_shiina.png")
- dev_shiina_label.grid(column=1, row=0, padx=0, pady=0, sticky="nse")
-
- dev_shiina_x = createContactButton(
- parent_frame=dev_shiina_label,
- image_file_name="dev_x_icon.png",
- callback_arg="X_SHIINA",
- fg_color=settings.ctm.ABOUT_VRCT_DEV_BG
- )
- dev_shiina_x.place(x=about_vrct_uism.DEVS_SHIINA_X_X, y=about_vrct_uism.DEVS_CONTACTS_Y1, anchor="nw")
-
-
- section_row+=1
- # Project Links And Logo ----------------------------------
- _project_links_and_logo, project_links_and_logo_contents_wrapper = createSectionContainer(
- section_bottom_padding=about_vrct_uism.PROJECT_LINKS_SECTION_BOTTOM_PADDING,
- section_row=section_row,
- )
-
- project_links_and_logo_wrapper = CTkFrame(project_links_and_logo_contents_wrapper, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- project_links_and_logo_wrapper.grid(column=0, row=0, padx=about_vrct_uism.PROJECT_LINK_CONTENTS_PADX, pady=0, sticky="nsew")
- project_links_and_logo_wrapper.grid_columnconfigure(1, weight=1)
-
-
- vrct_logo_label = settings.about_vrct.embedImageCTkLabel(project_links_and_logo_wrapper, "vrct_logo_for_about_vrct.png")
- vrct_logo_label.grid(column=0, row=0, padx=0, pady=0, sticky="nsw")
-
-
- project_links_wrapper = CTkFrame(project_links_and_logo_wrapper, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- project_links_wrapper.grid(column=2, row=0, padx=0, pady=0, sticky="nse")
-
- project_link_settings = [
- {
- "image_file_name": "project_link_booth.png",
- "callback": lambda _e: callFunctionIfCallable(view_variable.CALLBACK_OPEN_WEBPAGE_ABOUT_VRCT, "BOOTH")
- },
- {
- "image_file_name": "project_link_documents.png",
- "callback": lambda _e: callFunctionIfCallable(view_variable.CALLBACK_OPEN_WEBPAGE_ABOUT_VRCT, "VRCT_DOCUMENTS")
- },
- {
- "image_file_name": "project_link_vrct_github.png",
- "callback": lambda _e: callFunctionIfCallable(view_variable.CALLBACK_OPEN_WEBPAGE_ABOUT_VRCT, "VRCT_GITHUB")
- },
- {
- "image_file_name": "project_link_contact_us.png",
- "callback": lambda _e: callFunctionIfCallable(view_variable.CALLBACK_OPEN_WEBPAGE_ABOUT_VRCT, "CONTACT_US")
- },
- ]
-
- createImageButtonRows(
- parent_frame=project_links_wrapper,
- image_buttons_settings=project_link_settings,
- bottom_pady=about_vrct_uism.PROJECT_LINK_BOTTOM_PADY,
- corner_radius=about_vrct_uism.PROJECT_LINK_CORNER_RADIUS,
- ipadx=about_vrct_uism.PROJECT_LINK_ITEM_IPADX,
- ipady=about_vrct_uism.PROJECT_LINK_ITEM_IPADY,
- )
-
-
-
-
-
-
- section_row+=1
- # Contributors ----------------------------------
- _contributors, contributors_contents_wrapper = createSectionContainer(
- section_row=section_row,
- section_title_image_file_name="contributors_section_title.png",
- section_bottom_padding=about_vrct_uism.SECTION_BOTTOM_PADY,
- section_title_bottom_padding=about_vrct_uism.CONTRIBUTORS_SECTION_TITLE_BOTTOM_PADY
- )
-
- contributors_members = settings.about_vrct.embedImageCTkLabel(contributors_contents_wrapper, "contributors_members.png")
- contributors_members.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
-
-
-
- # done_san
- contributors_done_san_x = createContactButton(
- parent_frame=contributors_members,
- image_file_name="contributors_x_icon.png",
- callback_arg="X_DONE_SAN",
- )
- contributors_done_san_x.place(x=about_vrct_uism.CONTRIBUTORS_DONE_SAN_X_X, y=about_vrct_uism.CONTRIBUTORS_CONTACTS_Y1, anchor="nw")
-
- # IYA
- contributors_iya_x = createContactButton(
- parent_frame=contributors_members,
- image_file_name="contributors_x_icon.png",
- callback_arg="X_IYA",
- )
- contributors_iya_x.place(x=about_vrct_uism.CONTRIBUTORS_IYA_X_X, y=about_vrct_uism.CONTRIBUTORS_CONTACTS_Y1, anchor="nw")
-
- # RERA
- contributors_rera_x = createContactButton(
- parent_frame=contributors_members,
- image_file_name="contributors_x_icon.png",
- callback_arg="X_RERA",
- )
- contributors_rera_x.place(x=about_vrct_uism.CONTRIBUTORS_RERA_X_X, y=about_vrct_uism.CONTRIBUTORS_CONTACTS_Y1, anchor="nw")
-
- contributors_rera_github = createContactButton(
- parent_frame=contributors_members,
- image_file_name="contributors_github_icon.png",
- callback_arg="GITHUB_RERA",
- )
- contributors_rera_github.place(x=about_vrct_uism.CONTRIBUTORS_RERA_GITHUB_X, y=about_vrct_uism.CONTRIBUTORS_CONTACTS_Y1, anchor="nw")
-
-
- # POPOSUKE
- contributors_poposuke_x = createContactButton(
- parent_frame=contributors_members,
- image_file_name="contributors_x_icon.png",
- callback_arg="X_POPOSUKE",
- )
- contributors_poposuke_x.place(x=about_vrct_uism.CONTRIBUTORS_POPOSUKE_X_X, y=about_vrct_uism.CONTRIBUTORS_CONTACTS_Y2, anchor="nw")
-
- # KUMAGUMA
- contributors_kumaguma_x = createContactButton(
- parent_frame=contributors_members,
- image_file_name="contributors_x_icon.png",
- callback_arg="X_KUMAGUMA",
- )
- contributors_kumaguma_x.place(x=about_vrct_uism.CONTRIBUTORS_KUMAGUMA_X_X, y=about_vrct_uism.CONTRIBUTORS_CONTACTS_Y2, anchor="nw")
-
-
-
-
-
-
- section_row+=1
- # Localization ----------------------------------
- _localization, localization_contents_wrapper = createSectionContainer(
- section_row=section_row,
- section_title_image_file_name="localization_title.png",
- section_bottom_padding=about_vrct_uism.SECTION_BOTTOM_PADY,
- section_title_bottom_padding=about_vrct_uism.LOCALIZATION_TITLE_BOTTOM_PADY
- )
-
- localization_members = settings.about_vrct.embedImageCTkLabel(localization_contents_wrapper, "localization_members.png")
- localization_members.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
-
-
-
- section_row+=1
- # Special Thanks & Supporters ----------------------------------
- _special_thanks, special_thanks_contents_wrapper = createSectionContainer(
- section_row=section_row,
- section_title_image_file_name="special_thanks_section_title.png",
- section_bottom_padding=about_vrct_uism.SECTION_BOTTOM_PADY,
- section_title_bottom_padding=about_vrct_uism.SPECIAL_THANKS_SECTION_TITLE_BOTTOM_PADY
- )
-
- special_thanks_members = settings.about_vrct.embedImageCTkLabel(special_thanks_contents_wrapper, "special_thanks_members.png")
- special_thanks_members.grid(column=0, row=0, padx=0, pady=(0,about_vrct_uism.SPECIAL_THANKS_MEMBERS_BOTTOM_PADY), sticky="nsew")
-
- special_thanks_message = settings.about_vrct.embedImageCTkLabel(special_thanks_contents_wrapper, settings.about_vrct.image_file.SPECIAL_THANKS_MESSAGE)
- special_thanks_message.grid(column=0, row=1, padx=0, pady=(0,about_vrct_uism.SPECIAL_THANKS_MESSAGE_BOTTOM_PADY), sticky="nsew")
-
- special_thanks_message_and_you = settings.about_vrct.embedImageCTkLabel(special_thanks_contents_wrapper, "special_thanks_message_and_you.png")
- special_thanks_message_and_you.grid(column=0, row=2, padx=0, pady=(0,about_vrct_uism.SPECIAL_THANKS_MESSAGE_AND_YOU_BOTTOM_PADY), sticky="nsw")
-
- special_thanks_tell_us_message = createTellUsButton(
- parent_frame=special_thanks_contents_wrapper,
- image_file_name=settings.about_vrct.image_file.SPECIAL_THANKS_TELL_US_MESSAGE,
- callback=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_OPEN_WEBPAGE_ABOUT_VRCT, "SUPPORTER_REGISTRATION"),
- )
- special_thanks_tell_us_message.grid(column=0, row=3)
-
-
-
-
- section_row+=1
- # Special Thanks & Supporters ----------------------------------
- _poster_showcase, poster_showcase_contents_wrapper = createSectionContainer(
- section_row=section_row,
- section_title_image_file_name="poster_showcase_section_title.png",
- section_bottom_padding=about_vrct_uism.SECTION_BOTTOM_PADY,
- section_title_bottom_padding=about_vrct_uism.POSTER_SHOWCASE_SECTION_TITLE_BOTTOM_PADY
- )
-
- poster_showcase_worlds_wrapper = CTkFrame(poster_showcase_contents_wrapper, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- poster_showcase_worlds_wrapper.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
- poster_showcase_worlds_wrapper.grid_columnconfigure(0, weight=1)
-
-
- poster_showcase_worlds = CTkFrame(poster_showcase_worlds_wrapper, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- poster_showcase_worlds.grid(column=0, row=0, padx=0, pady=(0,about_vrct_uism.POSTER_SHOWCASE_WORLD_BOTTOM_PADY), sticky="nsew")
- poster_showcase_worlds.grid_columnconfigure(0, weight=1)
-
-
-
- compounded_poster_showcase_worlds_list = []
- for each_author_settings in poster_showcase_worlds_settings:
- for data in each_author_settings["data"]:
- if data["x_post_num"] is None:
- append_settings = {
- "image_file_name": data["image_file_name"],
- "no_bind": True,
- }
- else:
- x_post_num = data["x_post_num"]
- callback = lambda _e,arg=x_post_num: view_variable.CALLBACK_OPEN_WEBPAGE_ABOUT_VRCT("X_SHIINA_POSTER_SHOWCASE_POST", arg)
- append_settings = {
- "image_file_name": data["image_file_name"],
- "callback": callback,
- }
- compounded_poster_showcase_worlds_list.append(append_settings)
-
- result = splitList(compounded_poster_showcase_worlds_list, 8)
- poster_showcase_worlds_frame_list = []
- for split_poster_showcase_worlds_settings in result:
- poster_showcase_worlds_frame = CTkFrame(poster_showcase_worlds_wrapper, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- poster_showcase_worlds_frame.grid_columnconfigure(0, weight=1)
-
- createImageButtonRows(
- parent_frame=poster_showcase_worlds_frame,
- image_buttons_settings=split_poster_showcase_worlds_settings,
- bottom_pady=about_vrct_uism.POSTER_SHOWCASE_WORLD_ITEM_BOTTOM_PADY,
- directly_type="showcased_worlds",
- corner_radius=about_vrct_uism.POSTER_SHOWCASE_WORLD_CORNER_RADIUS,
- ipadx=about_vrct_uism.POSTER_SHOWCASE_WORLD_ITEM_IPADX,
- ipady=about_vrct_uism.POSTER_SHOWCASE_WORLD_ITEM_IPADY,
- )
-
- poster_showcase_worlds_frame_list.append(poster_showcase_worlds_frame)
-
-
- pagination_button_settings = settings.about_vrct.image_file.POSTER_SHOWCASE_WORLD_PAGINATION_BUTTON
-
- def defineAngles(index):
- start_angle = 0
- goal_angle = 90
- if index == 0:
- start_angle = 0
- goal_angle = 90
- elif index == 1:
- start_angle = 90
- goal_angle = 180
- elif index == 2:
- start_angle = 180
- goal_angle = 270
- elif index == 3:
- start_angle = 270
- goal_angle = 360
- return(start_angle, goal_angle)
-
- def toNextPagePosterShowcase():
- current_function_index = view_variable.CALLBACK_ABOUT_VRCT_POSTER_SHOWCASE_CURRENT_PAGE_NUM
- view_variable.CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_WORLD_LIST=None
- poster_showcase_worlds_frame_list[current_function_index].grid_remove()
- pre_function_index = current_function_index
- current_function_index = (current_function_index + 1) % len(poster_showcase_worlds_frame_list)
- poster_showcase_worlds_frame_list[current_function_index].grid(column=0, row=0, padx=0, pady=(0,about_vrct_uism.POSTER_SHOWCASE_WORLD_BOTTOM_PADY), sticky="nsew")
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_SHOWCASE_CURRENT_PAGE_NUM = current_function_index
-
- start_angle, goal_angle = defineAngles(pre_function_index)
-
- animateRotation(
- tk_root=config_window,
- img_frame=config_window.poster_showcase_pagination_button.img_label,
- img=pagination_button_settings.img,
- img_width=pagination_button_settings.width,
- img_height=pagination_button_settings.height,
- start_angle=start_angle,
- goal_angle=goal_angle,
- duration=0.5,
- )
-
- view_variable.CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_WORLD_LIST=toNextPagePosterShowcase
-
- # Initialize
- view_variable.CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_WORLD_LIST=toNextPagePosterShowcase
-
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_SHOWCASE_CURRENT_PAGE_NUM = randint(0, len(poster_showcase_worlds_frame_list)-1)
-
- start_angle, _goal_angle = defineAngles(view_variable.CALLBACK_ABOUT_VRCT_POSTER_SHOWCASE_CURRENT_PAGE_NUM)
-
- poster_showcase_worlds_frame_list[view_variable.CALLBACK_ABOUT_VRCT_POSTER_SHOWCASE_CURRENT_PAGE_NUM].grid(column=0, row=0, padx=0, pady=(0,about_vrct_uism.POSTER_SHOWCASE_WORLD_BOTTOM_PADY), sticky="nsew")
-
- poster_showcase_worlds_wrapper.grid_rowconfigure(1, weight=1)
-
- poster_showcase_pagination_button_wrapper = CTkFrame(poster_showcase_worlds_wrapper, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- poster_showcase_pagination_button_wrapper.grid(column=0, row=2, padx=0, pady=(0, about_vrct_uism.POSTER_SHOWCASE_WORLD_PAGINATION_BUTTON_BOTTOM_PADY), sticky="nsew")
-
-
- poster_showcase_pagination_button_wrapper.grid_columnconfigure((0,2), weight=1)
- config_window.poster_showcase_pagination_button = settings.about_vrct.embedImageButtonCTkLabel(
- parent_frame=poster_showcase_pagination_button_wrapper,
- image_file_name="poster_showcase_pagination_button.png",
- callback=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_WORLD_LIST),
- hovered_color="transparent",
- clicked_color="transparent",
- rotate_angle=-start_angle # for clockwise angle, put negative "-"
- )
- config_window.poster_showcase_pagination_button.grid(column=1, row=0, padx=0, pady=0, sticky="nsew")
-
-
- # poster_showcase_pagination_button_wrapper.grid_columnconfigure((0,2), weight=1)
- poster_showcase_pagination_button_chato = settings.about_vrct.embedImageButtonCTkLabel(
- parent_frame=poster_showcase_pagination_button_wrapper,
- image_file_name="poster_showcase_pagination_button_chato.png",
- callback=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_WORLD_LIST),
- hovered_color="transparent",
- clicked_color="transparent",
- )
- poster_showcase_pagination_button_chato.place(relx=0.502, rely=0.51, anchor="center")
-
- pagination_button_chato_settings = settings.about_vrct.image_file.POSTER_SHOWCASE_WORLD_PAGINATION_BUTTON_CHATO
-
- def rotateChatoAnimation():
- view_variable.CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_BUTTON_HOVERED = None
-
- animateRotation(
- tk_root=config_window,
- img_frame=poster_showcase_pagination_button_chato.img_label,
- img=pagination_button_chato_settings.img,
- img_width=pagination_button_chato_settings.width,
- img_height=pagination_button_chato_settings.height,
- start_angle=0,
- goal_angle=360,
- duration=0.5,
- )
- view_variable.CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_BUTTON_HOVERED = rotateChatoAnimation
-
-
- view_variable.CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_BUTTON_HOVERED = rotateChatoAnimation
-
- bindEnterAndLeaveFunction(
- target_widgets=[config_window.poster_showcase_pagination_button.img_label,poster_showcase_pagination_button_chato.img_label],
- enterFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_ABOUT_VRCT_CHANGE_POSTER_SHOWCASE_BUTTON_HOVERED),
- leaveFunction=None,
- )
-
-
-
-
- poster_container = CTkFrame(poster_showcase_contents_wrapper, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- poster_container.grid(column=1, row=0, padx=0, pady=0, sticky="nsew")
- poster_container.grid_columnconfigure(1, weight=1)
-
-
- poster_images_wrapper = CTkFrame(poster_container, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- poster_images_wrapper.grid(column=0, row=0, padx=0, pady=(0,about_vrct_uism.POSTER_SHOWCASE_POSTER_IMAGES_BOTTOM_PADY), sticky="nsew")
- poster_images_wrapper.grid_columnconfigure(1, weight=1)
-
-
-
-
- poster_image_arrow_left = settings.about_vrct.embedImageButtonCTkLabel(poster_images_wrapper, "arrow_left.png", lambda _e: callFunctionIfCallable(view_variable.CALLBACK_ABOUT_VRCT_POSTER_PREV_BUTTON))
- poster_image_arrow_left.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
- poster_image_arrow_left.configure(corner_radius=about_vrct_uism.POSTER_CHANGE_BUTTON_CORNER_RADIUS)
-
- bindButtonFunctionAndColor(
- target_widgets=[poster_image_arrow_left],
- enter_color=settings.ctm.ABOUT_VRCT_BUTTON_HOVERED_BG_COLOR,
- leave_color=ABOUT_VRCT_BG,
- clicked_color=settings.ctm.ABOUT_VRCT_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=None,
- )
-
-
- poster_image_frame_settings_list = [
- {
- "file_name": "iya_vrct_poster_ja.png",
- "poster_type": "poster",
- },
- {
- "file_name": "iya_vrct_poster_en.png",
- "poster_type": "poster",
- },
- {
- "file_name": "iya_vrct_poster_cn.png",
- "poster_type": "poster",
- },
- {
- "file_name": "iya_vrct_poster_ko.png",
- "poster_type": "poster",
- },
- {
- "file_name": "iya_vrct_manga_ja.png",
- "poster_type": "manga",
- },
- {
- "file_name": "iya_vrct_manga_en.png",
- "poster_type": "manga",
- },
- {
- "file_name": "iya_vrct_manga_ko.png",
- "poster_type": "manga",
- },
- ]
-
- poster_frame_list = []
- for poster_frame_settings in poster_image_frame_settings_list:
- poster_frame = settings.about_vrct.embedImageCTkLabel(poster_images_wrapper, poster_frame_settings["file_name"], directly_type="vrct_posters")
- poster_frame_list.append(poster_frame)
-
-
-
-
- poster_images_authors_wrapper = CTkFrame(poster_container, fg_color=ABOUT_VRCT_BG, corner_radius=0, width=0, height=0)
- poster_images_authors_wrapper.grid(column=0, row=1, padx=0, pady=0, sticky="nsew")
-
- config_window.poster_images_authors = settings.about_vrct.embedImageCTkLabel(poster_images_authors_wrapper, settings.about_vrct.image_file.POSTER_IMAGES_AUTHOR)
- config_window.poster_images_authors_m = settings.about_vrct.embedImageCTkLabel(poster_images_authors_wrapper, settings.about_vrct.image_file.POSTER_IMAGES_AUTHOR_M)
-
-
-
- def toPrevPagePosterImage():
- current_function_index = view_variable.CALLBACK_ABOUT_VRCT_POSTER_IMAGE_CURRENT_PAGE_NUM
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_PREV_BUTTON=None
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_NEXT_BUTTON=None
- poster_frame_list[current_function_index].grid_remove()
- current_function_index = (current_function_index - 1) % len(poster_frame_list)
- poster_frame_list[current_function_index].grid(column=1, row=0, padx=0, pady=0, sticky="nsew")
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_IMAGE_CURRENT_PAGE_NUM = current_function_index
-
- if poster_image_frame_settings_list[current_function_index]["poster_type"] == "poster":
- config_window.poster_images_authors_m.grid_remove()
- config_window.poster_images_authors.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
- elif poster_image_frame_settings_list[current_function_index]["poster_type"] == "manga":
- config_window.poster_images_authors.grid_remove()
- config_window.poster_images_authors_m.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
-
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_PREV_BUTTON=toPrevPagePosterImage
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_NEXT_BUTTON=toNextPagePosterImage
-
-
-
-
- def toNextPagePosterImage():
- current_function_index = view_variable.CALLBACK_ABOUT_VRCT_POSTER_IMAGE_CURRENT_PAGE_NUM
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_PREV_BUTTON=None
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_NEXT_BUTTON=None
- poster_frame_list[current_function_index].grid_remove()
- current_function_index = (current_function_index + 1) % len(poster_frame_list)
- poster_frame_list[current_function_index].grid(column=1, row=0, padx=0, pady=0, sticky="nsew")
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_IMAGE_CURRENT_PAGE_NUM = current_function_index
-
- if poster_image_frame_settings_list[current_function_index]["poster_type"] == "poster":
- config_window.poster_images_authors_m.grid_remove()
- config_window.poster_images_authors.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
- elif poster_image_frame_settings_list[current_function_index]["poster_type"] == "manga":
- config_window.poster_images_authors.grid_remove()
- config_window.poster_images_authors_m.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
-
-
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_PREV_BUTTON=toPrevPagePosterImage
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_NEXT_BUTTON=toNextPagePosterImage
-
-
-
- # Initialize
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_PREV_BUTTON=toPrevPagePosterImage
- view_variable.CALLBACK_ABOUT_VRCT_POSTER_NEXT_BUTTON=toNextPagePosterImage
-
- config_window.poster_images_authors.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
-
- poster_frame_list[0].grid(column=1, row=0, padx=0, pady=0, sticky="nsew")
-
-
-
-
- poster_image_arrow_right = settings.about_vrct.embedImageButtonCTkLabel(poster_images_wrapper, "arrow_right.png", lambda _e: callFunctionIfCallable(view_variable.CALLBACK_ABOUT_VRCT_POSTER_NEXT_BUTTON))
- poster_image_arrow_right.grid(column=2, row=0, padx=0, pady=0, sticky="nsew")
- poster_image_arrow_right.configure(corner_radius=about_vrct_uism.POSTER_CHANGE_BUTTON_CORNER_RADIUS)
-
-
- bindButtonFunctionAndColor(
- target_widgets=[poster_image_arrow_right],
- enter_color=settings.ctm.ABOUT_VRCT_BUTTON_HOVERED_BG_COLOR,
- leave_color=ABOUT_VRCT_BG,
- clicked_color=settings.ctm.ABOUT_VRCT_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=None,
- )
-
-
-
-
-
-
-
-
- poster_tell_us_message = createTellUsButton(
- parent_frame=poster_showcase_contents_wrapper,
- image_file_name=settings.about_vrct.image_file.POSTER_TELL_US_MESSAGE,
- callback=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_OPEN_WEBPAGE_ABOUT_VRCT, "POSTER_CONTACT_US"),
- )
- poster_tell_us_message.grid(column=0, row=1, columnspan=2, padx=0, pady=(about_vrct_uism.POSTER_TELL_US_MESSAGE_TOP_PADY,0), sticky="nse")
-
-
-
-
-
-
-
-
-
-
-
- section_row+=1
- # VRChat disclaimer ----------------------------------
- vrchat_disclaimer, vrchat_disclaimer_contents_wrapper = createSectionContainer(
- section_row=section_row,
- )
-
-
- vrchat_disclaimer_label = settings.about_vrct.embedImageCTkLabel(vrchat_disclaimer_contents_wrapper, "vrchat_disclaimer.png")
- vrchat_disclaimer_label.grid(column=0, row=0, padx=0, pady=about_vrct_uism.VRCHAT_DISCLAIMER_SECTION_PADY, sticky="nsew")
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_advanced_settings/__init__.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_advanced_settings/__init__.py
deleted file mode 100644
index 0ceb6231..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_advanced_settings/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .createSettingBox_AdvancedSettings import createSettingBox_AdvancedSettings
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_advanced_settings/createSettingBox_AdvancedSettings.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_advanced_settings/createSettingBox_AdvancedSettings.py
deleted file mode 100644
index 330adc6e..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_advanced_settings/createSettingBox_AdvancedSettings.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_AdvancedSettings(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBoxEntry = sbg.createSettingBoxEntry
- createSettingBoxButtonWithImage = sbg.createSettingBoxButtonWithImage
-
-
- def entryIpAddressCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_OSC_IP_ADDRESS, value)
-
- def entryPortCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_OSC_PORT, value)
-
- def openConfigFilepathCallback():
- callFunctionIfCallable(view_variable.CALLBACK_OPEN_FILEPATH_CONFIG_FILE)
-
- row=0
- config_window.sb__ip_address = createSettingBoxEntry(
- for_var_label_text=view_variable.VAR_LABEL_OSC_IP_ADDRESS,
- for_var_desc_text=view_variable.VAR_DESC_OSC_IP_ADDRESS,
- entry_attr_name="sb__entry_ip_address",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_150,
- entry_bind__Any_KeyRelease=lambda value: entryIpAddressCallback(value),
- entry_textvariable=view_variable.VAR_OSC_IP_ADDRESS,
- )
- config_window.sb__ip_address.grid(row=row)
- row+=1
-
-
- config_window.sb__port = createSettingBoxEntry(
- for_var_label_text=view_variable.VAR_LABEL_OSC_PORT,
- for_var_desc_text=view_variable.VAR_DESC_OSC_PORT,
- entry_attr_name="sb__entry_port",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_150,
- entry_bind__Any_KeyRelease=lambda value: entryPortCallback(value),
- entry_textvariable=view_variable.VAR_OSC_PORT,
- )
- config_window.sb__port.grid(row=row)
- row+=1
-
- config_window.sb__open_config_filepath = createSettingBoxButtonWithImage(
- for_var_label_text=view_variable.VAR_LABEL_OPEN_CONFIG_FILEPATH,
- for_var_desc_text=view_variable.VAR_DESC_OPEN_CONFIG_FILEPATH,
- button_attr_name="sb__button_open_config_filepath",
- button_command=lambda _e: openConfigFilepathCallback(),
- button_image=settings.image_file.FOLDER_OPEN_ICON,
- )
- config_window.sb__open_config_filepath.grid(row=row, pady=0)
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_appearance/__init__.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_appearance/__init__.py
deleted file mode 100644
index 7dd435d8..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_appearance/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .createSettingBox_Appearance import createSettingBox_Appearance
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_appearance/createSettingBox_Appearance.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_appearance/createSettingBox_Appearance.py
deleted file mode 100644
index 8eecc9c5..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_appearance/createSettingBox_Appearance.py
+++ /dev/null
@@ -1,135 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBoxDropdownMenu = sbg.createSettingBoxDropdownMenu
- createSettingBoxSlider = sbg.createSettingBoxSlider
- createSettingBoxCheckbox = sbg.createSettingBoxCheckbox
-
-
- def sliderTransparencyCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_TRANSPARENCY, value)
-
- def optionmenuAppearanceThemeCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_APPEARANCE, value)
-
- def optionmenuUiScalingCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_UI_SCALING, value)
-
- def sliderTextBoxUiScalingCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_TEXTBOX_UI_SCALING, value)
-
- def sliderMessageBoxRatioCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_MESSAGE_BOX_RATIO, value)
-
- def optionmenuFontFamilyCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_FONT_FAMILY, value)
-
- def optionmenuUiLanguageCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_UI_LANGUAGE, value)
-
- def checkboxEnableRestoreMainWindowGeometryCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY, checkbox_box_widget.get())
-
- row=0
- config_window.sb__transparency = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_TRANSPARENCY,
- for_var_desc_text=view_variable.VAR_DESC_TRANSPARENCY,
- slider_attr_name="sb__slider_transparency",
- slider_range=view_variable.SLIDER_RANGE_TRANSPARENCY,
- command=lambda value: sliderTransparencyCallback(value),
- variable=view_variable.VAR_TRANSPARENCY,
- slider_bind__ButtonPress=view_variable.CALLBACK_BUTTON_PRESS_TRANSPARENCY,
- slider_bind__ButtonRelease=view_variable.CALLBACK_BUTTON_RELEASE_TRANSPARENCY,
- sliderTooltipFormatter=view_variable.CALLBACK_SLIDER_TOOLTIP_PERCENTAGE_FORMATTER,
- )
- config_window.sb__transparency.grid(row=row)
- row+=1
-
-
- config_window.sb__appearance_theme = createSettingBoxDropdownMenu(
- for_var_label_text=view_variable.VAR_LABEL_APPEARANCE_THEME,
- for_var_desc_text=view_variable.VAR_DESC_APPEARANCE_THEME,
- optionmenu_attr_name="sb__optionmenu_appearance_theme",
- dropdown_menu_values=view_variable.LIST_APPEARANCE_THEME,
- command=lambda value: optionmenuAppearanceThemeCallback(value),
- variable=view_variable.VAR_APPEARANCE_THEME,
- )
- config_window.sb__appearance_theme.grid(row=row)
- row+=1
-
-
-
- config_window.sb__ui_scaling = createSettingBoxDropdownMenu(
- for_var_label_text=view_variable.VAR_LABEL_UI_SCALING,
- for_var_desc_text=view_variable.VAR_DESC_UI_SCALING,
- optionmenu_attr_name="sb__optionmenu_ui_scaling",
- dropdown_menu_values=view_variable.LIST_UI_SCALING,
- command=lambda value: optionmenuUiScalingCallback(value),
- variable=view_variable.VAR_UI_SCALING,
- )
- config_window.sb__ui_scaling.grid(row=row)
- row+=1
-
- config_window.sb__textbox_uis_scaling = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_TEXTBOX_UI_SCALING,
- for_var_desc_text=view_variable.VAR_DESC_TEXTBOX_UI_SCALING,
- slider_attr_name="sb__slider_transparency",
- slider_range=view_variable.SLIDER_RANGE_TEXTBOX_UI_SCALING,
- command=lambda value: sliderTextBoxUiScalingCallback(value),
- variable=view_variable.VAR_TEXTBOX_UI_SCALING,
- slider_bind__ButtonPress=view_variable.CALLBACK_BUTTON_PRESS_TEXTBOX_UI_SCALING,
- slider_bind__ButtonRelease=view_variable.CALLBACK_BUTTON_RELEASE_TEXTBOX_UI_SCALING,
- sliderTooltipFormatter=view_variable.CALLBACK_SLIDER_TOOLTIP_PERCENTAGE_FORMATTER,
- )
- config_window.sb__textbox_uis_scaling.grid(row=row)
- row+=1
-
- config_window.sb__message_box_ratio = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_MESSAGE_BOX_RATIO,
- for_var_desc_text=view_variable.VAR_DESC_MESSAGE_BOX_RATIO,
- slider_attr_name="sb__slider_message_box_ratio",
- slider_range=view_variable.SLIDER_RANGE_MESSAGE_BOX_RATIO,
- command=lambda value: sliderMessageBoxRatioCallback(value),
- variable=view_variable.VAR_MESSAGE_BOX_RATIO,
- slider_bind__ButtonPress=view_variable.CALLBACK_BUTTON_PRESS_MESSAGE_BOX_RATIO,
- slider_bind__ButtonRelease=view_variable.CALLBACK_BUTTON_RELEASE_MESSAGE_BOX_RATIO,
- sliderTooltipFormatter=view_variable.CALLBACK_SLIDER_TOOLTIP_PERCENTAGE_FORMATTER,
- )
- config_window.sb__message_box_ratio.grid(row=row)
- row+=1
-
- config_window.sb__font_family = createSettingBoxDropdownMenu(
- for_var_label_text=view_variable.VAR_LABEL_FONT_FAMILY,
- for_var_desc_text=view_variable.VAR_DESC_FONT_FAMILY,
- optionmenu_attr_name="sb__optionmenu_font_family",
- dropdown_menu_values=view_variable.LIST_FONT_FAMILY,
- command=lambda value: optionmenuFontFamilyCallback(value),
- variable=view_variable.VAR_FONT_FAMILY,
- )
- config_window.sb__font_family.grid(row=row)
- row+=1
-
-
- config_window.sb__ui_language = createSettingBoxDropdownMenu(
- for_var_label_text=view_variable.VAR_LABEL_UI_LANGUAGE,
- for_var_desc_text=view_variable.VAR_DESC_UI_LANGUAGE,
- optionmenu_attr_name="sb__optionmenu_ui_language",
- dropdown_menu_values=view_variable.LIST_UI_LANGUAGE,
- command=lambda value: optionmenuUiLanguageCallback(value),
- variable=view_variable.VAR_UI_LANGUAGE,
- )
- config_window.sb__ui_language.grid(row=row)
- row+=1
-
- config_window.sb__enable_restore_main_window_geometry = createSettingBoxCheckbox(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY,
- for_var_desc_text=view_variable.VAR_DESC_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY,
- checkbox_attr_name="sb__checkbox_enable_restore_main_window_geometry",
- command=lambda: checkboxEnableRestoreMainWindowGeometryCallback(config_window.sb__checkbox_enable_restore_main_window_geometry),
- variable=view_variable.VAR_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY,
- )
- config_window.sb__enable_restore_main_window_geometry.grid(row=row, pady=0)
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/__init__.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/__init__.py
deleted file mode 100644
index 9b7e583c..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from .createSettingBox_Others import createSettingBox_Others
-from .createSettingBox_Others_SendMessageFormats import createSettingBox_Others_SendMessageFormats
-from .createSettingBox_Others_ReceivedMessageFormats import createSettingBox_Others_ReceivedMessageFormats
-from .createSettingBox_Others_Additional import createSettingBox_Others_Additional
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others.py
deleted file mode 100644
index 72391a8a..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others.py
+++ /dev/null
@@ -1,99 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBoxCheckbox = sbg.createSettingBoxCheckbox
- createSettingBoxRadioButtons = sbg.createSettingBoxRadioButtons
- createSettingBoxAutoExportMessageLogs = sbg.createSettingBoxAutoExportMessageLogs
-
-
- def checkboxAutoClearMessageBoxCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_AUTO_CLEAR_MESSAGE_BOX, checkbox_box_widget.get())
-
- def checkboxSendOnlyTranslatedMessagesCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES, checkbox_box_widget.get())
-
- def checkboxSendMessageButtonTypeCallback():
- callFunctionIfCallable(view_variable.CALLBACK_SET_SEND_MESSAGE_BUTTON_TYPE, view_variable.VAR_SEND_MESSAGE_BUTTON_TYPE.get())
-
-
- def checkboxAutoExportMessageLogsCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_AUTO_EXPORT_MESSAGE_LOGS, checkbox_box_widget.get())
-
- def buttonAutoExportMessageLogsCallback():
- callFunctionIfCallable(view_variable.CALLBACK_OPEN_FILEPATH_LOGS)
-
- def checkboxVrcMuteSyncCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_VRC_MIC_MUTE_SYNC, checkbox_box_widget.get())
-
- def checkboxEnableSendMessageToVrcCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC, checkbox_box_widget.get())
-
-
- row=0
- config_window.sb__auto_clear_message_box = createSettingBoxCheckbox(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_AUTO_CLEAR_MESSAGE_BOX,
- for_var_desc_text=view_variable.VAR_DESC_ENABLE_AUTO_CLEAR_MESSAGE_BOX,
- checkbox_attr_name="sb__checkbox_auto_clear_message_box",
- command=lambda: checkboxAutoClearMessageBoxCallback(config_window.sb__checkbox_auto_clear_message_box),
- variable=view_variable.VAR_ENABLE_AUTO_CLEAR_MESSAGE_BOX,
- )
- config_window.sb__auto_clear_message_box.grid(row=row)
- row+=1
-
- config_window.sb__send_only_translated_messages = createSettingBoxCheckbox(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES,
- for_var_desc_text=view_variable.VAR_DESC_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES,
- checkbox_attr_name="sb__checkbox_send_only_translated_messages",
- command=lambda: checkboxSendOnlyTranslatedMessagesCallback(config_window.sb__checkbox_send_only_translated_messages),
- variable=view_variable.VAR_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES,
- )
- config_window.sb__send_only_translated_messages.grid(row=row)
- row+=1
-
- config_window.sb__send_message_button_type = createSettingBoxRadioButtons(
- for_var_label_text=view_variable.VAR_LABEL_SEND_MESSAGE_BUTTON_TYPE,
- for_var_desc_text=view_variable.VAR_DESC_SEND_MESSAGE_BUTTON_TYPE,
- radio_button_attr_name="sb__radiobutton_send_message_button_type",
- command=lambda: checkboxSendMessageButtonTypeCallback(),
- variable=view_variable.VAR_SEND_MESSAGE_BUTTON_TYPE,
- radiobutton_keys_values=view_variable.KEYS_VALUES_SEND_MESSAGE_BUTTON_TYPE,
- )
- config_window.sb__send_message_button_type.grid(row=row)
- row+=1
-
-
- config_window.sb__auto_export_message_logs = createSettingBoxAutoExportMessageLogs(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_AUTO_EXPORT_MESSAGE_LOGS,
- for_var_desc_text=view_variable.VAR_DESC_ENABLE_AUTO_EXPORT_MESSAGE_LOGS,
- checkbox_attr_name="sb__checkbox_auto_export_message_logs",
- checkbox_command=lambda: checkboxAutoExportMessageLogsCallback(config_window.sb__checkbox_auto_export_message_logs),
- button_command=lambda _e: buttonAutoExportMessageLogsCallback(),
- variable=view_variable.VAR_ENABLE_AUTO_EXPORT_MESSAGE_LOGS,
- )
- config_window.sb__auto_export_message_logs.grid(row=row)
- row+=1
-
-
- config_window.sb__vrc_mic_mute_sync = createSettingBoxCheckbox(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_VRC_MIC_MUTE_SYNC,
- for_var_desc_text=view_variable.VAR_DESC_ENABLE_VRC_MIC_MUTE_SYNC,
- checkbox_attr_name="sb__checkbox_vrc_mic_mute_sync",
- command=lambda: checkboxVrcMuteSyncCallback(config_window.sb__checkbox_vrc_mic_mute_sync),
- variable=view_variable.VAR_ENABLE_VRC_MIC_MUTE_SYNC,
- )
- config_window.sb__vrc_mic_mute_sync.grid(row=row)
- row+=1
-
-
- config_window.sb__enable_send_message_to_vrc = createSettingBoxCheckbox(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_SEND_MESSAGE_TO_VRC,
- for_var_desc_text=view_variable.VAR_DESC_ENABLE_SEND_MESSAGE_TO_VRC,
- checkbox_attr_name="sb__checkbox_enable_send_message_to_vrc",
- command=lambda: checkboxEnableSendMessageToVrcCallback(config_window.sb__checkbox_enable_send_message_to_vrc),
- variable=view_variable.VAR_ENABLE_SEND_MESSAGE_TO_VRC,
- )
- config_window.sb__enable_send_message_to_vrc.grid(row=row, pady=0)
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others_Additional.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others_Additional.py
deleted file mode 100644
index 577ef373..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others_Additional.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_Others_Additional(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBoxCheckbox = sbg.createSettingBoxCheckbox
-
- def checkboxEnableSendReceivedMessageToVrcCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC, checkbox_box_widget.get())
-
-
- row=0
- config_window.sb__enable_send_received_message_to_vrc = createSettingBoxCheckbox(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC,
- for_var_desc_text=view_variable.VAR_DESC_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC,
- checkbox_attr_name="sb__checkbox_enable_send_received_message_to_vrc",
- command=lambda: checkboxEnableSendReceivedMessageToVrcCallback(config_window.sb__checkbox_enable_send_received_message_to_vrc),
- variable=view_variable.VAR_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC,
- )
- config_window.sb__enable_send_received_message_to_vrc.grid(row=row, pady=0)
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others_ReceivedMessageFormats.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others_ReceivedMessageFormats.py
deleted file mode 100644
index ac8bffa6..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others_ReceivedMessageFormats.py
+++ /dev/null
@@ -1,65 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_Others_ReceivedMessageFormats(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBox_Labels = sbg.createSettingBox_Labels
- createSettingBoxMessageFormatEntries = sbg.createSettingBoxMessageFormatEntries
- createSettingBoxMessageFormatEntries_WithTranslation = sbg.createSettingBoxMessageFormatEntries_WithTranslation
-
- def entryReceivedMessageFormatCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT, value)
-
-
- def entryReceivedMessageFormatWithTCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT_WITH_T, value)
-
- def entrySwapReceivedMessageFormatWithTCallback(_e):
- callFunctionIfCallable(view_variable.CALLBACK_SWAP_RECEIVED_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT)
-
- row=0
- config_window.sb__received_message_format_labels = createSettingBox_Labels(
- for_var_label_text=view_variable.VAR_LABEL_RECEIVED_MESSAGE_FORMAT,
- for_var_desc_text=view_variable.VAR_DESC_RECEIVED_MESSAGE_FORMAT,
- labels_attr_name="sb__labels_received_message_format",
- )
- config_window.sb__received_message_format_labels.grid(row=row, pady=0)
- row+=1
-
- config_window.sb__received_message_format = createSettingBoxMessageFormatEntries(
- base_entry_attr_name="sb__entry_received_message_format",
- entry_textvariable_0=view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT,
- entry_textvariable_1=view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT,
- textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT,
- example_label_textvariable=view_variable.VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT,
- entry_bind__Any_KeyRelease=lambda value: entryReceivedMessageFormatCallback(value),
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_RECEIVED_MESSAGE_FORMAT,
- )
- config_window.sb__received_message_format.grid(row=row)
- row+=1
-
-
-
- config_window.sb__received_message_format_with_t_labels = createSettingBox_Labels(
- for_var_label_text=view_variable.VAR_LABEL_RECEIVED_MESSAGE_FORMAT_WITH_T,
- for_var_desc_text=view_variable.VAR_DESC_RECEIVED_MESSAGE_FORMAT_WITH_T,
- labels_attr_name="sb__labels_message_format_with_t",
- )
- config_window.sb__received_message_format_with_t_labels.grid(row=row, pady=0)
- row+=1
-
- config_window.sb__received_message_format_with_t = createSettingBoxMessageFormatEntries_WithTranslation(
- base_entry_attr_name="sb__entry_received_message_format_with_t",
- entry_textvariable_0=view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT_WITH_T,
- entry_textvariable_1=view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT_WITH_T,
- entry_textvariable_2=view_variable.VAR_ENTRY_2_RECEIVED_MESSAGE_FORMAT_WITH_T,
- textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T,
- textvariable_1=view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T,
- example_label_textvariable=view_variable.VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT_WITH_T,
- entry_bind__Any_KeyRelease=lambda value: entryReceivedMessageFormatWithTCallback(value),
- swap_button_command=entrySwapReceivedMessageFormatWithTCallback,
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_RECEIVED_MESSAGE_FORMAT_WITH_T,
- )
- config_window.sb__received_message_format_with_t.grid(row=row, pady=0)
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others_SendMessageFormats.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others_SendMessageFormats.py
deleted file mode 100644
index 61c89dd2..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_others/createSettingBox_Others_SendMessageFormats.py
+++ /dev/null
@@ -1,66 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_Others_SendMessageFormats(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBox_Labels = sbg.createSettingBox_Labels
- createSettingBoxMessageFormatEntries = sbg.createSettingBoxMessageFormatEntries
- createSettingBoxMessageFormatEntries_WithTranslation = sbg.createSettingBoxMessageFormatEntries_WithTranslation
-
- def entrySendMessageFormatCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT, value)
-
-
- def entrySendMessageFormatWithTCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT_WITH_T, value)
-
- def entrySwapMessageFormatWithTCallback(_e):
- callFunctionIfCallable(view_variable.CALLBACK_SWAP_SEND_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT)
-
-
- row=0
- config_window.sb__send_message_format_labels = createSettingBox_Labels(
- for_var_label_text=view_variable.VAR_LABEL_SEND_MESSAGE_FORMAT,
- for_var_desc_text=view_variable.VAR_DESC_SEND_MESSAGE_FORMAT,
- labels_attr_name="sb__labels_send_message_format",
- )
- config_window.sb__send_message_format_labels.grid(row=row, pady=0)
- row+=1
-
- config_window.sb__message_format = createSettingBoxMessageFormatEntries(
- base_entry_attr_name="sb__entry_send_message_format",
- entry_textvariable_0=view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT,
- entry_textvariable_1=view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT,
- textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT,
- example_label_textvariable=view_variable.VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT,
- entry_bind__Any_KeyRelease=lambda value: entrySendMessageFormatCallback(value),
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SEND_MESSAGE_FORMAT,
- )
- config_window.sb__message_format.grid(row=row)
- row+=1
-
-
-
- config_window.sb__send_message_format_with_t_labels = createSettingBox_Labels(
- for_var_label_text=view_variable.VAR_LABEL_SEND_MESSAGE_FORMAT_WITH_T,
- for_var_desc_text=view_variable.VAR_DESC_SEND_MESSAGE_FORMAT_WITH_T,
- labels_attr_name="sb__labels_send_message_format_with_t",
- )
- config_window.sb__send_message_format_with_t_labels.grid(row=row, pady=0)
- row+=1
-
- config_window.sb__message_format_with_t = createSettingBoxMessageFormatEntries_WithTranslation(
- base_entry_attr_name="sb__entry_send_message_format_with_t",
- entry_textvariable_0=view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT_WITH_T,
- entry_textvariable_1=view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT_WITH_T,
- entry_textvariable_2=view_variable.VAR_ENTRY_2_SEND_MESSAGE_FORMAT_WITH_T,
- textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T,
- textvariable_1=view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T,
- example_label_textvariable=view_variable.VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT_WITH_T,
- entry_bind__Any_KeyRelease=lambda value: entrySendMessageFormatWithTCallback(value),
- swap_button_command=entrySwapMessageFormatWithTCallback,
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SEND_MESSAGE_FORMAT_WITH_T,
- )
- config_window.sb__message_format_with_t.grid(row=row, pady=0)
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/__init__.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/__init__.py
deleted file mode 100644
index b06ff822..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .createSettingBox_Mic import createSettingBox_Mic
-from .createSettingBox_Speaker import createSettingBox_Speaker
-from .createSettingBox_InternalModel import createSettingBox_InternalModel
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/createSettingBox_InternalModel.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/createSettingBox_InternalModel.py
deleted file mode 100644
index 0a6b3e69..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/createSettingBox_InternalModel.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_InternalModel(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBoxSwitch = sbg.createSettingBoxSwitch
- createSettingBoxDropdownMenu = sbg.createSettingBoxDropdownMenu
-
- def switchUseWhisperFeatureCallback(switch_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_USE_WHISPER_FEATURE, switch_widget.get())
-
- def optionmenuWhisperWeightTypeCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_WHISPER_WEIGHT_TYPE, value)
-
-
- row=0
- config_window.sb__use_whisper_feature = createSettingBoxSwitch(
- for_var_label_text=view_variable.VAR_LABEL_USE_WHISPER_FEATURE,
- for_var_desc_text=view_variable.VAR_DESC_USE_WHISPER_FEATURE,
- switch_attr_name="sb__switch_use_whisper_feature",
- command=lambda: switchUseWhisperFeatureCallback(config_window.sb__switch_use_whisper_feature),
- variable=view_variable.VAR_USE_WHISPER_FEATURE
- )
- config_window.sb__use_whisper_feature.grid(row=row, pady=0)
- row+=1
-
- config_window.sb__whisper_weight_type = createSettingBoxDropdownMenu(
- for_var_label_text=view_variable.VAR_LABEL_WHISPER_WEIGHT_TYPE,
- for_var_desc_text=view_variable.VAR_DESC_WHISPER_WEIGHT_TYPE,
- optionmenu_attr_name="sb__optionmenu_whisper_weight_type",
- dropdown_menu_values=view_variable.DICT_WHISPER_WEIGHT_TYPE,
- command=lambda value: optionmenuWhisperWeightTypeCallback(value),
- variable=view_variable.VAR_WHISPER_WEIGHT_TYPE,
- )
- config_window.sb__whisper_weight_type.grid(row=row, pady=0)
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/createSettingBox_Mic.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/createSettingBox_Mic.py
deleted file mode 100644
index 50eb8d2e..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/createSettingBox_Mic.py
+++ /dev/null
@@ -1,171 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBoxDropdownMenu = sbg.createSettingBoxDropdownMenu
- createSettingBoxSwitch = sbg.createSettingBoxSwitch
- createSettingBoxProgressbarXSlider = sbg.createSettingBoxProgressbarXSlider
- createSettingBoxEntry = sbg.createSettingBoxEntry
- createSettingBoxArrowSwitch = sbg.createSettingBoxArrowSwitch
- createSettingBoxAddAndDeleteAbleList = sbg.createSettingBoxAddAndDeleteAbleList
-
-
- def checkboxInputMicThresholdCheckCallback(is_turned_on):
- callFunctionIfCallable(view_variable.CALLBACK_CHECK_MIC_THRESHOLD, is_turned_on)
-
-
- def optionmenuMicHostCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_HOST, value)
-
- def optionmenuInputMicDeviceCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_DEVICE, value)
-
- def sliderInputMicEnergyThresholdCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_ENERGY_THRESHOLD, value)
-
- def checkboxInputMicDynamicEnergyThresholdCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_DYNAMIC_ENERGY_THRESHOLD, checkbox_box_widget.get())
-
-
- def entryInputMicRecordTimeoutCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_RECORD_TIMEOUT, value)
-
- def entryInputMicPhraseTimeoutCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_PHRASE_TIMEOUT, value)
-
- def entryInputMicMaxPhrasesCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_MAX_PHRASES, value)
-
- def arrowSwitchMicWordFilterListOpenCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_ARROW_SWITCH_MIC_WORD_FILTER_LIST_OPEN)
- def arrowSwitchMicWordFilterListCloseCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_ARROW_SWITCH_MIC_WORD_FILTER_LIST_CLOSE)
-
-# 直接 SettingBoxGenerator.pyでcallFunctionIfCallableから呼んでいます。(word filter 専用関数になっているのでそのままですが、良くはない)
- # def entry_input_mic_word_filters_callback(value):
- # callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_WORD_FILTER, value)
-
-
- row=0
- # Mic Host と Mic Device は一つの項目として引っ付ける予定
- config_window.sb__mic_host = createSettingBoxDropdownMenu(
- for_var_label_text=view_variable.VAR_LABEL_MIC_HOST,
- for_var_desc_text=view_variable.VAR_DESC_MIC_HOST,
- optionmenu_attr_name="sb__optionmenu_mic_host",
- dropdown_menu_values=view_variable.LIST_MIC_HOST,
- command=lambda value: optionmenuMicHostCallback(value),
- variable=view_variable.VAR_MIC_HOST,
- )
- config_window.sb__mic_host.grid(row=row)
- row+=1
-
- config_window.sb__mic_device = createSettingBoxDropdownMenu(
- for_var_label_text=view_variable.VAR_LABEL_MIC_DEVICE,
- for_var_desc_text=view_variable.VAR_DESC_MIC_DEVICE,
- optionmenu_attr_name="sb__optionmenu_mic_device",
- dropdown_menu_values=view_variable.LIST_MIC_DEVICE,
- command=lambda value: optionmenuInputMicDeviceCallback(value),
- variable=view_variable.VAR_MIC_DEVICE,
- )
- config_window.sb__mic_device.grid(row=row)
- row+=1
-
- config_window.sb__mic_dynamic_energy_threshold = createSettingBoxSwitch(
- for_var_label_text=view_variable.VAR_LABEL_MIC_DYNAMIC_ENERGY_THRESHOLD,
- for_var_desc_text=view_variable.VAR_DESC_MIC_DYNAMIC_ENERGY_THRESHOLD,
- switch_attr_name="sb__checkbox_mic_dynamic_energy_threshold",
- command=lambda: checkboxInputMicDynamicEnergyThresholdCallback(config_window.sb__checkbox_mic_dynamic_energy_threshold),
- variable=view_variable.VAR_MIC_DYNAMIC_ENERGY_THRESHOLD
- )
- config_window.sb__mic_dynamic_energy_threshold.grid(row=row, pady=0)
- row+=1
-
- config_window.sb__mic_energy_threshold = createSettingBoxProgressbarXSlider(
- command=sliderInputMicEnergyThresholdCallback,
- progressbar_x_slider_attr_name="sb__mic_energy_threshold",
-
- entry_attr_name="sb__progressbar_x_slider__entry_mic_energy_threshold",
- entry_variable=view_variable.VAR_MIC_ENERGY_THRESHOLD__ENTRY,
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_MIC_ENERGY_THRESHOLD,
-
-
- slider_attr_name="progressbar_x_slider__slider_mic_energy_threshold",
- slider_range=view_variable.SLIDER_RANGE_MIC_ENERGY_THRESHOLD,
- slider_variable=view_variable.VAR_MIC_ENERGY_THRESHOLD__SLIDER,
-
- progressbar_attr_name="sb__progressbar_x_slider__progressbar_mic_energy_threshold",
-
- passive_button_attr_name="sb__progressbar_x_slider__passive_button_mic_energy_threshold",
- passive_button_command=lambda _e: checkboxInputMicThresholdCheckCallback(True),
- active_button_attr_name="sb__progressbar_x_slider__active_button_mic_energy_threshold",
- active_button_command=lambda _e: checkboxInputMicThresholdCheckCallback(False),
- button_image_file=settings.image_file.MIC_ICON,
- disabled_button_attr_name="sb__progressbar_x_slider__disabled_button_mic_energy_threshold",
- disabled_button_image_file=settings.image_file.MIC_ICON_DISABLED,
- )
- config_window.sb__mic_energy_threshold.grid(row=row)
- row+=1
-
-
- # 以下3つも一つの項目にまとめるかもしれない
- config_window.sb__mic_record_timeout = createSettingBoxEntry(
- for_var_label_text=view_variable.VAR_LABEL_MIC_RECORD_TIMEOUT,
- for_var_desc_text=view_variable.VAR_DESC_MIC_RECORD_TIMEOUT,
- entry_attr_name="sb__entry_mic_record_timeout",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
- entry_bind__Any_KeyRelease=lambda value: entryInputMicRecordTimeoutCallback(value),
- entry_textvariable=view_variable.VAR_MIC_RECORD_TIMEOUT,
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_MIC_RECORD_TIMEOUT,
- )
- config_window.sb__mic_record_timeout.grid(row=row)
- row+=1
-
- config_window.sb__mic_phrase_timeout = createSettingBoxEntry(
- for_var_label_text=view_variable.VAR_LABEL_MIC_PHRASE_TIMEOUT,
- for_var_desc_text=view_variable.VAR_DESC_MIC_PHRASE_TIMEOUT,
- entry_attr_name="sb__entry_mic_phrase_timeout",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
- entry_bind__Any_KeyRelease=lambda value: entryInputMicPhraseTimeoutCallback(value),
- entry_textvariable=view_variable.VAR_MIC_PHRASE_TIMEOUT,
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_MIC_PHRASE_TIMEOUT,
- )
- config_window.sb__mic_phrase_timeout.grid(row=row)
- row+=1
-
- config_window.sb__mic_max_phrases = createSettingBoxEntry(
- for_var_label_text=view_variable.VAR_LABEL_MIC_MAX_PHRASES,
- for_var_desc_text=view_variable.VAR_DESC_MIC_MAX_PHRASES,
- entry_attr_name="sb__entry_mic_max_phrases",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
- entry_bind__Any_KeyRelease=lambda value: entryInputMicMaxPhrasesCallback(value),
- entry_textvariable=view_variable.VAR_MIC_MAX_PHRASES,
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_MIC_MAX_PHRASES,
- )
- config_window.sb__mic_max_phrases.grid(row=row)
- row+=1
- # # __________
-
-
- config_window.sb__mic_word_filter = createSettingBoxArrowSwitch(
- for_var_label_text=view_variable.VAR_LABEL_MIC_WORD_FILTER,
- for_var_desc_text=view_variable.VAR_DESC_MIC_WORD_FILTER,
- arrow_switch_attr_name="sb__arrow_switch_mic_word_filter",
- open_command=lambda value: arrowSwitchMicWordFilterListOpenCallback(value),
- close_command=lambda value: arrowSwitchMicWordFilterListCloseCallback(value),
- var_switch_desc=view_variable.VAR_SWITCH_DESC_MIC_WORD_FILTER,
- )
- config_window.sb__mic_word_filter.grid(row=row, pady=0)
- row+=1
-
- config_window.sb__mic_word_filter_list = createSettingBoxAddAndDeleteAbleList(
- add_and_delete_able_list_attr_name="sb__add_and_delete_able_list_mic_word_filter_list",
- entry_attr_name="sb__entry_mic_word_filter_list",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_300,
- mic_word_filter_list=view_variable.MIC_WORD_FILTER_LIST,
- )
- config_window.sb__mic_word_filter_list.grid(row=row, pady=0)
- # Default, close the list.
- config_window.sb__mic_word_filter_list.grid_remove()
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/createSettingBox_Speaker.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/createSettingBox_Speaker.py
deleted file mode 100644
index 402adaa1..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_transcription/createSettingBox_Speaker.py
+++ /dev/null
@@ -1,123 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_Speaker(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBoxDropdownMenu = sbg.createSettingBoxDropdownMenu
- createSettingBoxSwitch = sbg.createSettingBoxSwitch
- createSettingBoxProgressbarXSlider = sbg.createSettingBoxProgressbarXSlider
- createSettingBoxEntry = sbg.createSettingBoxEntry
-
-
- def checkboxInputSpeakerThresholdCheckCallback(is_turned_on):
- callFunctionIfCallable(view_variable.CALLBACK_CHECK_SPEAKER_THRESHOLD, is_turned_on)
-
-
- def optionmenuInputSpeakerDeviceCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_DEVICE, value)
-
- def sliderInputSpeakerEnergyThresholdCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_ENERGY_THRESHOLD, value)
-
- def checkboxInputSpeakerDynamicEnergyThresholdCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_DYNAMIC_ENERGY_THRESHOLD, checkbox_box_widget.get())
-
-
- def entryInputSpeakerRecordTimeoutCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_RECORD_TIMEOUT, value)
-
- def entryInputSpeakerPhraseTimeoutCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_PHRASE_TIMEOUT, value)
-
- def entryInputSpeakerMaxPhrasesCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_MAX_PHRASES, value)
-
-
-
- row=0
- config_window.sb__speaker_device = createSettingBoxDropdownMenu(
- for_var_label_text=view_variable.VAR_LABEL_SPEAKER_DEVICE,
- for_var_desc_text=view_variable.VAR_DESC_SPEAKER_DEVICE,
- optionmenu_attr_name="sb__optionmenu_speaker_device",
- dropdown_menu_values=view_variable.LIST_SPEAKER_DEVICE,
- command=lambda value: optionmenuInputSpeakerDeviceCallback(value),
- variable=view_variable.VAR_SPEAKER_DEVICE,
- )
- config_window.sb__speaker_device.grid(row=row)
- row+=1
-
- config_window.sb__speaker_dynamic_energy_threshold = createSettingBoxSwitch(
- for_var_label_text=view_variable.VAR_LABEL_SPEAKER_DYNAMIC_ENERGY_THRESHOLD,
- for_var_desc_text=view_variable.VAR_DESC_SPEAKER_DYNAMIC_ENERGY_THRESHOLD,
- switch_attr_name="sb__checkbox_speaker_dynamic_energy_threshold",
- command=lambda: checkboxInputSpeakerDynamicEnergyThresholdCallback(config_window.sb__checkbox_speaker_dynamic_energy_threshold),
- variable=view_variable.VAR_SPEAKER_DYNAMIC_ENERGY_THRESHOLD,
- )
- config_window.sb__speaker_dynamic_energy_threshold.grid(row=row, pady=0)
- row+=1
-
- config_window.sb__speaker_energy_threshold = createSettingBoxProgressbarXSlider(
- command=sliderInputSpeakerEnergyThresholdCallback,
- progressbar_x_slider_attr_name="sb__speaker_energy_threshold",
-
- entry_variable=view_variable.VAR_SPEAKER_ENERGY_THRESHOLD__ENTRY,
- entry_attr_name="sb__progressbar_x_slider__entry_speaker_energy_threshold",
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SPEAKER_ENERGY_THRESHOLD,
-
-
- slider_attr_name="progressbar_x_slider__slider_speaker_energy_threshold",
- slider_range=view_variable.SLIDER_RANGE_SPEAKER_ENERGY_THRESHOLD,
- slider_variable=view_variable.VAR_SPEAKER_ENERGY_THRESHOLD__SLIDER,
-
- progressbar_attr_name="sb__progressbar_x_slider__progressbar_speaker_energy_threshold",
-
- passive_button_attr_name="sb__progressbar_x_slider__passive_button_speaker_energy_threshold",
- passive_button_command=lambda _e: checkboxInputSpeakerThresholdCheckCallback(True),
- active_button_attr_name="sb__progressbar_x_slider__active_button_speaker_energy_threshold",
- active_button_command=lambda _e: checkboxInputSpeakerThresholdCheckCallback(False),
- button_image_file=settings.image_file.HEADPHONES_ICON,
- disabled_button_attr_name="sb__progressbar_x_slider__disabled_button_speaker_energy_threshold",
- disabled_button_image_file=settings.image_file.HEADPHONES_ICON_DISABLED,
- )
- config_window.sb__speaker_energy_threshold.grid(row=row)
- row+=1
-
-
- # 以下3つも一つの項目にまとめるかもしれない
- config_window.sb__speaker_record_timeout = createSettingBoxEntry(
- for_var_label_text=view_variable.VAR_LABEL_SPEAKER_RECORD_TIMEOUT,
- for_var_desc_text=view_variable.VAR_DESC_SPEAKER_RECORD_TIMEOUT,
- entry_attr_name="sb__entry_speaker_record_timeout",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
- entry_bind__Any_KeyRelease=lambda value: entryInputSpeakerRecordTimeoutCallback(value),
- entry_textvariable=view_variable.VAR_SPEAKER_RECORD_TIMEOUT,
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SPEAKER_RECORD_TIMEOUT,
- )
- config_window.sb__speaker_record_timeout.grid(row=row)
- row+=1
-
- config_window.sb__speaker_phrase_timeout = createSettingBoxEntry(
- for_var_label_text=view_variable.VAR_LABEL_SPEAKER_PHRASE_TIMEOUT,
- for_var_desc_text=view_variable.VAR_DESC_SPEAKER_PHRASE_TIMEOUT,
- entry_attr_name="sb__entry_speaker_phrase_timeout",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
- entry_bind__Any_KeyRelease=lambda value: entryInputSpeakerPhraseTimeoutCallback(value),
- entry_textvariable=view_variable.VAR_SPEAKER_PHRASE_TIMEOUT,
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SPEAKER_PHRASE_TIMEOUT,
- )
- config_window.sb__speaker_phrase_timeout.grid(row=row)
- row+=1
-
- config_window.sb__speaker_max_phrases = createSettingBoxEntry(
- for_var_label_text=view_variable.VAR_LABEL_SPEAKER_MAX_PHRASES,
- for_var_desc_text=view_variable.VAR_DESC_SPEAKER_MAX_PHRASES,
- entry_attr_name="sb__entry_speaker_max_phrases",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
- entry_bind__Any_KeyRelease=lambda value: entryInputSpeakerMaxPhrasesCallback(value),
- entry_textvariable=view_variable.VAR_SPEAKER_MAX_PHRASES,
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SPEAKER_MAX_PHRASES,
- )
- config_window.sb__speaker_max_phrases.grid(row=row, pady=0)
- row+=1
- # __________
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_translation/__init__.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_translation/__init__.py
deleted file mode 100644
index d965431e..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_translation/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .createSettingBox_Translation import createSettingBox_Translation
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_translation/createSettingBox_Translation.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_translation/createSettingBox_Translation.py
deleted file mode 100644
index 3350b4d8..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_translation/createSettingBox_Translation.py
+++ /dev/null
@@ -1,57 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_Translation(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBoxSwitch = sbg.createSettingBoxSwitch
- createSettingBoxDropdownMenu = sbg.createSettingBoxDropdownMenu
- createSettingBoxEntry_AuthKey = sbg.createSettingBoxEntry_AuthKey
-
- def switchUseTranslationFeatureCallback(switch_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_USE_TRANSLATION_FEATURE, switch_widget.get())
-
- def optionmenuCtranslate2WeightTypeCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_CTRANSLATE2_WEIGHT_TYPE, value)
-
- def deeplAuthKeyCallback(value):
- callFunctionIfCallable(view_variable.CALLBACK_SET_DEEPL_AUTH_KEY, value)
-
-
- row=0
- config_window.sb__use_translation_feature = createSettingBoxSwitch(
- for_var_label_text=view_variable.VAR_LABEL_USE_TRANSLATION_FEATURE,
- for_var_desc_text=view_variable.VAR_DESC_USE_TRANSLATION_FEATURE,
- switch_attr_name="sb__switch_use_translation_feature",
- command=lambda: switchUseTranslationFeatureCallback(config_window.sb__switch_use_translation_feature),
- variable=view_variable.VAR_USE_TRANSLATION_FEATURE
- )
- config_window.sb__use_translation_feature.grid(row=row, pady=0)
- row+=1
-
- config_window.sb__ctranslate2_weight_type = createSettingBoxDropdownMenu(
- for_var_label_text=view_variable.VAR_LABEL_CTRANSLATE2_WEIGHT_TYPE,
- for_var_desc_text=view_variable.VAR_DESC_CTRANSLATE2_WEIGHT_TYPE,
- optionmenu_attr_name="sb__optionmenu_ctranslate2_weight_type",
- dropdown_menu_values=view_variable.DICT_CTRANSLATE2_WEIGHT_TYPE,
- command=lambda value: optionmenuCtranslate2WeightTypeCallback(value),
- variable=view_variable.VAR_CTRANSLATE2_WEIGHT_TYPE,
- )
- config_window.sb__ctranslate2_weight_type.grid(row=row)
- row+=1
-
-
- config_window.sb__deepl_auth_key = createSettingBoxEntry_AuthKey(
- for_var_label_text=view_variable.VAR_LABEL_DEEPL_AUTH_KEY,
- for_var_desc_text=view_variable.VAR_DESC_DEEPL_AUTH_KEY,
- entry_attr_name="sb__entry_deepl_auth_key",
- entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_300,
- entry_bind__Any_KeyRelease=lambda value: deeplAuthKeyCallback(value),
- entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_DEEPL_AUTH_KEY,
- entry_textvariable=view_variable.VAR_DEEPL_AUTH_KEY,
- open_authkey_page_command=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_OPEN_WEBPAGE_DEEPL_AUTH_KEY),
- open_authkey_text_variable=view_variable.VAR_OPEN_DEEPL_WEB_PAGE,
- image_file=settings.image_file.LINK_ICON
- )
- config_window.sb__deepl_auth_key.grid(row=row, pady=0)
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/__init__.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/__init__.py
deleted file mode 100644
index 78090aef..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .createSettingBox_Vr import createSettingBox_Vr
\ No newline at end of file
diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/createSettingBox_Vr.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/createSettingBox_Vr.py
deleted file mode 100644
index 8bb78264..00000000
--- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/createSettingBox_Vr.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from utils import callFunctionIfCallable
-
-from .._SettingBoxGenerator import _SettingBoxGenerator
-
-def createSettingBox_Vr(setting_box_wrapper, config_window, settings, view_variable):
- sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
- createSettingBox_Overlay = sbg.createSettingBox_Overlay
- createSettingBoxCheckbox = sbg.createSettingBoxCheckbox
-
- def switchEnableOverlayUiCallback(switch_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_OVERLAY_SMALL_LOG, switch_widget.get())
-
- def buttonOpenOverlaySettingsWindow(_e):
- callFunctionIfCallable(view_variable.CALLBACK_SET_OPEN_OVERLAY_SETTINGS_WINDOW)
-
-
- def checkboxNoticeXsoverlayCallback(checkbox_box_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_NOTICE_XSOVERLAY, checkbox_box_widget.get())
-
-
- row=0
- config_window.sb__enable_overlay_small_log = createSettingBox_Overlay(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_OVERLAY_SMALL_LOG,
- for_var_desc_text=view_variable.VAR_DESC_ENABLE_OVERLAY_SMALL_LOG,
- switch_attr_name="sb__switch_enable_overlay_small_log",
- command=lambda: switchEnableOverlayUiCallback(config_window.sb__switch_enable_overlay_small_log),
- variable=view_variable.VAR_ENABLE_OVERLAY_SMALL_LOG,
- for_var_button_label=view_variable.VAR_OPEN_OVERLAY_SETTINGS_BUTTON,
- label_button_clicked_command=buttonOpenOverlaySettingsWindow,
- )
- config_window.sb__enable_overlay_small_log.grid(row=row)
- row+=1
-
-
- config_window.sb__notice_xsoverlay = createSettingBoxCheckbox(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_NOTICE_XSOVERLAY,
- for_var_desc_text=view_variable.VAR_DESC_ENABLE_NOTICE_XSOVERLAY,
- checkbox_attr_name="sb__checkbox_notice_xsoverlay",
- command=lambda: checkboxNoticeXsoverlayCallback(config_window.sb__checkbox_notice_xsoverlay),
- variable=view_variable.VAR_ENABLE_NOTICE_XSOVERLAY,
- )
- config_window.sb__notice_xsoverlay.grid(row=row, pady=0)
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/main_window/__init__.py b/vrct_gui/main_window/__init__.py
deleted file mode 100644
index a34b6566..00000000
--- a/vrct_gui/main_window/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .createMainWindowWidgets import createMainWindowWidgets
\ No newline at end of file
diff --git a/vrct_gui/main_window/createMainWindowWidgets.py b/vrct_gui/main_window/createMainWindowWidgets.py
deleted file mode 100644
index 3fb7d105..00000000
--- a/vrct_gui/main_window/createMainWindowWidgets.py
+++ /dev/null
@@ -1,232 +0,0 @@
-from .widgets import createSidebar, createMinimizeSidebarButton, createTextbox, createEntryMessageBox
-
-from customtkinter import CTkFrame, CTkLabel, CTkFont, CTkImage
-
-from utils import callFunctionIfCallable
-from ..ui_utils import createButtonWithImage, getImagePath, bindButtonFunctionAndColor
-
-def createMainWindowWidgets(vrct_gui, settings, view_variable):
- vrct_gui.protocol("WM_DELETE_WINDOW", lambda: callFunctionIfCallable(view_variable.CALLBACK_DELETE_MAIN_WINDOW))
-
-
- vrct_gui.iconbitmap(getImagePath("vrct_logo_mark_black.ico"))
- vrct_gui.title("VRCT")
-
-
- # Main Container
- vrct_gui.grid_columnconfigure(0, weight=1)
- vrct_gui.grid_rowconfigure(0, weight=1)
-
- vrct_gui.configure(fg_color=settings.ctm.MAIN_BG_COLOR)
-
- vrct_gui.toplevel_wrapper = CTkFrame(vrct_gui, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- vrct_gui.toplevel_wrapper.grid(row=0, column=0, sticky="nsew")
- vrct_gui.toplevel_wrapper.grid_columnconfigure(1, weight=1)
-
-
- # Main Container
- vrct_gui.main_bg_container = CTkFrame(vrct_gui.toplevel_wrapper, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- vrct_gui.main_bg_container.grid(row=0, column=1, sticky="nsew")
-
-
- # top bar
- vrct_gui.main_bg_container.grid_columnconfigure(0, weight=1)
- vrct_gui.main_topbar_container = CTkFrame(vrct_gui.main_bg_container, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- vrct_gui.main_topbar_container.grid(row=0, column=0, sticky="ew")
-
-
-
-
-
- vrct_gui.main_topbar_container.grid_columnconfigure(1,weight=1)
- vrct_gui.main_topbar_center_container = CTkFrame(vrct_gui.main_topbar_container, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- vrct_gui.main_topbar_center_container.grid(row=0, column=1, sticky="nsew")
-
-
-
- # Main Top Bar Container - Right Side
- # start from 3
- main_topbar_column=3
-
- # VRChat Mic Mute Sync Settings Button
- vrct_gui.vrc_mic_mute_sync_settings_container = CTkFrame(
- vrct_gui.main_topbar_container,
- corner_radius=settings.uism.UPDATE_AVAILABLE_BUTTON_CORNER_RADIUS,
- fg_color=settings.ctm.MAIN_BG_COLOR,
- cursor="hand2",
- )
- vrct_gui.vrc_mic_mute_sync_settings_container.grid(row=0, column=main_topbar_column, padx=settings.uism.UPDATE_AVAILABLE_BUTTON_PADX, pady=settings.uism.TOP_BAR_BUTTON_PADY, sticky="nsw")
- vrct_gui.vrc_mic_mute_sync_settings_container.grid_rowconfigure((0,3), weight=1)
-
- vrct_gui.vrc_mic_mute_sync_settings_label = CTkLabel(
- vrct_gui.vrc_mic_mute_sync_settings_container,
- textvariable=view_variable.VAR_VRC_MIC_MUTE_SYNC_SETTINGS,
- height=0,
- corner_radius=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.QUICK_SETTINGS_BUTTON_FONT_SIZE, weight="normal"),
- anchor="e",
- text_color=settings.ctm.TOP_BAR_BUTTON_TEXT_COLOR,
- # text_color=settings.ctm.UPDATE_AVAILABLE_BUTTON_TEXT_COLOR,
- )
- # This "right padx +1" is for fixing a bug that sticks out from the frame. I don't know why that happens...
- vrct_gui.vrc_mic_mute_sync_settings_label.grid(row=1, column=1, padx=(0,settings.uism.UPDATE_AVAILABLE_BUTTON_IPADX+1), pady=0)
-
-
- vrct_gui.vrc_mic_mute_sync_settings_state_label = CTkLabel(
- vrct_gui.vrc_mic_mute_sync_settings_container,
- textvariable=view_variable.VAR_VRC_MIC_MUTE_SYNC_STATE,
- height=0,
- corner_radius=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.QUICK_SETTINGS_BUTTON_STATE_FONT_SIZE, weight="normal"),
- anchor="e",
- text_color=settings.ctm.TOP_BAR_BUTTON_TEXT_COLOR,
- # text_color=settings.ctm.UPDATE_AVAILABLE_BUTTON_TEXT_COLOR,
- )
- # This "right padx +1" is for fixing a bug that sticks out from the frame. I don't know why that happens...
- vrct_gui.vrc_mic_mute_sync_settings_state_label.grid(row=2, column=1, padx=(0,settings.uism.UPDATE_AVAILABLE_BUTTON_IPADX+1), pady=0)
-
-
- bindButtonFunctionAndColor(
- target_widgets=[
- vrct_gui.vrc_mic_mute_sync_settings_container,
- vrct_gui.vrc_mic_mute_sync_settings_label,
- vrct_gui.vrc_mic_mute_sync_settings_state_label,
- ],
- enter_color=settings.ctm.TOP_BAR_BUTTON_HOVERED_BG_COLOR,
- leave_color=settings.ctm.TOP_BAR_BUTTON_BG_COLOR,
- clicked_color=settings.ctm.TOP_BAR_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=lambda e: callFunctionIfCallable(view_variable.CALLBACK_SET_OPEN_VRC_MIC_MUTE_SYNC_SETTINGS_WINDOW),
- )
-
-
-
-
-
- main_topbar_column+=1
- # Overlay Settings Button
- vrct_gui.overlay_settings_container = CTkFrame(
- vrct_gui.main_topbar_container,
- corner_radius=settings.uism.UPDATE_AVAILABLE_BUTTON_CORNER_RADIUS,
- fg_color=settings.ctm.MAIN_BG_COLOR,
- cursor="hand2",
- )
- vrct_gui.overlay_settings_container.grid(row=0, column=main_topbar_column, padx=settings.uism.UPDATE_AVAILABLE_BUTTON_PADX, pady=settings.uism.TOP_BAR_BUTTON_PADY, sticky="nsw")
- vrct_gui.overlay_settings_container.grid_rowconfigure((0,3), weight=1)
-
- vrct_gui.overlay_settings_label = CTkLabel(
- vrct_gui.overlay_settings_container,
- textvariable=view_variable.VAR_OVERLAY_SETTINGS,
- height=0,
- corner_radius=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.QUICK_SETTINGS_BUTTON_FONT_SIZE, weight="normal"),
- anchor="e",
- text_color=settings.ctm.TOP_BAR_BUTTON_TEXT_COLOR,
- # text_color=settings.ctm.UPDATE_AVAILABLE_BUTTON_TEXT_COLOR,
- )
- # This "right padx +1" is for fixing a bug that sticks out from the frame. I don't know why that happens...
- vrct_gui.overlay_settings_label.grid(row=1, column=1, padx=(0,settings.uism.UPDATE_AVAILABLE_BUTTON_IPADX+1), pady=0)
-
-
- vrct_gui.overlay_settings_state_label = CTkLabel(
- vrct_gui.overlay_settings_container,
- textvariable=view_variable.VAR_OVERLAY_SMALL_LOG_STATE,
- height=0,
- corner_radius=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.QUICK_SETTINGS_BUTTON_STATE_FONT_SIZE, weight="normal"),
- anchor="e",
- text_color=settings.ctm.TOP_BAR_BUTTON_TEXT_COLOR,
- )
- # This "right padx +1" is for fixing a bug that sticks out from the frame. I don't know why that happens...
- vrct_gui.overlay_settings_state_label.grid(row=2, column=1, padx=(0,settings.uism.UPDATE_AVAILABLE_BUTTON_IPADX+1), pady=0)
-
-
- bindButtonFunctionAndColor(
- target_widgets=[
- vrct_gui.overlay_settings_container,
- vrct_gui.overlay_settings_label,
- vrct_gui.overlay_settings_state_label,
- ],
- enter_color=settings.ctm.TOP_BAR_BUTTON_HOVERED_BG_COLOR,
- leave_color=settings.ctm.TOP_BAR_BUTTON_BG_COLOR,
- clicked_color=settings.ctm.TOP_BAR_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=lambda e: callFunctionIfCallable(view_variable.CALLBACK_SET_OPEN_OVERLAY_SETTINGS_WINDOW),
- )
-
-
-
-
- main_topbar_column+=1
- # Update Available Button
- vrct_gui.update_available_container = CTkFrame(
- vrct_gui.main_topbar_container,
- corner_radius=settings.uism.UPDATE_AVAILABLE_BUTTON_CORNER_RADIUS,
- fg_color=settings.ctm.MAIN_BG_COLOR,
- cursor="hand2",
- )
- vrct_gui.update_available_container.grid(row=0, column=main_topbar_column, padx=settings.uism.UPDATE_AVAILABLE_BUTTON_PADX, pady=settings.uism.TOP_BAR_BUTTON_PADY, sticky="nse")
- vrct_gui.update_available_container.grid_remove()
- main_topbar_column+=1
-
-
- vrct_gui.update_available_container.grid_rowconfigure((0,2), weight=1)
-
- vrct_gui.update_available_icon = CTkLabel(
- vrct_gui.update_available_container,
- text=None,
- corner_radius=0,
- height=0,
- image=CTkImage(settings.image_file.REFRESH_UPDATE_ICON.rotate(25), size=settings.uism.UPDATE_AVAILABLE_BUTTON_SIZE)
- )
- vrct_gui.update_available_icon.grid(row=1, column=0, padx=(settings.uism.UPDATE_AVAILABLE_BUTTON_IPADX, settings.uism.UPDATE_AVAILABLE_PADX_BETWEEN_LABEL_AND_ICON), pady=0)
-
-
- vrct_gui.update_available_label = CTkLabel(
- vrct_gui.update_available_container,
- textvariable=view_variable.VAR_UPDATE_AVAILABLE,
- height=0,
- corner_radius=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.UPDATE_AVAILABLE_BUTTON_FONT_SIZE, weight="normal"),
- anchor="e",
- text_color=settings.ctm.UPDATE_AVAILABLE_BUTTON_TEXT_COLOR,
- )
- # This "right padx +1" is for fixing a bug that sticks out from the frame. I don't know why that happens...
- vrct_gui.update_available_label.grid(row=1, column=1, padx=(0,settings.uism.UPDATE_AVAILABLE_BUTTON_IPADX+1), pady=0)
-
-
- bindButtonFunctionAndColor(
- target_widgets=[
- vrct_gui.update_available_container,
- vrct_gui.update_available_label,
- vrct_gui.update_available_icon,
- ],
- enter_color=settings.ctm.TOP_BAR_BUTTON_HOVERED_BG_COLOR,
- leave_color=settings.ctm.TOP_BAR_BUTTON_BG_COLOR,
- clicked_color=settings.ctm.TOP_BAR_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=lambda e: callFunctionIfCallable(view_variable.CALLBACK_CLICKED_UPDATE_AVAILABLE),
- )
-
-
-
-
-
- # Help and Info button
- vrct_gui.help_and_info_button_container = createButtonWithImage(
- parent_widget=vrct_gui.main_topbar_container,
- button_fg_color=settings.ctm.TOP_BAR_BUTTON_BG_COLOR,
- button_enter_color=settings.ctm.TOP_BAR_BUTTON_HOVERED_BG_COLOR,
- button_clicked_color=settings.ctm.TOP_BAR_BUTTON_CLICKED_BG_COLOR,
- button_image_file=settings.image_file.HELP_ICON,
- button_image_size=settings.uism.HELP_AND_INFO_BUTTON_SIZE,
- button_ipadxy=settings.uism.HELP_AND_INFO_BUTTON_IPADXY,
- button_command=lambda e: callFunctionIfCallable(view_variable.CALLBACK_CLICKED_HELP_AND_INFO),
- corner_radius=settings.uism.HELP_AND_INFO_BUTTON_CORNER_RADIUS,
- )
- vrct_gui.help_and_info_button_container.grid(row=0, column=main_topbar_column, padx=settings.uism.HELP_AND_INFO_BUTTON_PADX, pady=settings.uism.TOP_BAR_BUTTON_PADY, sticky="e")
- main_topbar_column+=1
- createSidebar(settings, vrct_gui, view_variable)
-
- createMinimizeSidebarButton(settings, vrct_gui, view_variable)
-
- createTextbox(settings, vrct_gui, view_variable)
-
- createEntryMessageBox(settings, vrct_gui, view_variable)
\ No newline at end of file
diff --git a/vrct_gui/main_window/widgets/__init__.py b/vrct_gui/main_window/widgets/__init__.py
deleted file mode 100644
index ac037cb8..00000000
--- a/vrct_gui/main_window/widgets/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from .create_sidebar import createSidebar
-from .create_minimize_sidebar_button import createMinimizeSidebarButton
-from .create_textbox import createTextbox
-from .create_entry_message_box import createEntryMessageBox
diff --git a/vrct_gui/main_window/widgets/_create_sidebar/__init__.py b/vrct_gui/main_window/widgets/_create_sidebar/__init__.py
deleted file mode 100644
index cda02e0d..00000000
--- a/vrct_gui/main_window/widgets/_create_sidebar/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from .createSidebarFeatures import createSidebarFeatures
-from .createSidebarLanguagesSettings import createSidebarLanguagesSettings
\ No newline at end of file
diff --git a/vrct_gui/main_window/widgets/_create_sidebar/createSidebarFeatures.py b/vrct_gui/main_window/widgets/_create_sidebar/createSidebarFeatures.py
deleted file mode 100644
index bce4113f..00000000
--- a/vrct_gui/main_window/widgets/_create_sidebar/createSidebarFeatures.py
+++ /dev/null
@@ -1,287 +0,0 @@
-from functools import partial
-
-from customtkinter import CTkFont, CTkFrame, CTkLabel, CTkSwitch, CTkImage
-
-from ....ui_utils import openImageKeepAspectRatio, retag, bindEnterAndLeaveFunction, bindButtonReleaseFunction, bindButtonPressAndReleaseFunction
-
-from utils import callFunctionIfCallable
-
-def createSidebarFeatures(settings, main_window, view_variable):
-
- def toggleSidebarFeatureSelectedMarkIfTurnedOn(is_turned_on, mark_widget):
- mark_widget.place(relx=0.85) if is_turned_on else mark_widget.place(relx=-1)
-
-
- def toggleTranslationFeature():
- is_turned_on = main_window.translation_switch_box.get()
- callFunctionIfCallable(view_variable.CALLBACK_TOGGLE_TRANSLATION, is_turned_on)
- main_window.translation_frame.markToggleManually(is_turned_on=is_turned_on)
-
- def toggleTranscriptionSendFeature():
- is_turned_on = main_window.transcription_send_switch_box.get()
- callFunctionIfCallable(view_variable.CALLBACK_TOGGLE_TRANSCRIPTION_SEND, is_turned_on)
- main_window.transcription_send_frame.markToggleManually(is_turned_on=is_turned_on)
-
- def toggleTranscriptionReceiveFeature():
- is_turned_on = main_window.transcription_receive_switch_box.get()
- callFunctionIfCallable(view_variable.CALLBACK_TOGGLE_TRANSCRIPTION_RECEIVE, is_turned_on)
- main_window.transcription_receive_frame.markToggleManually(is_turned_on=is_turned_on)
-
- def toggleForegroundFeature():
- is_turned_on = main_window.foreground_switch_box.get()
- callFunctionIfCallable(view_variable.CALLBACK_TOGGLE_FOREGROUND, is_turned_on)
- main_window.foreground_frame.markToggleManually(is_turned_on=is_turned_on)
-
-
-
-
- def changeSidebarFeaturesColorByEvents(ww, event_name):
- target_frame_widget = getattr(main_window, ww)
- target_compact_mode_frame_widget = getattr(main_window, "compact_mode_"+ww)
- if event_name == "enter":
- target_frame_widget.configure(fg_color=settings.ctm.SF__HOVERED_BG_COLOR)
- target_frame_widget.children["!ctkswitch"].configure(fg_color=settings.ctm.SF__SWITCH_BOX_HOVERED_BG_COLOR, progress_color=settings.ctm.SF__SWITCH_BOX_ACTIVE_HOVERED_BG_COLOR)
- target_compact_mode_frame_widget.configure(fg_color=settings.ctm.SF__HOVERED_BG_COLOR)
- target_compact_mode_frame_widget.children["!ctkframe"].configure(fg_color=settings.ctm.SF__SELECTED_MARK_ACTIVE_HOVERED_BG_COLOR)
-
- elif event_name == "leave":
- target_frame_widget.configure(fg_color=settings.ctm.SF__BG_COLOR)
- target_frame_widget.children["!ctkswitch"].configure(fg_color=settings.ctm.SF__SWITCH_BOX_BG_COLOR, progress_color=settings.ctm.SF__SWITCH_BOX_ACTIVE_BG_COLOR)
- target_compact_mode_frame_widget.configure(fg_color=settings.ctm.SF__BG_COLOR)
- target_compact_mode_frame_widget.children["!ctkframe"].configure(fg_color=settings.ctm.SF__SELECTED_MARK_ACTIVE_BG_COLOR)
-
- elif event_name == "button_press":
- target_frame_widget.configure(fg_color=settings.ctm.SF__CLICKED_BG_COLOR)
- target_frame_widget.children["!ctkswitch"].configure(fg_color=settings.ctm.SF__SWITCH_BOX_CLICKED_BG_COLOR, progress_color=settings.ctm.SF__SWITCH_BOX_ACTIVE_CLICKED_BG_COLOR)
- target_compact_mode_frame_widget.configure(fg_color=settings.ctm.SF__CLICKED_BG_COLOR)
- target_compact_mode_frame_widget.children["!ctkframe"].configure(fg_color=settings.ctm.SF__SELECTED_MARK_ACTIVE_CLICKED_BG_COLOR)
-
- elif event_name == "button_release":
- target_frame_widget.configure(fg_color=settings.ctm.SF__BG_COLOR)
- target_frame_widget.children["!ctkswitch"].configure(fg_color=settings.ctm.SF__SWITCH_BOX_BG_COLOR, progress_color=settings.ctm.SF__SWITCH_BOX_ACTIVE_BG_COLOR)
- target_compact_mode_frame_widget.configure(fg_color=settings.ctm.SF__BG_COLOR)
- target_compact_mode_frame_widget.children["!ctkframe"].configure(fg_color=settings.ctm.SF__SELECTED_MARK_ACTIVE_BG_COLOR)
-
-
-
-
-
-
-
-
-
- (img, width, height) = openImageKeepAspectRatio(settings.image_file.VRCT_LOGO, settings.uism.SF__LOGO_MAX_SIZE)
- main_window.sidebar_logo = CTkLabel(
- main_window.sidebar_bg_container,
- fg_color=settings.ctm.SIDEBAR_BG_COLOR,
- text=None,
- height=0,
- image=CTkImage(img, size=(width,height))
- )
- main_window.sidebar_logo.grid(row=0, column=0, pady=settings.uism.SF__LOGO_PADY)
-
- # "height-a_s" represents the adjustment in size, and the "pady+a_s/2" indicates a padding increase of 4 pixels to compensate for the reduction.
- a_s = settings.uism.SF__LOGO_HEIGHT_FOR_ADJUSTMENT
- (img, width, height) = openImageKeepAspectRatio(settings.image_file.VRCT_LOGO_MARK, height-a_s)
- main_window.sidebar_compact_mode_logo = CTkLabel(
- main_window.sidebar_compact_mode_bg_container,
- fg_color=settings.ctm.SIDEBAR_BG_COLOR,
- text=None,
- height=0,
- image=CTkImage(img, size=(width,height))
- )
- main_window.sidebar_compact_mode_logo.grid(row=0, column=0, pady=(
- int(settings.uism.SF__LOGO_PADY[0]+a_s/2),
- int(settings.uism.SF__LOGO_PADY[1]+a_s/2)
- ))
-
- # Sidebar Features
- main_window.sidebar_features_container = CTkFrame(main_window.sidebar_bg_container, corner_radius=0, fg_color="transparent", width=0, height=0)
- main_window.sidebar_features_container.grid(row=1, column=0, pady=0, sticky="ew")
- main_window.sidebar_features_container.grid_columnconfigure(0, weight=1)
-
-
-
- # Sidebar Features Compact Mode
- main_window.sidebar_compact_mode_features_container = CTkFrame(main_window.sidebar_compact_mode_bg_container, corner_radius=0, fg_color="transparent", width=0, height=0)
- main_window.sidebar_compact_mode_features_container.grid(row=1, column=0, pady=0, sticky="ew")
- main_window.sidebar_compact_mode_features_container.grid_columnconfigure(0, weight=1)
-
-
-
- sidebar_features_settings = [
- {
- "frame_attr_name": "translation_frame",
- "command": toggleTranslationFeature,
- "switch_box_attr_name": "translation_switch_box",
- "toggle_switch_box_command": lambda e: main_window.translation_switch_box.toggle(),
- "label_attr_name": "label_translation",
- "compact_mode_icon_attr_name": "translation_compact_mode_icon",
- "compact_mode_frame_attr_name": "compact_mode_translation_frame",
- "selected_mark_attr_name": "translation_selected_mark",
- "var_label_text": view_variable.VAR_LABEL_TRANSLATION,
- "icon_file": settings.image_file.TRANSLATION_ICON,
- },
- {
- "frame_attr_name": "transcription_send_frame",
- "command": toggleTranscriptionSendFeature,
- "switch_box_attr_name": "transcription_send_switch_box",
- "toggle_switch_box_command": lambda e: main_window.transcription_send_switch_box.toggle(),
- "label_attr_name": "label_transcription_send",
- "compact_mode_icon_attr_name": "transcription_send_compact_mode_icon",
- "compact_mode_frame_attr_name": "compact_mode_transcription_send_frame",
- "selected_mark_attr_name": "transcription_send_selected_mark",
- "var_label_text": view_variable.VAR_LABEL_TRANSCRIPTION_SEND,
- "icon_file": settings.image_file.MIC_ICON,
- },
- {
- "frame_attr_name": "transcription_receive_frame",
- "command": toggleTranscriptionReceiveFeature,
- "switch_box_attr_name": "transcription_receive_switch_box",
- "toggle_switch_box_command": lambda e: main_window.transcription_receive_switch_box.toggle(),
- "label_attr_name": "label_transcription_receive",
- "compact_mode_icon_attr_name": "transcription_receive_compact_mode_icon",
- "compact_mode_frame_attr_name": "compact_mode_transcription_receive_frame",
- "selected_mark_attr_name": "transcription_receive_selected_mark",
- "var_label_text": view_variable.VAR_LABEL_TRANSCRIPTION_RECEIVE,
- "icon_file": settings.image_file.HEADPHONES_ICON,
- },
- {
- "frame_attr_name": "foreground_frame",
- "command": toggleForegroundFeature,
- "switch_box_attr_name": "foreground_switch_box",
- "toggle_switch_box_command": lambda e: main_window.foreground_switch_box.toggle(),
- "label_attr_name": "label_foreground",
- "compact_mode_icon_attr_name": "foreground_compact_mode_icon",
- "compact_mode_frame_attr_name": "compact_mode_foreground_frame",
- "selected_mark_attr_name": "foreground_selected_mark",
- "var_label_text": view_variable.VAR_LABEL_FOREGROUND,
- "icon_file": settings.image_file.FOREGROUND_ICON,
- },
- ]
-
-
-
- row=0
- for sfs in sidebar_features_settings:
- frame_attr_name = sfs["frame_attr_name"]
- command = sfs["command"]
- switch_box_attr_name = sfs["switch_box_attr_name"]
- toggle_switch_box_command = sfs["toggle_switch_box_command"]
- label_attr_name = sfs["label_attr_name"]
- compact_mode_icon_attr_name = sfs["compact_mode_icon_attr_name"]
- compact_mode_frame_attr_name = sfs["compact_mode_frame_attr_name"]
- selected_mark_attr_name = sfs["selected_mark_attr_name"]
- var_label_text = sfs["var_label_text"]
- icon_file = sfs["icon_file"]
-
- frame_widget = CTkFrame(main_window.sidebar_features_container, corner_radius=0, fg_color=settings.ctm.SF__BG_COLOR, cursor="hand2", width=0, height=0)
- setattr(main_window, frame_attr_name, frame_widget)
-
- frame_widget.grid(row=row, column=0, pady=(0,1), sticky="ew")
- frame_widget.grid_columnconfigure(0, weight=1)
-
- compact_mode_frame_widget = CTkFrame(main_window.sidebar_compact_mode_features_container, corner_radius=0, fg_color=settings.ctm.SF__BG_COLOR, cursor="hand2", width=0, height=0)
- setattr(main_window, compact_mode_frame_attr_name, compact_mode_frame_widget)
-
- compact_mode_frame_widget.grid(row=row, column=0, pady=(0,1), sticky="ew")
- compact_mode_frame_widget.grid_columnconfigure(0, weight=1)
-
-
- label_widget = CTkLabel(
- frame_widget,
- textvariable=var_label_text,
- height=0,
- corner_radius=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.SF__LABEL_FONT_SIZE, weight="normal"),
- anchor="w",
- text_color=settings.ctm.LABELS_TEXT_COLOR,
- )
- setattr(main_window, label_attr_name, label_widget)
-
-
- switch_box_widget = CTkSwitch(
- frame_widget,
- text=None,
- height=0,
- width=0,
- corner_radius=int(settings.uism.SF__SWITCH_BOX_HEIGHT/2),
- border_width=0,
- switch_height=settings.uism.SF__SWITCH_BOX_HEIGHT,
- switch_width=settings.uism.SF__SWITCH_BOX_WIDTH,
- onvalue=True,
- offvalue=False,
- command=command,
- fg_color=settings.ctm.SF__SWITCH_BOX_BG_COLOR,
- bg_color=settings.ctm.SF__BG_COLOR,
- progress_color=settings.ctm.SF__SWITCH_BOX_ACTIVE_BG_COLOR,
- button_color=settings.ctm.SF__SWITCH_BOX_BUTTON_COLOR,
- # button_hover_color=settings.ctm.SF__SWITCH_BOX_BUTTON_HOVERED_COLOR,
- )
- setattr(main_window, switch_box_attr_name, switch_box_widget)
-
-
-
- # for compact mode
- compact_mode_icon_widget = CTkLabel(
- compact_mode_frame_widget,
- text=None,
- height=0,
- corner_radius=0,
- image=CTkImage(icon_file, size=settings.uism.SF__COMPACT_MODE_IMAGE_SIZE),
- )
- setattr(main_window, compact_mode_icon_attr_name, compact_mode_icon_widget)
-
- selected_mark_widget = CTkFrame(
- compact_mode_frame_widget,
- corner_radius=0,
- fg_color=settings.ctm.SF__SELECTED_MARK_ACTIVE_BG_COLOR,
- width=settings.uism.SF__SELECTED_MARK_WIDTH,
- height=0
- )
- setattr(main_window, selected_mark_attr_name, selected_mark_widget)
-
-
- # Arrange
- compact_mode_icon_widget.grid(row=row, column=0, padx=settings.uism.SF__COMPACT_MODE_ICON_PADX, pady=settings.uism.SF__COMPACT_MODE_ICON_PADY)
- selected_mark_widget.place(relx=-1, rely=0.5, relheight=0.75, anchor="center")
-
- label_widget.grid(row=row, column=0, pady=settings.uism.SF__LABELS_IPADY, padx=(settings.uism.SF__LABEL_LEFT_PAD,0), sticky="ew")
- switch_box_widget.grid(row=row, column=1, padx=settings.uism.SF__SWITCH_BOX_PADX, sticky="e")
-
-
- # Unbind the event "" originally set up by the widget to manually control it.
- switch_box_widget._canvas.unbind("")
- switch_box_widget._text_label.unbind("")
-
- bindButtonReleaseFunction([compact_mode_icon_widget, frame_widget, compact_mode_frame_widget, label_widget, selected_mark_widget, switch_box_widget._canvas, switch_box_widget._bg_canvas], toggle_switch_box_command)
-
- retag("vrct_"+frame_attr_name, compact_mode_icon_widget, frame_widget, compact_mode_frame_widget, label_widget, selected_mark_widget, switch_box_widget)
-
- def commonEventFunction(e, event_type):
- for ww in e.widget.master.bindtags():
- if ww.startswith("vrct_"):
- ww = ww.replace("vrct_", "")
- changeSidebarFeaturesColorByEvents(ww, event_type)
- break
-
- def enterFunction(e):
- commonEventFunction(e, "enter")
-
- def leaveFunction(e):
- commonEventFunction(e, "leave")
-
- def buttonPressFunction(e):
- commonEventFunction(e, "button_press")
-
- def buttonReleasedFunction(e):
- commonEventFunction(e, "button_release")
-
- bindEnterAndLeaveFunction([compact_mode_icon_widget, frame_widget, compact_mode_frame_widget, label_widget, selected_mark_widget, switch_box_widget._canvas, switch_box_widget._bg_canvas], enterFunction, leaveFunction)
-
- bindButtonPressAndReleaseFunction([compact_mode_icon_widget, frame_widget, compact_mode_frame_widget, label_widget, selected_mark_widget, switch_box_widget._canvas, switch_box_widget._bg_canvas], buttonPressFunction, buttonReleasedFunction)
-
- callback = partial(toggleSidebarFeatureSelectedMarkIfTurnedOn, mark_widget=selected_mark_widget)
- frame_widget.markToggleManually = callback
-
- row+=1
\ No newline at end of file
diff --git a/vrct_gui/main_window/widgets/_create_sidebar/createSidebarLanguagesSettings.py b/vrct_gui/main_window/widgets/_create_sidebar/createSidebarLanguagesSettings.py
deleted file mode 100644
index d8f37965..00000000
--- a/vrct_gui/main_window/widgets/_create_sidebar/createSidebarLanguagesSettings.py
+++ /dev/null
@@ -1,379 +0,0 @@
-from customtkinter import CTkFont, CTkFrame, CTkLabel, CTkImage
-
-from ...._CreateDropdownMenuWindow import _CreateDropdownMenuWindow
-
-from ....ui_utils import bindEnterAndLeaveColor, bindButtonPressColor, bindButtonReleaseFunction, switchActiveTabAndPassiveTab, switchTabsColor, createOptionMenuBox, bindButtonFunctionAndColor, bindEnterAndLeaveFunction, createLabelButton
-
-from utils import callFunctionIfCallable
-
-
-def createSidebarLanguagesSettings(settings, main_window, view_variable):
-
-
- def switchActiveAndPassivePresetsTabsColor(target_active_widget):
- quick_setting_tabs = [
- getattr(main_window, "sls__presets_button_1"),
- getattr(main_window, "sls__presets_button_2"),
- getattr(main_window, "sls__presets_button_3")
- ]
-
- switchTabsColor(
- target_widget=target_active_widget,
- tab_buttons=quick_setting_tabs,
- active_bg_color=settings.ctm.SLS__PRESETS_TAB_BG_ACTIVE_COLOR,
- active_text_color=settings.ctm.SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR,
- passive_bg_color=settings.ctm.SLS__PRESETS_TAB_BG_PASSIVE_COLOR,
- passive_text_color=settings.ctm.SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR_PASSIVE
- )
-
- def switchPresetTabFunction(target_active_widget):
- switchActiveAndPassivePresetsTabsColor(target_active_widget)
- switchActiveTabAndPassiveTab(target_active_widget, main_window.current_active_preset_tab, main_window.current_active_preset_tab.passive_function, settings.ctm.SLS__PRESETS_TAB_BG_HOVERED_COLOR, settings.ctm.SLS__PRESETS_TAB_BG_CLICKED_COLOR, settings.ctm.SLS__PRESETS_TAB_BG_PASSIVE_COLOR)
- main_window.current_active_preset_tab = target_active_widget
-
-
-
- def switchToPreset1(e):
- callFunctionIfCallable(view_variable.CALLBACK_SELECTED_LANGUAGE_PRESET_TAB, "1")
- target_active_widget = getattr(main_window, "sls__presets_button_1")
- switchPresetTabFunction(target_active_widget)
-
- def switchToPreset2(e):
- callFunctionIfCallable(view_variable.CALLBACK_SELECTED_LANGUAGE_PRESET_TAB, "2")
- target_active_widget = getattr(main_window, "sls__presets_button_2")
- switchPresetTabFunction(target_active_widget)
-
- def switchToPreset3(e):
- callFunctionIfCallable(view_variable.CALLBACK_SELECTED_LANGUAGE_PRESET_TAB, "3")
- target_active_widget = getattr(main_window, "sls__presets_button_3")
- switchPresetTabFunction(target_active_widget)
-
-
-
- def createLanguageSettingBox(parent_widget, var_title_text, title_text_attr_name, arrow_img_attr_name, open_selectable_language_window_command, variable):
- sls__box = CTkFrame(parent_widget, corner_radius=0, fg_color=settings.ctm.SLS__BOX_BG_COLOR, width=0, height=0)
-
- sls__box.grid_columnconfigure(1, weight=1)
-
- sls__box_wrapper = CTkFrame(sls__box, corner_radius=0, fg_color=settings.ctm.SLS__BOX_BG_COLOR, width=0, height=0)
- sls__box_wrapper.grid(row=2, column=1, padx=settings.uism.SLS__BOX_IPADX, pady=settings.uism.SLS__BOX_IPADY, sticky="ew")
-
- sls__box_wrapper.grid_columnconfigure(0, weight=1)
-
-
- sls__box_label_wrapper = CTkFrame(sls__box_wrapper, corner_radius=0, fg_color=settings.ctm.SLS__BOX_BG_COLOR, width=0, height=0)
- sls__box_label_wrapper.grid(row=0, column=0)
-
- sls__box_label_wrapper.grid_columnconfigure((0,2), weight=1)
- sls__label = CTkLabel(
- sls__box_label_wrapper,
- textvariable=var_title_text,
- height=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.SLS__BOX_SECTION_TITLE_FONT_SIZE, weight="normal"),
- text_color=settings.ctm.SLS__BOX_SECTION_TITLE_TEXT_COLOR
- )
- sls__label.grid(row=0, column=1, pady=(0,settings.uism.SLS__BOX_SECTION_TITLE_BOTTOM_PADY))
- setattr(main_window, title_text_attr_name, sls__label)
-
-
-
-
- sls__box_optionmenu_wrapper = CTkFrame(sls__box_wrapper, corner_radius=0, fg_color=settings.ctm.SLS__BOX_BG_COLOR, width=0, height=0)
- sls__box_optionmenu_wrapper.grid(row=1, column=0, sticky="ew")
-
- sls__box_optionmenu_wrapper.grid_columnconfigure(0, weight=1)
- (sls__selected_language_box, optionmenu_label_widget, optionmenu_img_widget) = createOptionMenuBox(
- parent_widget=sls__box_optionmenu_wrapper,
- optionmenu_bg_color=settings.ctm.SLS__OPTIONMENU_BG_COLOR,
- optionmenu_hovered_bg_color=settings.ctm.SLS__OPTIONMENU_HOVERED_BG_COLOR,
- optionmenu_clicked_bg_color=settings.ctm.SLS__OPTIONMENU_CLICKED_BG_COLOR,
- optionmenu_ipadx=(0,0),
- optionmenu_ipady=settings.uism.SLS__BOX_OPTION_MENU_IPADY,
- variable=variable,
- font_family=settings.FONT_FAMILY,
- font_size=settings.uism.SLS__BOX_OPTION_MENU_FONT_SIZE,
- text_color=settings.ctm.LABELS_TEXT_COLOR,
- image_file=settings.image_file.ARROW_LEFT.rotate(180),
- image_size=settings.uism.SLS__BOX_OPTION_MENU_ARROW_IMAGE_SIZE,
- optionmenu_clicked_command=open_selectable_language_window_command,
-
- optionmenu_position="center",
- setattr_widget=main_window,
- image_widget_attr_name=arrow_img_attr_name,
- )
- sls__selected_language_box.grid(row=0, column=0, sticky="ew")
-
- sls__box_optionmenu_wrapper_fix_1px_bug = CTkFrame(optionmenu_label_widget, corner_radius=0, width=0, height=0)
- sls__box_optionmenu_wrapper_fix_1px_bug.grid(row=0, column=1, sticky="ns")
-
- return sls__box
-
-
-
-
-
- # Sidebar Languages Settings, SLS
- main_window.sls__container = CTkFrame(main_window.sidebar_bg_container, corner_radius=0, fg_color=settings.ctm.SIDEBAR_BG_COLOR, width=0, height=0)
-
- main_window.sls__container.grid(row=2, column=0, sticky="new")
-
- main_window.sls__container.grid_columnconfigure(0, weight=1)
-
-
- main_window.sls__container_title = CTkLabel(main_window.sls__container,
- textvariable=view_variable.VAR_LABEL_LANGUAGE_SETTINGS,
- height=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.SLS__TITLE_FONT_SIZE, weight="normal"),
- text_color=settings.ctm.SLS__TITLE_TEXT_COLOR
- )
- main_window.sls__container_title.grid(row=0, column=0, pady=settings.uism.SLS__TITLE_PADY, sticky="nsew")
-
-
-
- # Presets buttons
- main_window.sidebar_bg_container.grid_rowconfigure(2, weight=1)
- main_window.sls__presets_buttons_container = CTkFrame(main_window.sls__container, corner_radius=0, fg_color=settings.ctm.SIDEBAR_BG_COLOR, width=0, height=settings.uism.SLS__PRESET_TAB_NUMBER_HEIGHT)
- main_window.sls__presets_buttons_container.grid(row=1, column=0, sticky="nsew")
-
- main_window.sls__presets_buttons_box = CTkFrame(main_window.sls__presets_buttons_container, corner_radius=0, fg_color=settings.ctm.SIDEBAR_BG_COLOR, width=0, height=0)
- main_window.sls__presets_buttons_box.place(relwidth=1, relx=0, rely=1.15, anchor="sw")
-
- main_window.sls__presets_buttons_box.grid_columnconfigure((0,1,2), weight=1)
-
-
- preset_tabs_settings = [
- {
- "preset_tab_attr_name": "sls__presets_button_1",
- "command": switchToPreset1,
- "text": "1",
- },
- {
- "preset_tab_attr_name": "sls__presets_button_2",
- "command": switchToPreset2,
- "text": "2",
- },
- {
- "preset_tab_attr_name": "sls__presets_button_3",
- "command": switchToPreset3,
- "text": "3",
- },
- ]
-
- column=0
- for preset_tab_settings in preset_tabs_settings:
- preset_tab_attr_name = preset_tab_settings["preset_tab_attr_name"]
- command = preset_tab_settings["command"]
- text = preset_tab_settings["text"]
-
- setattr(
- main_window,
- preset_tab_attr_name,
- CTkFrame(
- main_window.sls__presets_buttons_box,
- corner_radius=settings.uism.SLS__PRESET_TAB_NUMBER_CORNER_RADIUS,
- fg_color=settings.ctm.SLS__PRESETS_TAB_BG_PASSIVE_COLOR,
- width=0,
- height=settings.uism.SLS__PRESET_TAB_NUMBER_ADJUSTED_HEIGHT,
- cursor="hand2",
- )
- )
- parent_widget = getattr(main_window, preset_tab_attr_name)
- parent_widget.grid(row=0, column=column, sticky="ew")
-
- label_widget = CTkLabel(
- parent_widget,
- text=text,
- height=0,
- fg_color=settings.ctm.SLS__PRESETS_TAB_BG_PASSIVE_COLOR,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.SLS__PRESET_TAB_NUMBER_FONT_SIZE, weight="bold"),
- anchor="center",
- text_color=settings.ctm.SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR_PASSIVE
- )
- label_widget.place(relx=0.5, rely=0.44, anchor="center")
-
-
-
- bindEnterAndLeaveColor([parent_widget, label_widget], settings.ctm.SLS__PRESETS_TAB_BG_HOVERED_COLOR, settings.ctm.SLS__PRESETS_TAB_BG_PASSIVE_COLOR)
- bindButtonPressColor([parent_widget, label_widget], settings.ctm.SLS__PRESETS_TAB_BG_CLICKED_COLOR, settings.ctm.SLS__PRESETS_TAB_BG_PASSIVE_COLOR)
-
- parent_widget.passive_function = command
- bindButtonReleaseFunction([parent_widget, label_widget], command)
-
- column+=1
-
-
- def callbackOpenSelectableYourLanguageWindow(value):
- callFunctionIfCallable(view_variable.CALLBACK_OPEN_SELECTABLE_YOUR_LANGUAGE_WINDOW, value)
-
-
- def callbackOpenSelectableTargetLanguageWindow(value):
- callFunctionIfCallable(view_variable.CALLBACK_OPEN_SELECTABLE_TARGET_LANGUAGE_WINDOW, value)
-
- # Language Settings BOX
- main_window.sls__box_frame = CTkFrame(main_window.sls__container, corner_radius=0, fg_color=settings.ctm.SLS__BG_COLOR, width=0, height=0)
- main_window.sls__box_frame.grid(row=2, column=0, sticky="ew")
- main_window.sls__box_frame.grid_columnconfigure(0, weight=1)
-
- # Your language
- main_window.sls__box_your_language = createLanguageSettingBox(
- parent_widget=main_window.sls__box_frame,
- var_title_text=view_variable.VAR_LABEL_YOUR_LANGUAGE,
- title_text_attr_name="sls__title_text_your_language",
- arrow_img_attr_name="sls__arrow_img_your_language",
- open_selectable_language_window_command=callbackOpenSelectableYourLanguageWindow,
- variable=view_variable.VAR_YOUR_LANGUAGE
- )
- main_window.sls__box_your_language.grid(row=2, column=0, pady=(settings.uism.SLS__BOX_TOP_PADY,0),sticky="ew")
-
-
- # Both direction arrow icon
- main_window.sls__arrow_direction_box = CTkFrame(main_window.sls__box_frame, corner_radius=0, fg_color=settings.ctm.SLS__BG_COLOR, width=0, height=0)
- main_window.sls__arrow_direction_box.grid(row=3, column=0, pady=settings.uism.SLS__BOX_ARROWS_PADY, sticky="ew")
-
- main_window.sls__arrow_direction_box.grid_columnconfigure((0,2), weight=0, minsize=settings.uism.SLS__BOX_ARROWS_SWAP_BUTTON_PADX)
- main_window.sls__arrow_direction_box.grid_columnconfigure(1, weight=1)
-
- main_window.sls__arrow_direction_swap_box = CTkFrame(main_window.sls__arrow_direction_box, corner_radius=settings.uism.SLS__BOX_ARROWS_SWAP_BUTTON_CORNER_RADIUS, fg_color=settings.ctm.SLS__BG_COLOR, width=0, height=0, cursor="hand2")
- main_window.sls__arrow_direction_swap_box.grid(row=0, column=1, ipady=settings.uism.SLS__BOX_ARROWS_SWAP_BUTTON_IPADY, sticky="ew")
-
- main_window.sls__arrow_direction_swap_box.grid_rowconfigure((0,2), weight=1)
- main_window.sls__arrow_direction_swap_box.grid_columnconfigure(1, weight=1)
-
- main_window.sls__both_direction_up = CTkLabel(
- main_window.sls__arrow_direction_swap_box,
- text=None,
- height=0,
- image=CTkImage((settings.image_file.NARROW_ARROW_DOWN).rotate(180),size=settings.uism.SLS__BOX_ARROWS_IMAGE_SIZE)
-
- )
- main_window.sls__both_direction_up.grid(row=1, column=0, padx=(settings.uism.SLS__BOX_ARROWS_SWAP_BUTTON_IPADX, 0), pady=0)
-
- main_window.sls__both_direction_desc = CTkLabel(
- main_window.sls__arrow_direction_swap_box,
- textvariable=view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON,
- height=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.SLS__BOX_ARROWS_DESC_FONT_SIZE, weight="normal"),
- text_color=settings.ctm.SLS__BOX_ARROWS_TEXT_COLOR,
- )
- main_window.sls__both_direction_desc.grid(row=1, column=1, padx=settings.uism.SLS__BOX_ARROWS_DESC_PADX)
-
- main_window.sls__both_direction_down = CTkLabel(
- main_window.sls__arrow_direction_swap_box,
- text=None,
- height=0,
- image=CTkImage((settings.image_file.NARROW_ARROW_DOWN).rotate(0),size=settings.uism.SLS__BOX_ARROWS_IMAGE_SIZE)
-
- )
- main_window.sls__both_direction_down.grid(row=1, column=2, padx=(0, settings.uism.SLS__BOX_ARROWS_SWAP_BUTTON_IPADX))
-
-
-
- def adjustedCommand_ButtonReleased():
- callFunctionIfCallable(view_variable.CALLBACK_SWAP_LANGUAGES)
-
- bindButtonFunctionAndColor(
- target_widgets=[
- main_window.sls__arrow_direction_swap_box,
- main_window.sls__both_direction_up,
- main_window.sls__both_direction_desc,
- main_window.sls__both_direction_down
- ],
- enter_color=settings.ctm.SLS__BOX_ARROWS_SWAP_BUTTON_HOVERED_COLOR,
- leave_color=settings.ctm.SLS__BG_COLOR,
- clicked_color=settings.ctm.SLS__BOX_ARROWS_SWAP_BUTTON_CLICKED_COLOR,
- buttonReleasedFunction=lambda _e: adjustedCommand_ButtonReleased(),
- )
-
-
- def adjustedCommand_Entered():
- callFunctionIfCallable(view_variable.CALLBACK_ENTERED_SWAP_LANGUAGES_BUTTON)
-
- def adjustedCommand_Leaved():
- callFunctionIfCallable(view_variable.CALLBACK_LEAVED_SWAP_LANGUAGES_BUTTON)
-
- bindEnterAndLeaveFunction(
- target_widgets=[
- main_window.sls__arrow_direction_swap_box,
- main_window.sls__both_direction_up,
- main_window.sls__both_direction_desc,
- main_window.sls__both_direction_down
- ],
- enterFunction=lambda _e: adjustedCommand_Entered(),
- leaveFunction=lambda _e: adjustedCommand_Leaved(),
- )
-
-
-
- # Target language
- main_window.sls__box_target_language = createLanguageSettingBox(
- parent_widget=main_window.sls__box_frame,
- var_title_text=view_variable.VAR_LABEL_TARGET_LANGUAGE,
- title_text_attr_name="sls__title_text_target_language",
- arrow_img_attr_name="sls__arrow_img_target_language",
- open_selectable_language_window_command=callbackOpenSelectableTargetLanguageWindow,
- variable=view_variable.VAR_TARGET_LANGUAGE
- )
- main_window.sls__box_target_language.grid(row=4, column=0, sticky="ew")
-
-
-
- # Set Transcription ON/OFF Indicator Widgets
- main_window.sls__box_your_language_mic_status__enabled = CTkLabel(
- main_window.sls__box_your_language,
- text=None,
- height=0,
- corner_radius=0,
- image=CTkImage(settings.image_file.MIC_ICON_DISABLED, size=settings.uism.SLS__BOX_TRANSCRIPTION_STATUS_IMAGE_SIZE),
- )
-
- main_window.sls__box_target_language_speaker_status__enabled = CTkLabel(
- main_window.sls__box_target_language,
- text=None,
- height=0,
- corner_radius=0,
- image=CTkImage(settings.image_file.HEADPHONES_ICON_DISABLED, size=settings.uism.SLS__BOX_TRANSCRIPTION_STATUS_IMAGE_SIZE),
- )
-
-
-
-
-
- main_window.sls__box_translation_optionmenu_wrapper = CTkFrame(main_window.sls__box_frame, corner_radius=0, fg_color=settings.ctm.SLS__BG_COLOR, width=0, height=0)
- main_window.sls__box_translation_optionmenu_wrapper.grid(row=5, column=0, pady=settings.uism.SLS__SELECTABLE_TRANSLATION_PADY, sticky="ew")
-
- main_window.sls__box_translation_optionmenu_wrapper.grid_columnconfigure((0,2), weight=0, minsize=settings.uism.SLS__SELECTABLE_TRANSLATION_MIN_PADX)
- main_window.sls__box_translation_optionmenu_wrapper.grid_columnconfigure(1, weight=1)
-
-
-
-
- def adjustedCommand(value):
- callFunctionIfCallable(view_variable.CALLBACK_SELECTED_TRANSLATION_ENGINE, value)
-
- main_window.translation_engine_dropdown_menu_window.createDropdownMenuBox(
- dropdown_menu_widget_id="translation_engine_dropdown_menu",
- dropdown_menu_values=[],
- command=adjustedCommand,
- wrapper_widget=main_window,
- attach_widget=main_window.sls__box_translation_optionmenu_wrapper,
- )
-
- (sls__selected_translation_engine_box, label_button_label_widget) = createLabelButton(
- parent_widget=main_window.sls__box_translation_optionmenu_wrapper,
- label_button_bg_color=settings.ctm.SLS__BG_COLOR,
- label_button_hovered_bg_color=settings.ctm.SLS__OPTIONMENU_HOVERED_BG_COLOR,
- label_button_clicked_bg_color=settings.ctm.SLS__OPTIONMENU_CLICKED_BG_COLOR,
- label_button_ipadx=settings.uism.SLS__SELECTABLE_TRANSLATION_IPADX,
- label_button_ipady=settings.uism.SLS__SELECTABLE_TRANSLATION_IPADY,
- variable=view_variable.VAR_SELECTED_TRANSLATION_ENGINE,
- font_family=settings.FONT_FAMILY,
- font_size=settings.uism.SLS__SELECTABLE_TRANSLATION_FONT_SIZE,
- text_color=settings.ctm.LABELS_TEXT_COLOR,
- label_button_clicked_command=lambda _e: main_window.translation_engine_dropdown_menu_window.show(
- dropdown_menu_widget_id="translation_engine_dropdown_menu"
- ),
-
- label_button_position="center",
- )
- sls__selected_translation_engine_box.grid(row=0, column=1, sticky="ew")
-
diff --git a/vrct_gui/main_window/widgets/create_entry_message_box.py b/vrct_gui/main_window/widgets/create_entry_message_box.py
deleted file mode 100644
index d153749e..00000000
--- a/vrct_gui/main_window/widgets/create_entry_message_box.py
+++ /dev/null
@@ -1,112 +0,0 @@
-from customtkinter import CTkFont, CTkFrame, CTkTextbox, CTkLabel, CTkImage
-
-from ...ui_utils import bindButtonFunctionAndColor
-from utils import callFunctionIfCallable
-
-def createEntryMessageBox(settings, main_window, view_variable):
- main_window.main_entry_message_container = CTkFrame(main_window.main_bg_container, corner_radius=settings.uism.TEXTBOX_ENTRY_CORNER_RADIUS, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- main_window.main_entry_message_container.grid(row=2, column=0, sticky="nsew")
-
-
- main_window.main_entry_message_container.grid_columnconfigure(0, weight=1)
- main_window.main_entry_message_container.grid_rowconfigure(0, weight=1)
- main_window.entry_message_box = CTkTextbox(
- main_window.main_entry_message_container,
- corner_radius=settings.uism.TEXTBOX_ENTRY_CORNER_RADIUS,
- border_color=settings.ctm.TEXTBOX_ENTRY_BORDER_COLOR,
- fg_color=settings.ctm.TEXTBOX_ENTRY_BG_COLOR,
- text_color=settings.ctm.TEXTBOX_ENTRY_TEXT_COLOR,
- border_width=settings.uism.TEXTBOX_ENTRY_BORDER_SIZE,
- height=0,
- font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.TEXTBOX_ENTRY_FONT_SIZE, weight="normal"),
- undo=True,
- autoseparators=True,
- maxundo=64,
- )
- main_window.entry_message_box.grid(row=0, column=0, padx=settings.uism.TEXTBOX_ENTRY_PADX, pady=settings.uism.TEXTBOX_ENTRY_PADY, sticky="nsew")
-
-
- def messageBoxAnyKeyPress(e):
- BREAK_KEYSYM_LIST = [
- "Delete", "Select", "Up", "Down", "Next", "End", "Print",
- "Prior","Insert","Home", "Left", "Clear", "Right", "Linefeed"
- ]
- if e.keysym == "Up":
- callFunctionIfCallable(view_variable.CALLBACK_MESSAGE_BOX_BIND_KEYSYM__UP)
- return "break"
-
- if e.keysym == "Down":
- callFunctionIfCallable(view_variable.CALLBACK_MESSAGE_BOX_BIND_KEYSYM__DOWN)
- return "break"
-
- if e.keysym != "??":
- if len(e.char) != 0 and e.keysym in BREAK_KEYSYM_LIST:
- main_window.entry_message_box.insert("end", e.char)
- return "break"
-
- main_window.entry_message_box.bind("", messageBoxAnyKeyPress)
-
- def messageBoxRedoFunction(_e):
- try:
- main_window.entry_message_box.edit_redo()
- except:
- pass
-
- main_window.entry_message_box.bind("", messageBoxRedoFunction, "+")
- main_window.entry_message_box.bind("", messageBoxRedoFunction, "+")
-
-
- main_window.main_send_message_button_container = CTkFrame(main_window.main_entry_message_container, corner_radius=settings.uism.SEND_MESSAGE_BUTTON_CORNER_RADIUS, fg_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_COLOR, width=0, height=0)
- main_window.main_send_message_button_container.grid(row=0, column=1, padx=(0, settings.uism.TEXTBOX_ENTRY_PADX), pady=settings.uism.TEXTBOX_ENTRY_PADY, sticky="nsew")
-
- main_window.main_send_message_button_container.grid_columnconfigure(0, weight=0, minsize=settings.uism.SEND_MESSAGE_BUTTON_MIN_WIDTH)
- main_window.main_send_message_button_container.grid_rowconfigure(0, weight=1)
-
-
-
-
- main_window.main_send_message_button = CTkFrame(main_window.main_send_message_button_container, corner_radius=0, fg_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_COLOR, height=0, width=0)
- main_window.main_send_message_button.grid(row=0, column=0, sticky="nsew")
- main_window.main_send_message_button.configure(cursor="hand2")
-
- main_window.main_send_message_button.grid_columnconfigure((0,2), weight=1)
- main_window.main_send_message_button.grid_rowconfigure((0,2), weight=1)
-
- main_window.main_send_message_button_image = CTkLabel(
- main_window.main_send_message_button,
- text=None,
- height=0,
- image=CTkImage((settings.image_file.SEND_MESSAGE_ICON),size=(settings.uism.SEND_MESSAGE_BUTTON_IMAGE_SIZE,settings.uism.SEND_MESSAGE_BUTTON_IMAGE_SIZE)),
- )
- main_window.main_send_message_button_image.grid(row=1, column=1)
-
-
-
- bindButtonFunctionAndColor(
- target_widgets=[main_window.main_send_message_button, main_window.main_send_message_button_image],
- enter_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_HOVERED_COLOR,
- leave_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_COLOR,
- clicked_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_CLICKED_COLOR,
- buttonReleasedFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_CLICKED_SEND_MESSAGE_BUTTON, _e),
- )
-
-
-
-
-
-
- main_window.main_send_message_button__disabled = CTkFrame(main_window.main_send_message_button_container, corner_radius=0, fg_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_COLOR, height=0, width=0)
- main_window.main_send_message_button__disabled.grid(row=0, column=0, sticky="nsew")
-
- main_window.main_send_message_button__disabled.grid_columnconfigure((0,2), weight=1)
- main_window.main_send_message_button__disabled.grid_rowconfigure((0,2), weight=1)
-
- main_window.main_send_message_button_image__disabled = CTkLabel(
- main_window.main_send_message_button__disabled,
- text=None,
- height=0,
- image=CTkImage((settings.image_file.SEND_MESSAGE_ICON_DISABLED),size=(settings.uism.SEND_MESSAGE_BUTTON_IMAGE_SIZE,settings.uism.SEND_MESSAGE_BUTTON_IMAGE_SIZE)),
- )
- main_window.main_send_message_button_image__disabled.grid(row=1, column=1)
-
- main_window.main_send_message_button__disabled.grid_remove()
\ No newline at end of file
diff --git a/vrct_gui/main_window/widgets/create_minimize_sidebar_button.py b/vrct_gui/main_window/widgets/create_minimize_sidebar_button.py
deleted file mode 100644
index 83585e98..00000000
--- a/vrct_gui/main_window/widgets/create_minimize_sidebar_button.py
+++ /dev/null
@@ -1,70 +0,0 @@
-
-from customtkinter import CTkFrame, CTkLabel, CTkImage
-
-from ...ui_utils import bindEnterAndLeaveColor, bindButtonPressColor, bindButtonReleaseFunction
-
-from utils import callFunctionIfCallable
-
-def createMinimizeSidebarButton(settings, main_window, view_variable):
-
- def enableCompactMode(e):
- callFunctionIfCallable(view_variable.CALLBACK_ENABLE_MAIN_WINDOW_SIDEBAR_COMPACT_MODE)
-
- def disableCompactMode(e):
- callFunctionIfCallable(view_variable.CALLBACK_DISABLE_MAIN_WINDOW_SIDEBAR_COMPACT_MODE)
-
-
-
- main_window.minimize_sidebar_button_container__for_closing = CTkFrame(main_window.main_topbar_container, corner_radius=0, fg_color=settings.ctm.MINIMIZE_SIDEBAR_BUTTON_BG_COLOR, cursor="hand2", width=0, height=0)
- main_window.minimize_sidebar_button_container__for_opening = CTkFrame(main_window.main_topbar_container, corner_radius=0, fg_color=settings.ctm.MINIMIZE_SIDEBAR_BUTTON_BG_COLOR, cursor="hand2", width=0, height=0)
-
-
-
-
- # For Closing [<]
- main_window.minimize_sidebar_button__for_closing = CTkLabel(
- main_window.minimize_sidebar_button_container__for_closing,
- text=None,
- corner_radius=0,
- height=0,
- image=CTkImage((settings.image_file.ARROW_LEFT),size=(settings.uism.MINIMIZE_SIDEBAR_BUTTON_ICON_SIZE_X,settings.uism.MINIMIZE_SIDEBAR_BUTTON_ICON_SIZE_Y))
- )
-
- main_window.minimize_sidebar_button_container__for_closing.grid_rowconfigure((0,2), weight=1)
- main_window.minimize_sidebar_button__for_closing.grid(row=1, column=0, padx=0, pady=0)
-
-
- bindEnterAndLeaveColor([main_window.minimize_sidebar_button__for_closing, main_window.minimize_sidebar_button_container__for_closing], settings.ctm.MINIMIZE_SIDEBAR_BUTTON_HOVERED_BG_COLOR, settings.ctm.MINIMIZE_SIDEBAR_BUTTON_BG_COLOR)
- bindButtonPressColor([main_window.minimize_sidebar_button__for_closing, main_window.minimize_sidebar_button_container__for_closing], settings.ctm.MINIMIZE_SIDEBAR_BUTTON_CLICKED_BG_COLOR, settings.ctm.MINIMIZE_SIDEBAR_BUTTON_BG_COLOR)
- bindButtonReleaseFunction([main_window.minimize_sidebar_button_container__for_closing, main_window.minimize_sidebar_button__for_closing], enableCompactMode)
-
-
-
-
-# For Opening [>]
- main_window.minimize_sidebar_button__for_opening = CTkLabel(
- main_window.minimize_sidebar_button_container__for_opening,
- text=None,
- corner_radius=0,
- height=0,
- image=CTkImage((settings.image_file.ARROW_LEFT).rotate(180),size=(settings.uism.MINIMIZE_SIDEBAR_BUTTON_ICON_SIZE_X,settings.uism.MINIMIZE_SIDEBAR_BUTTON_ICON_SIZE_Y))
- )
-
-
-
-
- main_window.minimize_sidebar_button_container__for_opening.grid_rowconfigure((0,2), weight=1)
- main_window.minimize_sidebar_button__for_opening.grid(row=1, column=0, padx=0, pady=0)
-
-
- bindEnterAndLeaveColor([main_window.minimize_sidebar_button__for_opening, main_window.minimize_sidebar_button_container__for_opening], settings.ctm.MINIMIZE_SIDEBAR_BUTTON_HOVERED_BG_COLOR, settings.ctm.MINIMIZE_SIDEBAR_BUTTON_BG_COLOR)
- bindButtonPressColor([main_window.minimize_sidebar_button__for_opening, main_window.minimize_sidebar_button_container__for_opening], settings.ctm.MINIMIZE_SIDEBAR_BUTTON_CLICKED_BG_COLOR, settings.ctm.MINIMIZE_SIDEBAR_BUTTON_BG_COLOR)
- bindButtonReleaseFunction([main_window.minimize_sidebar_button_container__for_opening, main_window.minimize_sidebar_button__for_opening], disableCompactMode)
-
-
-
-
-
- main_window.minimize_sidebar_button_container__for_opening.grid(row=0, column=0, sticky="nsw")
- main_window.minimize_sidebar_button_container__for_closing.grid(row=0, column=0, sticky="nsw")
- main_window.minimize_sidebar_button_container__for_opening.grid_remove()
\ No newline at end of file
diff --git a/vrct_gui/main_window/widgets/create_sidebar.py b/vrct_gui/main_window/widgets/create_sidebar.py
deleted file mode 100644
index 9f30d269..00000000
--- a/vrct_gui/main_window/widgets/create_sidebar.py
+++ /dev/null
@@ -1,64 +0,0 @@
-from customtkinter import CTkFrame, CTkLabel, CTkImage
-
-from ...ui_utils import bindButtonFunctionAndColor
-from utils import callFunctionIfCallable
-
-from ._create_sidebar import createSidebarFeatures, createSidebarLanguagesSettings
-
-def createSidebar(settings, main_window, view_variable):
- # Side Bar Container
- main_window.toplevel_wrapper.grid_rowconfigure(0, weight=1)
-
- main_window.sidebar_bg_container_wrapper = CTkFrame(main_window.toplevel_wrapper, corner_radius=0, fg_color=settings.ctm.SIDEBAR_BG_COLOR, width=0, height=0)
- main_window.sidebar_bg_container_wrapper.grid(row=0, column=0, sticky="nsew")
-
-
- main_window.sidebar_bg_container = CTkFrame(main_window.sidebar_bg_container_wrapper, corner_radius=0, fg_color=settings.ctm.SIDEBAR_BG_COLOR, width=0, height=0)
- main_window.sidebar_compact_mode_bg_container = CTkFrame(main_window.sidebar_bg_container_wrapper, corner_radius=0, fg_color=settings.ctm.SIDEBAR_BG_COLOR, width=0, height=0)
-
-
- main_window.sidebar_bg_container.grid_columnconfigure(0, weight=1, minsize=settings.uism.SIDEBAR_MIN_WIDTH)
- main_window.sidebar_compact_mode_bg_container.grid_columnconfigure(0, weight=1)
-
-
- createSidebarFeatures(settings, main_window, view_variable)
- createSidebarLanguagesSettings(settings, main_window, view_variable)
-
-
- main_window.sidebar_bg_container.grid(row=0, column=0, sticky="nsew")
- main_window.sidebar_compact_mode_bg_container.grid(row=0, column=0, sticky="nsew")
- main_window.sidebar_compact_mode_bg_container.grid_remove()
-
-
- # Config Button
- main_window.sidebar_bg_container_wrapper.grid_rowconfigure(3, weight=1)
-
- main_window.sidebar_config_button_container = CTkFrame(main_window.sidebar_bg_container_wrapper, corner_radius=0, fg_color=settings.ctm.CONFIG_BUTTON_BG_COLOR, width=0, height=0)
- main_window.sidebar_config_button_container.grid(row=4, column=0, sticky="sew")
-
-
- main_window.sidebar_config_button_container.grid_columnconfigure(0, weight=1)
- main_window.sidebar_config_button_wrapper = CTkFrame(main_window.sidebar_config_button_container, corner_radius=settings.uism.SIDEBAR_CONFIG_BUTTON_CORNER_RADIUS, fg_color=settings.ctm.CONFIG_BUTTON_BG_COLOR, height=0, width=0, cursor="hand2")
- main_window.sidebar_config_button_wrapper.grid(row=0, column=0, padx=settings.uism.SIDEBAR_CONFIG_BUTTON_PADX, pady=settings.uism.SIDEBAR_CONFIG_BUTTON_PADY, sticky="ew")
-
-
-
-
- main_window.sidebar_config_button_wrapper.grid_columnconfigure(0, weight=1)
-
- main_window.sidebar_config_button = CTkLabel(
- main_window.sidebar_config_button_wrapper,
- text=None,
- height=0,
- image=CTkImage(settings.image_file.CONFIGURATION_ICON, size=settings.uism.SIDEBAR_CONFIG_BUTTON_IMAGE_SIZE)
- )
- main_window.sidebar_config_button.grid(row=0, column=0, padx=0, pady=settings.uism.SIDEBAR_CONFIG_BUTTON_IPADY)
-
-
- bindButtonFunctionAndColor(
- target_widgets=[main_window.sidebar_config_button_wrapper, main_window.sidebar_config_button],
- enter_color=settings.ctm.CONFIG_BUTTON_HOVERED_BG_COLOR,
- leave_color=settings.ctm.CONFIG_BUTTON_BG_COLOR,
- clicked_color=settings.ctm.CONFIG_BUTTON_CLICKED_BG_COLOR,
- buttonReleasedFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_CLICKED_OPEN_CONFIG_WINDOW_BUTTON),
- )
\ No newline at end of file
diff --git a/vrct_gui/main_window/widgets/create_textbox.py b/vrct_gui/main_window/widgets/create_textbox.py
deleted file mode 100644
index ba048f26..00000000
--- a/vrct_gui/main_window/widgets/create_textbox.py
+++ /dev/null
@@ -1,164 +0,0 @@
-from customtkinter import CTkFont, CTkFrame, CTkLabel, CTkTextbox
-
-from ...ui_utils import bindEnterAndLeaveColor, bindButtonPressColor, bindButtonReleaseFunction, setDefaultActiveTab, switchActiveTabAndPassiveTab, switchTabsColor
-
-
-def createTextbox(settings, main_window, view_variable):
-
- # def switchTextbox(target_textbox_attr_name):
- # main_window.current_active_textbox.grid_remove()
- # main_window.current_active_textbox = getattr(main_window, target_textbox_attr_name)
- # main_window.current_active_textbox.grid()
-
- # def switchToTextboxAll(e):
- # target_active_widget = getattr(main_window, "textbox_tab_all")
- # switchTextboxTabFunction(target_active_widget)
- # switchTextbox("textbox_all")
-
- # def switchToTextboxSent(e):
- # target_active_widget = getattr(main_window, "textbox_tab_sent")
- # switchTextboxTabFunction(target_active_widget)
- # switchTextbox("textbox_sent")
-
- # def switchToTextboxReceived(e):
- # target_active_widget = getattr(main_window, "textbox_tab_received")
- # switchTextboxTabFunction(target_active_widget)
- # switchTextbox("textbox_received")
-
- # def switchToTextboxSystem(e):
- # target_active_widget = getattr(main_window, "textbox_tab_system")
- # switchTextboxTabFunction(target_active_widget)
- # switchTextbox("textbox_system")
-
-
- # def switchTextboxTabFunction(target_active_widget):
- # switchActiveAndPassiveTextboxTabsColor(target_active_widget)
- # switchActiveTabAndPassiveTab(target_active_widget, main_window.current_active_textbox_tab, main_window.current_active_textbox_tab.passive_function, settings.ctm.TEXTBOX_TAB_BG_HOVERED_COLOR, settings.ctm.TEXTBOX_TAB_BG_CLICKED_COLOR, settings.ctm.TEXTBOX_TAB_BG_PASSIVE_COLOR)
- # main_window.current_active_textbox_tab = target_active_widget
-
- # def switchActiveAndPassiveTextboxTabsColor(target_active_widget):
- # textbox_tabs = [
- # getattr(main_window, "textbox_tab_all"),
- # getattr(main_window, "textbox_tab_sent"),
- # getattr(main_window, "textbox_tab_received"),
- # getattr(main_window, "textbox_tab_system")
- # ]
-
- # switchTabsColor(
- # target_widget=target_active_widget,
- # tab_buttons=textbox_tabs,
- # active_bg_color=settings.ctm.TEXTBOX_BG_COLOR,
- # active_text_color=settings.ctm.SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR,
- # passive_bg_color=settings.ctm.TEXTBOX_TAB_BG_PASSIVE_COLOR,
- # passive_text_color=settings.ctm.TEXTBOX_TAB_TEXT_PASSIVE_COLOR
- # )
-
-
-
-
- # Text box
- main_window.main_bg_container.grid_rowconfigure(1, weight=1)
- main_window.main_textbox_container = CTkFrame(main_window.main_bg_container, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- main_window.main_textbox_container.grid(row=1, column=0, columnspan=2, sticky="nsew")
-
- main_window.main_textbox_container.grid_columnconfigure(0,weight=1)
- main_window.main_textbox_container.grid_rowconfigure(0,weight=1)
-
- # main_window.textbox_switch_tabs_container = CTkFrame(main_window.main_topbar_center_container, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
- # main_window.textbox_switch_tabs_container.place(relx=0.07, rely=1.15, anchor="sw")
-
- # main_window.textbox_switch_tabs_container.grid_columnconfigure((0,1,2,3), weight=1, uniform="textbox_tabs")
-
- # textbox_settings = [
- # {
- # "textbox_tab_attr_name": "textbox_tab_all",
- # "command": switchToTextboxAll,
- # "textbox_attr_name": "textbox_all",
- # "textvariable": view_variable.VAR_LABEL_TEXTBOX_ALL
- # },
- # {
- # "textbox_tab_attr_name": "textbox_tab_sent",
- # "command": switchToTextboxSent,
- # "textbox_attr_name": "textbox_sent",
- # "textvariable": view_variable.VAR_LABEL_TEXTBOX_SENT
- # },
- # {
- # "textbox_tab_attr_name": "textbox_tab_received",
- # "command": switchToTextboxReceived,
- # "textbox_attr_name": "textbox_received",
- # "textvariable": view_variable.VAR_LABEL_TEXTBOX_RECEIVED
- # },
- # {
- # "textbox_tab_attr_name": "textbox_tab_system",
- # "command": switchToTextboxSystem,
- # "textbox_attr_name": "textbox_system",
- # "textvariable": view_variable.VAR_LABEL_TEXTBOX_SYSTEM
- # },
- # ]
-
-
- # column=0
- # for textbox_setting in textbox_settings:
- # setattr(main_window, textbox_setting["textbox_tab_attr_name"],
- # CTkFrame(
- # main_window.textbox_switch_tabs_container,
- # corner_radius=settings.uism.TEXTBOX_TAB_CORNER_RADIUS,
- # fg_color=settings.ctm.TEXTBOX_TAB_BG_PASSIVE_COLOR,
- # cursor="hand2",
- # width=0,
- # height=0
- # )
- # )
- # target_widget = getattr(main_window, textbox_setting["textbox_tab_attr_name"])
- # target_widget.grid(row=0, column=column, pady=0, padx=(0,2), sticky="ew")
-
-
-
- # target_widget.grid_columnconfigure((0,2), weight=1)
- # setattr(main_window, "label_widget", CTkLabel(
- # target_widget,
- # textvariable=textbox_setting["textvariable"],
- # corner_radius=0,
- # font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.TEXTBOX_TAB_FONT_SIZE, weight="normal"),
- # height=0,
- # width=0,
- # anchor="center",
- # text_color=settings.ctm.TEXTBOX_TAB_TEXT_PASSIVE_COLOR,
- # ))
- # label_widget = getattr(main_window, "label_widget")
- # label_widget.grid(row=0, column=1, pady=settings.uism.TEXTBOX_TAB_PADY, padx=settings.uism.TEXTBOX_TAB_PADX)
-
- # bindEnterAndLeaveColor([target_widget, label_widget], settings.ctm.TEXTBOX_TAB_BG_HOVERED_COLOR, settings.ctm.TEXTBOX_TAB_BG_PASSIVE_COLOR)
- # bindButtonPressColor([target_widget, label_widget], settings.ctm.TEXTBOX_TAB_BG_CLICKED_COLOR, settings.ctm.TEXTBOX_TAB_BG_PASSIVE_COLOR)
-
- # target_widget.passive_function = textbox_setting["command"]
- # bindButtonReleaseFunction([target_widget, label_widget], textbox_setting["command"])
-
-
-
- main_window.textbox_all = CTkTextbox(
- main_window.main_textbox_container,
- corner_radius=settings.uism.TEXTBOX_CORNER_RADIUS,
- fg_color=settings.ctm.TEXTBOX_BG_COLOR,
- text_color="lime", # Textbox's text_color is set when printing. so this is for prevent from non-setting text_color like the gloves used in food factories are blue.
- wrap="word",
- height=0,
- )
- # main_window.textbox_all = getattr(main_window, textbox_setting["textbox_attr_name"])
- main_window.textbox_all.grid(row=0, column=0, padx=settings.uism.TEXTBOX_PADX, pady=0, sticky="nsew")
- main_window.textbox_all.grid_remove()
- main_window.textbox_all.configure(state="disabled")
-
- # column+=1
-
- # Set default active textbox tab
- # main_window.current_active_textbox_tab = getattr(main_window, "textbox_tab_all")
- # setDefaultActiveTab(
- # active_tab_widget=main_window.current_active_textbox_tab,
- # active_bg_color=settings.ctm.TEXTBOX_TAB_BG_ACTIVE_COLOR,
- # active_text_color=settings.ctm.TEXTBOX_TAB_TEXT_ACTIVE_COLOR
- # )
-
- # main_window.current_active_textbox = getattr(main_window, "textbox_all")
- # main_window.current_active_textbox.grid()
- main_window.textbox_all.grid()
diff --git a/vrct_gui/quick_settings_window/QuickSettingsWindow.py b/vrct_gui/quick_settings_window/QuickSettingsWindow.py
deleted file mode 100644
index 993243a9..00000000
--- a/vrct_gui/quick_settings_window/QuickSettingsWindow.py
+++ /dev/null
@@ -1,364 +0,0 @@
-from utils import callFunctionIfCallable, floatToPctStr
-
-from customtkinter import CTkToplevel, CTkFrame
-from ..ui_utils import getImagePath, setGeometryToCenterOfScreen, fadeInAnimation, createLabelButton
-
-from ._CreateQuickSettingBox import _CreateQuickSettingBox
-
-class QuickSettingsWindow(CTkToplevel):
- def __init__(self, vrct_gui, settings, view_variable):
- super().__init__()
- self.withdraw()
- self.title("Overlay Settings")
- self.protocol("WM_DELETE_WINDOW", self.withdraw)
- self.after(200, lambda: self.iconbitmap(getImagePath("vrct_logo_mark_black.ico")))
-
-
- self.settings = settings
-
- self.configure(fg_color=self.settings.ctm.SB__BG_COLOR)
-
- BG_HEX_COLOR = "#292a2d"
- self.grid_columnconfigure(0, weight=1)
-
- self.qsw_background = CTkFrame(self, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR)
- self.qsw_background.grid(row=0, column=0, pady=0, sticky="ew")
- self.qsw_background.grid_columnconfigure(0, weight=1, minsize=self.settings.uism.QSB__MIN_WIDTH)
-
-
- self.qsw_background__overlay = CTkFrame(self.qsw_background, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR)
- self.qsw_background__overlay.grid(row=0, column=0, pady=self.settings.uism.QSB__BOX_PADY, sticky="ew")
- self.qsw_background__overlay.grid_columnconfigure(0, weight=1)
-
-
- self.qsw_setting_box__overlay = CTkFrame(self.qsw_background__overlay, corner_radius=0, fg_color=BG_HEX_COLOR)
- self.qsw_setting_box__overlay.grid(row=0, column=0, sticky="ew")
- self.qsw_setting_box__overlay.grid_columnconfigure(0, weight=1)
-
- cqsb = _CreateQuickSettingBox(self.qsw_setting_box__overlay, vrct_gui, settings, view_variable)
- createSettingBoxSlider = cqsb.createSettingBoxSlider
- createSettingBoxSwitch = cqsb.createSettingBoxSwitch
-
-
-
-
-
- # Overlay General Settings
- row=0
- def overlaySmallLogSwitchCallback(switch_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_OVERLAY_SMALL_LOG, switch_widget.get())
-
- self.qsb__enable_overlay_small_log = createSettingBoxSwitch(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_OVERLAY_SMALL_LOG,
- switch_attr_name="qsb__enable_overlay_small_log_switch",
- command=lambda: overlaySmallLogSwitchCallback(vrct_gui.qsb__enable_overlay_small_log_switch),
- variable=view_variable.VAR_ENABLE_OVERLAY_SMALL_LOG,
- )
- self.qsb__enable_overlay_small_log.grid(row=row)
-
-
- row+=1
- def overlayOpacitySliderCallback(e):
- value = round(e,2)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SETTINGS, value, "opacity")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_OPACITY.set(floatToPctStr(value))
-
- self.qsb__overlay_opacity = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_OPACITY,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_OPACITY,
- slider_attr_name="qsb__overlay_opacity_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_OPACITY,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_OPACITY,
- command=overlayOpacitySliderCallback,
- variable=view_variable.VAR_OVERLAY_OPACITY,
- )
- self.qsb__overlay_opacity.grid(row=row)
-
-
- row+=1
- def overlayUiScalingSliderCallback(e):
- value = round(e,2)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SETTINGS, value, "ui_scaling")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_UI_SCALING.set(floatToPctStr(value))
-
- self.qsb__overlay_ui_scaling = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_UI_SCALING,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_UI_SCALING,
- slider_attr_name="qsb__overlay_ui_scaling_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_UI_SCALING,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_UI_SCALING,
- command=overlayUiScalingSliderCallback,
- variable=view_variable.VAR_OVERLAY_UI_SCALING,
- )
- self.qsb__overlay_ui_scaling.grid(row=row)
-
-
-
- # Overlay Small Log Settings
-
- # row+=1
- # def switchCallback(switch_widget):
- # callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_OVERLAY_SMALL_LOG, switch_widget.get())
-
- # self.qsb__enable_overlay_small_log = createSettingBoxSwitch(
- # for_var_label_text=view_variable.VAR_LABEL_ENABLE_OVERLAY_SMALL_LOG,
- # switch_attr_name="qsb__enable_overlay_small_log_switch",
- # command=lambda: switchCallback(vrct_gui.qsb__enable_overlay_small_log_switch),
- # variable=view_variable.VAR_ENABLE_OVERLAY_SMALL_LOG,
- # )
- # self.qsb__enable_overlay_small_log.grid(row=row)
-
-
-
- row+=1
- def overlaySmallLogSettingsXPosSliderCallback(e):
- value = round(e,2)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "x_pos")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_POS.set(str(value))
-
- self.qsb__overlay_small_log_settings_x_pos = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_X_POS,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_POS,
- slider_attr_name="qsb__overlay_small_log_settings_x_pos_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_X_POS,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_X_POS,
- command=overlaySmallLogSettingsXPosSliderCallback,
- variable=view_variable.VAR_OVERLAY_SMALL_LOG_X_POS,
- )
- self.qsb__overlay_small_log_settings_x_pos.grid(row=row)
-
-
- row+=1
- def overlaySmallLogSettingsYPosSliderCallback(e):
- value = round(e,2)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "y_pos")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_POS.set(str(value))
-
- self.qsb__overlay_small_log_settings_y_pos = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_Y_POS,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_POS,
- slider_attr_name="qsb__overlay_small_log_settings_y_pos_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_Y_POS,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Y_POS,
- command=overlaySmallLogSettingsYPosSliderCallback,
- variable=view_variable.VAR_OVERLAY_SMALL_LOG_Y_POS,
- )
- self.qsb__overlay_small_log_settings_y_pos.grid(row=row)
-
-
- row+=1
- def overlaySmallLogSettingsZPosSliderCallback(e):
- value = round(e,2)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "z_pos")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Z_POS.set(str(value))
-
- self.qsb__overlay_small_log_settings_z_pos = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_Z_POS,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Z_POS,
- slider_attr_name="qsb__overlay_small_log_settings_z_pos_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_Z_POS,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Z_POS,
- command=overlaySmallLogSettingsZPosSliderCallback,
- variable=view_variable.VAR_OVERLAY_SMALL_LOG_Z_POS,
- )
- self.qsb__overlay_small_log_settings_z_pos.grid(row=row)
-
-
-
- row+=1
- def overlaySmallLogSettingsXRotationSliderCallback(e):
- value = round(e,2)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "x_rotation")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_ROTATION.set(str(value))
-
- self.qsb__overlay_small_log_settings_x_rotation = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_X_ROTATION,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_ROTATION,
- slider_attr_name="qsb__overlay_small_log_settings_x_rotation_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_X_ROTATION,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_X_ROTATION,
- command=overlaySmallLogSettingsXRotationSliderCallback,
- variable=view_variable.VAR_OVERLAY_SMALL_LOG_X_ROTATION,
- )
- self.qsb__overlay_small_log_settings_x_rotation.grid(row=row)
-
-
-
- row+=1
- def overlaySmallLogSettingsYRotationSliderCallback(e):
- value = round(e,2)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "y_rotation")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_ROTATION.set(str(value))
-
- self.qsb__overlay_small_log_settings_y_rotation = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_Y_ROTATION,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_ROTATION,
- slider_attr_name="qsb__overlay_small_log_settings_y_rotation_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_Y_ROTATION,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Y_ROTATION,
- command=overlaySmallLogSettingsYRotationSliderCallback,
- variable=view_variable.VAR_OVERLAY_SMALL_LOG_Y_ROTATION,
- )
- self.qsb__overlay_small_log_settings_y_rotation.grid(row=row)
-
-
-
- row+=1
- def overlaySmallLogSettingsZRotationSliderCallback(e):
- value = round(e,2)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "z_rotation")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Z_ROTATION.set(str(value))
-
- self.qsb__overlay_small_log_settings_z_rotation = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_Z_ROTATION,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Z_ROTATION,
- slider_attr_name="qsb__overlay_small_log_settings_z_rotation_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_Z_ROTATION,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Z_ROTATION,
- command=overlaySmallLogSettingsZRotationSliderCallback,
- variable=view_variable.VAR_OVERLAY_SMALL_LOG_Z_ROTATION,
- )
- self.qsb__overlay_small_log_settings_z_rotation.grid(row=row)
-
-
-
- row+=1
- def overlaySmallLogSettingsDisplayDurationSliderCallback(e):
- value = int(e)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "display_duration")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DISPLAY_DURATION.set(f"{value} second(s)")
-
- self.qsb__overlay_small_log_settings_display_duration = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_DISPLAY_DURATION,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DISPLAY_DURATION,
- slider_attr_name="qsb__overlay_small_log_settings_display_duration_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_DISPLAY_DURATION,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_DISPLAY_DURATION,
- command=overlaySmallLogSettingsDisplayDurationSliderCallback,
- variable=view_variable.VAR_OVERLAY_SMALL_LOG_DISPLAY_DURATION,
- )
- self.qsb__overlay_small_log_settings_display_duration.grid(row=row)
-
-
-
- row+=1
- def overlaySmallLogSettingsFadeoutDurationSliderCallback(e):
- value = int(e)
- callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "fadeout_duration")
- view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_FADEOUT_DURATION.set(f"{value} second(s)")
-
- self.qsb__overlay_small_log_settings_fadeout_duration = createSettingBoxSlider(
- for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_FADEOUT_DURATION,
- for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_FADEOUT_DURATION,
- slider_attr_name="qsb__overlay_small_log_settings_fadeout_duration_slider",
- slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_FADEOUT_DURATION,
- slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_FADEOUT_DURATION,
- command=overlaySmallLogSettingsFadeoutDurationSliderCallback,
- variable=view_variable.VAR_OVERLAY_SMALL_LOG_FADEOUT_DURATION,
- )
- self.qsb__overlay_small_log_settings_fadeout_duration.grid(row=row)
-
-
-
-
-
-
-
-
-
- self.qsw_setting_box_bottom = CTkFrame(self.qsw_background__overlay, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR)
- self.qsw_setting_box_bottom.grid(row=1, column=0, sticky="nsew")
-
- self.qsw_setting_box_bottom.grid_columnconfigure((0,2), weight=1)
- self.qsw_setting_box_bottom.grid_rowconfigure((0,2), weight=1)
-
- self.qsw_setting_box_bottom_restore_default_button = CTkFrame(self.qsw_setting_box_bottom, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR)
- self.qsw_setting_box_bottom_restore_default_button.grid(row=1, column=1, sticky="nsew")
-
-
- def toDefaultOverlaySettingsCallback(_e):
- callFunctionIfCallable(view_variable.CALLBACK_SET_TO_DEFAULT_OVERLAY_SETTINGS)
-
-
-
- (restore_default_settings_button, label_button_label_widget) = createLabelButton(
- parent_widget=self.qsw_setting_box_bottom_restore_default_button,
- label_button_bg_color=self.settings.ctm.SB__BUTTON_COLOR,
- label_button_hovered_bg_color=self.settings.ctm.SB__BUTTON_HOVERED_COLOR,
- label_button_clicked_bg_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
- label_button_ipadx=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_IPADX,
- label_button_ipady=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_IPADY,
- variable=view_variable.VAR_TO_DEFAULT_OVERLAY_SETTINGS,
- font_family=self.settings.FONT_FAMILY,
- font_size=self.settings.uism.SB__AUTHKEY_WEBPAGE_BUTTON_LABEL_FONT_SIZE,
- text_color=self.settings.ctm.LABELS_TEXT_COLOR,
- label_button_clicked_command=toDefaultOverlaySettingsCallback,
-
- label_button_position="center",
- )
- restore_default_settings_button.grid(row=0, column=0, pady=self.settings.uism.QSB__RESTORE_DEFAULT_SETTINGS_BUTTON_PADY)
-
- self.qsw_background__overlay.grid_remove()
-
-
-
-
-
-
- # VRChat mic mute sync
- self.qsw_background__vrc_mic_mute_sync = CTkFrame(self.qsw_background, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR)
- self.qsw_background__vrc_mic_mute_sync.grid(row=0, column=0, pady=self.settings.uism.QSB__BOX_PADY, sticky="ew")
- self.qsw_background__vrc_mic_mute_sync.grid_columnconfigure(0, weight=1)
-
-
- self.qsw_setting_box__vrc_mic_mute_sync = CTkFrame(self.qsw_background__vrc_mic_mute_sync, corner_radius=0, fg_color=BG_HEX_COLOR)
- self.qsw_setting_box__vrc_mic_mute_sync.grid(row=0, column=0, sticky="ew")
- self.qsw_setting_box__vrc_mic_mute_sync.grid_columnconfigure(0, weight=1)
-
-
-
-
-
-
- cqsb = _CreateQuickSettingBox(self.qsw_setting_box__vrc_mic_mute_sync, vrct_gui, settings, view_variable)
- createSettingBoxSlider = cqsb.createSettingBoxSlider
- createSettingBoxSwitch = cqsb.createSettingBoxSwitch
-
-
- row=0
- def enableVrcMicMuteSyncSwitchCallback(switch_widget):
- callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_VRC_MIC_MUTE_SYNC, switch_widget.get())
-
- self.qsb__enable_vrc_mic_mute_sync = createSettingBoxSwitch(
- for_var_label_text=view_variable.VAR_LABEL_ENABLE_VRC_MIC_MUTE_SYNC,
- switch_attr_name="qsb__enable_vrc_mic_mute_sync_switch",
- command=lambda: enableVrcMicMuteSyncSwitchCallback(vrct_gui.qsb__enable_vrc_mic_mute_sync_switch),
- variable=view_variable.VAR_ENABLE_VRC_MIC_MUTE_SYNC,
- )
- self.qsb__enable_vrc_mic_mute_sync.grid(row=row)
-
-
- self.qsw_background__vrc_mic_mute_sync.grid_remove()
-
-
-
-
-
-
-
- def show(self, target:str):
- if target == "overlay":
- self.qsw_background__vrc_mic_mute_sync.grid_remove()
- self.qsw_background__overlay.grid()
- elif target == "vrc_mic_mute_sync":
- self.qsw_background__overlay.grid_remove()
- self.qsw_background__vrc_mic_mute_sync.grid()
-
- self.attributes("-alpha", 0)
- self.deiconify()
-
- self.qsw_background.update()
- self.geometry("{}x{}".format(self.qsw_background.winfo_width(), self.qsw_background.winfo_height()))
-
- setGeometryToCenterOfScreen(root_widget=self)
- fadeInAnimation(self, steps=5, interval=0.02)
\ No newline at end of file
diff --git a/vrct_gui/quick_settings_window/_CreateQuickSettingBox.py b/vrct_gui/quick_settings_window/_CreateQuickSettingBox.py
deleted file mode 100644
index 3bb10ebc..00000000
--- a/vrct_gui/quick_settings_window/_CreateQuickSettingBox.py
+++ /dev/null
@@ -1,160 +0,0 @@
-from typing import Union
-from customtkinter import CTkLabel, CTkFrame, CTkSlider, CTkFont, CTkSwitch
-
-class _CreateQuickSettingBox():
- def __init__(self, parent_frame, vrct_gui, settings, view_variable):
- self.view_variable = view_variable
- self.vrct_gui = vrct_gui
- self.settings = settings
- self.parent_frame = parent_frame
-
-
- def _createSettingBoxFrame(self, for_var_label_text=None, for_var_current_value=None):
- setting_box_frame = CTkFrame(self.parent_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
-
- setting_box_frame.grid(row=0, column=0, pady=(0,1), sticky="ew")
- setting_box_frame.grid_columnconfigure(0, weight=1)
-
-
- setting_box_frame_wrapper = CTkFrame(setting_box_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- setting_box_frame_wrapper.grid(row=0, column=0, padx=self.settings.uism.QSB__IPADX, pady=self.settings.uism.QSB__IPADY, sticky="nsew")
- setting_box_frame_wrapper.grid_columnconfigure(0, weight=1)
-
-
- # Labels
- setting_box_labels_frame = CTkFrame(setting_box_frame_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
- setting_box_labels_frame.grid(row=0, column=0, padx=0, pady=(0,self.settings.uism.QSB__LABEL_BOTTOM_PADY), sticky="nsew")
-
- setting_box_labels_frame.grid_rowconfigure((0,2), weight=1)
- setting_box_labels_frame.grid_columnconfigure(1, weight=1)
- setting_box_label = CTkLabel(
- setting_box_labels_frame,
- textvariable=for_var_label_text,
- anchor="w",
- height=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__LABEL_FONT_SIZE, weight="normal"),
- text_color=self.settings.ctm.LABELS_TEXT_COLOR
- )
- setting_box_label.grid(row=1, column=0, padx=0, pady=0, sticky="nse")
-
-
- if for_var_current_value is not None:
- setting_box_label = CTkLabel(
- setting_box_labels_frame,
- textvariable=for_var_current_value,
- anchor="w",
- height=0,
- font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__LABEL_FONT_SIZE, weight="normal"),
- text_color=self.settings.ctm.LABELS_TEXT_COLOR
- )
- setting_box_label.grid(row=1, column=2, padx=0, pady=0, sticky="nsw")
-
-
-
-
- # Items
- setting_box_item_frame = CTkFrame(setting_box_frame_wrapper, corner_radius=0, width=0, height=0, fg_color=self.settings.ctm.SB__BG_COLOR)
- setting_box_item_frame.grid(row=1, column=0, padx=0, sticky="nsew")
-
- setting_box_item_frame.grid_rowconfigure((0,2), weight=1)
- setting_box_item_frame.grid_columnconfigure(1, weight=1)
-
- return (setting_box_frame, setting_box_item_frame)
-
-
-
-
-
-
- def createSettingBoxSlider(
- self,
- for_var_label_text,
- for_var_current_value,
- slider_attr_name,
- slider_range,
- command,
- variable,
- slider_number_of_steps: Union[int,
- None] = None,
- slider_bind__ButtonPress=None,
- slider_bind__ButtonRelease=None,
- sliderTooltipFormatter=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(for_var_label_text, for_var_current_value)
-
-
-
- slider_widget = CTkSlider(
- setting_box_item_frame,
- width=self.settings.uism.SB__SLIDER_WIDTH,
- height=self.settings.uism.SB__SLIDER_HEIGHT,
- from_=slider_range[0],
- to=slider_range[1],
- number_of_steps=slider_number_of_steps,
- fg_color=self.settings.ctm.SB__SLIDER_BG_COLOR,
- progress_color=self.settings.ctm.SB__SLIDER_PROGRESS_BG_COLOR,
- button_color=self.settings.ctm.SB__SLIDER_BUTTON_COLOR,
- button_hover_color=self.settings.ctm.SB__SLIDER_BUTTON_HOVERED_COLOR,
- command=command,
- variable=variable,
- )
- setattr(self.vrct_gui, slider_attr_name, slider_widget)
-
-
- slider_widget.grid(row=1, column=1, sticky="ew")
-
- if slider_bind__ButtonPress is not None:
- def adjusted_slider_bind__ButtonPress(e):
- command(e)
- slider_bind__ButtonPress()
- slider_widget.configure(command=adjusted_slider_bind__ButtonPress)
-
- if slider_bind__ButtonRelease is not None:
- def adjusted_slider_bind__ButtonRelease(_e):
- slider_bind__ButtonRelease()
- slider_widget.bind("", adjusted_slider_bind__ButtonRelease, "+")
-
- return setting_box_frame
-
-
-
-
-
-
-
- def createSettingBoxSwitch(
- self,
- for_var_label_text,
- switch_attr_name,
- variable,
- command,
- for_var_current_value=None,
- ):
-
- (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(for_var_label_text, for_var_current_value)
-
- switch_widget = CTkSwitch(
- setting_box_item_frame,
- text=None,
- height=0,
- width=0,
- corner_radius=int(self.settings.uism.SB__SWITCH_BOX_HEIGHT/2),
- border_width=0,
- switch_height=self.settings.uism.SB__SWITCH_BOX_HEIGHT,
- switch_width=self.settings.uism.SB__SWITCH_BOX_WIDTH,
- onvalue=True,
- offvalue=False,
- variable=variable,
- command=command,
- fg_color=self.settings.ctm.SB__SWITCH_BOX_BG_COLOR,
- progress_color=self.settings.ctm.SB__SWITCH_BOX_ACTIVE_BG_COLOR,
- button_color=self.settings.ctm.SB__SWITCH_BOX_BUTTON_COLOR,
- button_hover_color=self.settings.ctm.SB__SWITCH_BOX_BUTTON_HOVERED_COLOR,
- )
- setattr(self.vrct_gui, switch_attr_name, switch_widget)
-
-
- switch_widget.grid(row=1, column=1, sticky="w")
-
- return setting_box_frame
\ No newline at end of file
diff --git a/vrct_gui/quick_settings_window/__init__.py b/vrct_gui/quick_settings_window/__init__.py
deleted file mode 100644
index 4ee26014..00000000
--- a/vrct_gui/quick_settings_window/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .QuickSettingsWindow import *
\ No newline at end of file
diff --git a/vrct_gui/splash_window/SplashWindow.py b/vrct_gui/splash_window/SplashWindow.py
deleted file mode 100644
index 9d313931..00000000
--- a/vrct_gui/splash_window/SplashWindow.py
+++ /dev/null
@@ -1,235 +0,0 @@
-import math
-import time
-
-from customtkinter import CTkImage, CTkLabel, CTkToplevel, CTkProgressBar, CTkFrame
-from ..ui_utils import openImageKeepAspectRatio, getImageFileFromUiUtils, getImagePath, setGeometryToCenterOfScreen, fadeInAnimation, generateGradientColor
-
-class SplashWindow(CTkToplevel):
- def __init__(self):
- super().__init__()
- self.withdraw()
- self.overrideredirect(True)
- self.configure(fg_color="#292a2d")
- self.title("Starting Up...")
- self.after(200, lambda: self.iconbitmap(getImagePath("vrct_logo_mark_black.ico")))
- # self.wm_attributes("-toolwindow", True)
-
- self.is_showed_weight_download_progressbar = False
-
- BG_HEIGHT= 220
- BG_WIDTH= 450
- BG_HEX_COLOR = "#292a2d"
-
- self.grid_columnconfigure(0, weight=1)
- self.grid_rowconfigure(0, weight=1)
- self.splash_background = CTkFrame(self, corner_radius=0, fg_color=BG_HEX_COLOR, width=BG_WIDTH, height=BG_HEIGHT)
- self.splash_background.grid()
-
-
- self.progressbar_wrapper = CTkFrame(self, corner_radius=0, fg_color=BG_HEX_COLOR, width=0, height=0)
- self.progressbar_wrapper.place(relx=0.5, rely=0.5, anchor="center")
- self.progressbar_wrapper.rowconfigure(0, minsize=BG_HEIGHT)
-
- PROGRESSBAR_HEIGHT = 3
- PROGRESSBAR_WIDTH = 60
- PROGRESSBAR_RIGHT_PADX = 38
- ALL_PROGRESSBAR_WIDTH = (PROGRESSBAR_WIDTH + PROGRESSBAR_RIGHT_PADX)*3 + PROGRESSBAR_WIDTH
- WHITE_HEX_COLOR = "#f2f2f2"
- VRCT_HEX_COLOR = "#48a495"
- column = 0
-
- for i in range(3):
- progressbar = CTkProgressBar(
- self.progressbar_wrapper,
- height=PROGRESSBAR_HEIGHT,
- width=PROGRESSBAR_WIDTH,
- corner_radius=0,
- fg_color=BG_HEX_COLOR,
- progress_color=WHITE_HEX_COLOR,
- )
- progressbar.set(0)
- progressbar.grid(row=0, column=column, padx=(0,PROGRESSBAR_RIGHT_PADX))
-
- setattr(self, "progressbar_" + str(i), progressbar)
- column+=1
-
-
- self.progressbar_3 = CTkProgressBar(
- self.progressbar_wrapper,
- height=PROGRESSBAR_HEIGHT,
- width=PROGRESSBAR_WIDTH,
- corner_radius=0,
- fg_color=BG_HEX_COLOR,
- progress_color=VRCT_HEX_COLOR,
- )
- self.progressbar_3.set(0)
- self.progressbar_3.grid(row=0, column=column, padx=0)
-
-
-
- self.chato_img_mask_frame = CTkFrame(self.progressbar_wrapper, corner_radius=0, fg_color=BG_HEX_COLOR, width=ALL_PROGRESSBAR_WIDTH, height=0)
- self.chato_img_mask_frame.place(relx=1, rely=0.49, relheight=0.5, anchor="se")
-
-
- CHATO_POSITION = int( (ALL_PROGRESSBAR_WIDTH-(PROGRESSBAR_WIDTH/2)) + 2)
- (self.chato_img, self.CHATO_IMG_WIDTH, self.CHATO_IMG_HEIGHT) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrct_logo_mark_white_square.png"), int(PROGRESSBAR_WIDTH - (PROGRESSBAR_WIDTH/5)))
-
- self.chato_img_label = CTkLabel(
- self.chato_img_mask_frame,
- text=None,
- height=0,
- fg_color=BG_HEX_COLOR,
- image=CTkImage(self.chato_img, size=(self.CHATO_IMG_WIDTH, self.CHATO_IMG_HEIGHT))
- )
- self.chato_img_label.place(x=CHATO_POSITION, rely=1, relwidth=1, anchor="n")
-
-
-
- (img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("VRCT_starting_up.png"), 100)
- self.starting_up_text_label = CTkLabel(
- self,
- text=None,
- height=0,
- fg_color=BG_HEX_COLOR,
- image=CTkImage(img, size=(desired_width, height))
- )
- self.starting_up_text_label.place(relx=0.5, rely=0.7, anchor="center")
-
-
-
- (self.vrct_second_text_img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrchat_chatbox_trasnlator_transcription.png"), 280)
- self.vrct_second_text_img_label = CTkLabel(
- self,
- text=None,
- height=0,
- fg_color=BG_HEX_COLOR,
- image=CTkImage(self.vrct_second_text_img, size=(desired_width, height))
- )
- self.vrct_second_text_img_label.place(relx=0.98, rely=0.98, anchor="se")
-
-
-
-
- (self.vrct_logo_img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrct_logo_for_dark_mode.png"), 280)
- self.vrct_logo_img_label = CTkLabel(
- self,
- text=None,
- height=0,
- fg_color=BG_HEX_COLOR,
- image=CTkImage(self.vrct_logo_img, size=(desired_width, height))
- )
-
-
-
-
- self.weight_download_progressbar_widget = CTkProgressBar(
- self,
- height=8,
- corner_radius=0,
- fg_color="#4b4c4f",
- progress_color=VRCT_HEX_COLOR,
- )
- self.weight_download_progressbar_widget.set(0)
-
-
- (img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("VRCT_now_downloading.png"), 320)
- self.weight_download_text_label = CTkLabel(
- self,
- text=None,
- height=0,
- fg_color=BG_HEX_COLOR,
- image=CTkImage(img, size=(desired_width, height))
- )
-
-
- def toProgress(self, num:int):
- if self.is_showed_weight_download_progressbar is True:
- self.vrct_logo_img_label.place_forget()
- self.weight_download_progressbar_widget.place_forget()
- self.weight_download_text_label.place_forget()
-
- self.progressbar_wrapper.place(relx=0.5, rely=0.5, anchor="center")
- self.starting_up_text_label.place(relx=0.5, rely=0.7, anchor="center")
- self.vrct_second_text_img_label.place(relx=0.98, rely=0.98, anchor="se")
- self.update()
-
- target_progressbar_widget = getattr(self, "progressbar_" + str(num))
-
- # This animation process' base code was made by ChatGPT.
- start_time = time.time()
- DURATION = 0.2
- while True:
- elapsed_time = time.time() - start_time
- progress = min(elapsed_time / DURATION, 1.0)
- eased_progress = 1 - math.pow(1 - progress, 6)
-
-
- target_progressbar_widget.set(eased_progress)
- self.update_idletasks()
-
- if elapsed_time >= DURATION:
- break
-
- time.sleep(0.01)
-
- DURATION = 0.2
- if num == 3:
- start_time = time.time()
- while True:
- elapsed_time = time.time() - start_time
- progress = min(elapsed_time / DURATION, 1.0)
- eased_progress = 1 - math.pow(1 - progress, 6)
-
- # angleが45度未満の場合は0から45度に進むようにし、45度以上の場合は45度に固定
- angle = min(45, 45 * eased_progress)
- angle = -angle
-
- rotated_img = self.rotateImage(self.chato_img, angle)
- self.chato_img_label.configure(image=CTkImage(rotated_img, size=(self.CHATO_IMG_WIDTH, self.CHATO_IMG_HEIGHT)))
-
- rely = 1.0 - eased_progress * 0.6
- self.chato_img_label.place_configure(rely=rely)
- self.update()
-
- if elapsed_time >= DURATION:
- break
-
- time.sleep(0.01)
-
- def rotateImage(self, image, angle):
- # 画像を回転させる
- rotated_image = image.rotate(angle, expand=True)
- return rotated_image
-
-
- def updateDownloadProgress(self, progress:float):
- if self.is_showed_weight_download_progressbar is False:
- self.vrct_second_text_img_label.place_forget()
- self.progressbar_wrapper.place_forget()
- self.starting_up_text_label.place_forget()
-
- self.vrct_logo_img_label.place(relx=0.5, rely=0.4, anchor="center")
- self.weight_download_progressbar_widget.place(relwidth=0.9, relx=0.5, rely=0.84, anchor="s")
- self.weight_download_text_label.place(relx=0.98, rely=0.96, anchor="se")
- self.is_showed_weight_download_progressbar = True
- self.update()
-
- progress_color = generateGradientColor(
- value=progress,
- color_start=[242, 242, 242], # RGB values for #f2f2f2
- color_end=[72, 164, 149], # RGB values for #48a495
- )
- self.weight_download_progressbar_widget.configure(progress_color=progress_color)
- self.weight_download_progressbar_widget.set(progress)
- self.update()
-
-
- def showSplash(self):
- self.attributes("-alpha", 0)
- self.deiconify()
- setGeometryToCenterOfScreen(root_widget=self)
- fadeInAnimation(self, steps=5, interval=0.02)
-
-
- def destroySplash(self):
- self.destroy()
\ No newline at end of file
diff --git a/vrct_gui/splash_window/__init__.py b/vrct_gui/splash_window/__init__.py
deleted file mode 100644
index 3ce5e580..00000000
--- a/vrct_gui/splash_window/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .SplashWindow import *
\ No newline at end of file
diff --git a/vrct_gui/ui_managers/AboutVrctManager.py b/vrct_gui/ui_managers/AboutVrctManager.py
deleted file mode 100644
index 733eaacd..00000000
--- a/vrct_gui/ui_managers/AboutVrctManager.py
+++ /dev/null
@@ -1,191 +0,0 @@
-from types import SimpleNamespace
-
-from ..ui_utils import calculateUiSize, getImageFileFromUiUtils_AboutVrct, bindButtonFunctionAndColor
-from customtkinter import CTkFrame, CTkLabel, CTkImage
-
-IMAGE_STANDARD_SCALING = 2
-class AboutVrctManager():
- def __init__(self, scaling_percentage, ui_language, ctm):
- self.ctm = ctm
- scaling_float = int(scaling_percentage.replace("%", "")) / 100
- self.SCALING_FLOAT = max(scaling_float, 0.4)
-
- self.uism = SimpleNamespace()
-
- self.uism.ABOUT_VRCT_CONTAINER_LEFT_PADX = self.dupTuple(self._calculateUiSize(32))
-
- self.uism.SECTION_BOTTOM_PADY = self._calculateUiSize(22)
- self.uism.PROJECT_LINKS_SECTION_BOTTOM_PADDING = self._calculateUiSize(18) # Exception pady
-
- self.uism.VRCHAT_DISCLAIMER_SECTION_PADY = (self._calculateUiSize(80), self._calculateUiSize(20)) # Exception pady
-
- self.uism.THE_DEVELOPERS_SECTION_TITLE_BOTTOM_PADY = self._calculateUiSize(8)
- self.uism.DEVS_CONTACTS_Y1 = self._calculateUiSize(118)
- self.uism.DEVS_MISYA_X_X = self._calculateUiSize(269)
- self.uism.DEVS_MISYA_GITHUB_X = self._calculateUiSize(297)
- self.uism.DEVS_SHIINA_X_X = self._calculateUiSize(298)
-
- self.uism.PROJECT_LINK_BOTTOM_PADY = self._calculateUiSize(2)
- self.uism.PROJECT_LINK_CORNER_RADIUS = self._calculateUiSize(4)
- self.uism.PROJECT_LINK_CONTENTS_PADX = self._calculateUiSize(55)
- self.uism.PROJECT_LINK_ITEM_IPADX = self._calculateUiSize(10)
- self.uism.PROJECT_LINK_ITEM_IPADY = self._calculateUiSize(4)
-
- self.uism.CONTRIBUTORS_SECTION_TITLE_BOTTOM_PADY = self._calculateUiSize(10)
-
- self.uism.CONTRIBUTORS_CONTACTS_Y1 = self._calculateUiSize(66)
- self.uism.CONTRIBUTORS_DONE_SAN_X_X = self._calculateUiSize(25)
- self.uism.CONTRIBUTORS_IYA_X_X = self._calculateUiSize(281)
- self.uism.CONTRIBUTORS_RERA_X_X = self._calculateUiSize(530)
- self.uism.CONTRIBUTORS_RERA_GITHUB_X = self._calculateUiSize(554)
-
- self.uism.CONTRIBUTORS_CONTACTS_Y2 = self._calculateUiSize(170)
- self.uism.CONTRIBUTORS_POPOSUKE_X_X = self._calculateUiSize(154)
- self.uism.CONTRIBUTORS_KUMAGUMA_X_X = self._calculateUiSize(413)
-
-
- self.uism.TELL_US_BUTTON_CORNER_RADIUS = self._calculateUiSize(6)
- self.uism.TELL_US_BUTTON_PADX = self._calculateUiSize(8)
- self.uism.TELL_US_BUTTON_PADY = self._calculateUiSize(8)
- self.uism.TELL_US_BUTTON_BORDER_WIDTH = self._calculateUiSize(1)
-
-
- self.uism.LOCALIZATION_TITLE_BOTTOM_PADY = self._calculateUiSize(4)
-
-
- self.uism.SPECIAL_THANKS_SECTION_TITLE_BOTTOM_PADY = self._calculateUiSize(6)
- self.uism.SPECIAL_THANKS_MEMBERS_BOTTOM_PADY = self._calculateUiSize(4)
- self.uism.SPECIAL_THANKS_MESSAGE_BOTTOM_PADY = self._calculateUiSize(0)
- self.uism.SPECIAL_THANKS_MESSAGE_AND_YOU_BOTTOM_PADY = self._calculateUiSize(8)
-
- self.uism.POSTER_SHOWCASE_SECTION_TITLE_BOTTOM_PADY = self._calculateUiSize(6)
- self.uism.POSTER_SHOWCASE_POSTER_IMAGES_BOTTOM_PADY = self._calculateUiSize(6)
- self.uism.POSTER_SHOWCASE_WORLD_ITEM_BOTTOM_PADY = self._calculateUiSize(4)
- self.uism.POSTER_SHOWCASE_WORLD_ITEM_IPADX = self._calculateUiSize(12)
- self.uism.POSTER_SHOWCASE_WORLD_ITEM_IPADY = self._calculateUiSize(4)
- self.uism.POSTER_SHOWCASE_WORLD_BOTTOM_PADY = self._calculateUiSize(4)
- self.uism.POSTER_SHOWCASE_WORLD_CORNER_RADIUS = self._calculateUiSize(4)
- self.uism.POSTER_SHOWCASE_WORLD_PAGINATION_BUTTON_BOTTOM_PADY = self._calculateUiSize(18)
- self.uism.POSTER_TELL_US_MESSAGE_TOP_PADY = self._calculateUiSize(20)
- self.uism.POSTER_CHANGE_BUTTON_CORNER_RADIUS = self._calculateUiSize(6)
-
-
- self.image_file = SimpleNamespace()
-
-
- if ui_language == "ja":
- self.image_file.SPECIAL_THANKS_MESSAGE = "special_thanks_message_ja.png"
- self.image_file.SPECIAL_THANKS_TELL_US_MESSAGE = "special_thanks_tell_us_message_ja.png"
-
- self.image_file.POSTER_IMAGES_AUTHOR = "poster_images_authors_ja.png"
- self.image_file.POSTER_IMAGES_AUTHOR_M = "poster_images_authors_m_ja.png"
- self.image_file.POSTER_TELL_US_MESSAGE = "poster_tell_us_message_ja.png"
- else:
- self.image_file.SPECIAL_THANKS_MESSAGE = "special_thanks_message_en.png"
- self.image_file.SPECIAL_THANKS_TELL_US_MESSAGE = "special_thanks_tell_us_message_en.png"
-
- self.image_file.POSTER_IMAGES_AUTHOR = "poster_images_authors_en.png"
- self.image_file.POSTER_IMAGES_AUTHOR_M = "poster_images_authors_m_en.png"
- self.image_file.POSTER_TELL_US_MESSAGE = "poster_tell_us_message_en.png"
-
-
- poster_showcase_pagination_button_image = getImageFileFromUiUtils_AboutVrct("poster_showcase_pagination_button.png")
- self.image_file.POSTER_SHOWCASE_WORLD_PAGINATION_BUTTON = SimpleNamespace(
- img = poster_showcase_pagination_button_image,
- width = calculateUiSize(
- default_size = int(poster_showcase_pagination_button_image.width / IMAGE_STANDARD_SCALING),
- scaling_float=self.SCALING_FLOAT,
- is_allowed_odd=True,
- ),
- height = calculateUiSize(
- default_size = int(poster_showcase_pagination_button_image.height / IMAGE_STANDARD_SCALING),
- scaling_float=self.SCALING_FLOAT,
- is_allowed_odd=True,
- ),
- )
-
-
- poster_showcase_pagination_button_chato_image = getImageFileFromUiUtils_AboutVrct("poster_showcase_pagination_button_chato.png")
- self.image_file.POSTER_SHOWCASE_WORLD_PAGINATION_BUTTON_CHATO = SimpleNamespace(
- img = poster_showcase_pagination_button_chato_image,
- width = calculateUiSize(
- default_size = int(poster_showcase_pagination_button_chato_image.width / IMAGE_STANDARD_SCALING),
- scaling_float=self.SCALING_FLOAT,
- is_allowed_odd=True,
- ),
- height = calculateUiSize(
- default_size = int(poster_showcase_pagination_button_chato_image.height / IMAGE_STANDARD_SCALING),
- scaling_float=self.SCALING_FLOAT,
- is_allowed_odd=True,
- ),
- )
-
-
-
-
- def _calculateUiSize(self, default_size, is_allowed_odd:bool=True, is_zero_allowed:bool=False):
- size = calculateUiSize(default_size, self.SCALING_FLOAT, is_allowed_odd, is_zero_allowed)
- return size
-
-
- def embedImageCTkLabel(self, parent_frame, image_file_name, image_scaling=IMAGE_STANDARD_SCALING, directly_type:str=None, fg_color:str="transparent", anchor:str="w", rotate_angle:int=0):
-
- img = getImageFileFromUiUtils_AboutVrct(image_file_name, directly_type)
-
- image_width = calculateUiSize(
- default_size = int(img.width / image_scaling),
- scaling_float=self.SCALING_FLOAT,
- is_allowed_odd=True,
- )
- image_height = calculateUiSize(
- default_size = int(img.height / image_scaling),
- scaling_float=self.SCALING_FLOAT,
- is_allowed_odd=True,
- )
-
- img_label = CTkLabel(
- parent_frame,
- text=None,
- corner_radius=0,
- height=image_height,
- fg_color=fg_color,
- anchor=anchor,
- image=CTkImage((img).rotate(rotate_angle), size=(image_width, image_height))
- )
-
- return img_label
-
- def embedImageButtonCTkLabel(self, parent_frame, image_file_name, callback, image_scaling=IMAGE_STANDARD_SCALING, directly_type:str=None, fg_color:str=None, hovered_color:str=None, clicked_color:str=None, anchor:str="w", corner_radius:int=0, no_bind:bool=False, rotate_angle:int=0):
-
- fg_color = self.ctm.ABOUT_VRCT_BG if fg_color is None else fg_color
-
- if hovered_color is None:
- hovered_color = self.ctm.ABOUT_VRCT_BUTTON_HOVERED_BG_COLOR
- if clicked_color is None:
- clicked_color = self.ctm.ABOUT_VRCT_BUTTON_CLICKED_BG_COLOR
-
- img_label_frame = CTkFrame(parent_frame, fg_color=fg_color, corner_radius=corner_radius, width=0, height=0)
-
- img_label = self.embedImageCTkLabel(img_label_frame, image_file_name, image_scaling, directly_type, fg_color, anchor, rotate_angle)
-
- if no_bind is False:
- img_label_frame.configure(cursor="hand2")
- img_label.configure(cursor="hand2")
- img_label._canvas.configure(cursor="hand2")
- bindButtonFunctionAndColor(
- target_widgets=[img_label_frame, img_label],
- enter_color=hovered_color,
- leave_color=fg_color,
- clicked_color=clicked_color,
- buttonReleasedFunction=callback,
- )
-
- img_label.grid()
- img_label_frame.img_label = img_label
-
- return img_label_frame
-
-
- @staticmethod
- def dupTuple(value):
- return (value, value)
\ No newline at end of file
diff --git a/vrct_gui/ui_managers/ColorThemeManager.py b/vrct_gui/ui_managers/ColorThemeManager.py
deleted file mode 100644
index c9793403..00000000
--- a/vrct_gui/ui_managers/ColorThemeManager.py
+++ /dev/null
@@ -1,120 +0,0 @@
-from types import SimpleNamespace
-
-from .Themes import _darkTheme, _lightTheme
-
-class ColorThemeManager():
- def __init__(self, theme):
- # base_color 100, 200, 300...900 is generated by https://m2.material.io/design/color/the-color-system.html#tools-for-picking-colors . I put the comment "Source". I used it as a source color and generated.
- # and like 750, 888... is made by https://meyerweb.com/eric/tools/color-blend/#:::hex
-
- self.base_color = SimpleNamespace(
-
- PRIMARY_100_COLOR = "#b7ded8",
- PRIMARY_150_COLOR = "#A1D4CC",
- PRIMARY_200_COLOR = "#8acac0",
- PRIMARY_250_COLOR = "#76BFB4",
- PRIMARY_300_COLOR = "#61b4a7",
- PRIMARY_350_COLOR = "#55AC9E",
- PRIMARY_400_COLOR = "#48a495", # Source
- PRIMARY_450_COLOR = "#429c8c",
- PRIMARY_500_COLOR = "#3b9483",
- PRIMARY_600_COLOR = "#368777",
- PRIMARY_650_COLOR = "#347f6f",
- PRIMARY_700_COLOR = "#317767",
- PRIMARY_750_COLOR = "#2F6F60",
- PRIMARY_800_COLOR = "#2c6759",
- PRIMARY_900_COLOR = "#214b3f",
-
- SENT_400_COLOR = "#6197b4", # Source PRIMARY_300_COLOR #61b4a7. ANALOGOUS' Second one.
- RECEIVED_300_COLOR = "#a861b4", # Source PRIMARY_300_COLOR #61b4a7. TRIADIC' Second one.
-
- DARK_BASIC_TEXT_COLOR = "#f2f2f2", # Icon normal color too
- DARK_100_COLOR = "#f5f7fb", # THE LIGHTEST BG COLOR
- DARK_200_COLOR = "#f1f2f6",
- DARK_300_COLOR = "#e9eaee",
- DARK_350_COLOR = "#d8d9dd",
- DARK_400_COLOR = "#c7c8cc", # Icon second color
- DARK_450_COLOR = "#b8b9bd",
- DARK_500_COLOR = "#a9aaae",
- DARK_600_COLOR = "#7f8084",
- DARK_650_COLOR = "#75767a",
- DARK_700_COLOR = "#6a6c6f",
- DARK_725_COLOR = "#636467",
- DARK_750_COLOR = "#5b5c5f",
- DARK_775_COLOR = "#535457",
- DARK_800_COLOR = "#4b4c4f",
- DARK_825_COLOR = "#434447",
- DARK_850_COLOR = "#3a3b3e",
- DARK_863_COLOR = "#36373a",
- DARK_875_COLOR = "#323336",
- DARK_888_COLOR = "#2e2f32",
- DARK_900_COLOR = "#292a2d", # Source
- DARK_925_COLOR = "#242528",
- DARK_950_COLOR = "#1f2022",
- DARK_975_COLOR = "#1a1b1d",
- DARK_1000_COLOR = "#151517", # THE DARKEST BG COLOR
-
-
- LIGHT_BASIC_TEXT_COLOR = "#050505",
- LIGHT_100_COLOR = "#f5f7fb", # THE LIGHTEST BG COLOR
- LIGHT_125_COLOR = "#F4F6FA",
- LIGHT_150_COLOR = "#F2F4F8",
- LIGHT_175_COLOR = "#F1F3F7",
- LIGHT_200_COLOR = "#eff1f5",
- LIGHT_225_COLOR = "#ECEEF2",
- LIGHT_250_COLOR = "#E9EBEF",
- LIGHT_275_COLOR = "#E6E8EC",
- LIGHT_300_COLOR = "#e2e4e8",
- LIGHT_313_COLOR = "#DEE0E4",
- LIGHT_325_COLOR = "#DADCE0",
- LIGHT_333_COLOR = "#D6D8DC",
- LIGHT_350_COLOR = "#D1D3D7",
- LIGHT_375_COLOR = "#C9CBCF",
- LIGHT_400_COLOR = "#c0c2c6",
- LIGHT_450_COLOR = "#B1B3B7",
- LIGHT_500_COLOR = "#a2a3a7",
- LIGHT_550_COLOR = "#8D8F93",
- LIGHT_600_COLOR = "#787a7e",
- LIGHT_700_COLOR = "#646669", # Icon second color
- LIGHT_800_COLOR = "#45464a",
- LIGHT_900_COLOR = "#242528", # Icon normal color
- LIGHT_1000_COLOR = "#1b1b1b", # THE DARKEST BG COLOR
- )
-
-
- # It's actually meaningless to separate it from __init__. but it's just set to use the dark theme by default, so I did it just in case to change the default theme.
- selected_color_theme = _darkTheme(self.base_color)
- for each_key in selected_color_theme.__dict__.keys():
- setattr(self, each_key, getattr(selected_color_theme, each_key))
-
-
- if theme == "Dark":
- pass
-
- elif theme == "Light":
- selected_color_theme = _lightTheme(self.base_color)
- self._colorThemeDictsMerger(selected_color_theme)
-
-
-
-
-
- def _colorThemeDictsMerger(self, selected_color_theme):
- # Each section(main, selectable_language_window, config_window...) marge to default theme.
- for selected_theme_section_key in selected_color_theme.__dict__.keys():
- # Get same section data by section key from default theme.
- default_theme_target_section_data = getattr(self, selected_theme_section_key)
-
- selected_theme_section_data = getattr(selected_color_theme, selected_theme_section_key)
- self._mergeNestedDicts(default_theme_target_section_data.__dict__, selected_theme_section_data.__dict__)
-
-
-
- def _mergeNestedDicts(self, d1, d2):
- for key, value in d2.items():
- if key in d1 and isinstance(d1[key], dict) and isinstance(value, dict):
- self._mergeNestedDicts(d1[key], value)
- else:
- d1[key] = value
-
- return d1
diff --git a/vrct_gui/ui_managers/Themes/__init__.py b/vrct_gui/ui_managers/Themes/__init__.py
deleted file mode 100644
index fb61579d..00000000
--- a/vrct_gui/ui_managers/Themes/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from ._darkTheme import _darkTheme
-from ._lightTheme import _lightTheme
\ No newline at end of file
diff --git a/vrct_gui/ui_managers/Themes/_darkTheme.py b/vrct_gui/ui_managers/Themes/_darkTheme.py
deleted file mode 100644
index ed46a557..00000000
--- a/vrct_gui/ui_managers/Themes/_darkTheme.py
+++ /dev/null
@@ -1,351 +0,0 @@
-from types import SimpleNamespace
-from ...ui_utils import getImageFileFromUiUtils
-
-def _darkTheme(base_color):
- theme_settings = SimpleNamespace(
- main = SimpleNamespace(
- # Common
- BASIC_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
- LABELS_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
-
- # Main
- MAIN_BG_COLOR = base_color.DARK_888_COLOR,
-
-
- TEXTBOX_BG_COLOR = base_color.DARK_900_COLOR,
- TEXTBOX_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
- TEXTBOX_TEXT_SUB_COLOR = base_color.DARK_450_COLOR,
- TEXTBOX_SYSTEM_TAG_TEXT_COLOR = base_color.PRIMARY_300_COLOR,
- TEXTBOX_SENT_TAG_TEXT_COLOR = base_color.SENT_400_COLOR,
- TEXTBOX_RECEIVED_TAG_TEXT_COLOR = base_color.RECEIVED_300_COLOR,
- # TEXTBOX_ERROR_TAG_TEXT_COLOR = "#c27583",
- TEXTBOX_TIMESTAMP_TEXT_COLOR = base_color.DARK_600_COLOR,
-
- TEXTBOX_TAB_BG_PASSIVE_COLOR = base_color.DARK_850_COLOR,
- TEXTBOX_TAB_BG_ACTIVE_COLOR = base_color.DARK_900_COLOR,
- TEXTBOX_TAB_BG_HOVERED_COLOR = base_color.DARK_800_COLOR,
- TEXTBOX_TAB_BG_CLICKED_COLOR = base_color.DARK_925_COLOR,
- TEXTBOX_TAB_TEXT_ACTIVE_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
- TEXTBOX_TAB_TEXT_PASSIVE_COLOR = base_color.DARK_500_COLOR,
-
- TEXTBOX_ENTRY_TEXT_COLOR = base_color.DARK_300_COLOR,
- TEXTBOX_ENTRY_TEXT_DISABLED_COLOR = base_color.DARK_500_COLOR,
- TEXTBOX_ENTRY_BG_COLOR = base_color.DARK_875_COLOR,
- TEXTBOX_ENTRY_BORDER_COLOR = base_color.DARK_750_COLOR,
- TEXTBOX_ENTRY_PLACEHOLDER_COLOR = base_color.DARK_500_COLOR,
- TEXTBOX_ENTRY_PLACEHOLDER_DISABLED_COLOR = base_color.DARK_700_COLOR,
-
- SEND_MESSAGE_BUTTON_BG_COLOR = base_color.DARK_850_COLOR,
- SEND_MESSAGE_BUTTON_BG_HOVERED_COLOR = base_color.DARK_825_COLOR,
- SEND_MESSAGE_BUTTON_BG_CLICKED_COLOR = base_color.DARK_900_COLOR,
-
-
- # Sidebar
- SIDEBAR_BG_COLOR = base_color.DARK_850_COLOR,
-
- # Sidebar Features
- SF__BG_COLOR = base_color.DARK_825_COLOR,
- SF__HOVERED_BG_COLOR = base_color.DARK_800_COLOR,
- SF__CLICKED_BG_COLOR = base_color.DARK_875_COLOR,
- SF__TEXT_DISABLED_COLOR = base_color.DARK_500_COLOR,
-
- SF__SWITCH_BOX_BG_COLOR = base_color.DARK_775_COLOR,
- SF__SWITCH_BOX_HOVERED_BG_COLOR = base_color.DARK_725_COLOR,
- SF__SWITCH_BOX_CLICKED_BG_COLOR = base_color.DARK_825_COLOR,
- SF__SWITCH_BOX_ACTIVE_BG_COLOR = base_color.PRIMARY_500_COLOR,
- SF__SWITCH_BOX_ACTIVE_HOVERED_BG_COLOR = base_color.PRIMARY_400_COLOR,
- SF__SWITCH_BOX_ACTIVE_CLICKED_BG_COLOR = base_color.PRIMARY_700_COLOR,
- SF__SWITCH_BOX_DISABLE_BG_COLOR = base_color.PRIMARY_800_COLOR,
-
- SF__SWITCH_BOX_BUTTON_COLOR = base_color.DARK_400_COLOR,
- SF__SWITCH_BOX_BUTTON_DISABLED_COLOR = base_color.DARK_600_COLOR,
- # It's not working because It overrode internally.
- SF__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.DARK_350_COLOR,
-
- SF__SELECTED_MARK_ACTIVE_BG_COLOR = base_color.PRIMARY_500_COLOR,
- SF__SELECTED_MARK_ACTIVE_HOVERED_BG_COLOR = base_color.PRIMARY_400_COLOR,
- SF__SELECTED_MARK_ACTIVE_CLICKED_BG_COLOR = base_color.PRIMARY_700_COLOR,
- SF__SELECTED_MARK_DISABLE_BG_COLOR = base_color.PRIMARY_800_COLOR,
-
-
- # Sidebar Languages Settings
- SLS__TITLE_TEXT_COLOR = base_color.DARK_400_COLOR,
-
- SLS__BG_COLOR = base_color.DARK_800_COLOR,
-
- SLS__PRESETS_TAB_BG_HOVERED_COLOR = base_color.DARK_825_COLOR,
- SLS__PRESETS_TAB_BG_CLICKED_COLOR = base_color.DARK_875_COLOR,
- SLS__PRESETS_TAB_BG_PASSIVE_COLOR = base_color.DARK_850_COLOR,
- SLS__PRESETS_TAB_BG_ACTIVE_COLOR = base_color.DARK_800_COLOR,
- SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR_PASSIVE = base_color.DARK_600_COLOR,
- SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
-
- SLS__BOX_BG_COLOR = base_color.DARK_825_COLOR,
- SLS__BOX_SECTION_TITLE_TEXT_COLOR = base_color.DARK_400_COLOR,
- SLS__BOX_ARROWS_TEXT_COLOR = base_color.DARK_500_COLOR,
- SLS__BOX_ARROWS_SWAP_BUTTON_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
- SLS__BOX_ARROWS_SWAP_BUTTON_HOVERED_COLOR = base_color.DARK_750_COLOR,
- SLS__BOX_ARROWS_SWAP_BUTTON_CLICKED_COLOR = base_color.DARK_850_COLOR,
-
- SLS__OPTIONMENU_BG_COLOR = base_color.DARK_888_COLOR,
- SLS__OPTIONMENU_HOVERED_BG_COLOR = base_color.DARK_875_COLOR,
- SLS__OPTIONMENU_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
-
- SLS__DROPDOWN_MENU_WINDOW_BG_COLOR = base_color.DARK_888_COLOR,
- SLS__DROPDOWN_MENU_WINDOW_BORDER_COLOR = base_color.DARK_650_COLOR,
- SLS__DROPDOWN_MENU_BG_COLOR = base_color.DARK_888_COLOR,
- SLS__DROPDOWN_MENU_HOVERED_BG_COLOR = base_color.DARK_825_COLOR,
- SLS__DROPDOWN_MENU_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
-
- CONFIG_BUTTON_BG_COLOR = base_color.DARK_850_COLOR,
- CONFIG_BUTTON_HOVERED_BG_COLOR = base_color.DARK_800_COLOR,
- CONFIG_BUTTON_CLICKED_BG_COLOR = base_color.DARK_875_COLOR,
-
- MINIMIZE_SIDEBAR_BUTTON_BG_COLOR = base_color.DARK_850_COLOR,
- MINIMIZE_SIDEBAR_BUTTON_HOVERED_BG_COLOR = base_color.DARK_800_COLOR,
- MINIMIZE_SIDEBAR_BUTTON_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
-
-
-
- TOP_BAR_BUTTON_BG_COLOR = base_color.DARK_888_COLOR,
- TOP_BAR_BUTTON_HOVERED_BG_COLOR = base_color.DARK_850_COLOR,
- TOP_BAR_BUTTON_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
- TOP_BAR_BUTTON_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
- TOP_BAR_BUTTON_STATE_TEXT_ENABLED_COLOR = base_color.PRIMARY_300_COLOR,
- TOP_BAR_BUTTON_STATE_TEXT_DISABLED_COLOR = base_color.DARK_600_COLOR,
-
- UPDATE_AVAILABLE_BUTTON_BG_COLOR = base_color.DARK_888_COLOR,
- UPDATE_AVAILABLE_BUTTON_HOVERED_BG_COLOR = base_color.DARK_850_COLOR,
- UPDATE_AVAILABLE_BUTTON_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
- UPDATE_AVAILABLE_BUTTON_TEXT_COLOR = base_color.PRIMARY_300_COLOR,
-
- HELP_AND_INFO_BUTTON_BG_COLOR = base_color.DARK_888_COLOR,
- HELP_AND_INFO_BUTTON_HOVERED_BG_COLOR = base_color.DARK_850_COLOR,
- HELP_AND_INFO_BUTTON_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
- ),
-
-
- selectable_language_window = SimpleNamespace(
- # Selectable Language Window
- BASIC_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
-
- MAIN_BG_COLOR = base_color.DARK_875_COLOR,
-
- GO_BACK_BUTTON_BG_COLOR = base_color.DARK_800_COLOR,
- GO_BACK_BUTTON_BG_HOVERED_COLOR = base_color.DARK_750_COLOR,
- GO_BACK_BUTTON_BG_CLICKED_COLOR = base_color.DARK_875_COLOR,
-
- TOP_BG_COLOR = base_color.DARK_850_COLOR,
- TITLE_TEXT_COLOR = base_color.DARK_400_COLOR,
- LANGUAGE_BUTTON_BG_COLOR = base_color.DARK_875_COLOR,
- LANGUAGE_BUTTON_BG_HOVERED_COLOR = base_color.DARK_825_COLOR,
- LANGUAGE_BUTTON_BG_CLICKED_COLOR = base_color.DARK_888_COLOR,
- ),
-
-
-
- # Modal Window (Main Window)
- main_window_cover = SimpleNamespace(
- TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
- BG_COLOR = "#000",
- ),
-
-
- confirmation_modal = SimpleNamespace(
- MESSAGE_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
- FAKE_BORDER_COLOR = base_color.DARK_600_COLOR,
- BG_COLOR = base_color.DARK_800_COLOR,
- CONFIRMATION_BUTTONS_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
-
- ACCEPT_BUTTON_BG_COLOR = base_color.PRIMARY_600_COLOR,
- ACCEPT_BUTTON_HOVERED_BG_COLOR = base_color.PRIMARY_450_COLOR,
- ACCEPT_BUTTON_CLICKED_BG_COLOR = base_color.PRIMARY_750_COLOR,
- DENY_BUTTON_BG_COLOR = base_color.DARK_750_COLOR,
- DENY_BUTTON_HOVERED_BG_COLOR = base_color.DARK_700_COLOR,
- DENY_BUTTON_CLICKED_BG_COLOR = base_color.DARK_825_COLOR,
- ),
-
-
- config_window = SimpleNamespace(
- # Common
- BASIC_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
- LABELS_TEXT_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
- LABELS_DESC_TEXT_COLOR = base_color.DARK_500_COLOR,
-
- LABELS_TEXT_DISABLED_COLOR = base_color.DARK_600_COLOR,
-
- SB__BUTTON_COLOR = base_color.DARK_888_COLOR,
- SB__BUTTON_HOVERED_COLOR = base_color.DARK_800_COLOR,
- SB__BUTTON_CLICKED_COLOR = base_color.DARK_900_COLOR,
-
-
- # Top bar
- TOP_BAR_BG_COLOR = base_color.DARK_850_COLOR,
-
- # Restart Button
- RESTART_BUTTON_BG_COLOR = base_color.PRIMARY_600_COLOR,
- RESTART_BUTTON_HOVERED_BG_COLOR = base_color.PRIMARY_500_COLOR,
- RESTART_BUTTON_CLICKED_BG_COLOR = base_color.PRIMARY_700_COLOR,
-
-
- # Compact Mode
- COMPACT_MODE_SWITCH_BOX_BG_COLOR = base_color.DARK_775_COLOR,
- COMPACT_MODE_SWITCH_BOX_ACTIVE_BG_COLOR = base_color.PRIMARY_500_COLOR,
- COMPACT_MODE_SWITCH_BOX_BUTTON_COLOR = base_color.DARK_350_COLOR,
- COMPACT_MODE_SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.DARK_300_COLOR,
-
- # Main
- MAIN_BG_COLOR = base_color.DARK_950_COLOR,
-
- # This is for fake border color
- SB__WRAPPER_BG_COLOR = base_color.DARK_750_COLOR,
-
- SB__BG_COLOR = base_color.DARK_888_COLOR,
-
- SB__OPTIONMENU_BG_COLOR = base_color.DARK_925_COLOR,
- SB__OPTIONMENU_HOVERED_BG_COLOR = base_color.DARK_850_COLOR,
- SB__OPTIONMENU_CLICKED_BG_COLOR = base_color.DARK_950_COLOR,
- SB__DROPDOWN_MENU_WINDOW_BG_COLOR = base_color.DARK_950_COLOR,
- SB__DROPDOWN_MENU_WINDOW_BORDER_COLOR = base_color.DARK_600_COLOR,
- SB__DROPDOWN_MENU_BG_COLOR = base_color.DARK_875_COLOR,
- SB__DROPDOWN_MENU_HOVERED_BG_COLOR = base_color.DARK_800_COLOR,
- SB__DROPDOWN_MENU_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
-
- SB__SLIDER_BG_COLOR = base_color.DARK_700_COLOR,
- SB__SLIDER_PROGRESS_BG_COLOR = base_color.DARK_500_COLOR,
- SB__SLIDER_BUTTON_COLOR = base_color.DARK_700_COLOR,
- SB__SLIDER_BUTTON_HOVERED_COLOR = base_color.DARK_600_COLOR,
- SB__SLIDER_TOOLTIP_BG_COLOR = base_color.DARK_850_COLOR,
- SB__SLIDER_TOOLTIP_TEXT_COLOR = base_color.DARK_200_COLOR,
-
- SB__SWITCH_BOX_BG_COLOR = base_color.DARK_800_COLOR,
- SB__SWITCH_BOX_BG_DISABLED_COLOR = base_color.DARK_900_COLOR,
- SB__SWITCH_BOX_ACTIVE_BG_COLOR = base_color.PRIMARY_500_COLOR,
- SB__SWITCH_BOX_ACTIVE_BG_DISABLED_COLOR = base_color.PRIMARY_700_COLOR,
- SB__SWITCH_BOX_BUTTON_COLOR = base_color.DARK_400_COLOR,
- SB__SWITCH_BOX_BUTTON_DISABLED_COLOR = base_color.DARK_700_COLOR,
- SB__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.DARK_350_COLOR,
-
- SB__CHECKBOX_BORDER_COLOR = base_color.DARK_600_COLOR,
- SB__CHECKBOX_BORDER_DISABLED_COLOR = base_color.DARK_800_COLOR,
- SB__CHECKBOX_HOVER_COLOR = base_color.DARK_800_COLOR,
- SB__CHECKBOX_CHECKED_COLOR = base_color.PRIMARY_700_COLOR,
- SB__CHECKBOX_CHECKMARK_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
-
- SB__RADIOBUTTON_TEXT_COLOR = base_color.DARK_300_COLOR,
- SB__RADIOBUTTON_BORDER_COLOR = base_color.DARK_600_COLOR,
- SB__RADIOBUTTON_SELECTED_COLOR = base_color.PRIMARY_400_COLOR,
- SB__RADIOBUTTON_BG_HOVERED_COLOR = base_color.DARK_825_COLOR,
- SB__RADIOBUTTON_BG_CLICKED_COLOR = base_color.DARK_900_COLOR,
-
- SB__ENTRY_TEXT_COLOR = base_color.DARK_300_COLOR,
- SB__ENTRY_BG_COLOR = base_color.DARK_863_COLOR,
- SB__ENTRY_BORDER_COLOR = base_color.DARK_775_COLOR,
-
-
- SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_BG_COLOR = base_color.DARK_800_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_PROGRESS_BG_COLOR = base_color.PRIMARY_750_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_PROGRESS_EXCEED_THRESHOLD_BG_COLOR = base_color.PRIMARY_400_COLOR,
-
- SB__PROGRESSBAR_X_SLIDER__SLIDER_BUTTON_COLOR = base_color.PRIMARY_600_COLOR,
- SB__PROGRESSBAR_X_SLIDER__SLIDER_BUTTON_HOVERED_COLOR = base_color.PRIMARY_400_COLOR,
-
- SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_COLOR = base_color.DARK_800_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_HOVERED_COLOR = base_color.DARK_700_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_CLICKED_COLOR = base_color.DARK_900_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_DISABLED_COLOR = base_color.DARK_850_COLOR,
-
- SB__PROGRESSBAR_X_SLIDER__ACTIVE_BUTTON_COLOR = base_color.PRIMARY_600_COLOR,
- SB__PROGRESSBAR_X_SLIDER__ACTIVE_BUTTON_HOVERED_COLOR = base_color.PRIMARY_500_COLOR,
- SB__PROGRESSBAR_X_SLIDER__ACTIVE_BUTTON_CLICKED_COLOR = base_color.PRIMARY_800_COLOR,
-
- SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_COLOR = base_color.PRIMARY_600_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_HOVERED_COLOR = base_color.PRIMARY_500_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_CLICKED_COLOR = base_color.PRIMARY_700_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST_BG_COLOR = base_color.DARK_800_COLOR,
-
- SB__ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_HOVERED_BG_COLOR = base_color.DARK_750_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CLICKED_BG_COLOR = base_color.DARK_850_COLOR,
-
- SB__ADD_AND_DELETE_ABLE_LIST_DELETED_BG_COLOR = base_color.DARK_850_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__VALUES_DELETED_BUTTON_HOVERED_BG_COLOR = base_color.DARK_800_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__VALUES_DELETED_BUTTON_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
-
-
- SB__MESSAGE_FORMAT__EXAMPLE_BG_COLOR = "#3a4554", # from VRChat' chat display color
- SB__MESSAGE_FORMAT__EXAMPLE_TEXT_COLOR = base_color.DARK_100_COLOR,
- SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR = base_color.DARK_875_COLOR,
- SB__MESSAGE_FORMAT__SWAP_BUTTON_HOVERED_COLOR = base_color.DARK_800_COLOR,
- SB__MESSAGE_FORMAT__SWAP_BUTTON_CLICKED_COLOR = base_color.DARK_888_COLOR,
-
-
-
-
- # Side menu
- SIDE_MENU_BG_COLOR = base_color.DARK_950_COLOR,
-
- SIDE_MENU_LABELS_BG_COLOR = base_color.DARK_950_COLOR,
- SIDE_MENU_LABELS_BG_FOR_FAKE_BORDER_COLOR = base_color.DARK_950_COLOR,
- SIDE_MENU_LABELS_HOVERED_BG_COLOR = base_color.DARK_850_COLOR,
- SIDE_MENU_LABELS_CLICKED_BG_COLOR = base_color.PRIMARY_750_COLOR,
- SIDE_MENU_LABELS_SELECTED_TEXT_COLOR = base_color.PRIMARY_200_COLOR,
-
- SIDE_MENU_SELECTED_MARK_ACTIVE_BG_COLOR = base_color.PRIMARY_500_COLOR,
-
- NOW_VERSION_TEXT_COLOR = base_color.DARK_300_COLOR,
-
- # Error Message Window for Config Window
- # The color code [#bb4448] is a mixture of [#a9555c] and [#cc3333] (for a redder shade).
- SB__ERROR_MESSAGE_BG_COLOR = "#bb4448",
- SB__SUCCESS_MESSAGE_BG_COLOR = "#368777",
- SB__ERROR_MESSAGE_TEXT_COLOR = "#fff",
-
-
-
- # About VRCT
- ABOUT_VRCT_BG = base_color.DARK_950_COLOR,
- ABOUT_VRCT_DEV_BG = base_color.DARK_888_COLOR,
- ABOUT_VRCT_BUTTON_HOVERED_BG_COLOR = base_color.DARK_900_COLOR,
- ABOUT_VRCT_BUTTON_CLICKED_BG_COLOR = base_color.DARK_925_COLOR,
-
- ABOUT_VRCT_TELL_US_BUTTON_BORDER_COLOR = base_color.DARK_888_COLOR,
- ),
-
-
-
- image_file = SimpleNamespace(
- VRCT_LOGO = getImageFileFromUiUtils("vrct_logo_for_dark_mode.png"),
- VRCT_LOGO_MARK = getImageFileFromUiUtils("vrct_logo_mark_white.png"),
-
- TRANSLATION_ICON = getImageFileFromUiUtils("translation_icon_white.png"),
- TRANSLATION_ICON_DISABLED = getImageFileFromUiUtils("translation_icon_disabled.png"),
- MIC_ICON = getImageFileFromUiUtils("mic_icon_white.png"),
- MIC_ICON_DISABLED = getImageFileFromUiUtils("mic_icon_disabled.png"),
- HEADPHONES_ICON = getImageFileFromUiUtils("headphones_icon_white.png"),
- HEADPHONES_ICON_DISABLED = getImageFileFromUiUtils("headphones_icon_disabled.png"),
- FOREGROUND_ICON = getImageFileFromUiUtils("foreground_icon_white.png"),
- FOREGROUND_ICON_DISABLED = getImageFileFromUiUtils("foreground_icon_disabled.png"),
-
- NARROW_ARROW_DOWN = getImageFileFromUiUtils("narrow_arrow_down_white.png"),
-
- CONFIGURATION_ICON = getImageFileFromUiUtils("configuration_icon_white.png"),
- CONFIGURATION_ICON_DISABLED = getImageFileFromUiUtils("configuration_icon_disabled.png"),
-
- ARROW_LEFT = getImageFileFromUiUtils("arrow_left_white.png"),
- ARROW_LEFT_DISABLED = getImageFileFromUiUtils("arrow_left_disabled.png"),
-
- SEND_MESSAGE_ICON = getImageFileFromUiUtils("send_message_icon_white.png"),
- SEND_MESSAGE_ICON_DISABLED = getImageFileFromUiUtils("send_message_icon_black.png"),
- REFRESH_UPDATE_ICON = getImageFileFromUiUtils("refresh_update_icon.png"),
- REFRESH_ICON = getImageFileFromUiUtils("refresh_icon.png"),
- HELP_ICON = getImageFileFromUiUtils("help_icon_white.png"),
-
- CANCEL_ICON = getImageFileFromUiUtils("cancel_icon.png"),
- REDO_ICON = getImageFileFromUiUtils("redo_icon_white.png"),
- SWAP_ICON = getImageFileFromUiUtils("swap_icon_white.png"),
- FOLDER_OPEN_ICON = getImageFileFromUiUtils("folder_open_icon_white.png"),
- LINK_ICON = getImageFileFromUiUtils("link_icon_white.png"),
- ),
- )
-
- return theme_settings
\ No newline at end of file
diff --git a/vrct_gui/ui_managers/Themes/_lightTheme.py b/vrct_gui/ui_managers/Themes/_lightTheme.py
deleted file mode 100644
index b4e2d96d..00000000
--- a/vrct_gui/ui_managers/Themes/_lightTheme.py
+++ /dev/null
@@ -1,335 +0,0 @@
-from types import SimpleNamespace
-from ...ui_utils import getImageFileFromUiUtils
-
-def _lightTheme(base_color):
- theme_settings = SimpleNamespace(
- main = SimpleNamespace(
- # Common
- BASIC_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
- LABELS_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
-
- # Main
- MAIN_BG_COLOR = base_color.LIGHT_175_COLOR,
-
-
- TEXTBOX_BG_COLOR = base_color.LIGHT_100_COLOR,
- TEXTBOX_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
- TEXTBOX_TEXT_SUB_COLOR = base_color.LIGHT_600_COLOR,
- TEXTBOX_SYSTEM_TAG_TEXT_COLOR = base_color.PRIMARY_300_COLOR,
- TEXTBOX_SENT_TAG_TEXT_COLOR = base_color.SENT_400_COLOR,
- TEXTBOX_RECEIVED_TAG_TEXT_COLOR = base_color.RECEIVED_300_COLOR,
- # TEXTBOX_ERROR_TAG_TEXT_COLOR = "#c27583",
- TEXTBOX_TIMESTAMP_TEXT_COLOR = base_color.LIGHT_500_COLOR,
-
- TEXTBOX_TAB_BG_PASSIVE_COLOR = base_color.LIGHT_300_COLOR,
- TEXTBOX_TAB_BG_ACTIVE_COLOR = base_color.LIGHT_125_COLOR,
- TEXTBOX_TAB_BG_HOVERED_COLOR = base_color.LIGHT_250_COLOR,
- TEXTBOX_TAB_BG_CLICKED_COLOR = base_color.LIGHT_100_COLOR,
- TEXTBOX_TAB_TEXT_ACTIVE_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
- TEXTBOX_TAB_TEXT_PASSIVE_COLOR = base_color.LIGHT_600_COLOR,
-
- TEXTBOX_ENTRY_TEXT_COLOR = base_color.LIGHT_800_COLOR,
- TEXTBOX_ENTRY_TEXT_DISABLED_COLOR = base_color.LIGHT_500_COLOR,
- TEXTBOX_ENTRY_BG_COLOR = base_color.LIGHT_250_COLOR,
- TEXTBOX_ENTRY_BORDER_COLOR = base_color.LIGHT_400_COLOR,
- TEXTBOX_ENTRY_PLACEHOLDER_COLOR = base_color.LIGHT_600_COLOR,
- TEXTBOX_ENTRY_PLACEHOLDER_DISABLED_COLOR = base_color.LIGHT_400_COLOR,
-
- SEND_MESSAGE_BUTTON_BG_COLOR = base_color.LIGHT_300_COLOR,
- SEND_MESSAGE_BUTTON_BG_HOVERED_COLOR = base_color.LIGHT_325_COLOR,
- SEND_MESSAGE_BUTTON_BG_CLICKED_COLOR = base_color.LIGHT_350_COLOR,
-
-
- # Sidebar
- SIDEBAR_BG_COLOR = base_color.LIGHT_250_COLOR,
-
- # Sidebar Features
- SF__BG_COLOR = base_color.LIGHT_313_COLOR,
- SF__HOVERED_BG_COLOR = base_color.LIGHT_333_COLOR,
- SF__CLICKED_BG_COLOR = base_color.LIGHT_400_COLOR,
- SF__TEXT_DISABLED_COLOR = base_color.LIGHT_600_COLOR,
-
- SF__SWITCH_BOX_BG_COLOR = base_color.LIGHT_375_COLOR,
- SF__SWITCH_BOX_HOVERED_BG_COLOR = base_color.LIGHT_400_COLOR,
- SF__SWITCH_BOX_CLICKED_BG_COLOR = base_color.LIGHT_450_COLOR,
- SF__SWITCH_BOX_ACTIVE_BG_COLOR = base_color.PRIMARY_350_COLOR,
- SF__SWITCH_BOX_ACTIVE_HOVERED_BG_COLOR = base_color.PRIMARY_400_COLOR,
- SF__SWITCH_BOX_ACTIVE_CLICKED_BG_COLOR = base_color.PRIMARY_500_COLOR,
- SF__SWITCH_BOX_DISABLE_BG_COLOR = base_color.PRIMARY_200_COLOR,
-
- SF__SWITCH_BOX_BUTTON_COLOR = base_color.LIGHT_150_COLOR,
- SF__SWITCH_BOX_BUTTON_DISABLED_COLOR = base_color.LIGHT_300_COLOR,
- # It's not working because It overrode internally.
- SF__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.LIGHT_300_COLOR,
-
- SF__SELECTED_MARK_ACTIVE_BG_COLOR = base_color.PRIMARY_350_COLOR,
- SF__SELECTED_MARK_ACTIVE_HOVERED_BG_COLOR = base_color.PRIMARY_400_COLOR,
- SF__SELECTED_MARK_ACTIVE_CLICKED_BG_COLOR = base_color.PRIMARY_500_COLOR,
- SF__SELECTED_MARK_DISABLE_BG_COLOR = base_color.PRIMARY_200_COLOR,
-
-
- # Sidebar Languages Settings
- SLS__TITLE_TEXT_COLOR = base_color.LIGHT_800_COLOR,
-
- SLS__BG_COLOR = base_color.LIGHT_313_COLOR,
-
- SLS__PRESETS_TAB_BG_HOVERED_COLOR = base_color.LIGHT_300_COLOR,
- SLS__PRESETS_TAB_BG_CLICKED_COLOR = base_color.LIGHT_350_COLOR,
- SLS__PRESETS_TAB_BG_PASSIVE_COLOR = base_color.LIGHT_250_COLOR,
- SLS__PRESETS_TAB_BG_ACTIVE_COLOR = base_color.LIGHT_313_COLOR,
- SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR_PASSIVE = base_color.LIGHT_400_COLOR,
- SLS__PRESETS_TAB_ACTIVE_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
-
- SLS__BOX_BG_COLOR = base_color.LIGHT_333_COLOR,
- SLS__BOX_SECTION_TITLE_TEXT_COLOR = base_color.LIGHT_800_COLOR,
- SLS__BOX_ARROWS_TEXT_COLOR = base_color.LIGHT_700_COLOR,
- SLS__BOX_ARROWS_SWAP_BUTTON_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
- SLS__BOX_ARROWS_SWAP_BUTTON_HOVERED_COLOR = base_color.LIGHT_200_COLOR,
- SLS__BOX_ARROWS_SWAP_BUTTON_CLICKED_COLOR = base_color.LIGHT_350_COLOR,
-
- SLS__OPTIONMENU_BG_COLOR = base_color.LIGHT_200_COLOR,
- SLS__OPTIONMENU_HOVERED_BG_COLOR = base_color.LIGHT_250_COLOR,
- SLS__OPTIONMENU_CLICKED_BG_COLOR = base_color.LIGHT_400_COLOR,
-
- SLS__DROPDOWN_MENU_WINDOW_BG_COLOR = base_color.LIGHT_300_COLOR,
- SLS__DROPDOWN_MENU_WINDOW_BORDER_COLOR = base_color.LIGHT_700_COLOR,
- SLS__DROPDOWN_MENU_BG_COLOR = base_color.LIGHT_300_COLOR,
- SLS__DROPDOWN_MENU_HOVERED_BG_COLOR = base_color.LIGHT_200_COLOR,
- SLS__DROPDOWN_MENU_CLICKED_BG_COLOR = base_color.LIGHT_400_COLOR,
-
- CONFIG_BUTTON_BG_COLOR = base_color.LIGHT_250_COLOR,
- CONFIG_BUTTON_HOVERED_BG_COLOR = base_color.LIGHT_350_COLOR,
- CONFIG_BUTTON_CLICKED_BG_COLOR = base_color.LIGHT_400_COLOR,
-
- MINIMIZE_SIDEBAR_BUTTON_BG_COLOR = base_color.LIGHT_250_COLOR,
- MINIMIZE_SIDEBAR_BUTTON_HOVERED_BG_COLOR = base_color.LIGHT_350_COLOR,
- MINIMIZE_SIDEBAR_BUTTON_CLICKED_BG_COLOR = base_color.LIGHT_400_COLOR,
-
-
-
- TOP_BAR_BUTTON_BG_COLOR = base_color.LIGHT_175_COLOR,
- TOP_BAR_BUTTON_HOVERED_BG_COLOR = base_color.LIGHT_300_COLOR,
- TOP_BAR_BUTTON_CLICKED_BG_COLOR = base_color.LIGHT_350_COLOR,
- TOP_BAR_BUTTON_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
- TOP_BAR_BUTTON_STATE_TEXT_ENABLED_COLOR = base_color.PRIMARY_400_COLOR,
- TOP_BAR_BUTTON_STATE_TEXT_DISABLED_COLOR = base_color.LIGHT_600_COLOR,
-
- UPDATE_AVAILABLE_BUTTON_TEXT_COLOR = base_color.PRIMARY_400_COLOR,
- ),
-
-
- selectable_language_window = SimpleNamespace(
- # Selectable Language Window
- BASIC_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
-
- MAIN_BG_COLOR = base_color.LIGHT_175_COLOR,
-
- GO_BACK_BUTTON_BG_COLOR = base_color.LIGHT_325_COLOR,
- GO_BACK_BUTTON_BG_HOVERED_COLOR = base_color.LIGHT_400_COLOR,
- GO_BACK_BUTTON_BG_CLICKED_COLOR = base_color.LIGHT_500_COLOR,
-
- TOP_BG_COLOR = base_color.LIGHT_250_COLOR,
- TITLE_TEXT_COLOR = base_color.LIGHT_700_COLOR,
- LANGUAGE_BUTTON_BG_COLOR = base_color.LIGHT_175_COLOR,
- LANGUAGE_BUTTON_BG_HOVERED_COLOR = base_color.LIGHT_275_COLOR,
- LANGUAGE_BUTTON_BG_CLICKED_COLOR = base_color.LIGHT_325_COLOR,
- ),
-
-
-
- # Modal Window (Main Window)
- main_window_cover = SimpleNamespace(
- TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
- BG_COLOR = "#fff",
- ),
-
-
- confirmation_modal = SimpleNamespace(
- MESSAGE_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
- FAKE_BORDER_COLOR = base_color.LIGHT_500_COLOR,
- BG_COLOR = base_color.LIGHT_350_COLOR,
- CONFIRMATION_BUTTONS_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
-
- ACCEPT_BUTTON_BG_COLOR = base_color.PRIMARY_250_COLOR,
- ACCEPT_BUTTON_HOVERED_BG_COLOR = base_color.PRIMARY_200_COLOR,
- ACCEPT_BUTTON_CLICKED_BG_COLOR = base_color.PRIMARY_300_COLOR,
- DENY_BUTTON_BG_COLOR = base_color.LIGHT_200_COLOR,
- DENY_BUTTON_HOVERED_BG_COLOR = base_color.LIGHT_100_COLOR,
- DENY_BUTTON_CLICKED_BG_COLOR = base_color.LIGHT_300_COLOR,
- ),
-
-
- config_window = SimpleNamespace(
- # Common
- BASIC_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
- LABELS_TEXT_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
- LABELS_DESC_TEXT_COLOR = base_color.LIGHT_600_COLOR,
-
- LABELS_TEXT_DISABLED_COLOR = base_color.LIGHT_500_COLOR,
-
- SB__BUTTON_COLOR = base_color.LIGHT_100_COLOR,
- SB__BUTTON_HOVERED_COLOR = base_color.LIGHT_200_COLOR,
- SB__BUTTON_CLICKED_COLOR = base_color.LIGHT_300_COLOR,
-
-
- # Top bar
- TOP_BAR_BG_COLOR = base_color.LIGHT_150_COLOR,
-
- # Restart Button
- RESTART_BUTTON_BG_COLOR = base_color.PRIMARY_300_COLOR,
- RESTART_BUTTON_HOVERED_BG_COLOR = base_color.PRIMARY_250_COLOR,
- RESTART_BUTTON_CLICKED_BG_COLOR = base_color.PRIMARY_400_COLOR,
-
-
- # Compact Mode
- COMPACT_MODE_SWITCH_BOX_BG_COLOR = base_color.LIGHT_500_COLOR,
- COMPACT_MODE_SWITCH_BOX_ACTIVE_BG_COLOR = base_color.PRIMARY_300_COLOR,
- COMPACT_MODE_SWITCH_BOX_BUTTON_COLOR = base_color.LIGHT_300_COLOR,
- COMPACT_MODE_SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.LIGHT_250_COLOR,
-
- # Main
- MAIN_BG_COLOR = base_color.LIGHT_300_COLOR,
-
- # This is for fake border color
- SB__WRAPPER_BG_COLOR = base_color.LIGHT_400_COLOR,
-
- SB__BG_COLOR = base_color.LIGHT_100_COLOR,
-
- SB__OPTIONMENU_BG_COLOR = base_color.LIGHT_300_COLOR,
- SB__OPTIONMENU_HOVERED_BG_COLOR = base_color.LIGHT_250_COLOR,
- SB__OPTIONMENU_CLICKED_BG_COLOR = base_color.LIGHT_350_COLOR,
- SB__DROPDOWN_MENU_WINDOW_BG_COLOR = base_color.LIGHT_300_COLOR,
- SB__DROPDOWN_MENU_WINDOW_BORDER_COLOR = base_color.LIGHT_800_COLOR,
- SB__DROPDOWN_MENU_BG_COLOR = base_color.LIGHT_200_COLOR,
- SB__DROPDOWN_MENU_HOVERED_BG_COLOR = base_color.LIGHT_100_COLOR,
- SB__DROPDOWN_MENU_CLICKED_BG_COLOR = base_color.LIGHT_300_COLOR,
-
- SB__SLIDER_BG_COLOR = base_color.LIGHT_400_COLOR,
- SB__SLIDER_PROGRESS_BG_COLOR = base_color.LIGHT_550_COLOR,
- SB__SLIDER_BUTTON_COLOR = base_color.LIGHT_500_COLOR,
- SB__SLIDER_BUTTON_HOVERED_COLOR = base_color.LIGHT_600_COLOR,
- SB__SLIDER_TOOLTIP_BG_COLOR = base_color.LIGHT_200_COLOR,
- SB__SLIDER_TOOLTIP_TEXT_COLOR = base_color.LIGHT_800_COLOR,
-
- SB__SWITCH_BOX_BG_COLOR = base_color.LIGHT_400_COLOR,
- SB__SWITCH_BOX_BG_DISABLED_COLOR = base_color.LIGHT_200_COLOR,
- SB__SWITCH_BOX_ACTIVE_BG_COLOR = base_color.PRIMARY_300_COLOR,
- SB__SWITCH_BOX_ACTIVE_BG_DISABLED_COLOR = base_color.PRIMARY_150_COLOR,
- SB__SWITCH_BOX_BUTTON_COLOR = base_color.LIGHT_300_COLOR,
- SB__SWITCH_BOX_BUTTON_DISABLED_COLOR = base_color.LIGHT_150_COLOR,
- SB__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.LIGHT_200_COLOR,
-
- SB__CHECKBOX_BORDER_COLOR = base_color.LIGHT_600_COLOR,
- SB__CHECKBOX_BORDER_DISABLED_COLOR = base_color.LIGHT_300_COLOR,
- SB__CHECKBOX_HOVER_COLOR = base_color.LIGHT_350_COLOR,
- SB__CHECKBOX_CHECKED_COLOR = base_color.PRIMARY_250_COLOR,
- SB__CHECKBOX_CHECKMARK_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
-
- SB__RADIOBUTTON_TEXT_COLOR = base_color.LIGHT_900_COLOR,
- SB__RADIOBUTTON_BORDER_COLOR = base_color.LIGHT_600_COLOR,
- SB__RADIOBUTTON_SELECTED_COLOR = base_color.PRIMARY_400_COLOR,
- SB__RADIOBUTTON_BG_HOVERED_COLOR = base_color.LIGHT_300_COLOR,
- SB__RADIOBUTTON_BG_CLICKED_COLOR = base_color.LIGHT_325_COLOR,
-
- SB__ENTRY_TEXT_COLOR = base_color.LIGHT_900_COLOR,
- SB__ENTRY_BG_COLOR = base_color.LIGHT_300_COLOR,
- SB__ENTRY_BORDER_COLOR = base_color.LIGHT_400_COLOR,
-
-
- SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_BG_COLOR = base_color.LIGHT_350_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_PROGRESS_BG_COLOR = base_color.PRIMARY_500_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_PROGRESS_EXCEED_THRESHOLD_BG_COLOR = base_color.PRIMARY_300_COLOR,
-
- SB__PROGRESSBAR_X_SLIDER__SLIDER_BUTTON_COLOR = base_color.PRIMARY_300_COLOR,
- SB__PROGRESSBAR_X_SLIDER__SLIDER_BUTTON_HOVERED_COLOR = base_color.PRIMARY_450_COLOR,
-
- SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_COLOR = base_color.LIGHT_300_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_HOVERED_COLOR = base_color.LIGHT_250_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_CLICKED_COLOR = base_color.LIGHT_350_COLOR,
- SB__PROGRESSBAR_X_SLIDER__PASSIVE_BUTTON_DISABLED_COLOR = base_color.LIGHT_150_COLOR,
-
- SB__PROGRESSBAR_X_SLIDER__ACTIVE_BUTTON_COLOR = base_color.PRIMARY_250_COLOR,
- SB__PROGRESSBAR_X_SLIDER__ACTIVE_BUTTON_HOVERED_COLOR = base_color.PRIMARY_300_COLOR,
- SB__PROGRESSBAR_X_SLIDER__ACTIVE_BUTTON_CLICKED_COLOR = base_color.PRIMARY_400_COLOR,
-
- SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_COLOR = base_color.PRIMARY_250_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_HOVERED_COLOR = base_color.PRIMARY_300_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_CLICKED_COLOR = base_color.PRIMARY_400_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST_BG_COLOR = base_color.LIGHT_300_COLOR,
-
- SB__ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_HOVERED_BG_COLOR = base_color.LIGHT_375_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CLICKED_BG_COLOR = base_color.LIGHT_450_COLOR,
-
- SB__ADD_AND_DELETE_ABLE_LIST_DELETED_BG_COLOR = base_color.LIGHT_200_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__VALUES_DELETED_BUTTON_HOVERED_BG_COLOR = base_color.LIGHT_300_COLOR,
- SB__ADD_AND_DELETE_ABLE_LIST__VALUES_DELETED_BUTTON_CLICKED_BG_COLOR = base_color.LIGHT_400_COLOR,
-
-
- SB__MESSAGE_FORMAT__EXAMPLE_BG_COLOR = "#5a6b81", # from VRChat' chat display color
- # source #3a4554 (800). and this one is 600 (https://m2.material.io/design/color/the-color-system.html#tools-for-picking-colors)
- SB__MESSAGE_FORMAT__EXAMPLE_TEXT_COLOR = base_color.LIGHT_100_COLOR,
- SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR = base_color.LIGHT_200_COLOR,
- SB__MESSAGE_FORMAT__SWAP_BUTTON_HOVERED_COLOR = base_color.LIGHT_250_COLOR,
- SB__MESSAGE_FORMAT__SWAP_BUTTON_CLICKED_COLOR = base_color.LIGHT_300_COLOR,
-
-
-
-
- # Side menu
- SIDE_MENU_BG_COLOR = base_color.LIGHT_300_COLOR,
-
- SIDE_MENU_LABELS_BG_COLOR = base_color.LIGHT_300_COLOR,
- SIDE_MENU_LABELS_BG_FOR_FAKE_BORDER_COLOR = base_color.LIGHT_300_COLOR,
- SIDE_MENU_LABELS_HOVERED_BG_COLOR = base_color.LIGHT_350_COLOR,
- SIDE_MENU_LABELS_CLICKED_BG_COLOR = base_color.PRIMARY_200_COLOR,
- SIDE_MENU_LABELS_SELECTED_TEXT_COLOR = base_color.PRIMARY_350_COLOR,
-
- SIDE_MENU_SELECTED_MARK_ACTIVE_BG_COLOR = base_color.PRIMARY_350_COLOR,
-
- NOW_VERSION_TEXT_COLOR = base_color.LIGHT_800_COLOR,
-
- # Error Message Window for Config Window
- # Check DarkTheme's this part. Based on the color bb4448, used to source, and pick up the number 600 by the generator (https://m2.material.io/design/color/the-color-system.html#tools-for-picking-colors)
- SB__ERROR_MESSAGE_BG_COLOR = "#cd4c4f",
- SB__SUCCESS_MESSAGE_BG_COLOR = "#cd4c4f",
- SB__ERROR_MESSAGE_TEXT_COLOR = "#fff",
- ),
-
-
-
- image_file = SimpleNamespace(
- VRCT_LOGO = getImageFileFromUiUtils("vrct_logo_for_light_mode.png"),
- VRCT_LOGO_MARK = getImageFileFromUiUtils("vrct_logo_mark_black.png"),
-
- TRANSLATION_ICON = getImageFileFromUiUtils("translation_icon_black.png"),
- TRANSLATION_ICON_DISABLED = getImageFileFromUiUtils("translation_icon_disabled.png"),
- MIC_ICON = getImageFileFromUiUtils("mic_icon_black.png"),
- MIC_ICON_DISABLED = getImageFileFromUiUtils("mic_icon_disabled.png"),
- HEADPHONES_ICON = getImageFileFromUiUtils("headphones_icon_black.png"),
- HEADPHONES_ICON_DISABLED = getImageFileFromUiUtils("headphones_icon_disabled.png"),
- FOREGROUND_ICON = getImageFileFromUiUtils("foreground_icon_black.png"),
- FOREGROUND_ICON_DISABLED = getImageFileFromUiUtils("foreground_icon_disabled.png"),
-
- NARROW_ARROW_DOWN = getImageFileFromUiUtils("narrow_arrow_down_black.png"),
-
- CONFIGURATION_ICON = getImageFileFromUiUtils("configuration_icon_black.png"),
- CONFIGURATION_ICON_DISABLED = getImageFileFromUiUtils("configuration_icon_disabled.png"),
-
- ARROW_LEFT = getImageFileFromUiUtils("arrow_left_black.png"),
- ARROW_LEFT_DISABLED = getImageFileFromUiUtils("arrow_left_disabled.png"),
-
- SEND_MESSAGE_ICON = getImageFileFromUiUtils("send_message_icon_black.png"),
- SEND_MESSAGE_ICON_DISABLED = getImageFileFromUiUtils("send_message_icon_white.png"),
- REFRESH_UPDATE_ICON = getImageFileFromUiUtils("refresh_update_icon.png"),
- REFRESH_ICON = getImageFileFromUiUtils("refresh_icon.png"),
- HELP_ICON = getImageFileFromUiUtils("help_icon_black.png"),
-
- CANCEL_ICON = getImageFileFromUiUtils("cancel_icon.png"),
- REDO_ICON = getImageFileFromUiUtils("redo_icon_black.png"),
- SWAP_ICON = getImageFileFromUiUtils("swap_icon_black.png"),
- FOLDER_OPEN_ICON = getImageFileFromUiUtils("folder_open_icon_black.png"),
- LINK_ICON = getImageFileFromUiUtils("link_icon_black.png"),
- ),
- )
-
- return theme_settings
\ No newline at end of file
diff --git a/vrct_gui/ui_managers/UiScalingManager.py b/vrct_gui/ui_managers/UiScalingManager.py
deleted file mode 100644
index 3d4e2c30..00000000
--- a/vrct_gui/ui_managers/UiScalingManager.py
+++ /dev/null
@@ -1,399 +0,0 @@
-from types import SimpleNamespace
-
-from ..ui_utils import calculateUiSize
-
-class UiScalingManager():
- def __init__(self, scaling_percentage):
- scaling_float = int(scaling_percentage.replace("%", "")) / 100
- self.SCALING_FLOAT = max(scaling_float, 0.4)
-
- self.common = SimpleNamespace()
- self.main = SimpleNamespace()
- self.config_window = SimpleNamespace()
- self.selectable_language_window = SimpleNamespace()
- self.main_window_cover = SimpleNamespace()
- self.notification_message_window = SimpleNamespace()
- self.confirmation_modal = SimpleNamespace()
- self.dropdown_menu_window = SimpleNamespace()
-
- self._calculatedUiSizes()
-
-
-
-
- def _calculatedUiSizes(self):
- # Common
- # RESPONSIVE_UI_SIZE_INT_10 ... RESPONSIVE_UI_SIZE_INT_300
- self.common.SCROLLBAR_IPADX = (self._calculateUiSize(2), self._calculateUiSize(2))
- self.common.SCROLLBAR_WIDTH = self._calculateUiSize(16)
-
- for i in range(10, 501, 10):
- setattr(self.main, f"RESPONSIVE_UI_SIZE_INT_{i}", self._calculateUiSize(i))
- setattr(self.config_window, f"RESPONSIVE_UI_SIZE_INT_{i}", self._calculateUiSize(i))
-
-
- # Main
- self.main.MAIN_AREA_MIN_WIDTH = self._calculateUiSize(640)
- self.main.SIDEBAR_MIN_WIDTH = self._calculateUiSize(230)
-
- self.main.TEXTBOX_PADX = self._calculateUiSize(16)
- self.main.TEXTBOX_CORNER_RADIUS = self._calculateUiSize(6)
-
- self.main.TEXTBOX_TAB_CORNER_RADIUS = self._calculateUiSize(8)
- self.main.TEXTBOX_TAB_FONT_SIZE = self._calculateUiSize(12)
- self.main.TEXTBOX_TAB_PADX = self._calculateUiSize(10)
- self.main.TEXTBOX_TAB_PADY = (self._calculateUiSize(4), self._calculateUiSize(10))
-
- self.main.TEXTBOX_FIRST_INSERT_SPACING = self._calculateUiSize(16)
- self.main.TEXTBOX_FONT_SIZE__LABEL = self._calculateUiSize(12)
- self.main.TEXTBOX_FONT_SIZE__TIMESTAMP = self._calculateUiSize(12)
- self.main.TEXTBOX_FONT_SIZE__SYSTEM_TEXT_FONT = self._calculateUiSize(12)
- self.main.TEXTBOX_FONT_SIZE__SECONDARY_TEXT_FONT = self._calculateUiSize(12)
- self.main.TEXTBOX_FONT_SIZE__MAIN_TEXT_FONT = self._calculateUiSize(16)
-
- self.main.TEXTBOX_ENTRY_FONT_SIZE = self._calculateUiSize(16)
- self.main.TEXTBOX_ENTRY_CORNER_RADIUS = self._calculateUiSize(4)
- self.main.TEXTBOX_ENTRY_BORDER_SIZE = self._calculateUiSize(2, is_allowed_odd=True)
- self.main.TEXTBOX_ENTRY_HEIGHT = self._calculateUiSize(40)
- self.main.TEXTBOX_ENTRY_PADX = self.main.TEXTBOX_PADX
- self.main.TEXTBOX_ENTRY_PADY = self._calculateUiSize(10)
-
- self.main.SEND_MESSAGE_BUTTON_CORNER_RADIUS = self.main.TEXTBOX_ENTRY_CORNER_RADIUS
- self.main.SEND_MESSAGE_BUTTON_IMAGE_SIZE = self._calculateUiSize(20)
- self.main.SEND_MESSAGE_BUTTON_MIN_WIDTH = self._calculateUiSize(40)
- self.main.SEND_MESSAGE_BUTTON_RATE_WIDTH = self._calculateUiSize(6)
- self.main.SEND_MESSAGE_BUTTON_MAX_WIDTH = self._calculateUiSize(100)
-
-
- # Sidebar
- # Sidebar Features
- self.main.SF__LOGO_MAX_SIZE = self._calculateUiSize(120)
- self.main.SF__LOGO_PADY = (self._calculateUiSize(10),self._calculateUiSize(6))
- self.main.SF__LOGO_HEIGHT_FOR_ADJUSTMENT = (self._calculateUiSize(6))
-
- self.main.SF__LABELS_IPADY = self._calculateUiSize(16)
- self.main.SF__COMPACT_MODE_ICON_PADY = self.main.SF__LABELS_IPADY
- self.main.SF__COMPACT_MODE_ICON_PADX = self.main.SF__COMPACT_MODE_ICON_PADY
- self.main.SF__LABEL_LEFT_PAD = self._calculateUiSize(20)
- self.main.SF__LABEL_FONT_SIZE = self._calculateUiSize(16)
- self.main.SF__COMPACT_MODE_IMAGE_SIZE = (self._calculateUiSize(20), self._calculateUiSize(20))
-
- self.main.SF__SWITCH_BOX_PADX = (self.main.SF__LABEL_LEFT_PAD, self._calculateUiSize(10))
- self.main.SF__SWITCH_BOX_WIDTH = self._calculateUiSize(40)
- self.main.SF__SWITCH_BOX_HEIGHT = self._calculateUiSize(16)
-
- self.main.SF__SELECTED_MARK_WIDTH = self._calculateUiSize(3, True)
-
-
- # Sidebar Quick Language Settings, SQLS
- self.main.SLS__TITLE_FONT_SIZE = self._calculateUiSize(14)
- self.main.SLS__TITLE_PADY = (self._calculateUiSize(10), self._calculateUiSize(4))
-
- self.main.SLS__PRESET_TAB_NUMBER_FONT_SIZE = self._calculateUiSize(16)
- self.main.SLS__PRESET_TAB_NUMBER_HEIGHT = self._calculateUiSize(30)
- self.main.SLS__PRESET_TAB_NUMBER_CORNER_RADIUS = self._calculateUiSize(6)
- self.main.SLS__PRESET_TAB_NUMBER_ADJUSTED_HEIGHT = self._calculateUiSize(36)
-
- self.main.SLS__BOX_TOP_PADY = self._calculateUiSize(12)
-
- self.main.SLS__BOX_TRANSCRIPTION_STATUS_IMAGE_SIZE = self.dupTuple(self._calculateUiSize(14))
-
- self.main.SLS__BOX_SECTION_TITLE_FONT_SIZE = self._calculateUiSize(16)
- self.main.SLS__BOX_SECTION_TITLE_BOTTOM_PADY = self._calculateUiSize(10)
- self.main.SLS__BOX_IPADX = self._calculateUiSize(10)
- self.main.SLS__BOX_IPADY = (self._calculateUiSize(8),self._calculateUiSize(14))
- self.main.SLS__BOX_OPTION_MENU_FONT_SIZE = self._calculateUiSize(14)
- self.main.SLS__BOX_OPTION_MENU_IPADY = self._calculateUiSize(2)
- self.main.SLS__BOX_OPTION_MENU_ARROW_IMAGE_SIZE = self.dupTuple(self._calculateUiSize(20))
- # self.main.SLS__BOX_OPTION_MENU_WIDTH = self._calculateUiSize(200)
- self.main.SLS__BOX_ARROWS_PADY = self._calculateUiSize(6)
- self.main.SLS__BOX_ARROWS_SWAP_BUTTON_CORNER_RADIUS = self._calculateUiSize(6)
- self.main.SLS__BOX_ARROWS_SWAP_BUTTON_PADX = self._calculateUiSize(20)
- self.main.SLS__BOX_ARROWS_SWAP_BUTTON_IPADX = self._calculateUiSize(8)
- self.main.SLS__BOX_ARROWS_SWAP_BUTTON_IPADY = self._calculateUiSize(4)
- self.main.SLS__BOX_ARROWS_IMAGE_SIZE = self.dupTuple(self._calculateUiSize(16))
- self.main.SLS__BOX_ARROWS_DESC_FONT_SIZE = self._calculateUiSize(12)
- self.main.SLS__BOX_ARROWS_DESC_PADX = self._calculateUiSize(6)
-
- self.main.SIDEBAR_CONFIG_BUTTON_CORNER_RADIUS = self._calculateUiSize(6)
- self.main.SIDEBAR_CONFIG_BUTTON_IMAGE_SIZE = self.main.SF__COMPACT_MODE_IMAGE_SIZE
- self.main.SIDEBAR_CONFIG_BUTTON_PADX = self._calculateUiSize(10)
- self.main.SIDEBAR_CONFIG_BUTTON_PADY = self._calculateUiSize(10)
- self.main.SIDEBAR_CONFIG_BUTTON_IPADY = self._calculateUiSize(8)
-
- self.main.TOP_BAR_BUTTON_PADY = (self._calculateUiSize(6),0)
-
-
-
-
- self.main.QUICK_SETTINGS_BUTTON_FONT_SIZE = self._calculateUiSize(12)
- self.main.QUICK_SETTINGS_BUTTON_STATE_FONT_SIZE = self._calculateUiSize(10)
-
-
- self.main.UPDATE_AVAILABLE_BUTTON_CORNER_RADIUS = self._calculateUiSize(6)
- self.main.UPDATE_AVAILABLE_BUTTON_SIZE = (self._calculateUiSize(18), self._calculateUiSize(18))
- self.main.UPDATE_AVAILABLE_BUTTON_FONT_SIZE = self._calculateUiSize(12)
- self.main.UPDATE_AVAILABLE_BUTTON_PADX = (0, self._calculateUiSize(4))
- self.main.UPDATE_AVAILABLE_BUTTON_IPADX = self._calculateUiSize(6)
- self.main.UPDATE_AVAILABLE_ICON_PADX = (self._calculateUiSize(6), self._calculateUiSize(4))
- self.main.UPDATE_AVAILABLE_PADX_BETWEEN_LABEL_AND_ICON = self._calculateUiSize(4)
-
-
-
- self.main.HELP_AND_INFO_BUTTON_CORNER_RADIUS = self._calculateUiSize(6)
- self.main.HELP_AND_INFO_BUTTON_SIZE = self._calculateUiSize(24)
- self.main.HELP_AND_INFO_BUTTON_PADX = (0, self._calculateUiSize(6))
- self.main.HELP_AND_INFO_BUTTON_IPADXY = self._calculateUiSize(6)
-
- self.main.MINIMIZE_SIDEBAR_BUTTON_ICON_SIZE_X = int(self.main.TEXTBOX_PADX/2+self.main.TEXTBOX_CORNER_RADIUS*2)
- self.main.MINIMIZE_SIDEBAR_BUTTON_ICON_SIZE_Y = self._calculateUiSize(26)
-
-
- self.main.SLS__SELECTABLE_TRANSLATION_IPADX = self.dupTuple(self._calculateUiSize(10))
- self.main.SLS__SELECTABLE_TRANSLATION_IPADY = self._calculateUiSize(6)
- self.main.SLS__SELECTABLE_TRANSLATION_FONT_SIZE = self._calculateUiSize(12)
- self.main.SLS__SELECTABLE_TRANSLATION_IMAGE_SIZE = self.dupTuple(self._calculateUiSize(10))
- self.main.SLS__SELECTABLE_TRANSLATION_PADY = self._calculateUiSize(4)
- self.main.SLS__SELECTABLE_TRANSLATION_MIN_PADX = self._calculateUiSize(8)
-
-
- self.main.SLS__DROPDOWN_MENU_WINDOW_ADDITIONAL_Y_POS = self._calculateUiSize(4)
- self.main.SLS__DROPDOWN_MENU_WINDOW_BORDER_WIDTH = self._calculateUiSize(0, is_allowed_odd=True)
- self.main.SLS__DROPDOWN_MENU_SCROLLBAR_IPADX = self.common.SCROLLBAR_IPADX
- self.main.SLS__DROPDOWN_MENU_SCROLLBAR_WIDTH = self.common.SCROLLBAR_WIDTH
- self.main.SLS__DROPDOWN_MENU_VALUE_IPADX = (self._calculateUiSize(8), 0)
- self.main.SLS__DROPDOWN_MENU_VALUE_IPADY = self.dupTuple(self._calculateUiSize(8))
- self.main.SLS__DROPDOWN_MENU_VALUE_PADY = 0
- self.main.SLS__DROPDOWN_MENU_VALUE_FONT_SIZE = self._calculateUiSize(14)
- self.main.SLS__DROPDOWN_MENU_VALUE_DEFAULT_MIN_WIDTH = self._calculateUiSize(200)
-
-
- # Selectable Language Window
- self.selectable_language_window.TOP_BAR_MIN_HEIGHT = self._calculateUiSize(50)
- self.selectable_language_window.SCROLLBAR_IPADX = self.common.SCROLLBAR_IPADX
- self.selectable_language_window.SCROLLBAR_WIDTH = self.common.SCROLLBAR_WIDTH
-
- self.selectable_language_window.GO_BACK_BUTTON_LABEL_FONT_SIZE = self._calculateUiSize(14)
- self.selectable_language_window.GO_BACK_BUTTON_IPADX = self._calculateUiSize(10)
- self.selectable_language_window.GO_BACK_BUTTON_IPADY = self._calculateUiSize(8)
- self.selectable_language_window.TITLE_FONT_SIZE = self._calculateUiSize(18)
-
- self.selectable_language_window.VALUES_TEXT_FONT_SIZE = self._calculateUiSize(14)
- self.selectable_language_window.VALUES_TEXT_IPADX = (self._calculateUiSize(8), 0)
- self.selectable_language_window.VALUES_TEXT_IPADY = self._calculateUiSize(8)
-
-
- self.main_window_cover.TEXT_FONT_SIZE = self._calculateUiSize(20)
-
-
- self.confirmation_modal.FAKE_BORDER_SIZE = self._calculateUiSize(1, is_allowed_odd=True)
- self.confirmation_modal.CONTENTS_WRAPPER = self._calculateUiSize(20)
- self.confirmation_modal.MARGIN_BETWEEN_MESSAGE_AND_BUTTONS = self._calculateUiSize(40)
- self.confirmation_modal.MESSAGE_FONT_SIZE = self._calculateUiSize(20)
- self.confirmation_modal.CONFIRMATION_BUTTONS_TEXT_FONT_SIZE = self._calculateUiSize(18)
- self.confirmation_modal.BUTTONS_BETWEEN_PADDING = self._calculateUiSize(100)
- self.confirmation_modal.BUTTONS_CORNER_RADIUS = self._calculateUiSize(6)
- self.confirmation_modal.BUTTONS_IPADX = self._calculateUiSize(10)
- self.confirmation_modal.BUTTONS_IPADY = self._calculateUiSize(6)
-
- # Dropdown Menu Window
- self.dropdown_menu_window.MARGIN_WIDTH = self._calculateUiSize(16)
-
-
-
- # Quick Settings Box
- self.config_window.QSB__MIN_WIDTH = self._calculateUiSize(400)
- self.config_window.QSB__BOX_PADY = (0, self._calculateUiSize(18))
- self.config_window.QSB__IPADX = self._calculateUiSize(20)
- self.config_window.QSB__IPADY = (self._calculateUiSize(14), self._calculateUiSize(8))
- self.config_window.QSB__LABEL_BOTTOM_PADY = self._calculateUiSize(6)
- self.config_window.QSB__RESTORE_DEFAULT_SETTINGS_BUTTON_PADY = (self._calculateUiSize(40),0)
-
-
-
- # Config Window
- self.config_window.DEFAULT_WIDTH = self._calculateUiSize(1080)
- self.config_window.DEFAULT_HEIGHT = self._calculateUiSize(680)
-
- # Top bar common
- self.config_window.TOP_BAR__MIN_HEIGHT = self._calculateUiSize(40)
- self.config_window.TOP_BAR__IPADY = self._calculateUiSize(12)
-
- # Top bar Side
- self.config_window.TOP_BAR_SIDE_AREA_MIN_WIDTH = self._calculateUiSize(220)
- self.config_window.TOP_BAR_SIDE__CONFIG_LOGO_MARK_SIZE = self.dupTuple(self._calculateUiSize(28))
- self.config_window.TOP_BAR_SIDE__CONFIG_TITLE_FONT_SIZE = self._calculateUiSize(22)
- self.config_window.TOP_BAR_SIDE__CONFIG_TITLE_LEFT_PADX = int(self.config_window.TOP_BAR_SIDE__CONFIG_TITLE_FONT_SIZE + self._calculateUiSize(16))
- self.config_window.TOP_BAR_SIDE__TITLE_PADX= self._calculateUiSize(30)
-
- # Restart Button
- self.config_window.RESTART_BUTTON_LABEL_FONT_SIZE = self._calculateUiSize(12)
- self.config_window.RESTART_BUTTON_PADX = (0, self._calculateUiSize(20))
- self.config_window.RESTART_BUTTON_CORNER_RADIUS = self._calculateUiSize(20)
- self.config_window.RESTART_BUTTON_IPADX = self._calculateUiSize(20)
- self.config_window.RESTART_BUTTON_IPADY = self._calculateUiSize(10)
-
- # Compact Mode
- self.config_window.COMPACT_MODE_PADX = (0, self._calculateUiSize(20))
- self.config_window.COMPACT_MODE_LABEL_FONT_SIZE = self._calculateUiSize(12)
- self.config_window.COMPACT_MODE_LABEL_PADX = (0, self._calculateUiSize(10))
- self.config_window.COMPACT_MODE_SWITCH_WIDTH = self._calculateUiSize(40)
- self.config_window.COMPACT_MODE_SWITCH_HEIGHT = self._calculateUiSize(16)
-
-
- # Side menu
- self.config_window.SIDE_MENU_PADY = (self._calculateUiSize(54), self._calculateUiSize(72))
- self.config_window.SIDE_MENU_LABELS_SEPARATE_MIN_HEIGHT = self._calculateUiSize(40)
- self.config_window.SIDE_MENU_LABELS_IPADX = self._calculateUiSize(20)
- self.config_window.SIDE_MENU_LABELS_IPADY = self._calculateUiSize(8)
- self.config_window.SIDE_MENU_LABELS_FONT_SIZE = self._calculateUiSize(18)
-
- self.config_window.NOW_VERSION_FONT_SIZE = self._calculateUiSize(12)
-
- # Top bar Main
- self.config_window.TOP_BAR_MAIN__TITLE_FONT_SIZE = self._calculateUiSize(22)
- self.config_window.SCROLLBAR_IPADX = self.common.SCROLLBAR_IPADX
- self.config_window.SCROLLBAR_WIDTH = self.common.SCROLLBAR_WIDTH
-
-
- # Setting Box
- self.config_window.MAIN_AREA_MIN_WIDTH = self._calculateUiSize(720)
-
- self.config_window.ABOUT_VRCT_SB__TOP_PADY = self._calculateUiSize(42) # Exception
- self.config_window.SB__TOP_PADY = self._calculateUiSize(60)
-
- self.config_window.SB__IPADX = self._calculateUiSize(20)
- self.config_window.SB__IPADY = self._calculateUiSize(12)
- self.config_window.SB__BOTTOM_MARGIN = (0, self._calculateUiSize(120))
- self.config_window.SB__FAKE_BOTTOM_BORDER_SIZE = (0, self._calculateUiSize(1, is_allowed_odd=True))
-
- self.config_window.SB__SECTION_TITLE_FONT_SIZE = self._calculateUiSize(20)
- self.config_window.SB__SECTION_TITLE_BOTTOM_PADY = (0, self._calculateUiSize(10))
-
- self.config_window.SB__LABEL_FONT_SIZE = self._calculateUiSize(16)
- self.config_window.SB__DESC_FONT_SIZE = self._calculateUiSize(14)
- self.config_window.SB__DESC_TOP_PADY = self._calculateUiSize(2)
-
-
- self.config_window.BUTTONS_CORNER_RADIUS = self._calculateUiSize(6)
- # self.config_window.BUTTONS_IPADX = self._calculateUiSize(10)
- # self.config_window.BUTTONS_IPADY = self._calculateUiSize(6)
-
- self.config_window.SB__ERROR_MESSAGE_IPADX = (self._calculateUiSize(10), self._calculateUiSize(10))
- self.config_window.SB__ERROR_MESSAGE_IPADY = (self._calculateUiSize(6), self._calculateUiSize(6))
- self.config_window.SB__ERROR_MESSAGE_FONT_SIZE = self._calculateUiSize(14)
-
-
- self.config_window.SB__SELECTOR_FONT_SIZE = self._calculateUiSize(14)
- self.config_window.SB__RADIO_BUTTON_FONT_SIZE = self.config_window.SB__SELECTOR_FONT_SIZE
- self.config_window.SB__BUTTON_FONT_SIZE = self.config_window.SB__SELECTOR_FONT_SIZE
-
-
-
- self.config_window.SB__OPTION_MENU_FONT_SIZE = self.config_window.SB__SELECTOR_FONT_SIZE
- self.config_window.SB__OPTIONMENU_MIN_HEIGHT = self._calculateUiSize(30)
- self.config_window.SB__OPTIONMENU_MIN_WIDTH = self._calculateUiSize(200)
- self.config_window.SB__OPTIONMENU_IPADX = (self._calculateUiSize(8), self._calculateUiSize(8))
- self.config_window.SB__OPTIONMENU_IPADY = self._calculateUiSize(2)
- self.config_window.SB__OPTIONMENU_IPADX_BETWEEN_IMG = self._calculateUiSize(8)
- self.config_window.SB__OPTIONMENU_IMG_SIZE = (self._calculateUiSize(14), self._calculateUiSize(14))
-
- self.config_window.SB__DROPDOWN_MENU_WINDOW_ADDITIONAL_Y_POS = self._calculateUiSize(4)
- self.config_window.SB__DROPDOWN_MENU_WINDOW_BORDER_WIDTH = self._calculateUiSize(1, is_allowed_odd=True)
- self.config_window.SB__DROPDOWN_MENU_SCROLLBAR_IPADX = self.common.SCROLLBAR_IPADX
- self.config_window.SB__DROPDOWN_MENU_SCROLLBAR_WIDTH = self.common.SCROLLBAR_WIDTH
- self.config_window.SB__DROPDOWN_MENU_VALUE_IPADX = (self._calculateUiSize(8), 0)
- self.config_window.SB__DROPDOWN_MENU_VALUE_IPADY = (self._calculateUiSize(6), self._calculateUiSize(6))
- self.config_window.SB__DROPDOWN_MENU_VALUE_PADY = (0, self._calculateUiSize(1, is_allowed_odd=True))
- self.config_window.SB__DROPDOWN_MENU_VALUE_FONT_SIZE = self._calculateUiSize(14)
- self.config_window.SB__DROPDOWN_MENU_VALUE_DEFAULT_MIN_WIDTH = self._calculateUiSize(200)
-
-
- self.config_window.SB__SWITCH_WIDTH = self._calculateUiSize(50)
-
- self.config_window.SB__SWITCH_BOX_WIDTH = self._calculateUiSize(40)
- self.config_window.SB__SWITCH_BOX_HEIGHT = self._calculateUiSize(16)
-
- self.config_window.SB__CHECKBOX_SIZE = self._calculateUiSize(24)
- self.config_window.SB__CHECKBOX_BORDER_WIDTH = self._calculateUiSize(2)
- self.config_window.SB__CHECKBOX_CORNER_RADIUS = self._calculateUiSize(4)
-
- self.config_window.SB__ENTRY_FONT_SIZE = self.config_window.SB__SELECTOR_FONT_SIZE
- self.config_window.SB__ENTRY_HEIGHT = self._calculateUiSize(30)
-
- self.config_window.SB__SLIDER_WIDTH = self._calculateUiSize(200)
- self.config_window.SB__SLIDER_HEIGHT = self._calculateUiSize(16)
- self.config_window.SB__SLIDER_TOOLTIP_FONT_SIZE = self._calculateUiSize(16)
-
- self.config_window.SB__PROGRESSBAR_X_SLIDER__ENTRY_WIDTH = self.config_window.RESPONSIVE_UI_SIZE_INT_50
- self.config_window.SB__PROGRESSBAR_X_SLIDER__ENTRY_HEIGHT = self.config_window.SB__ENTRY_HEIGHT
- self.config_window.SB__PROGRESSBAR_X_SLIDER__SLIDER_HEIGHT = self._calculateUiSize(40)
- self.config_window.SB__PROGRESSBAR_X_SLIDER__PROGRESSBAR_HEIGHT = self._calculateUiSize(8)
- self.config_window.SB__PROGRESSBAR_X_SLIDER__SLIDER_BUTTON_LENGTH = self._calculateUiSize(2)
- self.config_window.SB__PROGRESSBAR_X_SLIDER__BAR_PADX = (self._calculateUiSize(30), self._calculateUiSize(30))
-
- self.config_window.SB__PROGRESSBAR_X_SLIDER__BUTTON_IPADXY = self._calculateUiSize(10)
- self.config_window.SB__PROGRESSBAR_X_SLIDER__BUTTON_ICON_SIZE = self._calculateUiSize(20)
-
- self.config_window.SB__ARROW_SWITCH_DESC_FONT_SIZE = self._calculateUiSize(16)
- self.config_window.SB__ARROW_SWITCH_LEFT_PADX = (self._calculateUiSize(20), 0)
-
- self.config_window.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_IPADX = self._calculateUiSize(16)
- self.config_window.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_IPADY = self._calculateUiSize(6)
-
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_CORNER_RADIUS = self._calculateUiSize(2)
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_LEFT_PADX = (0, self._calculateUiSize(4))
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_BOTTOM_PADY = (0, self._calculateUiSize(4))
-
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_FONT_SIZE = self._calculateUiSize(14)
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADX = (self._calculateUiSize(8), 0)
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADY = self._calculateUiSize(6)
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IMG_SIZE = self._calculateUiSize(14)
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CORNER_RADIUS = self._calculateUiSize(4)
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IPADXY = self._calculateUiSize(6)
- self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_PADX = (self._calculateUiSize(6), self._calculateUiSize(8))
-
- self.config_window.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_LEFT_PADX = (self._calculateUiSize(20), 0)
- self.config_window.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_FONT_SIZE = self._calculateUiSize(14)
-
-
- self.config_window.SB__MESSAGE_FORMAT__EXAMPLE_CORNER_RADIUS = self._calculateUiSize(16)
- self.config_window.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY = self._calculateUiSize(10)
- self.config_window.SB__MESSAGE_FORMAT__EXAMPLE_WRAP_LENGTH = self._calculateUiSize(300)
-
- self.config_window.SB__MESSAGE_FORMAT__ENTRY_HEIGHT = self.config_window.SB__ENTRY_HEIGHT
- self.config_window.SB__MESSAGE_FORMAT__REQUIRED_TEXT_PADX = self._calculateUiSize(10)
- self.config_window.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE = self._calculateUiSize(16)
-
- self.config_window.SB__MESSAGE_FORMAT__SWAP_BUTTON_ARROWS_IMG_SIZE = self.dupTuple(self._calculateUiSize(20))
- self.config_window.SB__MESSAGE_FORMAT__SWAP_BUTTON_IPADX = self._calculateUiSize(16)
- self.config_window.SB__MESSAGE_FORMAT__SWAP_BUTTON_IPADY = self._calculateUiSize(6)
- self.config_window.SB__MESSAGE_FORMAT__SWAP_BUTTON_FONT_SIZE = self._calculateUiSize(14)
- self.config_window.SB__MESSAGE_FORMAT__SWAP_TEXT_PADX = self._calculateUiSize(10)
-
- self.config_window.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY = (0, self._calculateUiSize(14))
-
- self.config_window.SB__AUTHKEY_WEBPAGE_BUTTON_IPADX = self._calculateUiSize(12)
- self.config_window.SB__AUTHKEY_WEBPAGE_BUTTON_IPADY = self._calculateUiSize(6)
- self.config_window.SB__AUTHKEY_WEBPAGE_BUTTON_LABEL_FONT_SIZE = self._calculateUiSize(12)
- self.config_window.SB__AUTHKEY_WEBPAGE_BUTTON_IMG_SIZE = self.dupTuple(self._calculateUiSize(12))
- self.config_window.SB__AUTHKEY_WEBPAGE_PADX_BETWEEN_LABEL_AND_ICON = self._calculateUiSize(10)
- self.config_window.SB__AUTHKEY_WEBPAGE_BUTTON_TOP_PADY = self._calculateUiSize(10)
-
- self.config_window.SB__OPEN_OVERLAY_SETTINGS_WINDOW = self._calculateUiSize(28)
-
-
- self.config_window.SB__BUTTON_IPADXY = self._calculateUiSize(16)
- self.config_window.SB__BUTTON_ICON_SIZE = self._calculateUiSize(24)
- self.config_window.SB__BUTTON_CORNER_RADIUS = self.config_window.BUTTONS_CORNER_RADIUS
-
- self.config_window.SB__OPEN_CONFIG_FILE_BUTTON_IPADXY = self._calculateUiSize(10)
-
-
- def _calculateUiSize(self, default_size, is_allowed_odd:bool=False, is_zero_allowed:bool=False):
- size = calculateUiSize(default_size, self.SCALING_FLOAT, is_allowed_odd, is_zero_allowed)
- return size
-
- @staticmethod
- def dupTuple(value):
- return (value, value)
\ No newline at end of file
diff --git a/vrct_gui/ui_managers/__init__.py b/vrct_gui/ui_managers/__init__.py
deleted file mode 100644
index 06adde02..00000000
--- a/vrct_gui/ui_managers/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from .ColorThemeManager import ColorThemeManager
-from .UiScalingManager import UiScalingManager
-
-from .AboutVrctManager import AboutVrctManager
\ No newline at end of file
diff --git a/vrct_gui/ui_utils/CustomizedCTkScrollableFrame.py b/vrct_gui/ui_utils/CustomizedCTkScrollableFrame.py
deleted file mode 100644
index 16b5460f..00000000
--- a/vrct_gui/ui_utils/CustomizedCTkScrollableFrame.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Override customtkinter's CTkScrollableFrame for scrolling speed up
-from customtkinter import CTkScrollableFrame, CTkFont
-from typing import Union, Tuple, Optional
-import sys
-try:
- from typing import Literal
-except ImportError:
- from typing_extensions import Literal
-
-class CustomizedCTkScrollableFrame(CTkScrollableFrame):
- def __init__(
- self,
- master: any,
- width: int = 200,
- height: int = 200,
- corner_radius: Optional[Union[int, str]] = None,
- border_width: Optional[Union[int, str]] = None,
-
- bg_color: Union[str, Tuple[str, str]] = "transparent",
- fg_color: Optional[Union[str, Tuple[str, str]]] = None,
- border_color: Optional[Union[str, Tuple[str, str]]] = None,
- scrollbar_fg_color: Optional[Union[str, Tuple[str, str]]] = None,
- scrollbar_button_color: Optional[Union[str, Tuple[str, str]]] = None,
- scrollbar_button_hover_color: Optional[Union[str, Tuple[str, str]]] = None,
- label_fg_color: Optional[Union[str, Tuple[str, str]]] = None,
- label_text_color: Optional[Union[str, Tuple[str, str]]] = None,
-
- label_text: str = "",
- label_font: Optional[Union[tuple, CTkFont]] = None,
- label_anchor: str = "center",
- orientation: Literal["vertical", "horizontal"] = "vertical"
- ):
-
- super().__init__(
- master,
- width,
- height,
- corner_radius,
- border_width,
-
- bg_color,
- fg_color,
- border_color,
- scrollbar_fg_color,
- scrollbar_button_color,
- scrollbar_button_hover_color,
- label_fg_color,
- label_text_color,
-
- label_text,
- label_font,
- label_anchor,
- orientation,
- )
-
- def _mouse_wheel_all(self, event):
- if self.check_if_master_is_canvas(event.widget):
- if sys.platform.startswith("win"):
- if self._shift_pressed:
- if self._parent_canvas.xview() != (0.0, 1.0):
- self._parent_canvas.xview("scroll", -int(event.delta / 6), "units")
- else:
- if self._parent_canvas.yview() != (0.0, 1.0):
- self._parent_canvas.yview("scroll", -int(event.delta / 2), "units")
-
- elif sys.platform == "darwin":
- if self._shift_pressed:
- if self._parent_canvas.xview() != (0.0, 1.0):
- self._parent_canvas.xview("scroll", -event.delta, "units")
- else:
- if self._parent_canvas.yview() != (0.0, 1.0):
- self._parent_canvas.yview("scroll", -event.delta, "units")
- else:
- if self._shift_pressed:
- if self._parent_canvas.xview() != (0.0, 1.0):
- self._parent_canvas.xview("scroll", -event.delta, "units")
- else:
- if self._parent_canvas.yview() != (0.0, 1.0):
- self._parent_canvas.yview("scroll", -event.delta, "units")
\ No newline at end of file
diff --git a/vrct_gui/ui_utils/__init__.py b/vrct_gui/ui_utils/__init__.py
deleted file mode 100644
index 49ee911d..00000000
--- a/vrct_gui/ui_utils/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from .ui_utils import *
-from .CustomizedCTkScrollableFrame import CustomizedCTkScrollableFrame
\ No newline at end of file
diff --git a/vrct_gui/ui_utils/ui_utils.py b/vrct_gui/ui_utils/ui_utils.py
deleted file mode 100644
index 7af40855..00000000
--- a/vrct_gui/ui_utils/ui_utils.py
+++ /dev/null
@@ -1,426 +0,0 @@
-from os import path as os_path
-from PIL.Image import open as Image_open, LANCZOS
-from time import sleep, time
-import math
-
-from customtkinter import CTkFrame, CTkLabel, CTkImage, CTkFont
-
-def getImagePath(file_name):
- # root\img\file_name
- return os_path.join(os_path.dirname(os_path.dirname(os_path.dirname(__file__))), "img", file_name)
-
-def getImageFileFromUiUtils(file_name):
- # root\img\file_name
- return Image_open(os_path.join(os_path.dirname(os_path.dirname(os_path.dirname(__file__))), "img", file_name))
-
-def getImageFileFromUiUtils_AboutVrct(file_name, directly_type:str=None):
- # root\img\about_vrct\file_name or directly_name...
- directly_path = ["img", "about_vrct"]
- if directly_type == "showcased_worlds":
- directly_path.append("showcased_worlds")
- elif directly_type == "vrct_posters":
- directly_path.append("vrct_posters")
-
- return Image_open(os_path.join(os_path.dirname(os_path.dirname(os_path.dirname(__file__))), *directly_path, file_name))
-
-def openImageKeepAspectRatio(image_file, desired_width):
- wpercent = (desired_width/float(image_file.size[0]))
- hsize = int((float(image_file.size[1])*float(wpercent)))
- img = image_file.resize((desired_width,hsize), LANCZOS)
- return (img, desired_width, hsize)
-
-def retag(tag, *args):
- for widget in args:
- widget.bindtags((tag,) + widget.bindtags())
-
-
-def getLatestWidth(target_widget):
- target_widget.update_idletasks()
- return target_widget.winfo_width()
-
-def getLatestHeight(target_widget):
- target_widget.update_idletasks()
- return target_widget.winfo_height()
-
-def getLongestText(text_list:list):
- max_length = 0
- longest_text = ""
-
- for text in text_list:
- if len(text) > max_length:
- max_length = len(text)
- longest_text = text
- return longest_text
-
-def getLongestText_Dict(text_dict:dict):
- max_length = 0
- longest_text = ""
-
- for key, text in text_dict.items():
- if len(text) > max_length:
- max_length = len(text)
- longest_text = text
-
- return longest_text
-
-def calculateUiSize(default_size, scaling_float, is_allowed_odd:bool=False, is_zero_allowed:bool=False):
- size = int(default_size * scaling_float)
- size += 1 if not is_allowed_odd and size % 2 != 0 else 0
- if size <= 0:
- size = 0 if is_zero_allowed else 1
-
- return size
-
-# This making gradient color process was made by ChatGPT.
-def generateGradientColor(value, color_start, color_end):
- # 補完色を計算
- interpolated_color = [
- int(start + (end - start) * value) for start, end in zip(color_start, color_end)
- ]
-
- # RGB値を0から255の範囲にクリップ
- interpolated_color = [max(0, min(255, val)) for val in interpolated_color]
-
- # RGBを16進数に変換
- hex_color = "#{:02x}{:02x}{:02x}".format(*interpolated_color)
-
- return hex_color
-
-
-def bindEnterAndLeaveColor(target_widgets, enter_color, leave_color):
- for target_widget in target_widgets:
- target_widget.bind("", lambda e, widgets=target_widgets: [w.configure(fg_color=enter_color) for w in widgets], "+")
- target_widget.bind("", lambda e, widgets=target_widgets: [w.configure(fg_color=leave_color) for w in widgets], "+")
-
-
-def bindButtonPressColor(target_widgets, clicked_color, released_color):
- for target_widget in target_widgets:
- target_widget.bind("", lambda e, widgets=target_widgets: [w.configure(fg_color=clicked_color) for w in widgets], "+")
- target_widget.bind("", lambda e, widgets=target_widgets: [w.configure(fg_color=released_color) for w in widgets], "+")
-
-def bindEnterAndLeaveFunction(target_widgets, enterFunction, leaveFunction):
- for target_widget in target_widgets:
- target_widget.bind("", enterFunction, "+")
- target_widget.bind("", leaveFunction, "+")
-
-def bindButtonPressFunction(target_widgets, buttonPressedFunction):
- for target_widget in target_widgets:
- target_widget.bind("", buttonPressedFunction, "+")
-
-def bindButtonReleaseFunction(target_widgets, buttonReleasedFunction):
- for target_widget in target_widgets:
- target_widget.bind("", buttonReleasedFunction, "+")
-
-def bindButtonPressAndReleaseFunction(target_widgets, buttonPressedFunction, buttonReleasedFunction):
- for target_widget in target_widgets:
- target_widget.bind("", buttonPressedFunction, "+")
- target_widget.bind("", buttonReleasedFunction, "+")
-
-
-def bindButtonFunctionAndColor(target_widgets, enter_color, leave_color, clicked_color, buttonReleasedFunction):
- bindEnterAndLeaveColor(target_widgets, enter_color, leave_color)
- bindButtonPressColor(target_widgets, clicked_color, enter_color)
- bindButtonReleaseFunction(target_widgets, buttonReleasedFunction)
-
-def unbindEnterLEaveButtonPressButtonReleaseFunction(target_widgets):
- for target_widget in target_widgets:
- for event_name in ["", "", "", ""]:
- target_widget.unbind(event_name)
-
-def unbindEventFromActiveTabWidget(active_tab_widget):
- for event_name in ["", "", "", ""]:
- active_tab_widget.unbind(event_name)
- active_tab_widget.children["!ctklabel"].unbind(event_name)
-
-def setDefaultActiveTab(active_tab_widget, active_bg_color, active_text_color):
- active_tab_widget.configure(fg_color=active_bg_color, cursor="")
- active_tab_widget.children["!ctklabel"].configure(fg_color=active_bg_color, text_color=active_text_color)
- unbindEventFromActiveTabWidget(active_tab_widget)
-
-
-def switchActiveTabAndPassiveTab(active_tab_widget, current_active_tab_widget, current_active_tab_passive_function, hovered_color, clicked_color, passive_color):
-
-
- active_tab_widget.configure(cursor="")
- unbindEventFromActiveTabWidget(active_tab_widget)
-
-
- rebindFunctionToTab(current_active_tab_widget, current_active_tab_passive_function, hovered_color, clicked_color, passive_color)
-
-def rebindFunctionToTab(passive_tab_widget, passive_tab_function, hovered_color, clicked_color, passive_color):
-
- passive_tab_widget.configure(cursor="hand2")
- bindEnterAndLeaveColor([passive_tab_widget, passive_tab_widget.children["!ctklabel"]], hovered_color, passive_color)
- bindButtonPressColor([passive_tab_widget, passive_tab_widget.children["!ctklabel"]], clicked_color, passive_color)
-
- bindButtonReleaseFunction([passive_tab_widget, passive_tab_widget.children["!ctklabel"]], passive_tab_function)
-
-def switchTabsColor(target_widget, tab_buttons, active_bg_color, active_text_color, passive_bg_color, passive_text_color):
- # Change all tabs' color to passive color at first
- for tab_button in tab_buttons:
- tab_button.configure(fg_color=passive_bg_color)
- tab_button.children["!ctklabel"].configure(fg_color=passive_bg_color, text_color=passive_text_color)
-
- # Then, set active color to the active tab
- target_widget.configure(fg_color=active_bg_color)
- target_widget.children["!ctklabel"].configure(fg_color=active_bg_color, text_color=active_text_color)
-
-
-
-
-
-
-def createButtonWithImage(parent_widget, button_image_size, button_ipadxy, button_fg_color, button_enter_color=None, button_clicked_color=None, button_image_file=None, button_command=None, corner_radius:int=0, no_bind:bool=False):
- button_wrapper = CTkFrame(parent_widget, corner_radius=corner_radius, fg_color=button_fg_color, height=0, width=0)
-
- button_widget = CTkLabel(
- button_wrapper,
- text=None,
- height=0,
- image=CTkImage((button_image_file),size=(button_image_size,button_image_size)),
- )
- button_widget.grid(row=0, column=0, padx=button_ipadxy, pady=button_ipadxy)
-
- if no_bind is False:
- button_wrapper.configure(cursor="hand2")
- bindButtonFunctionAndColor(
- target_widgets=[button_wrapper, button_widget],
- enter_color=button_enter_color,
- leave_color=button_fg_color,
- clicked_color=button_clicked_color,
- buttonReleasedFunction=button_command,
- )
-
- return button_wrapper
-
-
-def createLabelButton(
- parent_widget,
- label_button_bg_color,
- label_button_hovered_bg_color,
- label_button_clicked_bg_color,
- label_button_ipadx,
- label_button_ipady,
- variable,
- font_family,
- font_size,
- text_color,
- label_button_clicked_command,
- label_button_position=None,
- label_button_padx_between_img=0,
- image_file=None,
- image_size=None,
- image_widget_attr_name=None,
- label_button_min_height=None,
- label_button_min_width=None,
- setattr_widget=None,
- ):
-
- label_button_box = CTkFrame(parent_widget, corner_radius=6, fg_color=label_button_bg_color, cursor="hand2")
-
- label_button_box.grid_rowconfigure(0, weight=1)
- if label_button_min_height is not None:
- label_button_box.grid_rowconfigure(0, minsize=label_button_min_height)
-
- label_button_box.grid_columnconfigure(0, weight=1)
- if label_button_min_width is not None:
- label_button_box.grid_columnconfigure(0, minsize=label_button_min_width)
-
- label_button_label_wrapper = CTkFrame(label_button_box, corner_radius=0, fg_color=label_button_bg_color)
- label_button_label_wrapper.grid(row=0, column=0, padx=label_button_ipadx, pady=label_button_ipady)
-
- LABEL_COLUMN=0
- if label_button_position == "center":
- label_button_label_wrapper.grid_columnconfigure((0,2), weight=1)
- LABEL_COLUMN=1
-
- label_button_label_widget = CTkLabel(
- label_button_label_wrapper,
- textvariable=variable,
- height=0,
- font=CTkFont(family=font_family, size=font_size, weight="normal"),
- text_color=text_color
- )
- label_button_label_widget.grid(row=0, column=LABEL_COLUMN, padx=(0, label_button_padx_between_img))
-
-
- register_widgets = [label_button_label_wrapper, label_button_box, label_button_label_widget]
- if image_file is not None:
- label_button_label_wrapper.grid_columnconfigure((0,3), weight=1)
- label_button_img_widget = CTkLabel(
- label_button_label_wrapper,
- text=None,
- corner_radius=0,
- height=0,
- image=CTkImage(image_file, size=image_size)
- )
-
- if image_widget_attr_name is not None:
- setattr(setattr_widget, image_widget_attr_name, label_button_img_widget)
-
- label_button_img_widget.grid(row=0, column=LABEL_COLUMN+1)
- register_widgets.append(label_button_img_widget)
-
-
- bindEnterAndLeaveColor(register_widgets, label_button_hovered_bg_color, label_button_bg_color)
- bindButtonPressColor(register_widgets, label_button_clicked_bg_color, label_button_hovered_bg_color)
-
-
-
- def bindEventFromWidgets():
- bindButtonReleaseFunction(register_widgets, label_button_clicked_command)
-
- def unbindEventFromWidgets():
- unbindEnterLEaveButtonPressButtonReleaseFunction(register_widgets)
-
- bindEventFromWidgets()
-
- label_button_box.unbindFunction = unbindEventFromWidgets
- label_button_box.bindFunction = bindEventFromWidgets
-
- if image_file is not None:
- return (label_button_box, label_button_label_widget, label_button_img_widget)
- else:
- return (label_button_box, label_button_label_widget)
-
-
-
-
-
-
-
-def createOptionMenuBox(parent_widget, optionmenu_bg_color, optionmenu_hovered_bg_color, optionmenu_clicked_bg_color, optionmenu_ipadx, optionmenu_ipady, variable, font_family, font_size, text_color, image_file, image_size, optionmenu_clicked_command, optionmenu_position=None, optionmenu_padx_between_img=0, optionmenu_min_height=None, optionmenu_min_width=None, setattr_widget=None, image_widget_attr_name=None):
-
- option_menu_box = CTkFrame(parent_widget, corner_radius=6, fg_color=optionmenu_bg_color, cursor="hand2")
-
- option_menu_box.grid_rowconfigure(0, weight=1)
- if optionmenu_min_height is not None:
- option_menu_box.grid_rowconfigure(0, minsize=optionmenu_min_height)
-
- option_menu_box.grid_columnconfigure(0, weight=1)
- if optionmenu_min_width is not None:
- option_menu_box.grid_columnconfigure(0, minsize=optionmenu_min_width)
-
- optionmenu_label_wrapper = CTkFrame(option_menu_box, corner_radius=0, fg_color=optionmenu_bg_color)
- optionmenu_label_wrapper.grid(row=0, column=0, padx=(optionmenu_ipadx[0],0), pady=optionmenu_ipady, sticky="ew")
-
- LABEL_COLUMN=0
- if optionmenu_position == "center":
- optionmenu_label_wrapper.grid_columnconfigure((0,2), weight=1)
- LABEL_COLUMN=1
-
- optionmenu_label_widget = CTkLabel(
- optionmenu_label_wrapper,
- textvariable=variable,
- height=0,
- font=CTkFont(family=font_family, size=font_size, weight="normal"),
- text_color=text_color
- )
- optionmenu_label_widget.grid(row=0, column=LABEL_COLUMN, padx=(0, optionmenu_padx_between_img))
-
-
- optionmenu_img_widget = CTkLabel(
- option_menu_box,
- text=None,
- corner_radius=0,
- height=0,
- image=CTkImage(image_file, size=image_size)
- )
-
- if image_widget_attr_name is not None:
- setattr(setattr_widget, image_widget_attr_name, optionmenu_img_widget)
-
- optionmenu_img_widget.grid(row=0, column=1, padx=(0, optionmenu_ipadx[1]), pady=optionmenu_ipady)
-
-
- bindEnterAndLeaveColor([optionmenu_label_wrapper, option_menu_box, optionmenu_label_widget, optionmenu_img_widget], optionmenu_hovered_bg_color, optionmenu_bg_color)
- bindButtonPressColor([optionmenu_label_wrapper, option_menu_box, optionmenu_label_widget, optionmenu_img_widget], optionmenu_clicked_bg_color, optionmenu_hovered_bg_color)
-
-
- def bindEventFromWidgets():
- bindButtonReleaseFunction([optionmenu_label_wrapper, option_menu_box, optionmenu_label_widget, optionmenu_img_widget], optionmenu_clicked_command)
- bindEventFromWidgets()
-
- def unbindEventFromWidgets():
- unbindEnterLEaveButtonPressButtonReleaseFunction([optionmenu_label_wrapper, option_menu_box, optionmenu_label_widget, optionmenu_img_widget])
-
- option_menu_box.unbindFunction = unbindEventFromWidgets
- option_menu_box.bindFunction = bindEventFromWidgets
-
-
- return (option_menu_box, optionmenu_label_widget, optionmenu_img_widget)
-
-
-def applyUiScalingAndFixTheBugScrollBar(scrollbar_widget, padx, width):
- scrollbar_widget._scrollbar.grid_configure(padx=padx)
-
- # This is for CustomTkinter's spec change or bug fix.
- scrollbar_widget._scrollbar.configure(height=0)
- scrollbar_widget._scrollbar.configure(width=width)
-
-
-def setGeometryToCenterOfScreen(root_widget):
- root_widget.update()
- sw=root_widget.winfo_screenwidth()
- sh=root_widget.winfo_screenheight()
- geometry_width = root_widget.winfo_width()
- geometry_height = root_widget.winfo_height()
-
- root_widget.geometry(str(geometry_width)+"x"+str(geometry_height)+"+"+str((sw-geometry_width)//2)+"+"+str((sh-geometry_height)//2))
-
-
-def setGeometryToCenterOfTheWidget(attach_widget, target_widget):
- attach_widget.update()
- target_widget.update()
- current_window_x = attach_widget.winfo_rootx()
- current_window_y = attach_widget.winfo_rooty()
- current_window_width = attach_widget.winfo_width()
- current_window_height = attach_widget.winfo_height()
- desired_window_width = target_widget.winfo_width()
- desired_window_height = target_widget.winfo_height()
-
- desired_window_x = int((current_window_x + current_window_width / 2) - (desired_window_width / 2))
- desired_window_y = int((current_window_y + current_window_height / 2) - (desired_window_height / 2))
-
- target_widget.geometry(str(desired_window_width) + "x" + str(desired_window_height) + "+" + str(desired_window_x) + "+" + str(desired_window_y))
-
-
-def fadeInAnimation(root_widget, steps:int=10, interval:float=0.1, max_alpha:float=1):
- alpha_steps = 100
- alpha_steps*=max_alpha
- step_size = alpha_steps/steps
- root_widget.attributes("-alpha", 0)
- num = 0
- while num < alpha_steps:
- if not root_widget.winfo_exists():
- break
- root_widget.attributes("-alpha", num / 100)
- root_widget.update()
- sleep(interval)
- num += step_size
- root_widget.attributes("-alpha", max_alpha)
-
-
-def rotateImage(image, angle, to_expand=False):
- rotated_image = image.rotate(angle, expand=to_expand)
- return rotated_image
-
-def animateRotation(tk_root, img_frame, img, img_width, img_height, start_angle:int, goal_angle:int, duration=0.5, to_expand:bool=False):
- start_time = time()
- while True:
- elapsed_time = time() - start_time
- progress = min(elapsed_time / duration, 1.0)
- eased_progress = 1 - math.pow(1 - progress, 4)
-
- angle = start_angle + (goal_angle - start_angle) * eased_progress
- angle = -angle
-
- rotated_img = rotateImage(img, angle, to_expand)
- img_frame.configure(image=CTkImage(rotated_img, size=(img_width, img_height)))
-
- tk_root.update()
-
- if elapsed_time >= duration:
- break
-
- sleep(0.01)
diff --git a/vrct_gui/updating_window/UpdatingWindow.py b/vrct_gui/updating_window/UpdatingWindow.py
deleted file mode 100644
index d84fd7dd..00000000
--- a/vrct_gui/updating_window/UpdatingWindow.py
+++ /dev/null
@@ -1,177 +0,0 @@
-import math
-import time
-
-from customtkinter import CTkImage, CTkLabel, CTkToplevel, CTkProgressBar, CTkFrame
-from ..ui_utils import openImageKeepAspectRatio, getImageFileFromUiUtils, setGeometryToCenterOfScreen, fadeInAnimation, generateGradientColor, getImagePath
-
-class UpdatingWindow(CTkToplevel):
- def __init__(self, vrct_gui):
- super().__init__()
- self.withdraw()
- self.overrideredirect(True)
- self.configure(fg_color="#292a2d")
- self.title("Updating...")
- self.after(200, lambda: self.iconbitmap(getImagePath("vrct_logo_mark_black.ico")))
- self.protocol("WM_DELETE_WINDOW", vrct_gui._quitVRCT)
- # self.wm_attributes("-toolwindow", True)
- self.is_showed_downloading_process = False
- self.is_showed_unpackaging_process = False
- BG_WIDTH= 300
- BG_HEIGHT= 350
- self.BG_HEX_COLOR = "#292a2d"
-
- self.grid_columnconfigure(0, weight=1)
- self.grid_rowconfigure(0, weight=1)
- self.updating_background = CTkFrame(self, corner_radius=0, fg_color=self.BG_HEX_COLOR, width=BG_WIDTH, height=BG_HEIGHT)
- self.updating_background.grid()
-
-
- self.PROGRESSBAR_HEIGHT = 2
- self.PROGRESSBAR_WIDTH = 240
- self.PROGRESSBAR_Y = 240
- self.PROGRESSBAR_X = 30
-
-
-
-
- self.downloading_unpackaging_d = getImageFileFromUiUtils("downloading_unpackaging_d.png")
- self.downloading_unpackaging_d_label = CTkLabel(
- self.updating_background,
- text=None,
- height=0,
- fg_color=self.BG_HEX_COLOR,
- image=CTkImage(self.downloading_unpackaging_d, size=(self.downloading_unpackaging_d.width, self.downloading_unpackaging_d.height))
- )
-
-
- self.downloading_unpackaging_u = getImageFileFromUiUtils("downloading_unpackaging_u.png")
- self.downloading_unpackaging_u_label = CTkLabel(
- self.updating_background,
- text=None,
- height=0,
- fg_color=self.BG_HEX_COLOR,
- image=CTkImage(self.downloading_unpackaging_u, size=(self.downloading_unpackaging_u.width, self.downloading_unpackaging_u.height))
- )
-
-
-
-
-
-
-
-
- self.unpackage_img = getImageFileFromUiUtils("unpackage_icon.png")
-
- self.unpackage_img_label = CTkLabel(
- self.updating_background,
- text=None,
- height=0,
- fg_color=self.BG_HEX_COLOR,
- image=CTkImage(self.unpackage_img, size=(self.unpackage_img.width, self.unpackage_img.height))
- )
-
-
-
-
-
-
-
- self.progressbar = CTkProgressBar(
- self.updating_background,
- height=self.PROGRESSBAR_HEIGHT,
- width=self.PROGRESSBAR_WIDTH,
- corner_radius=0,
- fg_color=self.BG_HEX_COLOR,
- progress_color=self.BG_HEX_COLOR,
- )
- self.progressbar.set(0)
- self.progressbar.place(x=self.PROGRESSBAR_X, y=self.PROGRESSBAR_Y, anchor="nw")
-
-
- self.chato_delivering_img = getImageFileFromUiUtils("chato_delivering.png")
-
- self.chato_delivering_img_label = CTkLabel(
- self.updating_background,
- text=None,
- height=0,
- fg_color=self.BG_HEX_COLOR,
- image=CTkImage(self.chato_delivering_img, size=(self.chato_delivering_img.width, self.chato_delivering_img.height))
- )
- self.chato_delivering_img_label.place(x=-30, y=self.PROGRESSBAR_Y - 1, anchor="s")
-
-
-
- self.chato_unpackaging_img = getImageFileFromUiUtils("chato_unpackaging.png")
-
- self.chato_unpackaging_img_label = CTkLabel(
- self.updating_background,
- text=None,
- height=0,
- fg_color=self.BG_HEX_COLOR,
- image=CTkImage(self.chato_unpackaging_img, size=(self.chato_unpackaging_img.width, self.chato_unpackaging_img.height))
- )
- self.chato_unpackaging_img_label.place(x=-30, y=self.PROGRESSBAR_Y + self.PROGRESSBAR_HEIGHT + 1, anchor="n")
-
-
-
-
-
-
-
- self.vrct_update_process_img = getImageFileFromUiUtils("vrct_update_process.png")
-
- self.vrct_update_process_img_label = CTkLabel(
- self.updating_background,
- text=None,
- height=0,
- fg_color=self.BG_HEX_COLOR,
- image=CTkImage(self.vrct_update_process_img, size=(self.vrct_update_process_img.width, self.vrct_update_process_img.height))
- )
- self.vrct_update_process_img_label.place(x=87, y=300, anchor="nw")
-
-
-
-
-
-
- def updateDownloadProgress(self, progress:float, progress_type:str):
- if progress_type == "downloading":
- if self.is_showed_downloading_process is False:
- self.downloading_unpackaging_d_label.place(x=50, y=56, anchor="nw")
- self.is_showed_downloading_process = True
-
- fg_color = generateGradientColor(
- value=progress,
- color_start=[242, 242, 242], # RGB values for #f2f2f2
- color_end=[72, 164, 149], # RGB values for #48a495
- )
- self.progressbar.configure(fg_color=fg_color)
-
- chato_x = self.PROGRESSBAR_X + (progress * self.PROGRESSBAR_WIDTH)
- self.chato_delivering_img_label.place(x=chato_x)
- self.progressbar.set(progress)
- self.update_idletasks()
-
- elif progress_type == "extracting":
- if self.is_showed_unpackaging_process is False:
- self.chato_delivering_img_label.place_forget()
- self.downloading_unpackaging_u_label.place(x=50, y=56, anchor="nw")
- self.unpackage_img_label.place(x=130, y=174, anchor="nw")
- self.progressbar.configure(fg_color=self.BG_HEX_COLOR, progress_color="#4B4C4F")
- self.is_showed_unpackaging_process = True
-
- chato_x = (self.PROGRESSBAR_X - 3) + (self.PROGRESSBAR_WIDTH - (progress * self.PROGRESSBAR_WIDTH))
- self.chato_unpackaging_img_label.place(x=chato_x)
- self.progressbar.set(1 - progress)
- self.update_idletasks()
-
-
- def showUpdatingWindow(self):
- self.attributes("-alpha", 0)
- self.deiconify()
- setGeometryToCenterOfScreen(root_widget=self)
- fadeInAnimation(self, steps=5, interval=0.02)
-
-
- def destroyUpdatingWindow(self):
- self.destroy()
\ No newline at end of file
diff --git a/vrct_gui/updating_window/__init__.py b/vrct_gui/updating_window/__init__.py
deleted file mode 100644
index feed896e..00000000
--- a/vrct_gui/updating_window/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from .UpdatingWindow import UpdatingWindow
\ No newline at end of file
diff --git a/vrct_gui/vrct_gui.py b/vrct_gui/vrct_gui.py
deleted file mode 100644
index cc0d2d97..00000000
--- a/vrct_gui/vrct_gui.py
+++ /dev/null
@@ -1,334 +0,0 @@
-from customtkinter import CTk, CTkImage
-
-from ._CreateSelectableLanguagesWindow import _CreateSelectableLanguagesWindow
-
-from .updating_window import UpdatingWindow
-
-from ._CreateWindowCover import _CreateWindowCover
-from ._CreateNotificationWindow import _CreateNotificationWindow
-from ._CreateDropdownMenuWindow import _CreateDropdownMenuWindow
-from ._changeMainWindowWidgetsStatus import _changeMainWindowWidgetsStatus
-from ._changeConfigWindowWidgetsStatus import _changeConfigWindowWidgetsStatus
-from ._CreateConfirmationModal import _CreateConfirmationModal
-from ._PrintToTextbox import _PrintToTextbox
-
-from .main_window import createMainWindowWidgets
-from .config_window import ConfigWindow
-from .quick_settings_window import QuickSettingsWindow
-from .ui_utils import setDefaultActiveTab, setGeometryToCenterOfScreen, fadeInAnimation
-
-from utils import callFunctionIfCallable
-
-class VRCT_GUI(CTk):
- def __init__(self):
- super().__init__()
- self.withdraw()
- self.is_config_window_already_opened_once=False
- self.BIND_UNMAP_DETECT_MAIN_WINDOW_STATE_FUNC_ID = None
- self.BIND_MAP_DETECT_MAIN_WINDOW_STATE_FUNC_ID = None
-
- self.window_state = None
-
- def detectMainWindowState(self, _e=None):
- self.new_window_state = self.wm_state()
- if self.window_state == self.new_window_state:
- return
- else:
- self.window_state = self.new_window_state
-
- if self.window_state == "iconic":
- self.main_window_cover.withdraw()
- elif self.window_state == "normal":
- self.main_window_cover.show()
-
-
-
- def _showGUI(self):
- self.attributes("-alpha", 0)
- self.deiconify()
- if self.settings.main.to_restore_main_window_geometry is True:
- self.geometry("{}x{}+{}+{}".format(
- self.settings.main.geometry.width,
- self.settings.main.geometry.height,
- self.settings.main.geometry.x_pos,
- self.settings.main.geometry.y_pos,
- ))
- else:
- self.geometry("{}x{}".format(
- self.settings.main.uism.MAIN_AREA_MIN_WIDTH + self.settings.main.uism.SIDEBAR_MIN_WIDTH,
- self.winfo_height()
- ))
- setGeometryToCenterOfScreen(root_widget=self)
-
-
- if self._view_variable.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE is True:
- self._enableMainWindowSidebarCompactMode()
- fadeInAnimation(self, steps=5, interval=0.008)
-
-
- if self._isOverWindowSizeCheck() is True:
- callFunctionIfCallable(self._view_variable.CALLBACK_WHEN_DETECT_WINDOW_OVERED_SIZE)
-
-
- def _createGUI(self, settings, view_variable):
- self.settings = settings
- self._view_variable = view_variable
-
- self.translation_engine_dropdown_menu_window = _CreateDropdownMenuWindow(
- settings=settings.dropdown_menu_window,
- view_variable=self._view_variable,
-
- window_additional_y_pos=self.settings.main.uism.SLS__DROPDOWN_MENU_WINDOW_ADDITIONAL_Y_POS,
- window_border_width=self.settings.main.uism.SLS__DROPDOWN_MENU_WINDOW_BORDER_WIDTH,
- scrollbar_ipadx=self.settings.main.uism.SLS__DROPDOWN_MENU_SCROLLBAR_IPADX,
- scrollbar_width=self.settings.main.uism.SLS__DROPDOWN_MENU_SCROLLBAR_WIDTH,
- value_ipadx=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_IPADX,
- value_ipady=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_IPADY,
- value_pady=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_PADY,
- value_font_size=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_FONT_SIZE,
- dropdown_menu_default_min_width=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_DEFAULT_MIN_WIDTH,
-
- window_bg_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_WINDOW_BG_COLOR,
- window_border_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_WINDOW_BORDER_COLOR,
- values_bg_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_BG_COLOR,
- values_hovered_bg_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_HOVERED_BG_COLOR,
- values_clicked_bg_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_CLICKED_BG_COLOR,
- values_text_color=self.settings.main.ctm.BASIC_TEXT_COLOR,
- )
-
- createMainWindowWidgets(
- vrct_gui=self,
- settings=self.settings.main,
- view_variable=self._view_variable
- )
-
- # For Config Window
- self.dropdown_menu_window = _CreateDropdownMenuWindow(
- settings=self.settings.dropdown_menu_window,
- view_variable=self._view_variable,
-
- window_additional_y_pos=self.settings.config_window.uism.SB__DROPDOWN_MENU_WINDOW_ADDITIONAL_Y_POS,
- window_border_width=self.settings.config_window.uism.SB__DROPDOWN_MENU_WINDOW_BORDER_WIDTH,
- scrollbar_ipadx=self.settings.config_window.uism.SB__DROPDOWN_MENU_SCROLLBAR_IPADX,
- scrollbar_width=self.settings.config_window.uism.SB__DROPDOWN_MENU_SCROLLBAR_WIDTH,
- value_ipadx=self.settings.config_window.uism.SB__DROPDOWN_MENU_VALUE_IPADX,
- value_ipady=self.settings.config_window.uism.SB__DROPDOWN_MENU_VALUE_IPADY,
- value_pady=self.settings.config_window.uism.SB__DROPDOWN_MENU_VALUE_PADY,
- value_font_size=self.settings.config_window.uism.SB__DROPDOWN_MENU_VALUE_FONT_SIZE,
- dropdown_menu_default_min_width=self.settings.config_window.uism.SB__DROPDOWN_MENU_VALUE_DEFAULT_MIN_WIDTH,
-
- window_bg_color=self.settings.config_window.ctm.SB__DROPDOWN_MENU_WINDOW_BG_COLOR,
- window_border_color=self.settings.config_window.ctm.SB__DROPDOWN_MENU_WINDOW_BORDER_COLOR,
- values_bg_color=self.settings.config_window.ctm.SB__DROPDOWN_MENU_BG_COLOR,
- values_hovered_bg_color=self.settings.config_window.ctm.SB__DROPDOWN_MENU_HOVERED_BG_COLOR,
- values_clicked_bg_color=self.settings.config_window.ctm.SB__DROPDOWN_MENU_CLICKED_BG_COLOR,
- values_text_color=self.settings.config_window.ctm.BASIC_TEXT_COLOR,
- )
-
- self.config_window = ConfigWindow(
- vrct_gui=self,
- settings=self.settings.config_window,
- view_variable=self._view_variable
- )
-
- self.quick_settings_window = QuickSettingsWindow(
- vrct_gui=self,
- settings=self.settings.config_window,
- view_variable=self._view_variable
- )
-
- self.selectable_languages_window = _CreateSelectableLanguagesWindow(
- vrct_gui=self,
- settings=self.settings.selectable_language_window,
- view_variable=self._view_variable
- )
-
- self.main_window_cover = _CreateWindowCover(
- attach_window=self,
- settings=self.settings.main_window_cover,
- view_variable=self._view_variable
- )
-
- self.notification_message_window = _CreateNotificationWindow(
- settings=self.settings.notification_message_window,
- view_variable=self._view_variable,
- wrapper_widget=self.config_window.main_bg_container,
-
- message_ipadx=self.settings.config_window.uism.SB__ERROR_MESSAGE_IPADX,
- message_ipady=self.settings.config_window.uism.SB__ERROR_MESSAGE_IPADY,
- message_font_size=self.settings.config_window.uism.SB__ERROR_MESSAGE_FONT_SIZE,
-
- error_message_bg_color=self.settings.config_window.ctm.SB__ERROR_MESSAGE_BG_COLOR,
- success_message_bg_color=self.settings.config_window.ctm.SB__SUCCESS_MESSAGE_BG_COLOR,
- message_text_color=self.settings.config_window.ctm.SB__ERROR_MESSAGE_TEXT_COLOR,
- )
-
- self.confirmation_modal = _CreateConfirmationModal(
- attach_window=self.toplevel_wrapper,
- settings=self.settings.confirmation_modal,
- view_variable=self._view_variable
- )
-
- self.information_modal = _CreateConfirmationModal(
- attach_window=self.toplevel_wrapper,
- settings=self.settings.confirmation_modal,
- view_variable=self._view_variable,
- modal_type="information"
- )
-
- self.print_to_textbox = _PrintToTextbox(
- vrct_gui=self,
- settings=self.settings.main,
- init_scaling=(self._view_variable.VAR_TEXTBOX_UI_SCALING.get()/100)
- )
-
- self.updating_window = UpdatingWindow(vrct_gui=self)
-
-
-
-
- def _startMainLoop(self):
- self.mainloop()
-
-
- def _quitVRCT(self):
- self.quit()
- self.destroy()
-
-
- def _openConfigWindow(self):
- self.main_window_cover.show(bind_focusin=self.config_window.lift)
-
- self.BIND_UNMAP_DETECT_MAIN_WINDOW_STATE_FUNC_ID = self.bind("", self.detectMainWindowState, "+")
- self.BIND_MAP_DETECT_MAIN_WINDOW_STATE_FUNC_ID = self.bind("