From b1c2dd4eb5152899adefaa90449bc630ac2702ce Mon Sep 17 00:00:00 2001
From: Kevin Schmidt <kevin.schmidt@hmmh.de>
Date: Tue, 4 Mar 2025 15:25:27 +0100
Subject: [PATCH 1/3] TD-18: Setup Matchmaking

---
 export_presets.cfg                            |    2 +-
 gdlintrc                                      |    2 +-
 project.godot                                 |    8 +
 scenes/login.tscn                             |  120 --
 scenes/main_menu.tscn                         |  184 +-
 scenes/theme_test.tscn                        | 1680 -----------------
 .../matchmaking/match_aborted_message.gd      |   11 +
 .../matchmaking/match_accepted_message.gd     |   10 +
 .../matchmaking/match_established_message.gd  |   14 +
 .../matchmaking/match_found_message.gd        |   13 +
 .../match_set_search_state_message.gd         |   10 +
 .../matchmaking/matchmaking_channel.gd        |   57 +
 scripts/channel/message.gd                    |    2 +-
 scripts/ui/login.gd                           |    6 +
 scripts/ui/quit.gd                            |    9 +
 scripts/ui/search_match.gd                    |  157 ++
 scripts/ui/swap_menu.gd                       |   14 +
 scripts/ui/switch_to_scene.gd                 |   14 -
 scripts/ui/websocket_time.gd                  |    2 +-
 19 files changed, 479 insertions(+), 1836 deletions(-)
 delete mode 100644 scenes/login.tscn
 delete mode 100644 scenes/theme_test.tscn
 create mode 100644 scripts/channel/matchmaking/match_aborted_message.gd
 create mode 100644 scripts/channel/matchmaking/match_accepted_message.gd
 create mode 100644 scripts/channel/matchmaking/match_established_message.gd
 create mode 100644 scripts/channel/matchmaking/match_found_message.gd
 create mode 100644 scripts/channel/matchmaking/match_set_search_state_message.gd
 create mode 100644 scripts/channel/matchmaking/matchmaking_channel.gd
 create mode 100644 scripts/ui/quit.gd
 create mode 100644 scripts/ui/search_match.gd
 create mode 100644 scripts/ui/swap_menu.gd
 delete mode 100644 scripts/ui/switch_to_scene.gd

diff --git a/export_presets.cfg b/export_presets.cfg
index e7b443b..d53b0ac 100644
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -114,7 +114,7 @@ custom_features=""
 export_filter="all_resources"
 include_filter=""
 exclude_filter=""
-export_path=""
+export_path="../../../../../Downloads/TowerDefence.dmg"
 encryption_include_filters=""
 encryption_exclude_filters=""
 encrypt_pck=false
diff --git a/gdlintrc b/gdlintrc
index 2dfe0ce..8a695a5 100644
--- a/gdlintrc
+++ b/gdlintrc
@@ -37,7 +37,7 @@ loop-variable-name: _?[a-z][a-z0-9]*(_[a-z0-9]+)*
 max-file-lines: 1000
 max-line-length: 80
 max-public-methods: 20
-max-returns: 6
+max-returns: 20
 mixed-tabs-and-spaces: null
 no-elif-return: null
 no-else-return: null
diff --git a/project.godot b/project.godot
index 27843ab..77ddc6b 100644
--- a/project.godot
+++ b/project.godot
@@ -18,6 +18,14 @@ config/icon="res://textures/icon.svg"
 [autoload]
 
 ConnectionChannel="*res://scripts/channel/connection/connection_channel.gd"
+MatchmakingChannel="*res://scripts/channel/matchmaking/matchmaking_channel.gd"
+
+[display]
+
+window/size/viewport_width=1920
+window/size/viewport_height=1080
+window/stretch/mode="viewport"
+window/stretch/aspect="expand"
 
 [editor_plugins]
 
