blob: 75b66f63c6acebfd0291998ea4c9fa79b8fd7b83 [file] [log] [blame]
Matthias Andreas Benkardb291c362020-11-22 10:22:27 +01001= ÄndGgner -- Programmbibliothek zur Konsolidierung von Änderungsgesetzen des Bundes und der Länder
2Matthias Andreas Benkard
3// Meta
4:experimental:
5:data-uri:
6:sectnums:
7:toc:
8:stem:
9:toclevels: 2
10:description: ÄndGgner Manual
11:keywords: mulk
12// Settings
13:icons: font
14:source-highlighter: pygments
15
16
17== Resources
18
19|===
20|Resource |Links
21
22|Public Artifact
23|https://bintray.com/mulk/maven/aendggner[Bintray]
24
25|Bug Tracker
26|MantisBT
27|===
28
29
30[[building]]
31== Building a JAR
32
Matthias Andreas Benkardc7f11362020-11-22 15:01:07 +010033To build an executable JAR at `target/aendggner-${REVISION}.jar`:
Matthias Andreas Benkardb291c362020-11-22 10:22:27 +010034
35[source,shell script]
36----
37./mvnw package
38----
39
40`${REVISION}` defaults to `0.1.0-SNAPSHOT` unless you override it by
41passing the `-Drevision` flag to `mvnw`.
42
43
44== Running the Command Line Application
45
46To run the command line application after <<building,building>> it:
47
48[source,shell script]
49----
50./mvnw exec:java
51----
52
53
Matthias Andreas Benkard58e19982026-07-13 07:09:19 +020054[[usage]]
55== Usage
56
57ÄndGgner erzeugt aus einem Stammgesetz und einem Änderungsgesetz eine
58zweispaltige HTML-Synopse (alte Fassung links, neue rechts, Änderungen
59wortweise hervorgehoben).
60
61Eingaben:
62
Matthias Andreas Benkard65eff082026-07-18 12:24:32 +020063* Stammgesetz (Bundesrecht): XML im gii-norm-Format von
Matthias Andreas Benkard58e19982026-07-13 07:09:19 +020064 https://www.gesetze-im-internet.de/[gesetze-im-internet.de]
Matthias Andreas Benkard2cfea002026-07-26 13:32:26 +020065* Stammgesetz (Landesrecht): konsolidierte Fassung als PDF oder als
Matthias Andreas Benkardbac648b2026-07-28 07:51:09 +020066 kanonischer Klartext im Format der `--extract-only`-Ausgabe. Eine Zeile
67 Inhaltsübersicht eröffnet darin die gleichnamige Norm, auf die die
68 Angabe-Befehle zielen; ihre Zeilen tragen das Übersichtsformat
69 „§ N | Titel“. Amtliche
Matthias Andreas Benkard65eff082026-07-18 12:24:32 +020070 Satznummern und Fußnotenmarker stehen als Unicode-Superskripte im
Matthias Andreas Benkard2cfea002026-07-26 13:32:26 +020071 Text („¹Die freilebende Tierwelt …“, Enteignung⁶)“); ob sie erhalten
72 bleiben, ergibt sich aus der geladenen Stammfassung, nicht aus einer
73 Länderkennung. Ebenso folgt das Zitiersigel oder Art.) aus den
74 Normköpfen der Stammfassung.
Matthias Andreas Benkard7235b342026-08-14 18:58:25 +020075* Änderungsdokument: BGBl-, GVBl- oder Drucksachen-PDF (Bundestag,
76 Bundesrat, Landtage) oder Klartext. Die Dokumentart wird aus dem Text
77 erschlossen, nicht aus dem Dateinamen (siehe <<quellformate>>);
78 Änderungsanträge dürfen zusammen mit dem Entwurf angegeben werden, den
79 sie ändern.
Matthias Andreas Benkard58e19982026-07-13 07:09:19 +020080
81[source,shell script]
82----
83java -jar target/aendggner-0.1.0-SNAPSHOT.jar \
84 stammgesetz.xml aenderungsgesetz.pdf -o synopse.html
85----
86
87Wichtige Optionen:
88
89`-o, --output <file>`::
90 Ausgabedatei (Default `synopse.html`; `-` = Standardausgabe).
91`--vollstaendig`::
92 Auch unveränderte Normen in die Synopse aufnehmen.
93`--artikel <n>`::
94 Nur diesen Artikel des Änderungsgesetzes anwenden (Default: alle
95 Artikel, deren Einleitung das Stammgesetz nennt).
96`--extract-only`::
97 Nur den bereinigten Lineartext des Änderungsgesetzes ausgeben. Nützlich,
98 wenn die PDF-Extraktion fehlerhaft ist: Text prüfen, von Hand
99 korrigieren und als Klartextdatei wieder einspeisen.
100
101Erkannt werden die gebräuchlichsten Änderungsbefehle des Handbuchs der
102Rechtsförmlichkeit (Ersetzen, Neufassung, Einfügen, Anfügen, Aufheben,
Matthias Andreas Benkardebd5a7b2026-07-15 20:54:27 +0200103Streichen, Umnummerierung) einschließlich zahlreicher Sonderformen:
104Bereichs- und Koordinationsziele („Die Absätze 8 und 9 werden durch die
105folgenden Absätze 8 bis 10 ersetzt“), strukturelle Streichungen ganzer
106Einheiten („§ 9 wird gestrichen“), §- und Gliederungs-Umnummerierungen
107(„§ 9a wird zu § 9“, Der bisherige Abschnitt 2 wird zu Abschnitt 3“),
Matthias Andreas Benkardb7e9f0f2026-07-16 21:12:08 +0200108das Einfügen/Ersetzen ganzer §-Blöcke, Chapeau-Lokatoren („Im
109Satzteil vor Nummer 1 …“), Änderungen an Anhängen und Anlagen („Der
110Anhang wird wie folgt geändert: Nach Nummer 2 wird die folgende
111Nummer 2a eingefügt“), Angabe-Befehle auf die Inhaltsübersicht (gefasst,
112ersetzt, eingefügt, gestrichen sie werden auf die
113Inhaltsübersichts-Norm angewandt), das Einfügen und Ersetzen von
114Gliederungsberschriften („Nach § 33 werden die folgenden Überschriften
115zu Teil 3 eingefügt“), Voranstellungen, Mehrfach-Ersetzungs- und
Matthias Andreas Benkard5f30f562026-07-28 06:00:16 +0200116-Einfügepaare, Einfügungen, deren Position ein Wortanker statt einer
117Stellenangabe bestimmt („Vor den Wörtern Aus dem Bereich Verkehr:“ wird
118folgender Absatz 5 eingefügt“), Verbünde aus Umnummerierung und
Matthias Andreas Benkard5b2e6ef2026-08-02 20:01:37 +0200119Folgeänderung („§ 50 wird zu § 38 und wird wie folgt geändert“, Die
120bisherige Nr. 7 wird Nr. 5 und das Komma wird durch das Wort und
121ersetzt eine Satzzeichen-Operation meint dabei stets die soeben
122umnummerierte Einheit, weil ihr Zieltext nichts unterscheidet),
Matthias Andreas Benkardbac648b2026-07-28 07:51:09 +0200123Verb-Rahmen, deren Unterpunkte allein die Fundstelle tragen („Es werden
124ersetzt: in § 35 Absatz 3 die Angabe X jeweils durch die Angabe
125Y“,“) sowie die Neufassung der Gesetzesüberschrift.
126
127Angewandt wird nicht stur in Dokumentreihenfolge: Umnummerierungen
128beziehen sich stets auf die ursprüngliche Zählung, nicht auf den Stand
129nach den vorangegangenen Punkten. Wer eine Bezeichnung räumt, kommt
130deshalb vor den, der sie neu besetzt. Aus dieser einen Regel folgt die
131absteigende Abarbeitung einer aufsteigenden Kaskade („Der bisherige
132Absatz 3 wird Absatz 4“, Der bisherige Absatz 4 wird Absatz 5“, …)
133ebenso wie der Vorrang einer Umnummerierung vor der Einfügung, die deren
134Bezeichnung neu vergibt. Verschoben wird dabei nur nach vorn, sodass
135jede Folgeänderung hinter der Umnummerierung bleibt, auf deren neue
136Bezeichnung sie zeigt. Die PDF-Aufbereitung toleriert dabei
Matthias Andreas Benkardb7e9f0f2026-07-16 21:12:08 +0200137Drucksachen-Artefakte (Seitenköpfe und -füße, Vorabfassungs-Wasserzeichen,
Matthias Andreas Benkard5f30f562026-07-28 06:00:16 +0200138vertauschte oder gerade Anführungszeichen, verklebte Wortgrenzen, zerlegt
139kodierte Umlaute) und bestimmt die Brotschrift seitenweise, sodass auch
140Ministeriumsentwürfe mit gemischten Layouts vollständig extrahiert
141werden. Fehlt im amtlichen Satz ein schließendes Anführungszeichen, endet
142das Zitat an der nächsten Strukturgrenze an einer Artikelberschrift
143oder, wo die Anführungszeichen eines Artikels nachweislich nicht
144aufgehen, am nächsten Aufzählungspunkt des Änderungsgesetzes; gemeldet
145wird das als Warnung. Auf den
Matthias Andreas Benkardb7e9f0f2026-07-16 21:12:08 +0200146Beispieldaten werden damit alle Befehle der BGBl-Fassungen und der
147aktuellen Entwürfe angewandt (UWG/AGG/ProdHaftG: 0 manuell); was
148unsicher bleibt etwa Befehle gegen eine ältere Gesetzesfassung, deren
149Zieltext nicht mehr existiert landet mit Begründung im Abschnitt
150*Manuell prüfen* der Synopse und wird niemals stillschweigend verworfen.
Matthias Andreas Benkard58e19982026-07-13 07:09:19 +0200151
Matthias Andreas Benkard65eff082026-07-18 12:24:32 +0200152Für das bayerische Landesrecht versteht ÄndGgner die dortigen
153Konventionen: Stammgesetze gliedern sich in Artikel („Art. 6 Abs. 2
154Satz 1 Nr. 2“, durchgängig abgekürzt zitiert), Änderungsgesetze dagegen
155in Paragraphen auch mehrere Gesetze in einem GVBl-Heft, aus denen die
156auf das Stammgesetz zielenden §§ (einschließlich Weitere Änderung“)
157anhand des Einleitungssatzes ausgewählt werden. Amtliche Satznummern
158bleiben als Superskripte erhalten und dienen als exakte Satzgrenzen;
159zusätzlich erkannt werden die bayerischen Befehlsformen („Fußnote 1
160wird aufgehoben“, In Satz 1 wird die Satznummerierung 1 gestrichen“,
161Dem Wortlaut werden die folgenden Abs. 1 bis 4 vorangestellt“, Der
162bisherige Wortlaut wird Abs. 5“, Halbsatz-Ziele, Klauselketten mit
163gemeinsamem Schlussverb) sowie das Fortführungszeichen des GVBl (jedes
Matthias Andreas Benkard7235b342026-08-14 18:58:25 +0200164neugefasste Aufzählungsglied öffnet erneut mit „).
Matthias Andreas Benkard65eff082026-07-18 12:24:32 +0200165
Matthias Andreas Benkard2cfea002026-07-26 13:32:26 +0200166Die übrigen Länder gliedern ihre Stammgesetze wie der Bund in
167Paragraphen; die Unterschiede liegen im Gesetzblatt-Satz und in
168Befehlsidiomen. Belegt sind Sachsen (SächsBeamtVG), Niedersachsen
Matthias Andreas Benkarda201e832026-08-02 19:45:34 +0200169(NEFG) und Nordrhein-Westfalen dort alle vier ändernden Artikel eines
170Heftes: Telemedienzuständigkeitsgesetz, Landesmediengesetz,
171Ausführungsgesetz zum 17. Rundfunkänderungsstaatsvertrag und, mit 101
172Befehlen an 31 Normen der größte Landesrechtsfall, das WDR-Gesetz
173mit Akzeptanztests gegen die
Matthias Andreas Benkard5b2e6ef2026-08-02 20:01:37 +0200174amtlichen Nachfassungen; für Schleswig-Holstein, Berlin und Hessen
Matthias Andreas Benkard5f30f562026-07-28 06:00:16 +0200175reicht die Prüfung bis zur Befehlserkennung dort vollständig, aber ohne
176Anwendung —, weil deren Landesportale ihre Stammfassungen nur über eine
177anmeldepflichtige Schnittstelle ausgeben. Welche Konvention welches Land beisteuert, welche
Matthias Andreas Benkard2cfea002026-07-26 13:32:26 +0200178Stammfassungen woher stammen und was noch offen ist, verzeichnet
179`src/main/resources/sampledata/Landesrecht-Beispiele.adoc`.
180
Matthias Andreas Benkard58e19982026-07-13 07:09:19 +0200181
Matthias Andreas Benkard7235b342026-08-14 18:58:25 +0200182[[quellformate]]
183== Quellformate: Gesetz, Entwurf, Antrag
184
185Ein Änderungsbefehl steht nicht nur im verkündeten Gesetzblatt. Dasselbe
186Vorhaben durchläuft als Referenten-, Regierungs- und Fraktionsentwurf,
187als Änderungsantrag und als Beschlussempfehlung mehrere Fassungen, und
188die Frage was gälte, wenn das durchkommt?“ stellt sich in jeder davon.
189ÄndGgner erschließt die Art eines Dokuments deshalb aus seinem Kopf
190nie aus dem Dateinamen, der lügen kann (im Beispielkorpus heißt ein
191Entschließungsantrag `BT-Drs-21-7071_Beschlussempfehlung.pdf`) und nie
192aus einer Kennung, die von außen mitzugeben wäre.
193
194Unterschieden werden:
195
196Änderungsgesetz::
197 Das verkündete Artikelgesetz aus BGBl, GVBl oder GVOBl. Der Regelfall.
198Gesetzentwurf::
199 Referenten-, Regierungs- und Fraktionsentwürfe, auch als Drucksache von
200 Bundestag, Bundesrat oder Landtag. Der Begründungsteil hinter dem
201 Regelungstext erzeugt keine Befehle; erkannt wird er an Begründung
202 ebenso wie an den Entwurfsvarianten („A. Allgemeiner Teil“, Zu
203 Artikel 1“).
204Änderungsantrag::
205 Ändert nicht das Stammgesetz, sondern eine *Drucksache* siehe unten.
206Beschlussempfehlung::
Matthias Andreas Benkardffc553b2026-08-15 12:18:32 +0200207 Trägt ihre Fassung in einer zweispaltigen Zusammenstellung, die
208 aufgelöst wird die Synopse zeigt dann die vom Ausschuss beschlossene
209 Fassung (siehe unten).
Matthias Andreas Benkard7235b342026-08-14 18:58:25 +0200210Dokument ohne Änderungsbefehle::
211 Entschließungs- und schlichter Antrag, Plenarprotokoll, Bericht. Sie
212 werden übergangen und gemeldet nicht stillschweigend zu null
213 Befehlen verarbeitet.
214
215Sobald ein Entwurf, ein Antrag oder eine Beschlussempfehlung beteiligt
216ist, trägt die Synopse den Hinweis *Entwurfsfassung nicht geltendes
217Recht*; die Quellenzeile nennt je Datei die erkannte Art.
218
219=== Änderungsanträge
220
221Ein Änderungsantrag ist eine Metanderung: Er ändert den Entwurf, nicht
222das Gesetz. Sein Rahmensatz adressiert deshalb zwei Ebenen zugleich
223In § 3 Nr. 22 wird § 18 Nr. 1 wie folgt geändert:“ nennt erst die
224Stelle _in der Drucksache_ (den 22. Änderungsbefehl ihres dritten
225Paragraphen) und dann die Stelle _in dem Text, den dieser Befehl
226zitiert_. Angegeben wird der Antrag zusammen mit seinem Entwurf:
227
228[source,shell script]
229----
230java -jar target/aendggner-0.1.0-SNAPSHOT.jar \
231 BayJG-alt.txt Ltg-Drs-19-9707_Gesetzentwurf.pdf \
232 Ltg-Drs-19-10365_Aenderungsantrag-Gruene.pdf -o synopse.html
233----
234
235ÄndGgner wendet dann erst den Antrag auf den Entwurf an und danach den
236so geänderten Entwurf auf das Stammgesetz; die Synopse zeigt also, was
237gälte, wenn Entwurf _und_ Antrag durchkämen. Welcher Entwurf gemeint
238ist, entscheidet die Drucksachennummer, die der Antrag selbst nennt
239(„(Drs. 19/9707)“), nicht die Reihenfolge der Argumente. Fehlt der
240Entwurf, bleibt der Antrag unangewandt und wird gemeldet ihn
241ersatzweise auf das Stammgesetz loszulassen wäre falsch, denn seine
242Stellenangaben zielen auf die Drucksache. Erkannt wird auch die
243elliptische Antragsform, die das Hilfsverb nur einmal in der
244Beschlussformel führt („1. In Nr. 1.29 die Angabe „,“ am Ende durch die
245Angabe „;“ ersetzt.“).
246
Matthias Andreas Benkardffc553b2026-08-15 12:18:32 +0200247=== Beschlussempfehlungen: die beschlossene Fassung
Matthias Andreas Benkard7235b342026-08-14 18:58:25 +0200248
249Die maßgebliche Fassung einer Beschlussempfehlung steht in einer
250zweispaltigen Zusammenstellung: links der Entwurf, rechts die Beschlüsse
Matthias Andreas Benkardffc553b2026-08-15 12:18:32 +0200251des Ausschusses. Anders als beim alten BGBl und beim Berliner GVBl
252stehen die Spalten *nicht* nacheinander im Inhaltsstrom, sondern
253zeilenweise verschränkt; getrennt werden sie deshalb über die
254Koordinaten (`PatchTextExtraktor.extrahiereSpalten`, Schnitt an der
255Blattmitte, aber nur an einem tatsächlichen Spaltensteg, damit
256ganzseitenbreite Zeilen ungeschnitten bleiben).
Matthias Andreas Benkard7235b342026-08-14 18:58:25 +0200257
Matthias Andreas Benkardffc553b2026-08-15 12:18:32 +0200258Die rechte Spalte für sich gelesen ist allerdings kein vollständiges
259Dokument: Sie druckt Unverändertes nicht ab, sondern vermerkt bloß
260unverändert und zwar nicht nur je Gliederungspunkt, sondern auch
261zeilenweise innerhalb zitierter Blöcke, weshalb ihre Anführungszeichen
262nicht aufgehen. Eine Auflösung über die Gliederungspfade scheitert daran
263nachweislich. Maßgeblich ist stattdessen die *Grundlinie*: Beide Spalten
264sind zeilensynchron gesetzt, jeder Vermerk steht auf der Höhe der
265Entwurfszeile, die er meint. Der `ZusammenstellungsLeser` führt beide
266Spalten über Seite und Grundlinie in eine gemeinsame Lesereihenfolge
267zusammen und entscheidet dann Zeile für Zeile: unverändert holt den
268Wortlaut aus der Entwurfsspalte, entfällt streicht ihn, sonst gilt die
269Ausschussspalte. Dabei meint unverändert den Wortlaut, nicht die
270Zählung streicht der Ausschuss einen Punkt, rücken die folgenden auf,
271und seine Marke tritt an die Stelle der des Entwurfs.
272
273Die Quellenzeile der Synopse weist die verwendete Spalte als
274`[Beschlussempfehlung …, Ausschussfassung]` aus. Lässt sich die
275Zusammenstellung nicht auflösen, wird die Datei nach wie vor mit
276Begründung übergangen samt Hinweis auf die Drucksachennummer des
277Entwurfs, der sich stattdessen eignet. Eine halb aufgelöste Fassung
278auszugeben wäre schlimmer als keine.
279
280Belegt ist beides: dass die *linke* Spalte Befehl für Befehl den
281Regierungsentwurf ergibt, aus dem die Zusammenstellung gebaut ist, und
282dass die aufgelöste Fassung mehr Befehle trägt als er der Ausschuss
283hat der GEG-Novelle zwei Artikel hinzugefügt. Zwei Beispiele stehen im
284Test: BT-Drs. 20/7619 (GEG) und BT-Drs. 19/24334 (Drittes
285Bevölkerungsschutzgesetz).
Matthias Andreas Benkard7235b342026-08-14 18:58:25 +0200286
Matthias Andreas Benkard7b455cd2026-08-09 08:33:37 +0200287[[web]]
288== Web-App
289
Matthias Andreas Benkard2b1841e2026-08-15 10:51:11 +0200290Neben der CLI gibt es eine Browserfassung, die dieselbe Pipeline
291(`eu.mulk.aendggner.Pipeline`) über ein Upload-Formular zugänglich macht:
292Stammgesetz- und Änderungsgesetz-Datei(en) wählen, Synopse erhalten.
Matthias Andreas Benkard7b455cd2026-08-09 08:33:37 +0200293
Matthias Andreas Benkard2b1841e2026-08-15 10:51:11 +0200294Sie braucht keinen Server: Die vollständige Verarbeitung PDF-Textgewinnung
295mit PDFBox eingeschlossen läuft als WebAssembly-Modul im Browser, übersetzt
296mit GraalVM Web Image aus demselben Java-Quelltext. Ausgeliefert werden nur
297statische Dateien; die gewählten Dokumente verlassen den Rechner der
298Nutzer:innen nicht.
299
300Bauen (verlangt Oracle GraalVM 25.1 oder neuer Web Image ist dort enthalten,
301in der Community Edition nicht):
Matthias Andreas Benkard7b455cd2026-08-09 08:33:37 +0200302
303[source,shell script]
304----
Matthias Andreas Benkard2b1841e2026-08-15 10:51:11 +0200305JAVA_HOME=/pfad/zu/oracle-graalvm ./mvnw -Pwasm package
Matthias Andreas Benkard7b455cd2026-08-09 08:33:37 +0200306----
307
Matthias Andreas Benkard2b1841e2026-08-15 10:51:11 +0200308Ergebnis ist `target/web/` mit `index.html`, `app.js`, `worker.js`,
309`style.css`, `aendggner.js` und `aendggner.js.wasm` (rund 20 MB, komprimiert
310etwa 6 MB). Die daneben liegende `aendggner.js.wat` ist ein Zwischenschritt des
311Übersetzers und gehört nicht auf den Server.
312
313Lokal ansehen `file://` genügt nicht, Browser laden Wasm-Module und Worker
Matthias Andreas Benkard08f53072026-08-16 06:05:39 +0200314nur über HTTP (http://localhost:8000/):
Matthias Andreas Benkard2b1841e2026-08-15 10:51:11 +0200315
316[source,shell script]
317----
Matthias Andreas Benkard08f53072026-08-16 06:05:39 +0200318jwebserver -d target/web
Matthias Andreas Benkard2b1841e2026-08-15 10:51:11 +0200319----
320
321Der öffentliche Betrieb braucht nur einen Webserver für statische Dateien;
322eine `nginx`-Vorlage liegt unter `deploy/nginx-aendggner.conf`. Die
323Befehlszeilenfassung bleibt davon unberührt und ist weiterhin der Weg für
324Massenläufe.
325
326=== Warum WebAssembly und nicht ein Java-Server
327
328Der Kern ist reines Java ohne Dateisystem- oder Netzzugriff; nur vier Stellen
329berührten die Plattform (PDFBox, MIME-Erkennung, XML-Parser, Dateizugriff).
330Sie sind hinter `eu.mulk.aendggner.Quelle` (Name + Bytes) und
331`eu.mulk.aendggner.DateiTyp` (Signaturbytes statt Tika) gebündelt, sodass
332Befehlszeile und Browser dieselbe Pipeline speisen.
333
334Zwei Eigenheiten von Web Image sind dabei zu beachten und im Quelltext
335vermerkt:
336
337* Die nativen zlib-Bindungen des JDK fehlen (`java.util.zip.Inflater`), ohne
338 die kein PDF lesbar ist. `src/wasm/java/.../InflaterErsatz.java` ersetzt sie
339 durch die reine Java-Umsetzung von jzlib.
340* Typisierte Felder lassen sich derzeit nicht nach `byte[]` umsetzen; der
341 Dateiinhalt wandert deshalb als Base64-Text über die JS-Grenze.
342
Matthias Andreas Benkard7b455cd2026-08-09 08:33:37 +0200343
344Vor dem produktiven, öffentlichen Betrieb sind zwingend zu erledigen:
345
346* `impressum.html` und `datenschutz.html`
347 (`src/main/resources/eu/mulk/aendggner/web/`) mit den tatsächlich
348 zutreffenden Angaben statt der `TODO`-Platzhalter füllen (Pflicht
349 nach § 5 DDG bzw. DSGVO für öffentlich erreichbare Dienste).
350* Den Quellcode-Link im Footer von `index.html` auf das tatsächlich
351 öffentlich erreichbare Repository setzen das Projekt steht unter
352 AGPLv3 (`COPYING`), dessen §13 bei Netzwerkbetrieb einen
353 Quellcode-Zugriff für Nutzer:innen verlangt.
354
355
Matthias Andreas Benkardb291c362020-11-22 10:22:27 +0100356== Running the Tests
357
358To build and run the tests:
359
360[source,shell script]
361----
362./mvnw verify
363----