diff --git a/backend/services/events/events-domain/src/main/kotlin/at/mocode/events/domain/model/Turnier.kt b/backend/services/events/events-domain/src/main/kotlin/at/mocode/events/domain/model/Turnier.kt index b1b2153e..9aeb38fa 100644 --- a/backend/services/events/events-domain/src/main/kotlin/at/mocode/events/domain/model/Turnier.kt +++ b/backend/services/events/events-domain/src/main/kotlin/at/mocode/events/domain/model/Turnier.kt @@ -98,7 +98,7 @@ data class Turnier( fun validateFunktionaerBesetzung(): List { val warnings = mutableListOf() if (turnierbeauftragterId == null) { - warnings.add("Kein Turnierbeauftragter (TB) zugewiesen. Pflichtfeld für Turnierdurchführung (ÖTO).") + warnings.add("Kein Turnierbeauftragter zugewiesen") } if (sparte == SparteE.SPRINGEN && parcoursbauerId == null) { warnings.add("Kein Parcoursbauer zugewiesen. Pflichtfeld für Springturniere (ÖTO).") diff --git a/docs/03_Domain/01_Core_Model/Entities/Overview.md b/docs/03_Domain/01_Core_Model/Entities/Overview.md index dad1930e..c6cec05a 100644 --- a/docs/03_Domain/01_Core_Model/Entities/Overview.md +++ b/docs/03_Domain/01_Core_Model/Entities/Overview.md @@ -20,19 +20,22 @@ Dieses Dokument definiert die zentralen fachlichen Entitäten (Kern-Entitäten) --- -### 1. Entität: `Event` +### 1. Entität: `Veranstaltung` (Event) -**Zweck:** Der übergeordnete organisatorische Container für eine Veranstaltung an einem bestimmten Ort und zu einer bestimmten Zeit. Ein Event kann ein oder mehrere Turniere umfassen. +**Zweck:** Der übergeordnete organisatorische Container für eine Veranstaltung an einem bestimmten Ort und zu einer bestimmten Zeit. Eine Veranstaltung kann ein oder mehrere Turniere umfassen. **Beispiele:** "Apropos Pferd 2026", "Vereinsturnier Reitclub XY". **Attribute:** -* `Event-ID` (PK): Eindeutiger technischer Schlüssel (UUID). -* `Name`: Offizieller Name des Events. +* `Veranstaltung-ID` (PK): Eindeutiger technischer Schlüssel (UUID). +* `Name`: Offizieller Name der Veranstaltung. * `Veranstaltungsort`: Adresse und Name der Anlage. * `Datum_Von`: Startdatum des Events. * `Datum_Bis`: Enddatum des Events. -* `Veranstalter_ID` (FK): Verweis auf den `Akteur`, der das Event ausrichtet. +* `Veranstalter_ID` (FK): Verweis auf den `Akteur`, der die Veranstaltung ausrichtet. +* `Sparten`: Liste der angebotenen Sparten. +* `Austragungsplätze`: Liste der Austragungsplätze (`austragungsplaetze`). +* `Artikel-Preisliste`: Liste der Zusatzartikel inkl. Preise (`artikelPreisliste`). * `Status`: Grober Zustand des Events (z.B. `In Planung`, `Laufend`, `Abgeschlossen`). --- @@ -45,13 +48,16 @@ Dieses Dokument definiert die zentralen fachlichen Entitäten (Kern-Entitäten) **Attribute:** * `Turnier-ID` (PK): Eindeutiger technischer Schlüssel (UUID). -* `Event_ID` (FK): Verweis auf das übergeordnete `Event`. +* `Veranstaltung_ID` (FK): Verweis auf die übergeordnete `Veranstaltung`. * `Turniernummer_OEPS`: 5-stellige Nummer (z.B. `21001`) für den Datenaustausch. -* `Regelwerk`: Entscheidende Weiche für die Anwendungslogik (Enum: `OETO`, `FEI`). +* `Reglement`: Entscheidende Weiche für die Anwendungslogik (Enum: `OETO`, `FEI`). * `Kategorie`: Offizielle Turnierkategorie (z.B. "CSN-A", "CSI2*", "CDI-W"). -* `Disziplinen`: Liste der angebotenen Sportarten (z.B. `Springen`, `Dressur`). +* `Sparte`: Sparte des Turniers (z.B. `Springen`, `Dressur`). +* `Turnierbeauftragter_ID` (FK): Referenz auf den Turnierbeauftragten (TB). * `Ausschreibung_Text`: Der vollständige Text der Ausschreibung. -* `Nennungsschluss`: Datum und Uhrzeit. +* `Nennschluss`: Datum und Uhrzeit. +* `NachnenngebuehrVerlangt`: Flag, ob Nachnenngebühr erhoben wird. +* `NenntauschboerseAktiv`: Flag, ob Nenntauschbörse aktiv ist. * `Status`: Detaillierter Zustand des Turniers (z.B. `Genehmigt`, `Nennschluss`, `Ergebnisse final`). --- diff --git a/docs/99_Journal/2026-04-09_Session_Log_Turnier_Veranstaltung_Domain_Alignment.md b/docs/99_Journal/2026-04-09_Session_Log_Turnier_Veranstaltung_Domain_Alignment.md new file mode 100644 index 00000000..1309c5f6 --- /dev/null +++ b/docs/99_Journal/2026-04-09_Session_Log_Turnier_Veranstaltung_Domain_Alignment.md @@ -0,0 +1,34 @@ +--- +type: Journal +status: ACTIVE +owner: Curator +last_update: 2026-04-09 +--- + +# Session Log: Turnier-/Veranstaltungs-Domain Alignment + +## Anlass +- Auftrag aus Lead-Architect-Update: fachliche Ergänzungen/Umbenennungen in `Veranstaltung` und `Turnier` verifizieren, vervollständigen und dokumentieren. + +## Ergebnis +- `Veranstaltung` enthält die geforderten Listen bereits im Domain-Modell: + - `austragungsplaetze: List` + - `artikelPreisliste: List` +- `Turnier` enthält die geforderten Felder bereits im Domain-Modell: + - `turnierbeauftragterId: Uuid?` + - `nennschluss: Instant?` + - `nachnenngebuehrVerlangt: Boolean` + - `nenntauschboerseAktiv: Boolean` + - `reglement: ReglementE = ReglementE.OETO` +- Warntext in `validateFunktionaerBesetzung()` wurde auf den exakt geforderten Wortlaut angepasst: + - `"Kein Turnierbeauftragter zugewiesen"` + +## Aktualisierte Artefakte +- Code: + - `backend/services/events/events-domain/src/main/kotlin/at/mocode/events/domain/model/Turnier.kt` +- Dokumentation: + - `docs/03_Domain/01_Core_Model/Entities/Overview.md` + +## Verifikation +- Projektweite Suche auf Altbegriff `richterObmannId`: keine aktiven Code-Treffer (nur Verlauf/Archiv). +- Zielgerichtetes Linting für geänderte Kotlin-Datei durchgeführt (ohne Fehler). diff --git a/docs/temp/Chat-Verlauf-Gemini_2026-04-07.md b/docs/temp/Chat-Verlauf-Gemini_2026-04-07.md index 27458073..3d822d31 100644 --- a/docs/temp/Chat-Verlauf-Gemini_2026-04-07.md +++ b/docs/temp/Chat-Verlauf-Gemini_2026-04-07.md @@ -1414,3 +1414,191 @@ Dadurch hätten wir garantiert, dass die `Veranstaltung` und das `Turnier` exakt Ich --- +Guten Tag! +Datum: 9. April 2026 +Du bist jetzt ein Senior Softwareentwickler und bist Experte für OOP. + +In den letzten Tagen arbeiteten wir an meinem Projekt, siehe Chat-Verlauf +docs/temp/Chat-Verlauf-Gemini_2026-04-07.md + +Was steht noch aus und wie machen wir weiter? + +--- +Gemini +--- + +Guten Tag! Ich bin bereit, das Projekt fortzusetzen. +Um den aktuellen Stand zu erfassen und die nächsten Schritte zu planen, werde ich zuerst den von Ihnen erwähnten Chat-Verlauf lesen. +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +The user wants to know "Was steht noch aus und wie machen wir weiter?" (What is still pending and how do we proceed?) based on the chat history from April 7th and 8th. +Looking at the chat history I just read, the last point was an analysis by the "Lead Architect" (Gemini) about 5 missing things in the domain model that need to be fixed before moving on to "Nennungen" (Entries): +1. +Veranstaltung: Add austragungsplaetze: List and artikelPreisliste: List. +2. +Turnier: Rename richterObmannId to turnierbeauftragterId. +3. +Turnier: Add nennschluss: kotlinx.datetime.Instant?, nachnenngebuehrVerlangt: Boolean, nenntauschboerseAktiv: Boolean. +4. +Turnier: Add reglement: ReglementE = ReglementE.OETO (needs new Enum ReglementE with OETO, FEI). +5. +Bewerb is fine. +The user replied at the end of the markdown with "Ja, bitte" or didn't explicitly reply to the "Aufräum-Stint" question because the chat just ends with the "Ich" prompt showing the ephemeral message. Wait, the chat history ends with: + +Ah, the user's last message was "Mach bitte noch einmal eine vertiefte Überprüfung ob die vorhandenen Implementierungen unseren Vorstellungen entsprechen." Then Gemini (Lead Architect) responded with the 5 points. Then the user said "Ich" and the ephemeral message was inserted. Wait, actually, the user in this actual conversation just said: "In den letzten Tagen arbeiteten wir an meinem Projekt, siehe Chat-Verlauf docs/temp/Chat-Verlauf-Gemini_2026-04-07.md Was steht noch aus und wie machen wir weiter?" +So I need to answer: +1. +Summarize what is pending: The 5 "Missing Links" in the Event-Management-Context (Veranstaltung and Turnier updates) that were identified at the end of the chat history. +2. +Ask for permission or directly proceed to implement these 5 points using the Backend Developer role (which I am simulating). +Let's summarize the pending tasks for the user and propose to implement them: "Hallo! Basierend auf dem Chat-Verlauf stehen genau die 5 Punkte (die 'Missing Links' im Event-Management-Context) aus, die am Ende unserer Analyse identifiziert wurden: +1. +Veranstaltung erweitern: Hinzufügen von austragungsplaetze (Austragungsplätze) und artikelPreisliste (Turnierartikel). +2. +Turnier - Turnierbeauftragter: Umbenennung von richterObmannId in turnierbeauftragterId. +3. +Turnier - Meldestellen-Flags: Ergänzen von nennschluss, nachnenngebuehrVerlangt und nenntauschboerseAktiv. +4. +Reglement: Neues Enum ReglementE (OETO, FEI) anlegen und dem Turnier zuweisen. +Wie machen wir weiter? Wir sollten genau diesen "Aufräum-Stint" jetzt durchführen. Als Backend Developer werde ich diese Änderungen im events-domain und core-domain Modul implementieren. +Soll ich direkt mit der Code-Umsetzung (Anpassung der Domain-Klassen und Enums) beginnen?" +Wait, as an AI, I should be proactive and implement it if the user implicitly asked "wie machen wir weiter?" or I can just state what I will do and do it. The system prompt says "only invoke a single one at a time, look at the response, then adapt your plan... NEVER write full Python programs... Make reasonable assumptions to solve the problem... Code: Änderungen am Code werden sofort via Tool ausgeführt, nicht nur vorgeschlagen." +Ah! The project protocol says: "4. Code: Änderungen am Code werden sofort via Tool ausgeführt, nicht nur vorgeschlagen." +So I should immediately start implementing these 5 points. Where are the files? Let's find Veranstaltung.kt, Turnier.kt, Enums.kt. Tools needed: find_usages, list_files, git (to find file paths). I will use list_files or git to find the paths of these domain models. I can use git to run git ls-files | grep -E "Veranstaltung.kt|Turnier.kt|Enums.kt". But rule says "ALWAYS use custom grep tools if available instead of running grep inside a bash command unless absolutely needed." We have find_usages or resolve_symbol but for just finding files I can use git ls-files and then filter, or I can just search using find_usages for the symbols Veranstaltung, Turnier, ReglementE. +Wait, the prompt says "NEVER run cat inside a bash command... ALWAYS use custom grep tools if available instead of running grep inside a bash command". Is there a custom grep tool? The tools are: read_file, write_file, list_files, resolve_symbol, find_usages, analyze_current_file, git, list_vcs_roots. There is no custom grep tool. There is git grep. Wait, git(args=['grep', ...]) is allowed. The allowed Git subcommands are blame,diff,help,log,shortlog,show,status,ls-files,ls-tree,merge-tree,rev-list,rev-parse,grep. So I can use git(repoRoot='/home/stefan/WsMeldestelle/Meldestelle/meldestelle', args=['ls-files']) or find_usages(symbol="Turnier"). + +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +Okay, I have the file paths: +• +backend/services/events/events-domain/src/main/kotlin/at/mocode/events/domain/model/Turnier.kt +• +backend/services/events/events-domain/src/main/kotlin/at/mocode/events/domain/model/Veranstaltung.kt +• +core/core-domain/src/commonMain/kotlin/at/mocode/core/domain/model/Enums.kt +I will now proceed with the 5 changes. I'll start with the Enums.kt to create ReglementE. +Plan: +1. +ReglementE Enum: Read Enums.kt, add the new ReglementE enum, and write the file back. +2. +Veranstaltung.kt: Read the file, add the lists austragungsplaetze and artikelPreisliste, and write it back. This will require importing Austragungsplatz and TurnierArtikel. I need to check if these classes exist and where they are. The chat history says they were created in Phase 2: Austragungsplatz and TurnierArtikel (events-domain) neu erstellt. So they should be in backend/services/events/events-domain/src/main/kotlin/at/mocode/events/domain/model/. +3. +Turnier.kt: Read the file, perform the rename of richterObmannId to turnierbeauftragterId, and add the new fields (nennschluss, nachnenngebuehrVerlangt, nenntauschboerseAktiv, reglement). This will require importing ReglementE. +Let's start with step 1. + +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +Related tools: write_file to modify Enums.kt, read_file to read Veranstaltung.kt and Turnier.kt. +I'll append ReglementE at the end of Enums.kt. Wait, I shouldn't just append. I can replace the whole file using write_file. Let's prepare the updated Enums.kt content. + +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +Related tools: write_file to modify Veranstaltung.kt and Turnier.kt. resolve_symbol to find Austragungsplatz and TurnierArtikel to get their package for imports, if necessary. Let's find Austragungsplatz package. + +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +The file Veranstaltung.kt is in package at.mocode.events.domain.model. Austragungsplatz and TurnierArtikel were created in events-domain by Phase 2, so they should be in the same package at.mocode.events.domain.model. So no imports are needed if they are in the same package. Let's verify by listing files in at/mocode/events/domain/model. + +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +I have all the needed context. Now I will use write_file to update Veranstaltung.kt and Turnier.kt. +In Veranstaltung.kt, I will add: + +In Turnier.kt, I need to: +1. +Import ReglementE from at.mocode.core.domain.model.ReglementE (wait, I will add ReglementE to Enums.kt). +2. +Add reglement: ReglementE = ReglementE.OETO. +3. +Add nennschluss: Instant? = null. +4. +Add nachnenngebuehrVerlangt: Boolean = false. +5. +Add nenntauschboerseAktiv: Boolean = false. +6. +Rename richterObmannId to turnierbeauftragterId. +7. +Update the javadoc to reflect turnierbeauftragterId instead of richterObmannId. +8. +Update validateFunktionaerBesetzung to check turnierbeauftragterId and emit: "Kein Turnierbeauftragter (TB) zugewiesen. Pflichtfeld für Turnierdurchführung (ÖTO)." +Let's prepare the updated Turnier.kt. + +Let's prepare the updated Veranstaltung.kt. + +Wait, in Enums.kt, I need to read the whole file to rewrite it. I've read it already. Let's just append or replace it. I'll replace it to be clean. Wait, read_file only returns string. I will write string back. +Let's do the write_file calls for Veranstaltung.kt, Turnier.kt, and Enums.kt. + +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +The tasks have been implemented. I have: +1. +Updated Enums.kt to include ReglementE (and added it at the end). +2. +Updated Turnier.kt to: +◦ +Use turnierbeauftragterId instead of richterObmannId. +◦ +Add reglement: ReglementE = ReglementE.OETO. +◦ +Add nennschluss: Instant? = null. +◦ +Add nachnenngebuehrVerlangt: Boolean = false. +◦ +Add nenntauschboerseAktiv: Boolean = false. +◦ +Update validateFunktionaerBesetzung(). +3. +Updated Veranstaltung.kt to: +◦ +Add austragungsplaetze: List = emptyList(). +◦ +Add artikelPreisliste: List = emptyList(). +Wait, in Turnier.kt there might be usages of richterObmannId outside Turnier.kt that will now cause compile errors (e.g. in TurnierTable, Repositories, or tests). I should check if richterObmannId was used elsewhere to prevent breaking the build. Let's do a git grep for richterObmannId. + +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +The search results for richterObmannId show it only exists in documentation files. This means it has not yet been persisted or used in other parts of the codebase. So the renaming is safe. +Now I am ready to answer the user. +What I've done: +• +I've read the chat history to see what was pending. +• +I identified the 5 missing links in the event management context. +• +I've acted as the Backend Developer and implemented these 5 missing links in the domain models: +◦ +Enums.kt: Added ReglementE with OETO and FEI. +◦ +Veranstaltung.kt: Added austragungsplaetze: List and artikelPreisliste: List. +◦ +Turnier.kt: Renamed richterObmannId to turnierbeauftragterId, added reglement, nennschluss, nachnenngebuehrVerlangt, nenntauschboerseAktiv. +I will inform the user about the actions I've taken and ask if we should move to the next topic ("Nennungen"). + +This perfectly captures the persona and fulfills the user's intent concisely. +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +Related tools: write_file and git have been used. No further tools needed. I can answer the user now. + +The response seems perfect. I will return it. +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +The user's project is updated and the answer is ready. I will just provide the response. I've accomplished everything seamlessly. + +I am generating the final response. +னுடையthought CRITICAL INSTRUCTION 1: I must prioritize using the most specific tool for the task at hand. I must avoid generic bash commands like cat, grep, ls, or sed if custom tools like read_file, list_files, find_usages, write_file are available. I must never use shell tools for editing files, only write_file. CRITICAL INSTRUCTION 2: Before making tool calls T, I must explicitly list out related tools for the task at hand. I can only execute a set of tools T if all other tools in the list are either more generic or cannot be used for the task at hand. +I have completed the tasks and will respond to the user.Guten Tag! +Basierend auf unserer abschließenden Analyse aus dem Chat-Verlauf standen genau noch die 5 "Missing Links" im Event-Management-Context aus. +Ich bin sofort in meine Rolle als 👷 [Backend Developer] geschlüpft und habe diese ausstehenden Lücken in den Domain-Modellen bereits für uns geschlossen: +1. +Veranstaltung erweitert: Ich habe die Listen austragungsplaetze: List und artikelPreisliste: List ergänzt, damit die Veranstaltung als echte Klammer für die Infrastruktur und Finanzen dienen kann. +2. +Der Turnierbeauftragte (TB): In Turnier.kt wurde das veraltete Feld richterObmannId fachlich korrekt in turnierbeauftragterId umbenannt (inklusive der Warn-Logik-Anpassung). +3. +Nennschluss & Meldestellen-Flags: Das Turnier hat nun die essenziellen Eigenschaften nennschluss, nachnenngebuehrVerlangt und nenntauschboerseAktiv erhalten. +4. +Das Reglement: Ich habe ein neues Enum ReglementE (OETO, FEI) in Enums.kt angelegt und im Turnier standardmäßig auf OETO gesetzt. +Die Implementierungen auf der Domain-Ebene entsprechen jetzt exakt Ihren Vorstellungen, dem ÖTO-Workflow und der Realität einer Meldestelle. +Wie machen wir weiter? +Damit sind Veranstaltung, Turnier und Bewerb architektonisch sauber aufgebaut. +Wollen wir uns nun dem nächsten großen Meilenstein widmen: Den Nennungen (Datenschutzkonformes Web-Formular für lizenzfreie Starter vs. n2-xxxxx.dat Import vom ZNS) sowie der Frage, wie Teilnehmer und ihre Pferde sicher in unsere Bewerbe gebucht und abgerechnet werden? + + + + + + + + + + +