diff --git a/scenes/login.tscn b/scenes/login.tscn
deleted file mode 100644
index a9d38f5..0000000
--- a/scenes/login.tscn
+++ /dev/null
@@ -1,120 +0,0 @@
-[gd_scene load_steps=6 format=3 uid="uid://dtaaw31x3n22f"]
-
-[ext_resource type="Script" path="res://scripts/ui/login.gd" id="1_12w35"]
-[ext_resource type="Script" path="res://scripts/ui/show_banner_on_error.gd" id="1_41hxt"]
-[ext_resource type="Resource" uid="uid://cdixdbu3sqgjn" path="res://config/api_config.tres" id="2_60hb8"]
-
-[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_d0bbp"]
-
-[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bdovr"]
-bg_color = Color(0.74463, 0.147328, 0, 1)
-
-[node name="Login" type="Control"]
-layout_mode = 3
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-grow_horizontal = 2
-grow_vertical = 2
-
-[node name="Panel" type="Panel" parent="."]
-layout_mode = 1
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-grow_horizontal = 2
-grow_vertical = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_d0bbp")
-
-[node name="Container" type="VBoxContainer" parent="Panel"]
-layout_mode = 1
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-grow_horizontal = 2
-grow_vertical = 2
-
-[node name="Banner" type="PanelContainer" parent="Panel/Container" node_paths=PackedStringArray("login", "text")]
-layout_mode = 2
-script = ExtResource("1_41hxt")
-login = NodePath("../CenterContainer/VBoxContainer/Button")
-text = NodePath("CenterContainer/MarginContainer/RichTextLabel")
-
-[node name="Panel" type="Panel" parent="Panel/Container/Banner"]
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_bdovr")
-
-[node name="CenterContainer" type="CenterContainer" parent="Panel/Container/Banner"]
-layout_mode = 2
-
-[node name="MarginContainer" type="MarginContainer" parent="Panel/Container/Banner/CenterContainer"]
-layout_mode = 2
-theme_override_constants/margin_top = 8
-theme_override_constants/margin_bottom = 8
-
-[node name="RichTextLabel" type="RichTextLabel" parent="Panel/Container/Banner/CenterContainer/MarginContainer"]
-layout_mode = 2
-text = "Keine Verbindung"
-fit_content = true
-autowrap_mode = 0
-
-[node name="CenterContainer" type="CenterContainer" parent="Panel/Container"]
-layout_mode = 2
-size_flags_vertical = 3
-
-[node name="VBoxContainer" type="VBoxContainer" parent="Panel/Container/CenterContainer"]
-custom_minimum_size = Vector2(500, 0)
-layout_mode = 2
-theme_override_constants/separation = 16
-
-[node name="Header" type="RichTextLabel" parent="Panel/Container/CenterContainer/VBoxContainer"]
-layout_mode = 2
-theme_override_font_sizes/normal_font_size = 30
-text = "Login"
-fit_content = true
-scroll_active = false
-autowrap_mode = 0
-
-[node name="InputContainer" type="VBoxContainer" parent="Panel/Container/CenterContainer/VBoxContainer"]
-layout_mode = 2
-theme_override_constants/separation = 8
-
-[node name="UsernameContainer" type="VBoxContainer" parent="Panel/Container/CenterContainer/VBoxContainer/InputContainer"]
-layout_mode = 2
-
-[node name="UsernameLabel" type="RichTextLabel" parent="Panel/Container/CenterContainer/VBoxContainer/InputContainer/UsernameContainer"]
-layout_mode = 2
-text = "Username:
-"
-fit_content = true
-scroll_active = false
-autowrap_mode = 0
-
-[node name="UsernameInput" type="LineEdit" parent="Panel/Container/CenterContainer/VBoxContainer/InputContainer/UsernameContainer"]
-layout_mode = 2
-placeholder_text = "username"
-
-[node name="PasswordContainer" type="VBoxContainer" parent="Panel/Container/CenterContainer/VBoxContainer/InputContainer"]
-layout_mode = 2
-
-[node name="PaswordLabel" type="RichTextLabel" parent="Panel/Container/CenterContainer/VBoxContainer/InputContainer/PasswordContainer"]
-layout_mode = 2
-text = "Password:"
-fit_content = true
-scroll_active = false
-autowrap_mode = 0
-
-[node name="PasswordInput" type="LineEdit" parent="Panel/Container/CenterContainer/VBoxContainer/InputContainer/PasswordContainer"]
-layout_mode = 2
-placeholder_text = "password"
-secret = true
-
-[node name="Button" type="Button" parent="Panel/Container/CenterContainer/VBoxContainer" node_paths=PackedStringArray("username_field", "password_field")]
-layout_mode = 2
-text = "Login"
-script = ExtResource("1_12w35")
-username_field = NodePath("../InputContainer/UsernameContainer/UsernameInput")
-password_field = NodePath("../InputContainer/PasswordContainer/PasswordInput")
-api_config = ExtResource("2_60hb8")
-
-[node name="HTTPRequest" type="HTTPRequest" parent="Panel/Container/CenterContainer/VBoxContainer/Button"]
diff --git a/scenes/main_menu.tscn b/scenes/main_menu.tscn
index 2532656..7c4ac3c 100644
--- a/scenes/main_menu.tscn
+++ b/scenes/main_menu.tscn
@@ -1,7 +1,24 @@
-[gd_scene load_steps=3 format=3 uid="uid://bqfijb7bk2g7j"]
+[gd_scene load_steps=12 format=3 uid="uid://bqfijb7bk2g7j"]
 
 [ext_resource type="Theme" uid="uid://bt4hxdwromnxs" path="res://ui/theme.tres" id="1_6qgep"]
-[ext_resource type="Script" path="res://scripts/ui/switch_to_scene.gd" id="2_c477a"]
+[ext_resource type="Script" path="res://scripts/ui/show_banner_on_error.gd" id="2_1tbi1"]
+[ext_resource type="Script" path="res://scripts/ui/swap_menu.gd" id="2_c477a"]
+[ext_resource type="Script" path="res://scripts/ui/login.gd" id="3_33cgr"]
+[ext_resource type="Resource" uid="uid://cdixdbu3sqgjn" path="res://config/api_config.tres" id="4_5vuod"]
+[ext_resource type="Script" path="res://scripts/ui/quit.gd" id="6_cixwl"]
+[ext_resource type="Script" path="res://scripts/ui/search_match.gd" id="7_dmfpl"]
+
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q2pxx"]
+bg_color = Color(0.52, 0.52, 0.52, 1)
+
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_socr1"]
+bg_color = Color(0.74463, 0.147328, 0, 1)
+
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_fh0xh"]
+bg_color = Color(0.135012, 0.135012, 0.135012, 1)
+
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_x4jly"]
+bg_color = Color(7.89344e-06, 0.65411, 0.87403, 1)
 
 [node name="Root" type="Panel"]
 anchors_preset = 15
@@ -12,22 +29,26 @@ offset_right = -1.0
 grow_horizontal = 2
 grow_vertical = 2
 theme = ExtResource("1_6qgep")
+theme_override_styles/panel = SubResource("StyleBoxFlat_q2pxx")
 
-[node name="VBoxContainer" type="VBoxContainer" parent="."]
+[node name="Screens" type="TabContainer" parent="."]
 layout_mode = 1
-anchors_preset = 8
-anchor_left = 0.5
-anchor_top = 0.5
-anchor_right = 0.5
-anchor_bottom = 0.5
-offset_left = -180.5
-offset_top = -44.0
-offset_right = 180.5
-offset_bottom = 44.0
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
 grow_horizontal = 2
 grow_vertical = 2
+current_tab = 0
+tabs_visible = false
 
-[node name="Text" type="RichTextLabel" parent="VBoxContainer"]
+[node name="Start" type="CenterContainer" parent="Screens"]
+layout_mode = 2
+metadata/_tab_index = 0
+
+[node name="V" type="VBoxContainer" parent="Screens/Start"]
+layout_mode = 2
+
+[node name="Title" type="RichTextLabel" parent="Screens/Start/V"]
 clip_contents = false
 layout_mode = 2
 size_flags_stretch_ratio = 7.45
@@ -37,14 +58,141 @@ fit_content = true
 scroll_active = false
 autowrap_mode = 0
 
-[node name="Button" type="Button" parent="VBoxContainer"]
+[node name="Login" type="Button" parent="Screens/Start/V" node_paths=PackedStringArray("menu")]
 layout_mode = 2
 text = "Login"
 script = ExtResource("2_c477a")
-scene_name = "login"
+menu = NodePath("../../../Login")
 
-[node name="Button2" type="Button" parent="VBoxContainer"]
+[node name="Settings" type="Button" parent="Screens/Start/V"]
 layout_mode = 2
-text = "Testszene"
+text = "Settings"
 script = ExtResource("2_c477a")
-scene_name = "theme_test"
+
+[node name="Quit" type="Button" parent="Screens/Start/V"]
+layout_mode = 2
+text = "Quit"
+script = ExtResource("6_cixwl")
+
+[node name="Login" type="VBoxContainer" parent="Screens"]
+visible = false
+layout_mode = 2
+metadata/_tab_index = 1
+
+[node name="Banner" type="PanelContainer" parent="Screens/Login" node_paths=PackedStringArray("login", "text")]
+layout_mode = 2
+script = ExtResource("2_1tbi1")
+login = NodePath("../CenterContainer/VBoxContainer/Actions/Login")
+text = NodePath("CenterContainer/MarginContainer/RichTextLabel")
+
+[node name="Panel" type="Panel" parent="Screens/Login/Banner"]
+layout_mode = 2
+theme_override_styles/panel = SubResource("StyleBoxFlat_socr1")
+
+[node name="CenterContainer" type="CenterContainer" parent="Screens/Login/Banner"]
+layout_mode = 2
+
+[node name="MarginContainer" type="MarginContainer" parent="Screens/Login/Banner/CenterContainer"]
+layout_mode = 2
+theme_override_constants/margin_top = 8
+theme_override_constants/margin_bottom = 8
+
+[node name="RichTextLabel" type="RichTextLabel" parent="Screens/Login/Banner/CenterContainer/MarginContainer"]
+layout_mode = 2
+text = "Keine Verbindung"
+fit_content = true
+autowrap_mode = 0
+
+[node name="CenterContainer" type="CenterContainer" parent="Screens/Login"]
+layout_mode = 2
+size_flags_vertical = 3
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Screens/Login/CenterContainer"]
+custom_minimum_size = Vector2(500, 0)
+layout_mode = 2
+theme_override_constants/separation = 16
+
+[node name="UsernameInput" type="LineEdit" parent="Screens/Login/CenterContainer/VBoxContainer"]
+layout_mode = 2
+placeholder_text = "username"
+
+[node name="PasswordInput" type="LineEdit" parent="Screens/Login/CenterContainer/VBoxContainer"]
+layout_mode = 2
+placeholder_text = "password"
+secret = true
+
+[node name="Actions" type="HBoxContainer" parent="Screens/Login/CenterContainer/VBoxContainer"]
+layout_mode = 2
+
+[node name="Back" type="Button" parent="Screens/Login/CenterContainer/VBoxContainer/Actions" node_paths=PackedStringArray("menu")]
+layout_mode = 2
+size_flags_horizontal = 3
+text = "Back"
+script = ExtResource("2_c477a")
+menu = NodePath("../../../../../Start")
+
+[node name="Login" type="Button" parent="Screens/Login/CenterContainer/VBoxContainer/Actions" node_paths=PackedStringArray("username_field", "password_field", "next_view")]
+layout_mode = 2
+size_flags_horizontal = 3
+text = "Login"
+script = ExtResource("3_33cgr")
+username_field = NodePath("../../UsernameInput")
+password_field = NodePath("../../PasswordInput")
+api_config = ExtResource("4_5vuod")
+next_view = NodePath("../../../../../Lobby")
+
+[node name="HTTPRequest" type="HTTPRequest" parent="Screens/Login/CenterContainer/VBoxContainer/Actions/Login"]
+
+[node name="Lobby" type="CenterContainer" parent="Screens" node_paths=PackedStringArray("popup", "search_button", "abort_button", "accept_button", "decline_button", "time_bar", "login")]
+visible = false
+layout_mode = 2
+script = ExtResource("7_dmfpl")
+popup = NodePath("Popup")
+search_button = NodePath("Search")
+abort_button = NodePath("Abort")
+accept_button = NodePath("Popup/MarginContainer/HBoxContainer/Accept")
+decline_button = NodePath("Popup/MarginContainer/HBoxContainer/Decline")
+time_bar = NodePath("Popup/Time Bar")
+login = NodePath("../Login/CenterContainer/VBoxContainer/Actions/Login")
+metadata/_tab_index = 2
+
+[node name="Search" type="Button" parent="Screens/Lobby"]
+layout_mode = 2
+text = "Search"
+
+[node name="Abort" type="Button" parent="Screens/Lobby"]
+visible = false
+layout_mode = 2
+text = "Abort"
+
+[node name="Popup" type="PanelContainer" parent="Screens/Lobby"]
+visible = false
+layout_mode = 2
+theme_override_styles/panel = SubResource("StyleBoxFlat_fh0xh")
+
+[node name="MarginContainer" type="MarginContainer" parent="Screens/Lobby/Popup"]
+layout_mode = 2
+theme_override_constants/margin_left = 16
+theme_override_constants/margin_top = 16
+theme_override_constants/margin_right = 16
+theme_override_constants/margin_bottom = 16
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Screens/Lobby/Popup/MarginContainer"]
+layout_mode = 2
+theme_override_constants/separation = 16
+
+[node name="Accept" type="Button" parent="Screens/Lobby/Popup/MarginContainer/HBoxContainer"]
+layout_mode = 2
+text = "Accept
+"
+
+[node name="Decline" type="Button" parent="Screens/Lobby/Popup/MarginContainer/HBoxContainer"]
+layout_mode = 2
+text = "Decline"
+
+[node name="Time Bar" type="ProgressBar" parent="Screens/Lobby/Popup"]
+layout_mode = 2
+size_flags_vertical = 8
+theme_override_styles/fill = SubResource("StyleBoxFlat_x4jly")
+value = 100.0
+show_percentage = false
diff --git a/scenes/theme_test.tscn b/scenes/theme_test.tscn
deleted file mode 100644
index e3e61b0..0000000
--- a/scenes/theme_test.tscn
+++ /dev/null
@@ -1,1680 +0,0 @@
-[gd_scene load_steps=11 format=3 uid="uid://ctqxikky2g0nj"]
-
-[ext_resource type="Script" path="res://scripts/ui/switch_to_scene.gd" id="1_7goww"]
-[ext_resource type="Script" path="res://scripts/ui/show_banner_on_error.gd" id="1_hsvu7"]
-[ext_resource type="Script" path="res://scripts/ui/websocket_time.gd" id="1_qy4dl"]
-[ext_resource type="Resource" uid="uid://cdixdbu3sqgjn" path="res://config/api_config.tres" id="3_bphu2"]
-[ext_resource type="Script" path="res://scripts/ui/login.gd" id="4_pkjxs"]
-
-[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ujhhp"]
-bg_color = Color(0.289228, 0.413265, 0.44363, 1)
-
-[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3ekgj"]
-bg_color = Color(0.74463, 0.147328, 0, 1)
-
-[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_n6w75"]
-bg_color = Color(0.317774, 0.633168, 0.849623, 1)
-
-[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_a5xrb"]
-bg_color = Color(1, 0.254902, 0.301961, 1)
-
-[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_p6yiv"]
-bg_color = Color(0.67667, 0.502224, 0.889563, 1)
-
-[node name="Root" type="Panel"]
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-grow_horizontal = 2
-grow_vertical = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_ujhhp")
-
-[node name="VBoxContainer" type="VBoxContainer" parent="."]
-layout_mode = 1
-anchors_preset = 15
-anchor_right = 1.0
-anchor_bottom = 1.0
-grow_horizontal = 2
-grow_vertical = 2
-
-[node name="Banner" type="PanelContainer" parent="VBoxContainer" node_paths=PackedStringArray("login", "text")]
-layout_mode = 2
-script = ExtResource("1_hsvu7")
-login = NodePath("../Content/HBoxContainer/ScrollContainer/VBoxContainer/LoginButton")
-text = NodePath("CenterContainer/MarginContainer/RichTextLabel")
-
-[node name="Panel" type="Panel" parent="VBoxContainer/Banner"]
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_3ekgj")
-
-[node name="CenterContainer" type="CenterContainer" parent="VBoxContainer/Banner"]
-layout_mode = 2
-
-[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/Banner/CenterContainer"]
-layout_mode = 2
-theme_override_constants/margin_top = 8
-theme_override_constants/margin_bottom = 8
-
-[node name="RichTextLabel" type="RichTextLabel" parent="VBoxContainer/Banner/CenterContainer/MarginContainer"]
-layout_mode = 2
-text = "Keine Verbindung"
-fit_content = true
-autowrap_mode = 0
-
-[node name="Content" type="MarginContainer" parent="VBoxContainer"]
-layout_mode = 2
-size_flags_vertical = 3
-theme_override_constants/margin_left = 16
-theme_override_constants/margin_top = 16
-theme_override_constants/margin_right = 16
-theme_override_constants/margin_bottom = 16
-
-[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/Content"]
-layout_mode = 2
-size_flags_vertical = 3
-theme_override_constants/separation = 16
-
-[node name="TabContainer" type="TabContainer" parent="VBoxContainer/Content/HBoxContainer"]
-layout_mode = 2
-size_flags_horizontal = 3
-current_tab = 1
-
-[node name="Page 1" type="HSplitContainer" parent="VBoxContainer/Content/HBoxContainer/TabContainer"]
-visible = false
-layout_mode = 2
-metadata/_tab_index = 0
-
-[node name="Left" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 1"]
-layout_mode = 2
-size_flags_horizontal = 3
-theme_override_styles/panel = SubResource("StyleBoxFlat_n6w75")
-
-[node name="Right" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 1"]
-layout_mode = 2
-size_flags_horizontal = 3
-theme_override_styles/panel = SubResource("StyleBoxFlat_a5xrb")
-
-[node name="Page 2" type="ScrollContainer" parent="VBoxContainer/Content/HBoxContainer/TabContainer"]
-layout_mode = 2
-horizontal_scroll_mode = 0
-metadata/_tab_index = 1
-
-[node name="GridContainer" type="GridContainer" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2"]
-layout_mode = 2
-size_flags_horizontal = 3
-size_flags_vertical = 3
-columns = 3
-
-[node name="Box" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box2" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box3" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box4" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box5" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box6" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box7" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box8" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box9" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box10" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box11" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box12" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box13" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box14" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box15" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box16" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box17" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box18" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box19" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box20" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box21" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box22" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box23" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box24" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box25" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box26" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box27" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box28" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box29" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box30" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box31" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box32" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box33" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box34" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box35" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box36" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box37" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box38" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box39" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box40" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box41" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box42" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box43" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box44" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box45" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box46" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box47" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box48" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box49" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box50" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box51" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box52" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box53" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box54" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box55" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box56" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box57" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box58" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box59" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box60" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box61" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box62" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box63" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box64" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box65" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box66" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box67" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box68" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box69" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box70" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box71" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box72" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box73" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box74" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box75" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box76" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box77" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box78" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box79" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box80" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box81" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box82" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box83" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box84" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box85" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box86" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box87" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box88" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box89" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box90" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box91" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box92" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box93" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box94" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box95" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box96" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box97" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box98" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box99" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box100" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box101" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box102" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box103" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box104" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box105" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box106" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box107" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box108" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box109" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box110" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box111" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box112" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box113" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box114" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box115" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box116" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box117" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box118" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box119" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box120" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box121" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box122" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box123" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box124" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box125" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box126" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box127" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box128" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box129" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box130" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box131" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box132" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box133" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box134" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box135" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box136" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box137" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box138" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box139" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box140" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box141" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box142" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box143" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box144" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box145" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box146" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box147" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box148" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box149" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box150" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box151" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box152" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box153" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box154" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box155" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box156" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box157" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box158" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box159" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box160" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box161" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box162" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box163" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box164" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box165" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box166" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box167" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box168" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box169" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box170" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box171" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box172" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box173" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box174" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box175" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box176" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box177" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box178" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box179" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box180" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box181" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box182" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box183" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box184" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box185" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box186" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box187" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box188" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box189" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box190" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box191" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box192" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box193" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box194" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box195" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box196" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box197" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box198" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box199" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box200" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box201" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box202" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box203" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box204" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box205" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box206" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box207" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box208" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box209" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box210" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box211" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box212" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box213" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box214" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box215" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box216" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box217" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box218" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box219" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box220" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box221" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box222" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box223" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box224" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box225" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box226" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box227" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box228" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box229" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box230" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box231" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box232" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box233" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box234" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box235" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box236" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box237" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box238" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box239" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box240" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box241" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box242" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box243" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box244" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box245" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box246" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box247" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box248" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box249" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box250" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box251" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box252" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box253" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box254" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box255" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box256" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box257" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box258" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box259" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box260" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box261" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box262" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box263" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box264" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box265" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box266" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box267" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box268" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box269" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box270" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box271" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box272" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box273" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box274" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box275" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box276" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box277" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box278" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box279" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box280" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box281" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box282" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box283" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box284" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box285" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box286" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box287" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box288" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box289" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box290" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box291" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box292" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box293" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box294" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box295" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box296" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box297" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box298" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box299" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="Box300" type="Panel" parent="VBoxContainer/Content/HBoxContainer/TabContainer/Page 2/GridContainer"]
-custom_minimum_size = Vector2(128, 128)
-layout_mode = 2
-theme_override_styles/panel = SubResource("StyleBoxFlat_p6yiv")
-
-[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/Content/HBoxContainer"]
-layout_mode = 2
-size_flags_horizontal = 3
-
-[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer"]
-layout_mode = 2
-size_flags_horizontal = 6
-size_flags_vertical = 3
-
-[node name="Button" type="Button" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer"]
-layout_mode = 2
-text = "Back to Main Menu"
-script = ExtResource("1_7goww")
-scene_name = "main_menu"
-
-[node name="ToggleButton" type="Button" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer"]
-layout_mode = 2
-toggle_mode = true
-text = "A button in Check Mode"
-
-[node name="CheckButton" type="CheckButton" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer"]
-layout_mode = 2
-text = "A Toggle (Check) Button"
-
-[node name="ColorPickerButton" type="ColorPickerButton" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer"]
-layout_mode = 2
-text = "Color Picker"
-edit_alpha = false
-
-[node name="OptionButton" type="OptionButton" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer"]
-layout_mode = 2
-selected = 0
-item_count = 3
-popup/item_0/text = "Choose Your Poison!"
-popup/item_0/id = 0
-popup/item_1/text = "Cake"
-popup/item_1/id = 1
-popup/item_2/text = "Pie"
-popup/item_2/id = 2
-
-[node name="LinkButton" type="LinkButton" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer"]
-layout_mode = 2
-text = "Important Video!"
-uri = "https://www.youtube.com/watch?v=PXqcHi2fkXI"
-
-[node name="UsernameInput" type="LineEdit" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer"]
-layout_mode = 2
-text = "Player1"
-placeholder_text = "Username"
-
-[node name="PasswordInput" type="LineEdit" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer"]
-layout_mode = 2
-text = "1234"
-placeholder_text = "Password"
-secret = true
-
-[node name="LoginButton" type="Button" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer" node_paths=PackedStringArray("username_field", "password_field")]
-layout_mode = 2
-text = "Login"
-script = ExtResource("4_pkjxs")
-username_field = NodePath("../UsernameInput")
-password_field = NodePath("../PasswordInput")
-api_config = ExtResource("3_bphu2")
-
-[node name="HTTPRequest" type="HTTPRequest" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer/LoginButton"]
-
-[node name="CurrentTimeDisplay" type="RichTextLabel" parent="VBoxContainer/Content/HBoxContainer/ScrollContainer/VBoxContainer" node_paths=PackedStringArray("login")]
-layout_mode = 2
-text = "..."
-fit_content = true
-script = ExtResource("1_qy4dl")
-login = NodePath("../LoginButton")
-api_config = ExtResource("3_bphu2")
diff --git a/scripts/channel/matchmaking/match_aborted_message.gd b/scripts/channel/matchmaking/match_aborted_message.gd
new file mode 100644
index 0000000..c89d296
--- /dev/null
+++ b/scripts/channel/matchmaking/match_aborted_message.gd
@@ -0,0 +1,11 @@
+class_name MatchAbortedMessage
+extends Message
+
+const MESSAGE_ID := "MatchAborted"
+
+# gdlint:ignore = class-variable-name
+@export var matchId: String
+
+
+func get_message_id() -> String:
+	return MESSAGE_ID
diff --git a/scripts/channel/matchmaking/match_accepted_message.gd b/scripts/channel/matchmaking/match_accepted_message.gd
new file mode 100644
index 0000000..ed028df
--- /dev/null
+++ b/scripts/channel/matchmaking/match_accepted_message.gd
@@ -0,0 +1,10 @@
+class_name MatchAcceptedMessage
+extends Message
+
+# gdlint:ignore = class-variable-name
+@export var matchId: String
+@export var accepted: bool
+
+
+func get_message_id() -> String:
+	return "MatchAccepted"
diff --git a/scripts/channel/matchmaking/match_established_message.gd b/scripts/channel/matchmaking/match_established_message.gd
new file mode 100644
index 0000000..764b160
--- /dev/null
+++ b/scripts/channel/matchmaking/match_established_message.gd
@@ -0,0 +1,14 @@
+class_name MatchEstablishedMessage
+extends Message
+
+const MESSAGE_ID := "MatchEstablished"
+
+# gdlint:ignore = class-variable-name
+@export var matchId: String
+# gdlint:ignore = class-variable-name
+@export var opponentName: String
+@export var token: String
+
+
+func get_message_id() -> String:
+	return MESSAGE_ID
diff --git a/scripts/channel/matchmaking/match_found_message.gd b/scripts/channel/matchmaking/match_found_message.gd
new file mode 100644
index 0000000..270f6c2
--- /dev/null
+++ b/scripts/channel/matchmaking/match_found_message.gd
@@ -0,0 +1,13 @@
+class_name MatchFoundMessage
+extends Message
+
+const MESSAGE_ID := "MatchFound"
+
+# gdlint:ignore = class-variable-name
+@export var matchId: String
+@export var created: int
+@export var ttl: int
+
+
+func get_message_id() -> String:
+	return MESSAGE_ID
diff --git a/scripts/channel/matchmaking/match_set_search_state_message.gd b/scripts/channel/matchmaking/match_set_search_state_message.gd
new file mode 100644
index 0000000..3faea1e
--- /dev/null
+++ b/scripts/channel/matchmaking/match_set_search_state_message.gd
@@ -0,0 +1,10 @@
+class_name MatchSetSearchStateMessage
+extends Message
+
+const MESSAGE_ID := "MatchSetSearchState"
+
+@export var searching: bool
+
+
+func get_message_id() -> String:
+	return MESSAGE_ID
diff --git a/scripts/channel/matchmaking/matchmaking_channel.gd b/scripts/channel/matchmaking/matchmaking_channel.gd
new file mode 100644
index 0000000..f14ecb0
--- /dev/null
+++ b/scripts/channel/matchmaking/matchmaking_channel.gd
@@ -0,0 +1,57 @@
+extends Channel
+
+signal on_match_set_search_state(msg: MatchSetSearchStateMessage)
+signal on_match_found(msg: MatchFoundMessage)
+signal on_match_aborted
+signal on_match_established(msg: MatchEstablishedMessage)
+
+
+func get_channel_location() -> String:
+	return "matchmaking"
+
+
+func _process(_delta: float) -> void:
+	self.socket.poll()
+	if self.socket.get_ready_state() != WebSocketPeer.STATE_OPEN:
+		return
+	while self.socket.get_available_packet_count():
+		var msg := (
+			Message
+			. deserialize(
+				self.socket.get_packet().get_string_from_utf8(),
+				[
+					MatchSetSearchStateMessage,
+					MatchFoundMessage,
+					MatchAbortedMessage,
+					MatchEstablishedMessage,
+				]
+			)
+		)
+		match msg.get_message_id():
+			MatchSetSearchStateMessage.MESSAGE_ID:
+				on_match_set_search_state.emit(msg)
+			MatchFoundMessage.MESSAGE_ID:
+				on_match_found.emit(msg)
+			MatchAbortedMessage.MESSAGE_ID:
+				on_match_found.emit(msg)
+			MatchEstablishedMessage.MESSAGE_ID:
+				on_match_established.emit(msg)
+			_:
+				continue
+
+
+func send_search_state(searching: bool) -> void:
+	if self.socket.get_ready_state() != WebSocketPeer.STATE_OPEN:
+		return
+	var msg := MatchSetSearchStateMessage.new()
+	msg.searching = searching
+	self.socket.send_text(Message.serialize(msg))
+
+
+func send_match_accepted(accepted: bool, match_id: String) -> void:
+	if self.socket.get_ready_state() != WebSocketPeer.STATE_OPEN:
+		return
+	var msg := MatchAcceptedMessage.new()
+	msg.accepted = accepted
+	msg.matchId = match_id
+	self.socket.send_text(Message.serialize(msg))
diff --git a/scripts/channel/message.gd b/scripts/channel/message.gd
index 11e6250..14d89e0 100644
--- a/scripts/channel/message.gd
+++ b/scripts/channel/message.gd
@@ -1,6 +1,6 @@
 class_name Message
 
-enum Channels { CONNECTION, TIME }
+enum Channels { CONNECTION, MATCHMAKING }
 
 
 func get_message_id() -> String:
diff --git a/scripts/ui/login.gd b/scripts/ui/login.gd
index 04f2646..26f4576 100644
--- a/scripts/ui/login.gd
+++ b/scripts/ui/login.gd
@@ -7,6 +7,7 @@ signal login_error(error: ApiError)
 @export var username_field: LineEdit
 @export var password_field: LineEdit
 @export var api_config: ApiConfig
+@export var next_view: Control
 var api: ServerApi
 
 
@@ -20,6 +21,9 @@ func _ready() -> void:
 	if not api_config:
 		push_error("No API Configuration provided")
 		return
+	if not next_view:
+		push_error("No next view configured")
+		return
 	api = ServerApi.new(api_config)
 	connect("pressed", login)
 	username_field.connect("text_submitted", login_wrapper)
@@ -38,6 +42,8 @@ func login() -> void:
 
 
 func on_success(response: ApiResponse) -> void:
+	ConnectionChannel.connect_to_channel(response.data.token)
+	next_view.visible = true
 	login_successful.emit(response.data)
 
 
diff --git a/scripts/ui/quit.gd b/scripts/ui/quit.gd
new file mode 100644
index 0000000..4e4856b
--- /dev/null
+++ b/scripts/ui/quit.gd
@@ -0,0 +1,9 @@
+extends Button
+
+
+func _ready() -> void:
+	connect("pressed", on_pressed)
+
+
+func on_pressed() -> void:
+	get_tree().quit()
diff --git a/scripts/ui/search_match.gd b/scripts/ui/search_match.gd
new file mode 100644
index 0000000..60ab43d
--- /dev/null
+++ b/scripts/ui/search_match.gd
@@ -0,0 +1,157 @@
+extends Control
+
+@export var popup: PanelContainer
+@export var search_button: Button
+@export var abort_button: Button
+@export var accept_button: Button
+@export var decline_button: Button
+@export var time_bar: ProgressBar
+@export var login: Login
+
+var searching: bool = false
+var sent_accept_message: bool = false
+var match_id: String = ""
+
+
+func _ready() -> void:
+	if !export_valid():
+		return
+	login.connect("login_successful", on_login)
+
+	# Websockets
+	(
+		ConnectionChannel
+		. connect(
+			"on_channel_token_received",
+			on_channel_token_received,
+		)
+	)
+	(
+		MatchmakingChannel
+		. connect(
+			"on_match_set_search_state",
+			on_match_set_search_state,
+		)
+	)
+	MatchmakingChannel.connect("on_match_found", on_match_found)
+	MatchmakingChannel.connect("on_match_aborted", on_match_aborted)
+	MatchmakingChannel.connect("on_match_established", on_match_established)
+
+	# UI
+	search_button.connect("pressed", on_search_pressed)
+	abort_button.connect("pressed", on_abort_pressed)
+	accept_button.connect("pressed", on_accept_pressed)
+	decline_button.connect("pressed", on_decline_pressed)
+	popup.visible = false
+
+
+# gdlint:ignore = max-public-methods
+func export_valid() -> bool:
+	if not popup:
+		push_error("Popup not Set")
+		return false
+	if not search_button:
+		push_error("Search Button not Set")
+		return false
+	if not abort_button:
+		push_error("Abort Button not Set")
+		return false
+	if not accept_button:
+		push_error("Accept Button not Set")
+		return false
+	if not decline_button:
+		push_error("Decline Button not Set")
+		return false
+	if not time_bar:
+		push_error("Time Bar not Set")
+		return false
+	if not login:
+		push_error("No login configured")
+		return false
+	return true
+
+
+func on_login(_session: PlayerLoginSession) -> void:
+	ConnectionChannel.request_channel_token(Message.Channels.MATCHMAKING)
+
+
+##############################
+#   Websocket Interactions   #
+##############################
+
+
+func on_channel_token_received(msg: ProvidedConnectionTokenMessage) -> void:
+	if msg.channel != Message.Channels.MATCHMAKING:
+		return
+	MatchmakingChannel.connect_socket(msg.token)
+
+
+func on_match_set_search_state(msg: MatchSetSearchStateMessage) -> void:
+	set_searching_ui(msg.searching)
+
+
+func on_match_found(msg: MatchFoundMessage) -> void:
+	set_match_accptance_ui(true)
+	set_accaptence_buttons_enabled(true)
+	match_id = msg.matchId
+	# TODO: Show and Reset Timer bar
+
+
+func on_match_aborted() -> void:
+	set_match_accptance_ui(false)
+	set_searching_ui(false)
+	match_id = ""
+
+
+func on_match_established(msg: MatchEstablishedMessage) -> void:
+	print(msg.opponentName)
+	#TODO: Implement
+
+
+#############################
+#      UI Interactions      #
+#############################
+
+
+func on_search_pressed() -> void:
+	if searching:
+		return
+	set_searching_ui(true)
+	MatchmakingChannel.send_search_state(true)
+
+
+func on_abort_pressed() -> void:
+	if not searching:
+		return
+	set_searching_ui(false)
+	MatchmakingChannel.send_search_state(false)
+
+
+func on_accept_pressed() -> void:
+	set_accaptence_buttons_enabled(false)
+	MatchmakingChannel.send_match_accepted(true, match_id)
+
+
+func on_decline_pressed() -> void:
+	set_accaptence_buttons_enabled(false)
+	MatchmakingChannel.send_match_accepted(false, match_id)
+
+
+#############################
+#       UI Management       #
+#############################
+
+
+func set_searching_ui(new_searching: bool) -> void:
+	searching = new_searching
+	search_button.visible = !new_searching
+	abort_button.visible = new_searching
+
+
+func set_accaptence_buttons_enabled(enabled: bool) -> void:
+	accept_button.disabled = !enabled
+	decline_button.disabled = !enabled
+
+
+func set_match_accptance_ui(vissible: bool) -> void:
+	popup.visible = vissible
diff --git a/scripts/ui/swap_menu.gd b/scripts/ui/swap_menu.gd
new file mode 100644
index 0000000..2c068c7
--- /dev/null
+++ b/scripts/ui/swap_menu.gd
@@ -0,0 +1,14 @@
+extends Button
+
+@export var menu: Control
+
+
+func _ready() -> void:
+	connect("pressed", _on_Button_pressed)
+
+
+func _on_Button_pressed() -> void:
+	if not menu:
+		push_error("Menu to swap to not configgured")
+		return
+	menu.visible = true
diff --git a/scripts/ui/switch_to_scene.gd b/scripts/ui/switch_to_scene.gd
deleted file mode 100644
index 1bc11f4..0000000
--- a/scripts/ui/switch_to_scene.gd
+++ /dev/null
@@ -1,14 +0,0 @@
-extends Button
-
-@export var scene_name: String
-
-
-func _ready() -> void:
-	connect("pressed", _on_Button_pressed)
-
-
-func _on_Button_pressed() -> void:
-	if not scene_name:
-		push_error("Scene to switch to is not configured")
-		return
-	get_tree().change_scene_to_file("res://scenes/" + scene_name + ".tscn")
diff --git a/scripts/ui/websocket_time.gd b/scripts/ui/websocket_time.gd
index e25985a..3c77084 100644
--- a/scripts/ui/websocket_time.gd
+++ b/scripts/ui/websocket_time.gd
@@ -42,7 +42,7 @@ func _process(_delta: float) -> void:
 	if state != WebSocketPeer.STATE_OPEN:
 		return
 	while time_channel.get_available_packet_count():
-		var msg: CurrentUnixTimeMessage = Message.deserialize(
+		var msg: CurrentUnixTimeMessage = Messize(
 			time_channel.get_packet().get_string_from_utf8(), [CurrentUnixTimeMessage]
 		)
 		if msg == null:

From f6e650b6717cefbf6cd28f75c44056ac8bf3a39e Mon Sep 17 00:00:00 2001
From: Kevin Schmidt <kevin.schmidt@hmmh.de>
Date: Wed, 5 Mar 2025 11:35:40 +0100
Subject: [PATCH 2/3] TD-18: Matchmaking UI

---
 export_presets.cfg                            |  2 +-
 project.godot                                 |  2 +
 scenes/game.tscn                              | 49 ++++++++++++++++++
 scenes/main_menu.tscn                         |  6 +--
 .../match/current_unix_time_message.gd        | 12 +++++
 scripts/channel/match/match_channel.gd        | 20 ++++++++
 .../matchmaking/matchmaking_channel.gd        |  2 +-
 .../channel/time/current_unix_time_message.gd |  8 ---
 scripts/match/current_match.gd                | 13 +++++
 scripts/match/ui/current_game_time.gd         |  9 ++++
 scripts/match/ui/opponent_name.gd             |  5 ++
 scripts/ui/{ => lobby}/search_match.gd        | 21 +++++---
 scripts/ui/{ => login}/login.gd               |  0
 .../ui/{ => login}/show_banner_on_error.gd    |  0
 scripts/ui/websocket_time.gd                  | 50 -------------------
 15 files changed, 128 insertions(+), 71 deletions(-)
 create mode 100644 scenes/game.tscn
 create mode 100644 scripts/channel/match/current_unix_time_message.gd
 create mode 100644 scripts/channel/match/match_channel.gd
 delete mode 100644 scripts/channel/time/current_unix_time_message.gd
 create mode 100644 scripts/match/current_match.gd
 create mode 100644 scripts/match/ui/current_game_time.gd
 create mode 100644 scripts/match/ui/opponent_name.gd
 rename scripts/ui/{ => lobby}/search_match.gd (88%)
 rename scripts/ui/{ => login}/login.gd (100%)
 rename scripts/ui/{ => login}/show_banner_on_error.gd (100%)
 delete mode 100644 scripts/ui/websocket_time.gd

diff --git a/export_presets.cfg b/export_presets.cfg
index d53b0ac..a3556a0 100644
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -114,7 +114,7 @@ custom_features=""
 export_filter="all_resources"
 include_filter=""
 exclude_filter=""
-export_path="../../../../../Downloads/TowerDefence.dmg"
+export_path="../../../../../Downloads/TowerDefence.app"
 encryption_include_filters=""
 encryption_exclude_filters=""
 encrypt_pck=false
diff --git a/project.godot b/project.godot
index 77ddc6b..3f6dac5 100644
--- a/project.godot
+++ b/project.godot
@@ -19,6 +19,8 @@ config/icon="res://textures/icon.svg"
 
 ConnectionChannel="*res://scripts/channel/connection/connection_channel.gd"
 MatchmakingChannel="*res://scripts/channel/matchmaking/matchmaking_channel.gd"
+MatchChannel="*res://scripts/channel/match/match_channel.gd"
+CurrentMatch="*res://scripts/match/current_match.gd"
 
 [display]
 
diff --git a/scenes/game.tscn b/scenes/game.tscn
new file mode 100644
index 0000000..f61971f
--- /dev/null
+++ b/scenes/game.tscn
@@ -0,0 +1,49 @@
+[gd_scene load_steps=3 format=3 uid="uid://co1x3hlc2efr6"]
+
+[ext_resource type="Script" path="res://scripts/match/ui/opponent_name.gd" id="1_saby1"]
+[ext_resource type="Script" path="res://scripts/match/ui/current_game_time.gd" id="2_3jcub"]
+
+[node name="Game" type="Node2D"]
+
+[node name="CanvasLayer" type="CanvasLayer" parent="."]
+
+[node name="HUD" type="Control" parent="CanvasLayer"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="Opponent Name" type="RichTextLabel" parent="CanvasLayer/HUD"]
+layout_mode = 1
+anchors_preset = 5
+anchor_left = 0.5
+anchor_right = 0.5
+offset_left = -0.5
+offset_right = 0.5
+offset_bottom = 45.0
+grow_horizontal = 2
+text = "Unknown"
+fit_content = true
+scroll_active = false
+autowrap_mode = 0
+script = ExtResource("1_saby1")
+
+[node name="Time" type="RichTextLabel" parent="CanvasLayer/HUD"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -20.0
+offset_top = -20.0
+offset_right = 20.0
+offset_bottom = 20.0
+grow_horizontal = 2
+grow_vertical = 2
+fit_content = true
+scroll_active = false
+autowrap_mode = 0
+script = ExtResource("2_3jcub")
diff --git a/scenes/main_menu.tscn b/scenes/main_menu.tscn
index 7c4ac3c..3fcad8f 100644
--- a/scenes/main_menu.tscn
+++ b/scenes/main_menu.tscn
@@ -1,12 +1,12 @@
 [gd_scene load_steps=12 format=3 uid="uid://bqfijb7bk2g7j"]
 
 [ext_resource type="Theme" uid="uid://bt4hxdwromnxs" path="res://ui/theme.tres" id="1_6qgep"]
-[ext_resource type="Script" path="res://scripts/ui/show_banner_on_error.gd" id="2_1tbi1"]
+[ext_resource type="Script" path="res://scripts/ui/login/show_banner_on_error.gd" id="2_1tbi1"]
 [ext_resource type="Script" path="res://scripts/ui/swap_menu.gd" id="2_c477a"]
-[ext_resource type="Script" path="res://scripts/ui/login.gd" id="3_33cgr"]
+[ext_resource type="Script" path="res://scripts/ui/login/login.gd" id="3_33cgr"]
 [ext_resource type="Resource" uid="uid://cdixdbu3sqgjn" path="res://config/api_config.tres" id="4_5vuod"]
 [ext_resource type="Script" path="res://scripts/ui/quit.gd" id="6_cixwl"]
-[ext_resource type="Script" path="res://scripts/ui/search_match.gd" id="7_dmfpl"]
+[ext_resource type="Script" path="res://scripts/ui/lobby/search_match.gd" id="7_dmfpl"]
 
 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q2pxx"]
 bg_color = Color(0.52, 0.52, 0.52, 1)
diff --git a/scripts/channel/match/current_unix_time_message.gd b/scripts/channel/match/current_unix_time_message.gd
new file mode 100644
index 0000000..c6c16cb
--- /dev/null
+++ b/scripts/channel/match/current_unix_time_message.gd
@@ -0,0 +1,12 @@
+class_name CurrentUnixTimeMessage
+extends Message
+
+const MESSAGE_ID: String = "CurrentUnixTime"
+
+@export var time: int
+# gdlint:ignore = class-variable-name
+@export var matchId: String
+
+
+func get_message_id() -> String:
+	return MESSAGE_ID
diff --git a/scripts/channel/match/match_channel.gd b/scripts/channel/match/match_channel.gd
new file mode 100644
index 0000000..9bf6671
--- /dev/null
+++ b/scripts/channel/match/match_channel.gd
@@ -0,0 +1,20 @@
+extends Channel
+
+signal on_match_update(msg: CurrentUnixTimeMessage)
+
+
+func get_channel_location() -> String:
+	return "match"
+
+
+func _process(_delta: float) -> void:
+	self.socket.poll()
+	if self.socket.get_ready_state() != WebSocketPeer.STATE_OPEN:
+		return
+	while self.socket.get_available_packet_count():
+		var msg := CurrentUnixTimeMessage.deserialize(
+			self.socket.get_packet().get_string_from_utf8(), [CurrentUnixTimeMessage]
+		)
+		if msg.get_message_id() != CurrentUnixTimeMessage.MESSAGE_ID:
+			return
+		on_match_update.emit(msg)
diff --git a/scripts/channel/matchmaking/matchmaking_channel.gd b/scripts/channel/matchmaking/matchmaking_channel.gd
index f14ecb0..804ad06 100644
--- a/scripts/channel/matchmaking/matchmaking_channel.gd
+++ b/scripts/channel/matchmaking/matchmaking_channel.gd
@@ -33,7 +33,7 @@ func _process(_delta: float) -> void:
 			MatchFoundMessage.MESSAGE_ID:
 				on_match_found.emit(msg)
 			MatchAbortedMessage.MESSAGE_ID:
-				on_match_found.emit(msg)
+				on_match_aborted.emit()
 			MatchEstablishedMessage.MESSAGE_ID:
 				on_match_established.emit(msg)
 			_:
diff --git a/scripts/channel/time/current_unix_time_message.gd b/scripts/channel/time/current_unix_time_message.gd
deleted file mode 100644
index 68a1ae7..0000000
--- a/scripts/channel/time/current_unix_time_message.gd
+++ /dev/null
@@ -1,8 +0,0 @@
-class_name CurrentUnixTimeMessage
-extends Message
-
-var time: int
-
-
-func get_message_id() -> String:
-	return "CurrentUnixTime"
diff --git a/scripts/match/current_match.gd b/scripts/match/current_match.gd
new file mode 100644
index 0000000..ec6ff31
--- /dev/null
+++ b/scripts/match/current_match.gd
@@ -0,0 +1,13 @@
+extends Node
+
+enum State { NONE, RUNNING, WON, LOST }
+
+var state: State = State.NONE
+var opponent_name: String = ""
+
+
+func start_game(msg: MatchEstablishedMessage) -> void:
+	self.opponent_name = msg.opponentName
+	self.state = State.RUNNING
+	MatchChannel.connect_socket(msg.token)
+	get_tree().change_scene_to_file("res://scenes/game.tscn")
diff --git a/scripts/match/ui/current_game_time.gd b/scripts/match/ui/current_game_time.gd
new file mode 100644
index 0000000..de52222
--- /dev/null
+++ b/scripts/match/ui/current_game_time.gd
@@ -0,0 +1,9 @@
+extends RichTextLabel
+
+
+func _ready() -> void:
+	MatchChannel.connect("on_match_update", on_match_update)
+
+
+func on_match_update(msg: CurrentUnixTimeMessage) -> void:
+	self.text = str(msg.time)
diff --git a/scripts/match/ui/opponent_name.gd b/scripts/match/ui/opponent_name.gd
new file mode 100644
index 0000000..2415004
--- /dev/null
+++ b/scripts/match/ui/opponent_name.gd
@@ -0,0 +1,5 @@
+extends RichTextLabel
+
+
+func _ready() -> void:
+	self.text = CurrentMatch.opponent_name
diff --git a/scripts/ui/search_match.gd b/scripts/ui/lobby/search_match.gd
similarity index 88%
rename from scripts/ui/search_match.gd
rename to scripts/ui/lobby/search_match.gd
index 60ab43d..c62f7ab 100644
--- a/scripts/ui/search_match.gd
+++ b/scripts/ui/lobby/search_match.gd
@@ -10,7 +10,7 @@ extends Control
 
 var searching: bool = false
 var sent_accept_message: bool = false
-var match_id: String = ""
+var found_match: MatchFoundMessage
 
 
 func _ready() -> void:
@@ -45,6 +45,13 @@ func _ready() -> void:
 	popup.visible = false
 
 
+func _process(_delta: float) -> void:
+	if found_match:
+		var now := int(Time.get_unix_time_from_system() * 1000)
+		time_bar.max_value = found_match.ttl
+		time_bar.value = found_match.ttl - (now - found_match.created)
+
+
 # gdlint:ignore = max-public-methods
 func export_valid() -> bool:
 	if not popup:
@@ -93,19 +100,17 @@ func on_match_set_search_state(msg: MatchSetSearchStateMessage) -> void:
 func on_match_found(msg: MatchFoundMessage) -> void:
 	set_match_accptance_ui(true)
 	set_accaptence_buttons_enabled(true)
-	match_id = msg.matchId
-	# TODO: Show and Reset Timer bar
+	found_match = msg
 
 
 func on_match_aborted() -> void:
 	set_match_accptance_ui(false)
 	set_searching_ui(false)
-	match_id = ""
+	found_match = null
 
 
 func on_match_established(msg: MatchEstablishedMessage) -> void:
-	print(msg.opponentName)
-	#TODO: Implement
+	CurrentMatch.start_game(msg)
 
 
 #############################
@@ -129,12 +134,12 @@ func on_abort_pressed() -> void:
 
 func on_accept_pressed() -> void:
 	set_accaptence_buttons_enabled(false)
-	MatchmakingChannel.send_match_accepted(true, match_id)
+	MatchmakingChannel.send_match_accepted(true, found_match.matchId)
 
 
 func on_decline_pressed() -> void:
 	set_accaptence_buttons_enabled(false)
-	MatchmakingChannel.send_match_accepted(false, match_id)
+	MatchmakingChannel.send_match_accepted(false, found_match.matchId)
 
 
 #############################
diff --git a/scripts/ui/login.gd b/scripts/ui/login/login.gd
similarity index 100%
rename from scripts/ui/login.gd
rename to scripts/ui/login/login.gd
diff --git a/scripts/ui/show_banner_on_error.gd b/scripts/ui/login/show_banner_on_error.gd
similarity index 100%
rename from scripts/ui/show_banner_on_error.gd
rename to scripts/ui/login/show_banner_on_error.gd
diff --git a/scripts/ui/websocket_time.gd b/scripts/ui/websocket_time.gd
deleted file mode 100644
index 3c77084..0000000
--- a/scripts/ui/websocket_time.gd
+++ /dev/null
@@ -1,50 +0,0 @@
-extends RichTextLabel
-
-@export var login: Login
-@export var api_config: ApiConfig
-var api := ServerApi.new(api_config)
-
-# docs.redotengine.org/en/stable/tutorials/networking/websocket.html
-var time_channel = WebSocketPeer.new()
-
-
-func _ready() -> void:
-	login.connect("login_successful", on_login)
-	(
-		ConnectionChannel
-		. connect(
-			"on_channel_token_received",
-			on_channel_token_received,
-		)
-	)
-
-
-func on_login(session: PlayerLoginSession):
-	ConnectionChannel.connect_to_channel(session.token)
-	ConnectionChannel.request_channel_token(Message.Channels.TIME)
-
-
-func on_channel_token_received(msg: ProvidedConnectionTokenMessage) -> void:
-	if time_channel.get_ready_state() != WebSocketPeer.STATE_CLOSED:
-		return
-	if msg.channel != Message.Channels.TIME:
-		return
-	time_channel.handshake_headers = PackedStringArray(
-		["Authorization: " + msg.token],
-	)
-	time_channel.connect_to_url("ws://localhost:8080/ws/time")
-
-
-func _process(_delta: float) -> void:
-	time_channel.poll()
-	var state = time_channel.get_ready_state()
-
-	if state != WebSocketPeer.STATE_OPEN:
-		return
-	while time_channel.get_available_packet_count():
-		var msg: CurrentUnixTimeMessage = Messize(
-			time_channel.get_packet().get_string_from_utf8(), [CurrentUnixTimeMessage]
-		)
-		if msg == null:
-			continue
-		self.text = str(msg.time)

From 3abd94d604978afa8561cd4ec35523fa968accb5 Mon Sep 17 00:00:00 2001
From: SZUT-Kevin <kevin.schmidt9101@gmail.com>
Date: Wed, 5 Mar 2025 11:28:00 +0000
Subject: [PATCH 3/3] export_presets.cfg aktualisiert

---
 export_presets.cfg | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/export_presets.cfg b/export_presets.cfg
index a3556a0..e7b443b 100644
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -114,7 +114,7 @@ custom_features=""
 export_filter="all_resources"
 include_filter=""
 exclude_filter=""
-export_path="../../../../../Downloads/TowerDefence.app"
+export_path=""
 encryption_include_filters=""
 encryption_exclude_filters=""
 encrypt_pck=false