diff --git a/README.md b/README.md
index bd9fc2c..ae2e8a8 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,6 @@ This protocol handles game state synchronization, player actions, lobby and glob
├── documents/ # Project resources and documentation
│ ├── images/ # Images for README and documentation
│ ├── diary # Diary files for each organizational meetup
-│ ├── blog # Blog files covering project-related topics
│ ├── docs # Documentation
│ ├── milestones/ # Milestone deliverables (6 milestones)
│ └── (Other resources) # Additional project materials
diff --git a/build.gradle b/build.gradle
index 4360c82..99005a1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,6 +4,7 @@ plugins {
id 'org.openjfx.javafxplugin' version '0.1.0'
id 'checkstyle'
id 'com.diffplug.spotless' version '7.0.2'
+ id 'jacoco'
}
group = 'ch.unibas.dmi.dbis'
@@ -32,7 +33,7 @@ dependencies {
// Source: https://mvnrepository.com/artifact/org.apache.logging.log4j
implementation("org.apache.logging.log4j:log4j-api:2.25.3")
runtimeOnly("org.apache.logging.log4j:log4j-core:2.25.3")
-
+ implementation("org.jspecify:jspecify:1.0.0")
// Source: https://mvnrepository.com/artifact/org.fusesource.jansi/jansi
runtimeOnly("org.fusesource.jansi:jansi:2.4.2")
@@ -41,8 +42,17 @@ dependencies {
implementation 'org.json:json:20240303'
}
+jacoco {
+ toolVersion = "0.8.14"
+}
+
+jacocoTestReport {
+ dependsOn test
+}
+
test {
useJUnitPlatform()
+ finalizedBy jacocoTestReport
}
checkstyle {
diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml
index d532e42..6b91f4c 100644
--- a/config/checkstyle/suppressions.xml
+++ b/config/checkstyle/suppressions.xml
@@ -21,4 +21,7 @@
+
+
+
diff --git a/documents/blog/README.md b/documents/blog/README.md
deleted file mode 100644
index aa92b15..0000000
--- a/documents/blog/README.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Blog
-
-## Purpose
-This folder contains a collection of blog posts documenting the development process of our application. These blogs serve two key purposes:
-
-1. **For External Audiences**
-
- The blogs provide insights into the internal program flow and the interaction between components without requiring readers to dive into the source code. They offer a mixed-level overview of how different parts of the system work together.
-
-2. **For Our Team**
-
- The blogs serve as a record of our decision-making process. By documenting what decisions were made and why, we can track the evolution of our design choices and understand the reasoning behind them. This is invaluable for maintaining consistency across the team.
-
-But keep in mind that these blogs **do not replace** the detailed source code documentation.
-
-## Format
-All blog posts follow the naming convention: `_.md`
-
-## Blog Posts
-
-### General
-*(No posts yet)*
-
-### Client
-*(No posts yet)*
-
-### Server
-*(No posts yet)*
diff --git a/documents/diary/09-04.md b/documents/diary/09-04.md
new file mode 100644
index 0000000..3c5f992
--- /dev/null
+++ b/documents/diary/09-04.md
@@ -0,0 +1,9 @@
+# Besprechung über Veränderung der Aufgabenteilung
+
+## Verschieben von Aufgaben
+
+Da die Implementation der client server Kommunikation länger dauerte als geplant, wurden achivements erfüllt, die erst bei späteren Meilensteinen relevant sein werden.
+
+## Aufgabeverteilung
+
+Um zu vermeiden, dass sich Personen erst lange Zeit in den Code anderer einarbeiten müssen um zu helfen, wurden Dokumentation und das Erstellen von Materialien für MS4 auf ein Teammitgleid (Jona) ausgelagert um das Projekt nicht zu verlangsamen
diff --git a/documents/docs/game-engine/casono-rules-easy-description.html b/documents/docs/game-engine/casono-rules-easy-description.html
new file mode 100644
index 0000000..efdad20
--- /dev/null
+++ b/documents/docs/game-engine/casono-rules-easy-description.html
@@ -0,0 +1,537 @@
+
+
+
+
+
+
+ casono-rules-easy-description
+
+
+
+
Der Pokertisch ist ein unglaublich faszinierender Erlebnisraum, in
+dem man sehr viel lernen kann: über sich selbst, über andere Menschen
+und über Fragen wie: wie treffe ich eigentlich Entscheidungen, wie gehe
+ich mit Stress und Unsicherheit um und wie gut ich darin bin, mich in
+andere hineinzuversetzen und Situationen richtig einzuschätzen.
+
Damit Du in diesem Erlebnisraum starten kannst, ist es – wie bei
+jedem Spiel – notwendig, zuerst die Grundregeln und den Spielablauf zu
+verstehen.
+
Also los geht es:
+
Wir haben am Tisch 4 Spieler: Julian, Mathis, Jona
+und Lars. Jeder Spieler startet mit 20.000 Chips. Jeder
+bekommt 2 Karten auf die Hand und es gibt zusätzlich
+5 Gemeinschaftskarten, die später in der Mitte
+aufgedeckt werden.
+
+
+1. image
+
+
Die Spieler sitzen in folgender Reihenfolge: Julian, Mathis, Jona und
+Lars. Einer davon hat den Dealer-Button, der bestimmt, wer die Karten
+austeilt und von wo die Runde beginnt. Dieser Button wandert nach jeder
+Runde im Uhrzeigersinn weiter und verändert damit die Position
+ständig.
+
Regel: 34 Button Placement and Movement 🟢
+
Blinds (Small Blind & Big
+Blind)
+
Bevor die Karten verteilt werden, gibt es zwei Pflicht-Einsätze:
+
Der Small Blind und der Big Blind. Der Big Blind ist immer doppelt so
+hoch wie der Small Blind.
+
+
+2. image
+
+
Regel: 32 Dead Button 🟡
+
Diese Einsätze sorgen dafür, dass sofort ein Pot entsteht und das
+Spiel überhaupt beginnt, weil jeder schon “im Spiel” ist.
+
Danach werden die Karten verteilt: zuerst Small Blind, dann Big Blind
+und dann im Uhrzeigersinn alle anderen Spieler.
+
Erste Setzrunde (Preflop)
+
Die erste Setzrunde beginnt immer bei dem Spieler links vom Big
+Blind.
+
Jetzt muss jeder Spieler entscheiden:
+
+
Fold (aussteigen)
+
Call (mitgehen)
+
Raise (erhöhen)
+
+
Regel: 40 Methods of Betting 🟢 Regel: 41 Methods of
+Calling 🟢 Regel: 42 Methods of Raising 🟢 Regel: 50
+Acting in Turn 🟢
+
Beispiel Preflop
+
Julian schaut seine Karten an und entscheidet sich direkt für einen
+Call von 600 Chips.
+
+
+3. image
+
+
Mathis sieht seine Karten an und merkt, dass sie nicht gut sind, also
+foldet er und steigt aus.
+
+
+4. image
+
+
Jona ist nun dran und entscheidet sich ebenfalls für einen Call, weil
+seine Hand spielbar ist.
+
+
+5. image
+
+
Lars schaut seine Karten an, erkennt eine starke Hand und erhöht auf
+1200 Chips.
+
+
+6. image
+
+
Damit verändert sich sofort die Situation: Julian und Jona müssen
+entscheiden, ob sie diesen Raise bezahlen, selbst erhöhen oder
+aussteigen.
+
Flop (3 Gemeinschaftskarten)
+
Jetzt werden 3 Gemeinschaftskarten in die Mitte
+gelegt. Ab hier verändert sich das Spiel komplett, weil alle Spieler
+zusätzliche Informationen bekommen.
+
+
+7. image
+
+
Es beginnt eine neue Setzrunde.
+
Regel: 49 Accepted Action 🟢
+
Beispiel Flop
+
Lars setzt 1000 Chips als Erstes. Julian entscheidet
+sich mitzugehen (Call), weil seine Karten durch die Gemeinschaftskarten
+stärker geworden sind.
+
+
+8. image
+
+
Jona steigt aus, weil er keine gute Verbindung mehr sieht. Mathis ist
+bereits raus.
+
Turn (4. Karte)
+
Jetzt kommt die 4. Gemeinschaftskarte.
+
Wieder beginnt eine neue Setzrunde.
+
Lars setzt diesmal 3000 Chips. Julian bezahlt erneut
+(Call), weil seine Hand weiterhin gut spielbar ist.
+
+
+9. image
+
+
Regel: 53 Action Out of Turn 🟡
+
River (5. Karte)
+
Jetzt wird die letzte Gemeinschaftskarte aufgedeckt.
+
Dies ist die letzte Entscheidung im Spiel.
+
Lars setzt 5000 Chips.
+
+
+10. image
+
+
Julian muss jetzt entscheiden: Fold, Call oder Raise auf
+10000 Chips.
+
Regel: 54 Pot Size Bets 🟡
+
Showdown (Gewinnentscheidung)
+
Wenn nach der letzten Setzrunde noch zwei Spieler übrig sind, kommt
+es zum Showdown.
+
Beide Spieler zeigen ihre Karten offen. Gewonnen hat die
+beste 5-Karten-Kombination aus Handkarten und
+Gemeinschaftskarten.
+
+
+11. image
+
+
Regel: 12 Cards Speak at Showdown 🟢 Regel: 16 Face Up
+for All-Ins 🟢 Regel: 17 Non All-In Showdowns 🟢
+
Wenn Julian den letzten Einsatz bezahlt, werden die Hände verglichen.
+Wenn er foldet, gewinnt Lars automatisch den gesamten Pot.
+
Poker Hand Rankings
+(Gewichtung)
+
Die Kartenkombinationen sind klar geordnet – von schwach bis extrem
+stark:
+
+
+12. image
+
+
Je höher die Kombination, desto stärker die Hand und desto
+wahrscheinlicher der Gewinn.
+
Julian: 2. Paar:
+
+
+13. image
+
+
Lars: 1. Paar:
+
+
+14. image
+
+
Da zwei Paare in der Rangfolge über einem einzelnen Paar stehen,
+gewinnt Julian diese Runde.
+
Fazit
+
Poker ist kein Glücksspiel im klassischen Sinn, sondern ein Spiel aus
+Strategie, Psychologie und Mathematik. Jede Entscheidung von Julian,
+Mathis, Jona oder Lars verändert die komplette Dynamik am Tisch. Wer die
+Regeln versteht, versteht nicht nur Karten, sondern auch Menschen und
+Entscheidungen unter Druck.
+
Regel: 67 One Player One Hand 🟢 Regel: 52 Incorrect
+Bets 🟡 Regel: 57 Non-Standard Betting 🟡
+
English
+
The poker table is an incredibly fascinating experiential space where
+you can learn a great deal: about yourself, about other people, and
+about questions such as: How do I actually make decisions? How do I
+handle stress and uncertainty? And how good am I at empathizing with
+others and correctly assessing situations?
+
To enter this experiential space, it’s necessary—like with any
+game—to first understand the basic rules and game flow.
+
So let’s begin:
+
We have 4 players at the table: Julian, Mathis,
+Jona, and Lars. Each player starts with 20,000 chips.
+Each receives 2 hole cards, and there are 5
+community cards that will later be revealed in the center.
+
+
+1. image
+
+
The players are seated as follows: Julian, Mathis, Jona, and Lars.
+One of them holds the dealer button, which determines who deals the
+cards and where the round begins. This button moves clockwise after each
+hand, constantly changing the positions.
+
Rule: 34 Button Placement and Movement 🟢
+
Blinds (Small Blind & Big
+Blind)
+
Before cards are dealt, there are two mandatory bets:
+
The Small Blind and the Big Blind. The Big Blind is always double the
+amount of the Small Blind.
+
+
+2. image
+
+
Rule: 32 Dead Button 🟡
+
These forced bets ensure that a pot exists from the start, making the
+game begin with everyone already involved.
+
After this, the cards are dealt: first to the Small Blind, then the
+Big Blind, and then clockwise to all other players.
+
First Betting Round (Preflop)
+
The first betting round always begins with the player to the left of
+the Big Blind.
+
Now each player must decide:
+
+
Fold (exit the hand)
+
Call (match the current bet)
+
Raise (increase the bet)
+
+
Rule: 40 Methods of Betting 🟢
+Rule: 41 Methods of Calling 🟢
+Rule: 42 Methods of Raising 🟢
+Rule: 50 Acting in Turn 🟢
+
Preflop Example
+
Julian looks at his cards and decides to Call for 600
+chips.
+
+
+3. image
+
+
Mathis sees his cards and realizes they aren’t strong, so he Folds
+and exits the hand.
+
+
+4. image
+
+
Jona is next and decides to Call as well, because his hand is
+playable.
+
+
+5. image
+
+
Lars looks at his cards, recognizes a strong hand, and Raises to
+1200 chips.
+
+
+6. image
+
+
This immediately changes the situation: Julian and Jona must now
+decide whether to call this raise, re-raise, or fold.
+
Flop (3 Community Cards)
+
Now 3 community cards are placed face-up in the
+center. From this point, the game changes completely, as all players
+gain additional information.
+
+
+7. image
+
+
A new betting round begins.
+
Rule: 49 Accepted Action 🟢
+
Flop Example
+
Lars bets 1,000 chips first. Julian decides to Call
+because his hand has improved with the community cards.
+
+
+8. image
+
+
Jona folds, as he no longer sees a strong connection. Mathis is
+already out.
+
Turn (4th Card)
+
Now the 4th community card is revealed.
+
Another betting round begins.
+
Lars bets 3,000 chips this time. Julian calls again,
+as his hand remains strong.
+
+
+9. image
+
+
Rule: 53 Action Out of Turn 🟡
+
River (5th Card)
+
Now the final community card is revealed.
+
This is the last decision point in the hand.
+
Lars bets 5,000 chips.
+
+
+10. image
+
+
Julian must now decide: Fold, Call, or even Raise to 10,000
+chips.
+
Rule: 54 Pot Size Bets 🟡
+
Showdown (Winning Decision)
+
If two or more players remain after the final betting round, a
+showdown occurs.
+
All active players reveal their cards. The winner is the one with the
+best 5-card combination using any combination of their hole
+cards and the community cards.
+
+
+11. image
+
+
Rule: 12 Cards Speak at Showdown 🟢
+Rule: 16 Face Up for All-Ins 🟢
+Rule: 17 Non All-In Showdowns 🟢
+
If Julian calls the final bet, the hands are compared. If he folds,
+Lars wins the entire pot automatically.
+
Poker Hand Rankings
+(Hierarchy)
+
The card combinations are clearly ranked—from weakest to
+strongest:
+
+
+12. image
+
+
The higher the combination, the stronger the hand, and the greater
+the chance of winning.
+
Julian: Two Pair:
+
+
+13. image
+
+
Lars: One Pair:
+
+
+14. image
+
+
Since two pair ranks higher than one pair, Julian wins this
+round.
+
Conclusion
+
Poker is not gambling in the traditional sense, but rather a game of
+strategy, psychology, and mathematics. Every decision made by Julian,
+Mathis, Jona, or Lars changes the entire dynamic at the table.
+Understanding the rules means not only understanding cards, but also
+people and decision-making under pressure.
+
+
diff --git a/documents/docs/networking/client-network-architecture.md b/documents/docs/networking/client-network-architecture.md
new file mode 100644
index 0000000..38733fe
--- /dev/null
+++ b/documents/docs/networking/client-network-architecture.md
@@ -0,0 +1,249 @@
+# Client Nework Architecture
+
+
+* [Architecture Overview](#architecture-overview)
+ * [network/Card.java](#networkcardjava)
+ * [network/GameState.java](#networkgamestatejava)
+ * [network/Player.java](#networkplayerjava)
+ * [network/ChatClient.java](#networkchatclientjava)
+ * [ChatClient(ClientService clientService)](#chatclientclientservice-clientservice)
+ * [sendMessage(Message message)](#sendmessagemessage-message)
+ * [getMessages()](#getmessages)
+ * [network/ClientService.java](#networkclientservicejava)
+ * [ClientService(String ip, int port)](#clientservicestring-ip-int-port)
+ * [processCommand(String message)](#processcommandstring-message)
+ * [sendRequest(Runnable request)](#sendrequestrunnable-request)
+ * [getRuntimeException(Exception e)](#getruntimeexceptionexception-e)
+ * [closeSocket()](#closesocket)
+ * [writeToTransport(String s) throws IOException](#writetotransportstring-s-throws-ioexception)
+ * [network/CoreClient.java](#networkcoreclientjava)
+ * [CoreClient(ClientService clientservice)](#coreclientclientservice-clientservice)
+ * [ping()](#ping)
+ * [login(String user)](#loginstring-user)
+ * [network/GameClient.java](#networkgameclientjava)
+ * [GameClient(ClientService client)](#gameclientclientservice-client)
+ * [getGameState()](#getgamestate)
+ * [parseGameState(String input)](#parsegamestatestring-input)
+ * [Example server response](#example-server-response)
+ * [network/LobbyClient.java](#networklobbyclientjava)
+ * [LobbyClient(ClientService client)](#lobbyclientclientservice-client)
+ * [fetchLobbyStatusString(int lobbyId)](#fetchlobbystatusstringint-lobbyid)
+ * [createLobby()](#createlobby)
+ * [getLobbyId()](#getlobbyid)
+ * [joinLobby(int lobbyId)](#joinlobbyint-lobbyid)
+
+
+
+## Architecture Overview
+
+```text
+client/
+ ├── game/
+ │ ├── Card.java
+ │ ├── GameState.java
+ │ └── Player.java
+ │
+ └── network/
+ ├── ChatClient.java
+ ├── ClientService.java
+ ├── CoreClient.java
+ ├── GameClient.java
+ └── LobbyClient.java
+```
+
+### game/Card.java
+
+Represents a playing card with a value and suit.
+
+### game/GameState.java
+
+Represents the current state of the poker game, including the phase, pot size, current bet, dealer position, active player, community cards, and player information.
+
+### game/Player.java
+
+Represents a player in the poker game, including their name, chip count, current bet, state (e.g., `active`, `folded`), and their hole cards.
+
+### network/ChatClient.java
+
+The ChatClient class is responsible for sending messages to the server and retrieving messages from the server. It uses the ClientService to send commands and receive responses from the server.
+
+#### ChatClient(ClientService clientService)
+
+Constructs a ChatClient with the given ClientService for communication.
+
+- **Parameter (`clientService`)**: The ClientService instance used to send commands and receive responses from the server.
+
+#### sendMessage(Message message)
+
+Send a Message to the server by converting it to a string format and sending a `SEND_MESSAGE` command with the message content as arguments.
+
+- **Parameter (`message`)**: message The Message object to be sent to the server.
+
+#### getMessages()
+
+Retrieve messages from the server by first sending a `GET_MESSAGE_COUNT` command to determine how many messages are available and then sending `GET_NEXT_MESSAGE` commands in a loop to retrieve each message. The retrieved messages are parsed into Message objects and returned as a list.
+
+- **Parameter (`A`)**: list of Message objects representing the messages retrieved from the server.
+
+### network/ClientService.java
+
+The ClientService class is responsible for managing the connection to the server, sending commands, and receiving responses. It uses a TcpTransport to
+communicate with the server and an ExecutorService to handle asynchronous requests.
+
+#### ClientService(String ip, int port)
+
+Constructs a ClientService with the given server IP and port. It establishes a socket connection to the server and initializes the TcpTransport and ExecutorService for communication.
+
+- **Parameter (`ip`)**: The IP address of the server to connect to.
+- **Parameter (`port`)**: The port number of the server to connect to.
+
+#### processCommand(String message)
+
+Sends a command to the server and waits for the response. The command is sent using the TcpTransport, and the response is read in a loop until a valid response is received. The method handles `+OK` and `-ERROR` responses from the server and returns the actual response content.
+
+- **Parameter (`message`)**: The command message to be sent to the server.
+- **Return**: The response from the server as a string.
+
+#### sendRequest(Runnable request)
+
+Helper method to send a request to the server using the ExecutorService. It submits the request as a Runnable task and waits for its completion. If the task is interrupted or encounters an execution exception, it throws a
+RuntimeException with the appropriate cause.
+
+- **Parameter (`request`)**: The Runnable task representing the request to be sent to the server.
+
+#### getRuntimeException(Exception e)
+
+Helper method to extract the cause of an exception and return it as a RuntimeException. If the cause is null, it returns the original exception as a RuntimeException. If the cause is already a RuntimeException, it returns it directly. Otherwise, it wraps the cause in a new RuntimeException and returns it.
+
+- **Parameter (`e`)**: The exception from which to extract the cause.
+- **Return**: A RuntimeException representing the cause of the original exception.
+
+#### closeSocket()
+
+Closes the socket connection to the server and shuts down the ExecutorService. It also closes the TcpTransport used for communication. If any IOException occurs during this process, it prints the exception to the console.
+
+#### writeToTransport(String s) throws IOException
+
+Helper method to write a command string to the TcpTransport. It generates a unique ID for the command using the idGenerator and sends a RawPacket containing the ID and the command string to the server. If an IOException occurs during this process, it throws a RuntimeException with the cause.
+
+- **Parameter (`s`)**: The command string to be sent to the server.
+- **Throws IOException**: If an I/O error occurs while writing to the transport.
+
+### network/CoreClient.java
+
+The CoreClient class provides basic functionalities for communicating with the server, such as sending a ping command to check connectivity and logging in with a username. It uses the ClientService to send commands and receive responses from the server.
+
+#### CoreClient(ClientService clientservice)
+
+Constructs a CoreClient with the given ClientService for communication.
+
+- **Parameter (`clientservice`)**: The ClientService instance used to send commands and receive responses from the server.
+
+#### ping()
+
+Sends a `PING` command to the server to check connectivity. The server should respond with a `PONG` message if the connection is successful.
+
+#### login(String user)
+
+Logs in to the server with the given username by sending a `LOGIN` command.
+
+- **Parameter (`user`)**: The username to log in with.
+
+### network/GameClient.java
+
+The GameClient class is responsible for communicating with the server to retrieve the current game state. It sends a command to the server and parses the response into a structured GameState object.
+
+#### GameClient(ClientService client)
+
+Constructs a GameClient with the given ClientService for communication.
+
+- **Parameter (`client`)**: The ClientService instance used to send commands and receive responses from the server.
+
+#### getGameState()
+
+Retrieves the current game state from the server by sending a command and parsing the response.
+
+- **Return**: A GameState object representing the current state of the game.
+
+#### parseGameState(String input)
+
+Parses the raw response from the server into a structured GameState object.
+
+- **Parameter (`input`)**: The raw response string from the server.
+- **Return**: A GameState object representing the current state of the game.
+
+#### Example server response
+
+```text
++OK
+ PHASE=FLO P
+ POT=150
+ CURRENT_BET=50
+ DEALER=0
+ ACTIVE_PLAYER=1
+ CARDS
+ CARD
+ VALUE=10
+ SUIT=H
+ CARD
+ VALUE=7
+ SUIT=S
+ CARD
+ VALUE=A
+ SUIT=D
+ PLAYERS
+ PLAYER
+ NAME=Max
+ CHIPS=1200
+ BET=50
+ STATE=ACTIVE
+ CARDS
+ CARD
+ VALUE=K
+ SUIT=H
+ CARD
+ VALUE=3
+ SUIT=C
+ PLAYER
+ NAME=Anna
+ CHIPS=800
+ BET=0
+ STATE=FOLDED
+ CARDS
+END
+```
+
+### network/LobbyClient.java
+
+The LobbyClient class is responsible for communicating with the server to manage game lobbies. It provides methods to create a lobby, join a lobby, and fetch the current status of a lobby by sending appropriate commands to the server and processing the responses.
+
+#### LobbyClient(ClientService client)
+
+Constructs a LobbyClient with the given ClientService for communication.
+
+- **Parameter (`client`)**: The ClientService instance used to send commands and receive responses from the server.
+
+#### fetchLobbyStatusString(int lobbyId)
+
+Fetch the current status of the lobby with the given id from the server.
+
+- **Parameter (`lobbyId`)**: The id of the lobby to fetch the status for.
+- **Return**: A string representing the current status of the lobby, as returned by the server.
+
+#### createLobby()
+
+Request the server to create a new lobby and return the id of the newly created lobby.
+
+- **Return**: The id of the newly created lobby, as returned by the server.
+
+#### getLobbyId()
+
+Request the server to return the id of the lobby that the client is currently in.
+
+- **Return**: The id of the lobby that the client is currently in, as returned by the server.
+
+#### joinLobby(int lobbyId)
+
+Request the server to join the lobby with the given id.
+
+- **Parameter (`lobbyId`)**: The id of the lobby to join.
diff --git a/documents/docs/networking/commands/protocol-document.md b/documents/docs/networking/commands/protocol-document.md
index b08cf7f..2a5aca9 100644
--- a/documents/docs/networking/commands/protocol-document.md
+++ b/documents/docs/networking/commands/protocol-document.md
@@ -50,6 +50,42 @@ This document describes the protocol for client-server communication in our appl
- [Error Response](#error-response-6)
- [Example Request](#example-request-4)
- [Example Response](#example-response-4)
+ - [GET_LOBBY_LIST command](#get_lobby_list-command)
+ - [Required pre-execution checks](#required-pre-execution-checks)
+ - [Request Parameters](#request-parameters)
+ - [Success Response](#success-response)
+ - [Example Request](#example-request)
+ - [Example Response](#example-response)
+ - [GET_GAME_STATE command](#get_game_state-command)
+ - [Required pre-execution checks](#required-pre-execution-checks)
+ - [Request Parameters](#request-parameters)
+ - [Success Response](#success-response)
+ - [Example Request](#example-request)
+ - [Example Response](#example-response)
+ - [RAISE command](#raise-command)
+ - [CALL command](#call-command)
+ - [FOLD command](#fold-command)
+ - [BET command](#bet-command)
+ - [SEND_MESSAGE command](#send_message-command)
+ - [Required pre-execution checks](#required-pre-execution-checks)
+ - [Request Parameters](#request-parameters)
+ - [Success Response](#success-response)
+ - [GET_MESSAGE_COUNT command](#get_message_count-command)
+ - [Required pre-execution checks](#required-pre-execution-checks)
+ - [Request Parameters](#request-parameters)
+ - [Success Response](#success-response)
+ - [GET_NEXT_MESSAGE command](#get_next_message-command)
+ - [Required pre-execution checks](#required-pre-execution-checks)
+ - [Request Parameters](#request-parameters)
+ - [Success Response](#success-response)
+ - [JOIN_LOBBY command](#join_lobby-command)
+ - [Required pre-execution checks](#required-pre-execution-checks)
+ - [Request Parameters](#request-parameters)
+ - [Success Response](#success-response)
+ - [GET_LOBBY_STATUS command](#get_lobby_status-command)
+ - [Required pre-execution checks](#required-pre-execution-checks)
+ - [Request Parameters](#request-parameters)
+ - [Success Response](#success-response)
@@ -341,4 +377,738 @@ LIST_USERS
END
END
END
+```
+
+## SEND_MESSAGE command
+The `SEND_MESSAGE` command is used to transfer the chat message sent by a user to the server.
+### Required pre-execution checks
+None.
+
+### Request Parameters
+
+| Field | Type | Description |
+|:---------|:----------------|:-------------------------------------------------------------------|
+| `TYPE` | `Enum Source:
+
+
+* [Deustch](#deustch)
+ * [Blinds (Small Blind & Big Blind)](#blinds-small-blind--big-blind)
+ * [Erste Setzrunde (Preflop)](#erste-setzrunde-preflop)
+ * [Beispiel Preflop](#beispiel-preflop)
+ * [Flop (3 Gemeinschaftskarten)](#flop-3-gemeinschaftskarten)
+ * [Beispiel Flop](#beispiel-flop)
+ * [Turn (4. Karte)](#turn-4-karte)
+ * [River (5. Karte)](#river-5-karte)
+ * [Showdown (Gewinnentscheidung)](#showdown-gewinnentscheidung)
+ * [Poker Hand Rankings (Gewichtung)](#poker-hand-rankings-gewichtung)
+ * [Fazit](#fazit)
+* [English](#english)
+ * [Blinds (Small Blind & Big Blind)](#blinds-small-blind--big-blind-1)
+ * [First Betting Round (Preflop)](#first-betting-round-preflop)
+ * [Preflop Example](#preflop-example)
+ * [Flop (3 Community Cards)](#flop-3-community-cards)
+ * [Flop Example](#flop-example)
+ * [Turn (4th Card)](#turn-4th-card)
+ * [River (5th Card)](#river-5th-card)
+ * [Showdown (Winning Decision)](#showdown-winning-decision)
+ * [Poker Hand Rankings (Hierarchy)](#poker-hand-rankings-hierarchy)
+ * [Conclusion](#conclusion)
+
+
+
+## Deutsch
+
+Der Pokertisch ist ein unglaublich faszinierender Erlebnisraum, in dem man sehr viel lernen kann: über sich selbst, über andere Menschen und über Fragen wie: wie treffe ich eigentlich Entscheidungen, wie gehe ich mit Stress und Unsicherheit um und wie gut ich darin bin, mich in andere hineinzuversetzen und Situationen richtig einzuschätzen.
+
+Damit Du in diesem Erlebnisraum starten kannst, ist es – wie bei jedem Spiel – notwendig, zuerst die Grundregeln und den Spielablauf zu verstehen.
+
+Also los geht es:
+
+Wir haben am Tisch **4 Spieler**: Julian, Mathis, Jona und Lars. Jeder Spieler startet mit **20.000 Chips**. Jeder bekommt **2 Karten auf die Hand** und es gibt zusätzlich **5 Gemeinschaftskarten**, die später in der Mitte aufgedeckt werden.
+
+
+
+Die Spieler sitzen in folgender Reihenfolge: Julian, Mathis, Jona und Lars. Einer davon hat den Dealer-Button, der bestimmt, wer die Karten austeilt und von wo die Runde beginnt. Dieser Button wandert nach jeder Runde im Uhrzeigersinn weiter und verändert damit die Position ständig.
+
+Regel: *34 Button Placement and Movement 🟢*
+
+### Blinds (Small Blind & Big Blind)
+
+Bevor die Karten verteilt werden, gibt es zwei Pflicht-Einsätze:
+
+Der Small Blind und der Big Blind. Der Big Blind ist immer doppelt so hoch wie der Small Blind.
+
+
+
+Regel: *32 Dead Button 🟡*
+
+Diese Einsätze sorgen dafür, dass sofort ein Pot entsteht und das Spiel überhaupt beginnt, weil jeder schon “im Spiel” ist.
+
+Danach werden die Karten verteilt: zuerst Small Blind, dann Big Blind und dann im Uhrzeigersinn alle anderen Spieler.
+
+### Erste Setzrunde (Preflop)
+
+Die erste Setzrunde beginnt immer bei dem Spieler links vom Big Blind.
+
+Jetzt muss jeder Spieler entscheiden:
+
+* Fold (aussteigen)
+* Call (mitgehen)
+* Raise (erhöhen)
+
+Regel: *40 Methods of Betting 🟢*
+Regel: *41 Methods of Calling 🟢*
+Regel: *42 Methods of Raising 🟢*
+Regel: *50 Acting in Turn 🟢*
+
+### Beispiel Preflop
+
+Julian schaut seine Karten an und entscheidet sich direkt für einen Call von **600 Chips**.
+
+
+
+Mathis sieht seine Karten an und merkt, dass sie nicht gut sind, also foldet er und steigt aus.
+
+
+
+Jona ist nun dran und entscheidet sich ebenfalls für einen Call, weil seine Hand spielbar ist.
+
+
+
+Lars schaut seine Karten an, erkennt eine starke Hand und erhöht auf **1200 Chips**.
+
+
+
+Damit verändert sich sofort die Situation: Julian und Jona müssen entscheiden, ob sie diesen Raise bezahlen, selbst erhöhen oder aussteigen.
+
+### Flop (3 Gemeinschaftskarten)
+
+Jetzt werden **3 Gemeinschaftskarten** in die Mitte gelegt. Ab hier verändert sich das Spiel komplett, weil alle Spieler zusätzliche Informationen bekommen.
+
+
+
+Es beginnt eine neue Setzrunde.
+
+Regel: *49 Accepted Action 🟢*
+
+### Beispiel Flop
+
+Lars setzt **1000 Chips** als Erstes. Julian entscheidet sich mitzugehen (Call), weil seine Karten durch die Gemeinschaftskarten stärker geworden sind.
+
+
+
+Jona steigt aus, weil er keine gute Verbindung mehr sieht. Mathis ist bereits raus.
+
+### Turn (4. Karte)
+
+Jetzt kommt die **4. Gemeinschaftskarte**.
+
+Wieder beginnt eine neue Setzrunde.
+
+Lars setzt diesmal **3000 Chips**. Julian bezahlt erneut (Call), weil seine Hand weiterhin gut spielbar ist.
+
+
+
+Regel: *53 Action Out of Turn 🟡*
+
+### River (5. Karte)
+
+Jetzt wird die letzte Gemeinschaftskarte aufgedeckt.
+
+Dies ist die letzte Entscheidung im Spiel.
+
+Lars setzt **5000 Chips**.
+
+
+
+Julian muss jetzt entscheiden: Fold, Call oder Raise auf **10000 Chips**.
+
+Regel: *54 Pot Size Bets 🟡*
+
+### Showdown (Gewinnentscheidung)
+
+Wenn nach der letzten Setzrunde noch zwei Spieler übrig sind, kommt es zum Showdown.
+
+Beide Spieler zeigen ihre Karten offen. Gewonnen hat die **beste 5-Karten-Kombination aus Handkarten und Gemeinschaftskarten**.
+
+
+
+Regel: *12 Cards Speak at Showdown 🟢*
+Regel: *16 Face Up for All-Ins 🟢*
+Regel: *17 Non All-In Showdowns 🟢*
+
+Wenn Julian den letzten Einsatz bezahlt, werden die Hände verglichen. Wenn er foldet, gewinnt Lars automatisch den gesamten Pot.
+
+### Poker Hand Rankings (Gewichtung)
+
+Die Kartenkombinationen sind klar geordnet – von schwach bis extrem stark:
+
+
+
+Je höher die Kombination, desto stärker die Hand und desto wahrscheinlicher der Gewinn.
+
+Julian: 2. Paar:
+
+
+
+Lars: 1. Paar:
+
+
+
+Da zwei Paare in der Rangfolge über einem einzelnen Paar stehen, gewinnt Julian diese Runde.
+
+### Fazit
+
+Poker ist kein Glücksspiel im klassischen Sinn, sondern ein Spiel aus Strategie, Psychologie und Mathematik. Jede Entscheidung von Julian, Mathis, Jona oder Lars verändert die komplette Dynamik am Tisch. Wer die Regeln versteht, versteht nicht nur Karten, sondern auch Menschen und Entscheidungen unter Druck.
+
+Regel: *67 One Player One Hand 🟢*
+Regel: *52 Incorrect Bets 🟡*
+Regel: *57 Non-Standard Betting 🟡*
+
+## English
+
+The poker table is an incredibly fascinating experiential space where you can learn a great deal: about yourself, about other people, and about questions such as: How do I actually make decisions? How do I handle stress and uncertainty? And how good am I at empathizing with others and correctly assessing situations?
+
+To enter this experiential space, it’s necessary—like with any game—to first understand the basic rules and game flow.
+
+So let’s begin:
+
+We have **4 players** at the table: Julian, Mathis, Jona, and Lars. Each player starts with **20,000 chips**. Each receives **2 hole cards**, and there are **5 community cards** that will later be revealed in the center.
+
+
+
+The players are seated as follows: Julian, Mathis, Jona, and Lars. One of them holds the dealer button, which determines who deals the cards and where the round begins. This button moves clockwise after each hand, constantly changing the positions.
+
+Rule: *34 Button Placement and Movement 🟢*
+
+### Blinds (Small Blind & Big Blind)
+
+Before cards are dealt, there are two mandatory bets:
+
+The Small Blind and the Big Blind. The Big Blind is always double the amount of the Small Blind.
+
+
+
+Rule: *32 Dead Button 🟡*
+
+These forced bets ensure that a pot exists from the start, making the game begin with everyone already involved.
+
+After this, the cards are dealt: first to the Small Blind, then the Big Blind, and then clockwise to all other players.
+
+### First Betting Round (Preflop)
+
+The first betting round always begins with the player to the left of the Big Blind.
+
+Now each player must decide:
+
+* Fold (exit the hand)
+* Call (match the current bet)
+* Raise (increase the bet)
+
+Rule: *40 Methods of Betting 🟢*
+Rule: *41 Methods of Calling 🟢*
+Rule: *42 Methods of Raising 🟢*
+Rule: *50 Acting in Turn 🟢*
+
+### Preflop Example
+
+Julian looks at his cards and decides to Call for **600 chips**.
+
+
+
+Mathis sees his cards and realizes they aren’t strong, so he Folds and exits the hand.
+
+
+
+Jona is next and decides to Call as well, because his hand is playable.
+
+
+
+Lars looks at his cards, recognizes a strong hand, and Raises to **1200 chips**.
+
+
+
+This immediately changes the situation: Julian and Jona must now decide whether to call this raise, re-raise, or fold.
+
+### Flop (3 Community Cards)
+
+Now **3 community cards** are placed face-up in the center. From this point, the game changes completely, as all players gain additional information.
+
+
+
+A new betting round begins.
+
+Rule: *49 Accepted Action 🟢*
+
+### Flop Example
+
+Lars bets **1,000 chips** first. Julian decides to Call because his hand has improved with the community cards.
+
+
+
+Jona folds, as he no longer sees a strong connection. Mathis is already out.
+
+### Turn (4th Card)
+
+Now the **4th community card** is revealed.
+
+Another betting round begins.
+
+Lars bets **3,000 chips** this time. Julian calls again, as his hand remains strong.
+
+
+
+Rule: *53 Action Out of Turn 🟡*
+
+### River (5th Card)
+
+Now the final community card is revealed.
+
+This is the last decision point in the hand.
+
+Lars bets **5,000 chips**.
+
+
+
+Julian must now decide: Fold, Call, or even Raise to **10,000 chips**.
+
+Rule: *54 Pot Size Bets 🟡*
+
+### Showdown (Winning Decision)
+
+If two or more players remain after the final betting round, a showdown occurs.
+
+All active players reveal their cards. The winner is the one with the **best 5-card combination using any combination of their hole cards and the community cards**.
+
+
+
+Rule: *12 Cards Speak at Showdown 🟢*
+Rule: *16 Face Up for All-Ins 🟢*
+Rule: *17 Non All-In Showdowns 🟢*
+
+If Julian calls the final bet, the hands are compared. If he folds, Lars wins the entire pot automatically.
+
+### Poker Hand Rankings (Hierarchy)
+
+The card combinations are clearly ranked—from weakest to strongest:
+
+
+
+The higher the combination, the stronger the hand, and the greater the chance of winning.
+
+Julian: Two Pair:
+
+
+
+Lars: One Pair:
+
+
+
+Since two pair ranks higher than one pair, Julian wins this round.
+
+### Conclusion
+
+Poker is not gambling in the traditional sense, but rather a game of strategy, psychology, and mathematics. Every decision made by Julian, Mathis, Jona, or Lars changes the entire dynamic at the table. Understanding the rules means not only understanding cards, but also people and decision-making under pressure.
diff --git a/documents/milestones/ms-4/casono-rules-easy-description.pdf b/documents/milestones/ms-4/casono-rules-easy-description.pdf
new file mode 100644
index 0000000..7964001
--- /dev/null
+++ b/documents/milestones/ms-4/casono-rules-easy-description.pdf
@@ -0,0 +1,13777 @@
+%PDF-1.4
+%
+1 0 obj
+<<
+/Dests 2 0 R
+/MarkInfo <<
+/Marked true
+/Type /MarkInfo
+>>
+/Pages 3 0 R
+/StructTreeRoot 4 0 R
+/Type /Catalog
+/ViewerPreferences <<
+/DisplayDocTitle true
+/Type /ViewerPreferences
+>>
+>>
+endobj
+5 0 obj
+<<
+/CreationDate (D:20260409095903+00'00')
+/Creator (Mozilla/5.0 \(X11; Linux x86_64\) AppleWebKit/537.36 \(KHTML, like Gecko\) HeadlessChrome/146.0.0.0 Safari/537.36)
+/ModDate (D:20260409095903+00'00')
+/Producer (Skia/PDF m146)
+/Title (casono-rules-easy-description)
+>>
+endobj
+2 0 obj
+<<
+/beispiel-flop [6 0 R /XYZ 62.25 333 0]
+/beispiel-preflop [7 0 R /XYZ 62.25 492 0]
+/conclusion [8 0 R /XYZ 62.25 792 0]
+/english [9 0 R /XYZ 62.25 738.75 0]
+/erste-setzrunde-preflop [7 0 R /XYZ 62.25 677.25 0]
+/fazit [10 0 R /XYZ 62.25 157.5 0]
+/first-betting-round-preflop [11 0 R /XYZ 62.25 450.75 0]
+/flop-3-community-cards [12 0 R /XYZ 62.25 477 0]
+/flop-3-gemeinschaftskarten [6 0 R /XYZ 62.25 703.5 0]
+/flop-example [13 0 R /XYZ 62.25 792 0]
+/poker-hand-rankings-gewichtung [14 0 R /XYZ 62.25 792 0]
+/poker-hand-rankings-hierarchy [15 0 R /XYZ 62.25 689.25 0]
+/preflop-example [11 0 R /XYZ 62.25 222.75 0]
+/river-5th-card [16 0 R /XYZ 62.25 792 0]
+/showdown-gewinnentscheidung [17 0 R /XYZ 62.25 479.25 0]
+/showdown-winning-decision [16 0 R /XYZ 62.25 397.5 0]
+/turn-4th-card [13 0 R /XYZ 62.25 447 0]
+>>
+endobj
+3 0 obj
+<<
+/Count 18
+/Kids [18 0 R 19 0 R 20 0 R]
+/Type /Pages
+>>
+endobj
+4 0 obj
+<<
+/K 21 0 R
+/ParentTree 22 0 R
+/ParentTreeNextKey 18
+/Type /StructTreeRoot
+>>
+endobj
+6 0 obj
+<<
+/Contents [23 0 R 24 0 R 25 0 R 26 0 R]
+/MediaBox [0 0 612 792]
+/Parent 18 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F29 28 0 R
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X46 31 0 R
+/OL2 32 0 R
+>>
+>>
+/StructParents 4
+/Tabs /S
+/Type /Page
+>>
+endobj
+7 0 obj
+<<
+/Contents [33 0 R 34 0 R 35 0 R 36 0 R]
+/MediaBox [0 0 612 792]
+/Parent 18 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F29 28 0 R
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X34 37 0 R
+/OL2 38 0 R
+>>
+>>
+/StructParents 2
+/Tabs /S
+/Type /Page
+>>
+endobj
+8 0 obj
+<<
+/Contents [39 0 R 40 0 R 41 0 R 42 0 R]
+/MediaBox [0 0 612 792]
+/Parent 20 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/OL1 43 0 R
+>>
+>>
+/StructParents 17
+/Tabs /S
+/Type /Page
+>>
+endobj
+9 0 obj
+<<
+/Contents [44 0 R 45 0 R 46 0 R 47 0 R]
+/MediaBox [0 0 612 792]
+/Parent 19 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F29 28 0 R
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X26 48 0 R
+/OL2 49 0 R
+>>
+>>
+/StructParents 9
+/Tabs /S
+/Type /Page
+>>
+endobj
+10 0 obj
+<<
+/Contents [50 0 R 51 0 R 52 0 R 53 0 R]
+/MediaBox [0 0 612 792]
+/Parent 19 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X65 54 0 R
+/X67 55 0 R
+/OL3 56 0 R
+>>
+>>
+/StructParents 8
+/Tabs /S
+/Type /Page
+>>
+endobj
+11 0 obj
+<<
+/Contents [57 0 R 58 0 R 59 0 R 60 0 R]
+/MediaBox [0 0 612 792]
+/Parent 19 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F29 28 0 R
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X30 61 0 R
+/OL2 62 0 R
+>>
+>>
+/StructParents 10
+/Tabs /S
+/Type /Page
+>>
+endobj
+12 0 obj
+<<
+/Contents [63 0 R 64 0 R 65 0 R 66 0 R]
+/MediaBox [0 0 612 792]
+/Parent 19 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F29 28 0 R
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X42 67 0 R
+/X46 31 0 R
+/OL3 68 0 R
+>>
+>>
+/StructParents 12
+/Tabs /S
+/Type /Page
+>>
+endobj
+13 0 obj
+<<
+/Contents [69 0 R 70 0 R 71 0 R 72 0 R]
+/MediaBox [0 0 612 792]
+/Parent 19 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F29 28 0 R
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X50 73 0 R
+/X52 74 0 R
+/OL3 75 0 R
+>>
+>>
+/StructParents 13
+/Tabs /S
+/Type /Page
+>>
+endobj
+14 0 obj
+<<
+/Contents [76 0 R 77 0 R 78 0 R 79 0 R]
+/MediaBox [0 0 612 792]
+/Parent 18 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X62 80 0 R
+/OL2 81 0 R
+>>
+>>
+/StructParents 7
+/Tabs /S
+/Type /Page
+>>
+endobj
+15 0 obj
+<<
+/Contents [82 0 R 83 0 R 84 0 R 85 0 R]
+/MediaBox [0 0 612 792]
+/Parent 19 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F29 28 0 R
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X62 80 0 R
+/OL2 86 0 R
+>>
+>>
+/StructParents 15
+/Tabs /S
+/Type /Page
+>>
+endobj
+16 0 obj
+<<
+/Contents [87 0 R 88 0 R 89 0 R 90 0 R]
+/MediaBox [0 0 612 792]
+/Parent 19 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F29 28 0 R
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X56 91 0 R
+/X58 92 0 R
+/OL3 93 0 R
+>>
+>>
+/StructParents 14
+/Tabs /S
+/Type /Page
+>>
+endobj
+17 0 obj
+<<
+/Contents [94 0 R 95 0 R 96 0 R 97 0 R]
+/MediaBox [0 0 612 792]
+/Parent 18 0 R
+/Resources <<
+/ExtGState <<
+/G3 27 0 R
+>>
+/Font <<
+/F29 28 0 R
+/F4 29 0 R
+/F5 30 0 R
+>>
+/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
+/XObject <<
+/X56 91 0 R
+/X58 92 0 R
+/OL3 98 0 R
+>>
+>>
+/StructParents 6
+/Tabs /S
+/Type /Page
+>>
+endobj
+18 0 obj
+<<
+/Count 8
+/Kids [99 0 R 100 0 R 7 0 R 101 0 R 6 0 R 102 0 R 17 0 R 14 0 R]
+/Parent 3 0 R
+/Type /Pages
+>>
+endobj
+19 0 obj
+<<
+/Count 8
+/Kids [10 0 R 9 0 R 11 0 R 103 0 R 12 0 R 13 0 R 16 0 R 15 0 R]
+/Parent 3 0 R
+/Type /Pages
+>>
+endobj
+20 0 obj
+<<
+/Count 2
+/Kids [104 0 R 8 0 R]
+/Parent 3 0 R
+/Type /Pages
+>>
+endobj
+21 0 obj
+<<
+/K [105 0 R 106 0 R 107 0 R 108 0 R 109 0 R 110 0 R 111 0 R 112 0 R 113 0 R 114 0 R
+115 0 R 116 0 R 117 0 R 118 0 R 119 0 R 120 0 R 121 0 R 122 0 R 123 0 R 124 0 R
+125 0 R 126 0 R 127 0 R 128 0 R 129 0 R 130 0 R 131 0 R 132 0 R 133 0 R 134 0 R
+135 0 R 136 0 R 137 0 R 138 0 R 139 0 R 140 0 R 141 0 R 142 0 R 143 0 R 144 0 R
+145 0 R 146 0 R 147 0 R 148 0 R 149 0 R 150 0 R 151 0 R 152 0 R 153 0 R 154 0 R
+155 0 R 156 0 R 157 0 R 158 0 R 159 0 R 160 0 R 161 0 R 162 0 R 163 0 R 164 0 R
+165 0 R 166 0 R 167 0 R 168 0 R 169 0 R 170 0 R 171 0 R 172 0 R 173 0 R 174 0 R
+175 0 R 176 0 R 177 0 R 178 0 R 179 0 R 180 0 R 181 0 R 182 0 R 183 0 R 184 0 R
+185 0 R 186 0 R 187 0 R 188 0 R 189 0 R 190 0 R 191 0 R 192 0 R 193 0 R 194 0 R
+195 0 R 196 0 R 197 0 R 198 0 R 199 0 R 200 0 R 201 0 R 202 0 R 203 0 R 204 0 R
+205 0 R 206 0 R 207 0 R 208 0 R 209 0 R 210 0 R 211 0 R 212 0 R 213 0 R 214 0 R
+215 0 R 216 0 R 217 0 R 218 0 R 219 0 R 220 0 R 221 0 R 222 0 R 223 0 R 224 0 R
+225 0 R 226 0 R 227 0 R 228 0 R 229 0 R 230 0 R 231 0 R 232 0 R 233 0 R 234 0 R
+235 0 R 236 0 R 237 0 R 238 0 R 239 0 R 240 0 R 241 0 R 242 0 R 243 0 R 244 0 R
+245 0 R 246 0 R]
+/P 4 0 R
+/S /Document
+/Type /StructElem
+>>
+endobj
+22 0 obj
+<<
+/Nums [0 [106 0 R 247 0 R 248 0 R 249 0 R 250 0 R 251 0 R 252 0 R 253 0 R 254 0 R 255 0 R
+256 0 R 257 0 R 258 0 R 259 0 R 260 0 R 261 0 R 262 0 R 263 0 R 264 0 R 265 0 R
+266 0 R 267 0 R 268 0 R 269 0 R 270 0 R 271 0 R 272 0 R 273 0 R 274 0 R 275 0 R
+276 0 R 277 0 R 278 0 R 279 0 R 280 0 R 281 0 R 282 0 R 283 0 R 284 0 R 285 0 R
+286 0 R 287 0 R 288 0 R 289 0 R 290 0 R 291 0 R 292 0 R 293 0 R 294 0 R 295 0 R
+296 0 R]
+ 1 [297 0 R 298 0 R 299 0 R 300 0 R 301 0 R 302 0 R 303 0 R 304 0 R 305 0 R 306 0 R
+307 0 R 308 0 R 309 0 R 310 0 R 311 0 R 312 0 R 313 0 R]
+ 2 [314 0 R 315 0 R 316 0 R 317 0 R 318 0 R 319 0 R 320 0 R 321 0 R 322 0 R 323 0 R
+324 0 R 325 0 R 326 0 R 327 0 R 328 0 R 329 0 R 330 0 R 331 0 R 332 0 R 333 0 R
+334 0 R 335 0 R 336 0 R 337 0 R 338 0 R 339 0 R 340 0 R]
+ 3 [341 0 R 342 0 R 343 0 R 344 0 R 345 0 R 346 0 R 347 0 R]
+ 4 [348 0 R 349 0 R 350 0 R 351 0 R 352 0 R 353 0 R 354 0 R 355 0 R 356 0 R 357 0 R
+358 0 R 359 0 R 360 0 R]
+5 [361 0 R 362 0 R 363 0 R 364 0 R 365 0 R 366 0 R 367 0 R 368 0 R 369 0 R 370 0 R
+371 0 R 372 0 R 373 0 R 374 0 R 375 0 R 376 0 R]
+ 6 [377 0 R 378 0 R 379 0 R 380 0 R 381 0 R 382 0 R 383 0 R 384 0 R 385 0 R 386 0 R
+387 0 R 388 0 R 389 0 R 390 0 R 391 0 R 392 0 R 393 0 R 394 0 R 395 0 R 396 0 R
+397 0 R 398 0 R]
+ 7 [399 0 R 400 0 R 401 0 R 402 0 R 403 0 R]
+ 8 [404 0 R 405 0 R 406 0 R 407 0 R 408 0 R 409 0 R]
+ 9 [410 0 R 411 0 R 412 0 R 413 0 R 414 0 R 415 0 R 416 0 R 417 0 R 418 0 R 419 0 R
+420 0 R 421 0 R 422 0 R 423 0 R 424 0 R 425 0 R 426 0 R 427 0 R 428 0 R 429 0 R
+430 0 R 431 0 R 432 0 R 433 0 R 434 0 R 435 0 R]
+10 [436 0 R 437 0 R 438 0 R 439 0 R 440 0 R 441 0 R 442 0 R 443 0 R 444 0 R 445 0 R
+446 0 R 447 0 R 448 0 R 449 0 R 450 0 R 451 0 R 452 0 R 453 0 R 454 0 R 455 0 R
+456 0 R 457 0 R 458 0 R 459 0 R 460 0 R 461 0 R]
+ 11 [462 0 R 463 0 R 464 0 R 465 0 R 466 0 R]
+ 12 [467 0 R 468 0 R 469 0 R 470 0 R 471 0 R 472 0 R 473 0 R 474 0 R 475 0 R 476 0 R
+477 0 R 478 0 R 479 0 R]
+ 13 [480 0 R 481 0 R 482 0 R 483 0 R 484 0 R 485 0 R 486 0 R 487 0 R 488 0 R 489 0 R
+490 0 R 491 0 R 492 0 R 493 0 R 494 0 R 495 0 R 496 0 R]
+ 14 [497 0 R 498 0 R 499 0 R 500 0 R 501 0 R 502 0 R 503 0 R 504 0 R 505 0 R 506 0 R
+507 0 R 508 0 R 509 0 R 510 0 R 511 0 R 512 0 R 513 0 R 514 0 R]
+15 [515 0 R 516 0 R 517 0 R 518 0 R 519 0 R 520 0 R 521 0 R 522 0 R 523 0 R 524 0 R]
+ 16 [525 0 R 526 0 R 527 0 R 528 0 R 529 0 R 530 0 R]
+ 17 [531 0 R 532 0 R]
+ 100000 533 0 R 100001 534 0 R
+100002 535 0 R 100003 536 0 R 100004 537 0 R 100005 538 0 R 100006 539 0 R
+100007 540 0 R 100008 541 0 R 100009 542 0 R 100010 543 0 R 100011 544 0 R
+100012 545 0 R 100013 546 0 R 100014 547 0 R 100015 548 0 R 100016 549 0 R]
+/Type /ParentTree
+>>
+endobj
+23 0 obj
+<<
+/Length 2
+>>
+stream
+q
+
+endstream
+endobj
+24 0 obj
+<<
+/Length 2022
+/Filter /FlateDecode
+>>
+stream
+xZmo
b>
+D&% x~Hq}usNࢱ\h}1i]]pz5_D>|.:{g_CݧVΠ>|B$O_W~z
^˿VTEayo
C6p3ߡEƅd'~z
՞:
+7C:0 [ Mw/O__}z>l렻춊Jl6MJ b` >xM,vاqKm$Ygy?'Rms f8%gCZ\O>t-9F(GeF>~sl@ڈ.or2ir(ѤMJQ
Fcm7SjuՂ ~؞Jwlw(&@#\JMkB`#D@6PWܰ2˛R |hzcbˮ2|)&xИJ4^pjq{$(ɾAgPL
+FF4Zc&:lkP%-މY?}4:NO`&a3E`0#`]0 ƈIs4b A1Y59w1*$$m!S6C
+U(9gb0,ZfJ?kh1#=nW୯]"]h![ڙUK|n!D, 2I^;X7)n@l)-8T^HjXsMyA\,$PVafxBpJx%S%Mf6R¬%R!P;Jj