From 954d5989bb04f32aeb2627b70647d773011e4092 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 22 Aug 2026 21:03:13 +0200 Subject: =?UTF-8?q?Neufassung=20der=20Dokumentation,=20Entfernung=20der=20?= =?UTF-8?q?urspr=C3=BCnglichen=20Tabellenfassung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Das Wurzel-README beschrieb bislang vorrangig die Excel-Arbeitsmappe nebst ihrem Formelgenerator; die Web-App erschien lediglich in einer Tabellenzeile. Das Verhältnis hat sich umgekehrt, das README nunmehr auch. - README.md vollständig neu als Einstiegspunkt für Unkundige, in Paragraphen gegliedert und durchgängig in amtlicher Diktion. Die excelspezifischen Kapitel (Blattstruktur, feste Adressen, Neubau, LibreOffice-Fallstricke) entfallen ersatzlos. - app/README.md in dieselbe Diktion überführt; Gliederung und sämtliche Zahlen unverändert. Berichtigt: Überschrift „Neunzehn Sprachen" bei dreiundzwanzig Wörterbüchern, sowie die unvollständige Aufzählung der Vollsprachen (ine-x-proto, jbo, tok, akk-x-ob ergänzt). - Die Arbeitsmappe, der Formelgenerator und die leere recalc.log werden entfernt; sie sind über die Versionsgeschichte zugänglich. - Der Anbietername entfällt samt dem Dateinamen, den er trug: Fußzeile footer.2 in index.html und in sämtlichen dreiundzwanzig Sprachfassungen, jeweils mit dem der Sprache angemessenen Bindewort statt einer mechanischen Streichung. Die Keilschriftfassung ist über akk-keilschrift.js neu erzeugt worden, nicht von Hand geändert. In pruefe.js aus der Ausnahmeliste gestrichen. Der Schlüsselbestand bleibt bei 459; es werden ausschließlich Werte gekürzt. Co-Authored-By: Claude Opus 5 --- README.md | 455 ++++---- app/README.md | 1012 +++++++++-------- app/i18n.akk-x-ob.js | 2 +- app/i18n.akk-x-ob.translit.js | 2 +- app/i18n.bar.js | 2 +- app/i18n.de-x-amt.js | 2 +- app/i18n.de-x-sales.js | 2 +- app/i18n.de.js | 2 +- app/i18n.en.js | 2 +- app/i18n.eo.js | 2 +- app/i18n.eu.js | 2 +- app/i18n.fr.js | 2 +- app/i18n.gmh.js | 2 +- app/i18n.goh.js | 2 +- app/i18n.got.js | 2 +- app/i18n.grc.js | 2 +- app/i18n.ine-x-proto.js | 2 +- app/i18n.ja.js | 2 +- app/i18n.jbo.js | 2 +- app/i18n.la.js | 2 +- app/i18n.nds.js | 2 +- app/i18n.nl.js | 2 +- app/i18n.sa.js | 2 +- app/i18n.tok.js | 2 +- app/i18n.tr.js | 2 +- app/i18n.uk.js | 2 +- app/index.html | 6 +- app/pruefe.js | 2 +- bAV-DYNO_vs_Altersvorsorgedepot_vs_ETF.xlsx | Bin 121001 -> 0 bytes build_bav.py | 1592 --------------------------- recalc.log | 0 31 files changed, 776 insertions(+), 2339 deletions(-) delete mode 100644 bAV-DYNO_vs_Altersvorsorgedepot_vs_ETF.xlsx delete mode 100644 build_bav.py delete mode 100644 recalc.log diff --git a/README.md b/README.md index 909befc..c4aa87d 100644 --- a/README.md +++ b/README.md @@ -1,309 +1,286 @@ -# bAV (DYNO) vs. Altersvorsorgedepot vs. privates ETF-Depot +# Altersvorsorgerechner -Vergleichsmodell für drei Wege der Altersvorsorge mit **demselben ETF**, Rechtsstand 2026. -Vollständig formelbasierte Excel-Arbeitsmappe (6.359 Formeln), erzeugt aus einem Python-Skript. +**Vergleichsrechner für drei Gestaltungsvarianten der Altersvorsorge bei gleichem Nettoaufwand. +Rechtsstand 2026.** -| Datei | Rolle | -|---|---| -| `bAV-DYNO_vs_Altersvorsorgedepot_vs_ETF.xlsx` | Das Modell. Nur die gelben Zellen im Blatt `Eingaben` ändern. | -| `build_bav.py` | Generator. Erzeugt die Mappe vollständig neu. **Einzige Quelle der Wahrheit** — Änderungen gehören hierhin, nicht in die xlsx. | -| `app/` | **Web-App zum Weitergeben.** Derselbe Rechenkern in JavaScript, mobilfreundlich, offlinefähig, mit Sensitivitätskurven. Siehe `app/README.md`. | -| `tests/` (in den Sitzungsausgaben) | Regressionslauf gegen einen frischen LibreOffice-Recalc dieser Mappe. | -| `README.md` | Diese Datei. | - -> **Zwei Quellen der Wahrheit.** Der Rechenkern liegt zweimal vor: als Formelgenerator in -> `build_bav.py` und als JavaScript in Teil 1 von `app/index.html`. Sie stimmen auf 1,3·10⁻¹⁴ -> relativ überein — **sechs** Testfälle, jeweils rund 20 Aggregate, gegen einen frischen -> LibreOffice-Recalc dieser Mappe. Bei jeder Rechtsänderung **beide** anfassen und danach den -> Abgleich wiederholen; er ist der einzige Schutz davor, dass sie auseinanderlaufen. +Bei dem vorliegenden Bestand handelt es sich um eine Webanwendung. Sie stellt gegenüber, was +aus ein und demselben monatlichen Verzicht auf verfügbares Einkommen wird, je nachdem, ob +dieser Betrag in eine betriebliche Altersversorgung, in ein Altersvorsorgedepot oder in ein +privates ETF-Depot geleitet wird. Ein Server wird nicht betrieben; eine Übermittlung der +eingegebenen Daten findet nicht statt. --- -## 1. Das Vergleichsprinzip - -Ein Vergleich von Bruttobeiträgen wäre unfair: Entgeltumwandlung kommt aus dem Brutto, -privates Sparen aus dem Netto. Deshalb wird der **Nettoaufwand** gleichgesetzt: - -``` -Nettoaufwand = Bruttobeitrag − Lohnsteuerersparnis − ersparter AN-Anteil zur Sozialversicherung -``` - -Genau dieser Betrag wird in allen drei Optionen investiert. Was übrig bleibt, ist ein -Vergleich der Förderarchitekturen, nicht der Einzahlungshöhen. +## § 1 Gegenstand und Zweck -Über Zelle `C22` lässt sich die Richtung umkehren: Vorgabe des Nettoaufwands, Rückrechnung -des Bruttobeitrags. Da N(B) wegen der Knicke bei 4 % und 8 % der BBG-RV, an den -Beitragsbemessungsgrenzen und an den Tarifeckwerten nicht geschlossen invertierbar, -aber stetig und streng monoton wachsend ist, geschieht das per Bisektion (34 Schritte, -Blatt `Umrechnung`). +(1) Verglichen werden drei Gestaltungsvarianten, und zwar durchgängig unter Zugrundelegung +**desselben** Wertpapiers: -### Die vier Werttreiber - -Steueraufschub ist für sich genommen wertlos: (1−t)·(1+r)ⁿ = (1+r)ⁿ·(1−t). Multiplikation -kommutiert. Es bleiben nur: +| | Gestaltungsvariante | Wesentliches Merkmal | +|---|---|---| +| 1. | **Betriebliche Altersversorgung** durch Entgeltumwandlung (§ 1a BetrAVG) | Beitrag aus dem Bruttoentgelt; Arbeitgeberzuschuss; im Ruhestand Beiträge zur Kranken- und Pflegeversicherung auf den Versorgungsbezug (§§ 229, 250 SGB V) | +| 2. | **Altersvorsorgedepot** (Reform der geförderten privaten Altersvorsorge 2026) | Beitrag aus dem versteuerten Entgelt; Zulagen und Sonderausgabenabzug; keine Vorabpauschale; Verfügung vor Vollendung des 65. Lebensjahres förderschädlich | +| 3. | **Privates ETF-Depot** | Beitrag aus dem versteuerten Entgelt; keinerlei Förderung; jederzeitige Verfügbarkeit; Abgeltungsteuer nebst Vorabpauschale | -1. **Tarifarbitrage** t₀ − t₁ (Grenzsteuersatz beim Einzahlen minus beim Auszahlen) -2. **Fremdgeld** — AG-Zuschuss bzw. Zulagen -3. **Steuerfreie Thesaurierung** — bAV und Altersvorsorgedepot kennen keine Vorabpauschale -4. **Neue Abgaben, die nur eine Option treffen** — KV/PV auf Versorgungsbezüge (§ 229 SGB V) +(2) Die Auskunft richtet sich an Personen, welchen ein Angebot zur Entgeltumwandlung +unterbreitet worden ist und welche die Vorteilhaftigkeit desselben zu beurteilen beabsichtigen. +Vorkenntnisse werden nicht vorausgesetzt; sämtliche Eingabefelder sind mit sachgerechten +Voreinstellungen versehen, und zu jedem Feld wird über die Schaltfläche `?` eine Erläuterung +nebst Rechtsgrundlage bereitgehalten. -Punkt 4 ist der dominante Nachteil der bAV; Punkt 2 ihr einziger struktureller Vorteil. +(3) Es wird ausdrücklich darauf hingewiesen, dass es sich **nicht** um einen Produktvergleich, +**nicht** um eine Anlageempfehlung und **nicht** um einen Haushaltsplaner handelt. Verglichen +werden ausschließlich die Förderarchitekturen; die Anlageentscheidung ist in allen drei +Varianten dieselbe und wird daher nicht mitverglichen (vgl. § 4). --- -## 2. Blattstruktur - -| Blatt | Inhalt | -|---|---| -| `Anleitung` | Aufbau, Modellannahmen, Quellen | -| `Begriffe` | 43 Fachbegriffe mit Fundstelle bzw. Kennzeichnung als Modellkonvention | -| `Eingaben` | **Die einzigen Zellen, die man ändert.** Ergebnisblock am Fuß | -| `Parameter` | Rechengrößen 2026 mit Fundstelle, abgeleitete Größen | -| `Umrechnung` | Bisektion Nettoaufwand → Bruttobeitrag | -| `Ansparphase` | 62 Spalten × 50 Jahre (Zeilen 8–57) | -| `Auszahlung` | 58 Spalten × 34 Jahre (Zeilen 8–41) | -| `Cashflow` | Zahlungsströme für IRR und Barwerte (Zeilen 5–69) | -| `Vergleich` | Ergebnis, Diagnose, monatliche Leistung, Diagramm | +## § 2 Inbetriebnahme -### Feste Adressen im Blatt `Vergleich` +(1) **Einfachster Weg.** Die Datei `app/index.html` ist mittels Doppelklicks zu öffnen. Ein +Aufbau, eine Installation oder eine Verbindung zum Internet sind hierfür nicht erforderlich; +sämtliche Berechnungen werden im Browser durchgeführt. -Diese werden von anderen Blättern referenziert — beim Einfügen von Zeilen **mitziehen**: +(2) **Mit Installierbarkeit und Offline-Betrieb.** Sofern zusätzlich das Symbol auf dem +Startbildschirm sowie die Zwischenspeicherung durch den Dienstarbeiter (*service worker*) +gewünscht wird, ist der Ordner `app/` über einen Webserver auszuliefern: -| Zeile | Inhalt | -|---|---| -| 5–19 | Haupttabelle (13 = Barwert Netto-Auszahlungen, 15 = Barwert Netto-Ertrag, 17 = IRR) | -| 22–37 | Diagnose (31–35 = Freibetragsanalyse, 36/37 = Memo-Zeilen für Rentenzahlungen nach dem Horizont) | -| 40–48 | Monatliche Leistung (47 = äquivalente Monatsleistung real) | -| 50–52 | Diagrammdaten | -| 55 | Diagramm | +```bash +cd app && python3 -m http.server 8000 # sodann: http://localhost:8000 +``` -`Eingaben` verweist auf `Vergleich` **13, 15, 47**. +Ein Betrieb über `http://localhost` ist zulässig; die Adresse gilt als sicherer Kontext im +Sinne der einschlägigen Spezifikation und ist von dem Erfordernis einer +Transportverschlüsselung ausdrücklich ausgenommen. ---- +(3) **Weitergabe an Dritte.** Hinsichtlich der drei hierfür vorgesehenen Wege — Versendung der +Dateien, Bereitstellung auf einem Webspeicherplatz, Übermittlung eines Verweises einschließlich +sämtlicher eingegebener Werte — wird auf [`app/README.md` § 1](app/README.md) verwiesen. -## 3. Modellmechanik +(4) **Verbleib der Daten.** Die eingegebenen Werte werden ausschließlich im Browser der +nutzenden Person vorgehalten (`localStorage`, Schlüssel `altersvorsorge.v1`). Eine Übermittlung +an einen Server, eine Erhebung von Nutzungsdaten zu Auswertungszwecken sowie ein Nachladen von +Schriftarten oder Skripten von fremden Domänen finden nicht statt und sind auch nicht +vorgesehen. -### Ansparphase (jahresweise) +--- -- Gehalt, BBG, Bezugsgröße, Durchschnittsentgelt und Rentenwert wachsen mit `C13` -- Steuertarif: `ESt = s · λ · T(zvE / s / λ)` mit s = Splittingfaktor, λ = Tarifindex. - Das ist exakt äquivalent zu einer proportionalen Verschiebung aller Eckwerte; - λ = 1 zeigt volle kalte Progression -- zvE-Näherung: Brutto − AN-Pauschbetrag − SA-Pauschbetrag − abziehbare Vorsorgeaufwendungen - (RV voll, KV zu 96 %, PV voll). Genauigkeit ca. 1 % -- Beiträge unterjährig: Verzinsung mit (1+r)^0,5 im Einzahlungsjahr +## § 3 Verzeichnis der Bestandteile -### Arbeitgeberzuschuss: zwei additive Komponenten +| Datei bzw. Ordner | Zweckbestimmung | +|---|---| +| `app/index.html` | **Die vollständige Anwendung.** Rechenkern, Bedienoberfläche und Diagramme in einer einzigen Datei, gegliedert in nummerierte Teile 0 bis 14 | +| `app/i18n.*.js` | Wörterbücher, je Sprachfassung eines. Deutsch ist Hauptsprache und Rückfallebene | +| `app/manifest.json` | Angaben zur Installierbarkeit (Bezeichnung, Farben, Symbole) | +| `app/service-worker.js` | Zwischenspeicherung für den Offline-Betrieb | +| `app/pruefe.js` | Entwicklungswerkzeug zur Sprachprüfung; wird nicht ausgeliefert | +| `app/akk-keilschrift*.js` | Erzeugung der Keilschriftfassung aus der Umschrift | +| [`app/README.md`](app/README.md) | **Technische Dokumentation.** Aufbau, Modellmechanik im Einzelnen, Prüfung, Gestaltungsentscheidungen | -Seit der Erweiterung zerfällt der Zuschuss in `agz = agz_var + agz_fx`: +--- -| Komponente | Zelle | Rechtsgrund | Verhalten | -|---|---|---|---| -| `agz_var` — prozentual | `C26`, Modus `C30` | § 1a Abs. 1a BetrAVG bzw. Versorgungsordnung | proportional zum Beitrag, im Modus 2 auf die tatsächliche AG-Ersparnis gedeckelt | -| `agz_fx` — Festbetrag | `C27`, `C28`, `C29` | Tarifvertrag / Betriebsvereinbarung (z. B. Deutsche Bahn) | betragsunabhängig, vom Zuschussmodus unberührt, oben drauf | +## § 4 Das Vergleichsprinzip -Der Festbetrag ist **arbeitgeberfinanzierte Zuwendung nach § 3 Nr. 63 EStG** und belegt -deshalb den 8-%-Topf des § 3 Nr. 63 EStG *und* die 4-%-Beitragsfreiheit des -§ 1 Abs. 1 S. 1 Nr. 9 SvEV **vorrangig** (Vertrauen ~80 %): +(1) Ein Vergleich anhand der Bruttobeiträge wäre unsachgemäß: die Entgeltumwandlung wird aus +dem Bruttoentgelt geleistet, das private Sparen hingegen aus dem versteuerten Entgelt. +Gleichgesetzt wird daher der **Nettoaufwand**, mithin der Betrag, um welchen sich das +verfügbare Einkommen tatsächlich mindert: ``` -agz_fx = aktiv · [beitrag_mtl ≥ agz_fix_min] · 12 · agz_fix · (dyn ? Lohnindex : 1) -bav_svf = min(bav_br, max(0, 4 % · BBG_RV − agz_fx)) ← Verdrängung -agz_var = f(bav_svf, sverp_ag, Modus) -bav_stf = min(bav_br, max(0, 8 % · BBG_RV − agz_fx − agz_var)) +Nettoaufwand = Bruttobeitrag − Lohnsteuerersparnis − ersparter Arbeitnehmeranteil zur Sozialversicherung ``` -Die Reihenfolge ist zyklenfrei: `agz_fx` hängt nur am Beitrag, nicht an `sverp_ag`. -Ökonomisch ist der Festbetrag ein **Sockel, kein Hebel** — er hebt den Durchschnittsertrag -stark, die Grenzrendite des nächsten Beitragseuros senkt er sogar leicht -(∂²Ertrag/∂agz_fix ∂beitrag ≤ 0), weil er dem Eigenbeitrag Freibetrag wegnimmt. +(2) Ebendieser Betrag wird in sämtlichen drei Gestaltungsvarianten angelegt. Was verbleibt, ist +mithin ein Vergleich der Förderarchitekturen und nicht ein Vergleich der Einzahlungshöhen. -Die Mindestschwelle `agz_fix_min` macht N(B) **unstetig**: an der Schwelle springt der -Nettoaufwand nach oben (Basisfall, 150 €/Monat fest ab 300 €/Monat Eigenbeitrag: -164,54 € → 173,08 €). Monoton bleibt N, die Bisektion konvergiert also weiter, aber -Zielwerte im Sprungintervall sind schlicht nicht erreichbar — `resid` zeigt das an. +(3) Brutto- und Nettobetrag sind in der Anwendung wechselseitig gekoppelt; eine Vorgabe ist in +beiden Richtungen zulässig. Da die Funktion N(B) wegen der Knickstellen bei 4 bzw. 8 vom +Hundert der Beitragsbemessungsgrenze der Rentenversicherung, an den Beitragsbemessungsgrenzen +sowie an den Tarifeckwerten nicht geschlossen umkehrbar, jedoch stetig und streng monoton +wachsend ist, wird die Umkehrung durch ein Verfahren mit 34 Intervallhalbierungen bewirkt. -**Nicht modelliert:** Übersteigt `agz_fx` allein 4 % der BBG-RV, wäre der Überhang beim -Arbeitnehmer beitragspflichtiges Arbeitsentgelt. Diese Beitragslast wird nicht gegen- -gerechnet; das Blatt `Kennzahlen` und die Diagnosetabelle der Web-App weisen den Überhang -separat aus. Bei 2026er Werten greift das ab 338 €/Monat Festzuschuss. +### Die vier Werttreiber -### Schichtenmodell +Der Steueraufschub ist für sich genommen ohne Wert, da (1−t)·(1+r)ⁿ = (1+r)ⁿ·(1−t) gilt; die +Multiplikation ist kommutativ. Es verbleiben mithin ausschließlich: -Beide geförderten Produkte werden in **zwei Schichten** geführt, weil sonst derselbe Euro -zweimal besteuert würde: +1. **Tarifarbitrage** t₀ − t₁ — Grenzsteuersatz im Zeitpunkt der Einzahlung abzüglich desjenigen + im Zeitpunkt der Auszahlung; +2. **Fremdmittel** — Zuschuss des Arbeitgebers bzw. Zulagen; +3. **Steuerfreie Thesaurierung** — betriebliche Altersversorgung und Altersvorsorgedepot kennen + die Vorabpauschale nicht; +4. **Neu hinzutretende Abgaben, welche lediglich eine Variante betreffen** — Beiträge zur + Kranken- und Pflegeversicherung auf Versorgungsbezüge (§ 229 SGB V). -| | gefördert | nicht gefördert | -|---|---|---| -| **bAV** | bis 8 % BBG-RV (§ 3 Nr. 63 EStG) → 100 % nachgelagert steuerpflichtig | Rest, aus versteuertem Entgelt → halber Unterschiedsbetrag (Kapital) bzw. Ertragsanteil (Rente) | -| **AV-Depot** | Eigenbeitrag bis 1.800 € + Zulagen → 100 % nachgelagert | Beiträge darüber + reinvestierte Erstattung → halber Unterschiedsbetrag (Plan bzw. Einmalbetrag) oder Ertragsanteil (Rente) | - -Der Überschuss über den Jahreshöchstbetrag von 6.840 € läuft in eine eigene Schiene -(„Sleeve"), die wie das Privatdepot besteuert wird — so bleibt der Nettoaufwand identisch. - -### Auszahlungsphase - -- **Auszahlungsform je Produkt getrennt**: `auszform` für die bAV (Kapital oder Rente), - `av_auszform` für das Depot (Auszahlungsplan oder Rente), dazu `teilkap` für den Einmalbetrag - von bis zu 30 % beim Depot, der in beiden Formen wirkt. Bei Verrentung geht das Restkapital an - den Anbieter, ein Depotkonto gibt es danach nicht mehr -- **KV/PV nur bei der bAV**: voller Satz allein vom Rentner (§ 250 SGB V), Freibetrag - 1/20 Bezugsgröße für KV, Freigrenze für PV, Kapitalleistung auf 120 Monate verteilt, - gemeinsame BBG mit der gesetzlichen Rente (§ 223 Abs. 3 SGB V) -- **Verlust an Entgeltpunkten** wird der bAV netto gegengerechnet -- Alle Kennzahlen auf **Äquivalenzbasis**: jeder Zahlungsstrom wird mit dem - Wiederanlagezins nach Steuern auf den Rentenbeginn bezogen und dann als konstante - Monatszahlung über denselben Zeitraum ausgedrückt. Weil Annuitisierung linear ist, - addieren sich die Komponenten exakt (geprüft auf 10⁻¹²) +Nummer 4 stellt den beherrschenden Nachteil der betrieblichen Altersversorgung dar; Nummer 2 +ist deren einziger struktureller Vorteil. --- -## 4. Neu bauen - -```bash -python3 build_bav.py -python3 /xlsx/scripts/recalc.py bAV-DYNO_vs_Altersvorsorgedepot_vs_ETF.xlsx 32 -``` - -`recalc.py` schreibt die von openpyxl erzeugten Formeln mit LibreOffice durch und legt die -Werte im Cache ab — vorher liest jedes Werkzeug `None`. - -### Vier Fallstricke, die Zeit gekostet haben - -1. **`IRR()` ohne Startwert lässt LibreOffice hängen.** Immer `IRR(bereich; 0,05)` schreiben. -2. **Recalc auf dem gemounteten Ordner hängt.** Nach `/tmp` kopieren, dort rechnen, - zurückkopieren. -3. **Notiztexte dürfen nicht mit `=` beginnen** — openpyxl schreibt sie sonst als Formel. -4. **Hilfszellen kollidieren mit Datenspalten.** Die Auszahlung reicht inzwischen bis Spalte - **BF** (58 Spalten), die Hilfszellen liegen bei CE/CG **unterhalb** von Zeile 8. Das - funktioniert, ist aber fragil: beim Hinzufügen von Spalten jedes Mal nachrechnen. Die - Erweiterung um die Depotverrentung hat drei Spalten gekostet. +## § 5 Leistungsumfang + +- **Sensitivitätskurve** über denjenigen Regler, welcher zuletzt betätigt worden ist: 41 + vollständige Modellläufe nebst Kennzeichnung der Schnittpunkte gegenüber dem privaten Depot. + Gewinnschwellen sind hierdurch ablesbar und müssen nicht errechnet werden. +- **Wasserfalldarstellung der Werttreiber**, teleskopierend zerlegt und mithin exakt aufgehend. + Auf die Reihenfolgeabhängigkeit wird in der Anwendung ausdrücklich hingewiesen. +- **Kapital- und Liquiditätsverlauf** über die gesamte Zeitachse, einschließlich der + Kennzeichnung des gebundenen gegenüber dem frei verfügbaren Kapital. +- **Warnhinweis bei uneinheitlicher Rangfolge.** Barwert und äquivalente Monatsleistung ranken + unterschiedlich, sobald der Wiederanlagezins nach Steuern die Inflationsrate deutlich + übersteigt; hierauf wird hingewiesen. +- **Sämtliche 45 Rechengrößen sind änderbar**, jeweils unter Angabe der Fundstelle. Wer eine + Modellannahme nicht teilt, hat sie zu ändern; ein Eingriff in den Quelltext ist hierfür nicht + erforderlich. +- **Klartextfazit** in einem Satz nebst Belastbarkeitstest über ±1 Prozentpunkt Bruttorendite. + Die Formulierung ist beschreibend und nicht empfehlend gehalten. +- **Weitergabe des Berechnungsstandes** als Verweis; die Werte werden im Fragmentbezeichner + geführt und mithin nicht an einen Server übermittelt (RFC 3986 § 3.5). +- **23 Sprachfassungen**, darunter zwei Registervarianten des Deutschen (`de-x-amt` und + `de-x-sales`), welche denselben § 1a BetrAVG einmal als Verwaltungsschreiben und einmal als + Werbetext wiedergeben. Die Normzitate verbleiben in sämtlichen Sprachfassungen in deutscher + Sprache. Einzelheiten: [`app/README.md` § 3b](app/README.md). + +Hinsichtlich der Modellmechanik im Einzelnen — Schichtenmodell, Architektur des +Arbeitgeberzuschusses, Auszahlungsphase, die beiden Zinssätze — wird auf +[`app/README.md`](app/README.md) verwiesen; eine Wiedergabe an dieser Stelle unterbliebe nicht +ohne die Gefahr des Auseinanderlaufens beider Darstellungen. --- -## 5. Verifikation - -Vier Ebenen, alle bestanden: +## § 6 Belastbarkeit der Rechtsannahmen -1. **Recalc**: 0 Formelfehler -2. **Strukturaudit**: alle blattinternen Hartbezüge gegen Ziel-Labels geprüft, keine toten - Eingaben, alle Aggregatbereiche auf der korrekten Spannweite -3. **Unabhängige Zweitimplementierung in Python**, aus der Spezifikation geschrieben, nicht - aus den Excel-Formeln abgeleitet — 14 Aggregate, Abweichung **0,000000 %** -4. **Zweiter Testfall**, der die im Basisfall unberührten Zweige aktiviert (Splitting, - Kirchensteuer, Soli mit Milderungszone, Gehalt über BBG-RV, nicht geförderte Schicht, - Sleeve) — Abweichung **0,00000000 %** +Sämtliche nachstehend aufgeführten Annahmen sind in der Anwendung unter „Rechenweg → +Belastbarkeit der Annahmen" einsehbar und änderbar. -### Fehlerklassen, die der Recalc *nicht* findet +| Annahme | Vertrauensgrad | Anmerkung | +|---|---|---| +| Rechengrößen der Sozialversicherung 2026, Tarif gemäß § 32a EStG 2026 | ~97 % | SVBezGrV 2026, Steuerfortentwicklungsgesetz | +| Beitragspflicht in der Kranken- und Pflegeversicherung auf Versorgungsbezüge | ~95 % | §§ 229, 250 SGB V | +| Freibetrag gemäß § 226 Abs. 2 S. 2 SGB V (KV), Freigrenze in der PV | ~95 % / ~85 % | Der die Pflegeversicherung betreffende Punkt stellt die häufigste Fehlerquelle in Ratgebertexten dar | +| Beitragsfreiheit der Auszahlung aus dem Altersvorsorgedepot | ~85 % | Es handelt sich nicht um Versorgungsbezüge | +| Halber Unterschiedsbetrag für nicht geförderte Schichten | ~80 % | § 22 Nr. 5 S. 2 Buchst. b i. V. m. § 20 Abs. 1 Nr. 6 S. 2 EStG | +| Zuschuss lediglich bis zur Höhe der tatsächlichen Ersparnis des Arbeitgebers | ~75 % | Nach der Gegenauffassung sind die 15 vom Hundert als reine Pauschale zu verstehen | +| Fester Arbeitgeberzuschuss belegt den 4-%- und den 8-%-Höchstbetrag vorrangig | ~80 % | Arbeitgeberfinanzierte Zuwendung im Sinne des § 3 Nr. 63 EStG; die eigene Entgeltumwandlung wird insoweit verdrängt | +| **Sonderausgaben-Höchstbetrag 2.340 €** | **~70 %** | **Modellannahme.** Hiervon hängt ab, ob ein Kind den Wert des Altersvorsorgedepots hebt oder senkt | +| Günstigerprüfung als Höchstwert, nicht als Summe | ~90 % | § 10a Abs. 2 EStG | +| Unterstellt wird eine Pflichtversicherung in der KVdR im Ruhestand | ~70 % | Freiwillig Versicherte sind nicht geprüft worden | + +**Nicht abgebildet:** Abschläge bei vorzeitigem Rentenbezug; Auswirkungen der Entgeltumwandlung +auf Kranken-, Arbeitslosen- und Elterngeld; Hinterbliebenenversorgung; Insolvenzsicherung +(PSVaG); Portabilität bei einem Wechsel des Arbeitgebers; Kinderabschläge in der +Pflegeversicherung; Günstigerprüfung gemäß § 32d Abs. 6 EStG; Pfändungs- und +Grundsicherungsschutz. Ferner wird die Teilkapitalisierung der betrieblichen Altersversorgung +nicht abgebildet; insoweit kennt das Modell ausschließlich die vollständige oder die +unterbliebene Kapitalisierung. -Beide in diesem Projekt tatsächlich aufgetreten: +--- -- **Falsche Zeilenkonstanten** in handgeschriebenen Bezügen (`B26/B27` statt `B31/B32`). - Fiel nur auf, weil die Größenordnung nicht stimmte — die Zahlenwerte lagen zufällig 1 % - auseinander. -- **Spaltenkollision**: eine neue Datenspalte landete auf einer Hilfszelle; deren Text - wurde von SUMPRODUCT als 0 gewertet, wodurch ausgerechnet das erste Auszahlungsjahr - entfiel. Fiel nur am Vorzeichen auf. +## § 7 Ergebnisse des Regelfalls -**Konsequenz für Weiterarbeit:** Nach jeder Änderung nicht nur den Recalc laufen lassen, -sondern eine Größenordnung prüfen. Die Zweitimplementierung aus Abschnitt 5.3 ist das -schärfste Werkzeug dafür. +Zugrunde gelegt werden 40 Jahre Ansparphase, 75.000 € Jahresbruttoentgelt, 300 € Monatsbeitrag, +gesetzliche Krankenversicherung, spitz berechneter Zuschuss von 15 vom Hundert sowie eine +Bruttorendite von 7 vom Hundert: ---- - -## 6. Rechtliche Annahmen und ihre Belastbarkeit +| in heutiger Kaufkraft | bAV | AV-Depot | privat | +|---|---|---|---| +| Barwert des Nettoertrags | 27.737 € | 88.414 € | 73.740 € | +| Äquivalente Monatsleistung | 587,67 € | 768,45 € | 689,48 € | +| Interner Zinsfuß | 5,37 % | 6,61 % | 6,14 % | -Alle im Blatt `Parameter` änderbar. +Die betriebliche Altersversorgung obsiegt ausschließlich über zwei Hebel, welche beide +außerhalb der Steuerarchitektur liegen: + +- **Private Krankenversicherung im Ruhestand** — bereits diese Einstellung allein bewirkt eine + Umkehr des Ergebnisses; +- **Zuschuss ab etwa 30 vom Hundert** — die Gewinnschwelle folgt näherungsweise aus + (1+z)·(1−0,211) ≈ 1, mithin z ≈ 26,7 vom Hundert. + +> **Klarstellung.** Die vorstehenden Aussagen gelten für die *äquivalente Monatsleistung*, nicht +> hingegen für den *Barwert des Nettoertrags*. Bei privater Krankenversicherung steigt die +> betriebliche Altersversorgung auf 725,49 €/Monat gegenüber 689,48 € beim privaten Depot und +> obsiegt mithin; im Barwert verbleibt sie mit 49.653 € gegenüber 73.740 € deutlich zurück. Die +> Kennzahlen ranken deshalb unterschiedlich, weil der Barwert mit der Inflationsrate +> (2,00 vom Hundert) abgezinst, die Monatsleistung hingegen mit dem Wiederanlagezins nach +> Steuern (5,54 vom Hundert) verrentet wird; eine frühe Kapitalauszahlung wird hierdurch +> systematisch günstiger bewertet. Welche Kennzahl maßgeblich ist, hängt davon ab, ob das +> Kapital angelegt oder verbraucht wird. +> +> Die Gewinnschwelle von 26,7 vom Hundert ist überdies im spitz berechneten Zuschussmodus +> **nicht erreichbar**: dort begrenzt § 1a Abs. 1a BetrAVG den Zuschuss auf die tatsächliche +> Ersparnis des Arbeitgebers an Sozialversicherungsbeiträgen, im Regelfall rund 21 vom Hundert +> des umgewandelten Betrags. Eine weitere Erhöhung des Reglers bleibt sodann wirkungslos. -| Annahme | Vertrauen | Anmerkung | -|---|---|---| -| Rechengrößen SV 2026, § 32a-Tarif 2026 | ~97 % | SVBezGrV 2026, Steuerfortentwicklungsgesetz | -| KV/PV-Pflicht auf Versorgungsbezüge | ~95 % | §§ 229, 250 SGB V | -| Freibetrag § 226 Abs. 2 S. 2 SGB V (KV), Freigrenze in der PV | ~95 % / ~85 % | Der PV-Punkt ist die häufigste Fehlerquelle in Ratgebertexten | -| Beitragsfreiheit der Altersvorsorgedepot-Auszahlung | ~85 % | Keine Versorgungsbezüge | -| Halber Unterschiedsbetrag für nicht geförderte Schichten | ~80 % | § 22 Nr. 5 S. 2 Buchst. b i.V.m. § 20 Abs. 1 Nr. 6 S. 2 EStG | -| Zuschuss nur bis zur tatsächlichen AG-Ersparnis (Modus 2) | ~75 % | Gegenauffassung liest 15 % als reine Pauschale = Modus 1 | -| Fester AG-Zuschuss belegt 4-%- und 8-%-Topf vorrangig | ~80 % | Arbeitgeberfinanzierte Zuwendung nach § 3 Nr. 63 EStG; verdrängt eigene Umwandlung | -| **Sonderausgaben-Höchstbetrag 2.340 €** | **~70 %** | **Modellannahme.** Bestimmt, ob ein Kind den Wert des AV-Depots hebt oder senkt | -| Günstigerprüfung als Maximum, nicht Summe | ~90 % | § 10a Abs. 2 EStG | -| Modell unterstellt KVdR-Pflichtversicherung im Ruhestand | ~70 % | Freiwillig Versicherte nicht geprüft | - -**Nicht modelliert:** Abschläge bei vorzeitigem Rentenbezug, Wirkung der Entgeltumwandlung -auf Kranken-, Arbeitslosen- und Elterngeld, Hinterbliebenenversorgung, Insolvenzsicherung -(PSVaG), Portabilität bei Arbeitgeberwechsel, Kinderabschläge in der PV, Günstigerprüfung -nach § 32d Abs. 6 EStG, Pfändungs- und Grundsicherungsschutz. +Die Rendite der betrieblichen Altersversorgung **fällt streng monoton** mit der Beitragshöhe, +da der Freibetrag ein absoluter ist und seine Schutzwirkung mit 1/K abnimmt. Ein inneres Optimum +besteht mithin nicht. Der einzige beitragsfreie Bereich (Kapital ≤ 120 × Freibetrag ≈ 46.000 €, +entsprechend rund 42 €/Monat) ist zu gering bemessen, um als Vorsorgestrategie in Betracht zu +kommen; er hängt überdies vollständig an einer politisch gesetzten Zahl. --- -## 7. Wichtigste Befunde des Basisfalls +## § 8 Prüfung -40 Jahre, 75.000 € Brutto, 300 €/Monat, GKV, Zuschuss 15 % spitz, 7 % Bruttorendite: +(1) Der Rechenkern ist gegen ein unabhängig geführtes Zweitmodell auf Maschinengenauigkeit +abgeglichen worden: sechs unabhängige Testfälle zu je rund 20 Aggregaten, größte festgestellte +relative Abweichung 1,3·10⁻¹⁴, nebst vier weiteren Fällen zum festen Arbeitgeberzuschuss, welche +exakt übereinstimmen. Es handelt sich hierbei um wenige Dutzend Einheiten der letzten Stelle, +mithin um akkumulierten Gleitkommafehler und nicht um eine systematische Abweichung. -| in heutiger Kaufkraft | bAV | AV-Depot | privat | -|---|---|---|---| -| Barwert Netto-Ertrag | 27.737 € | 88.414 € | 73.740 € | -| Äquivalente Monatsleistung | 587,67 € | 768,45 € | 689,48 € | -| Interner Zinsfuß | 5,37 % | 6,61 % | 6,14 % | +(2) Ferner bestehen ein Stilblatt-Test, ein Test der Bedienoberfläche mit 57 Zusicherungen sowie +ein zweistufiger Test der Diagramme mit insgesamt 520 Kombinationen. Die Sprachprüfung +`app/pruefe.js` schaltet sämtliche 23 Sprachfassungen durch und weist unter anderem nach, dass +die Rechenergebnisse in allen Sprachfassungen identisch sind; sie umfasst 154 Prüfungen und +setzt `jsdom` voraus. -Die bAV gewinnt nur über zwei Hebel, beide außerhalb der Steuerarchitektur: +(3) Einzelheiten nebst der Fehlerklassen, welche die vorgenannten Prüfungen nachweislich +*nicht* auffinden, sind [`app/README.md` § 4](app/README.md) zu entnehmen. -- **PKV im Ruhestand** (`C39` = 2) — allein das dreht das Ergebnis -- **Zuschuss ≳ 30 %** — Break-even folgt näherungsweise aus (1+z)·(1−0,211) ≈ 1 ⟹ z ≈ 26,7 % +--- -> **Präzisierung, beim Portieren aufgefallen.** Beide Aussagen gelten für die *äquivalente -> Monatsleistung*, nicht für den *Barwert des Netto-Ertrags*. Mit PKV steigt die bAV auf -> 725,49 €/Monat gegen 689,48 € beim Privatdepot — gewinnt also. Im Barwert bleibt sie mit -> 49.653 € gegen 73.740 € klar hinten. Die Kennzahlen ranken unterschiedlich, weil der Barwert -> mit der Inflation (2,00 %) abzinst, die Monatsleistung aber mit dem Wiederanlagezins nach -> Steuern (5,54 %) verrentet: eine frühe Kapitalauszahlung wird dadurch systematisch besser -> bewertet. Welche Zahl gilt, hängt daran, ob das Kapital angelegt oder verkonsumiert wird. -> -> Der Break-even von 26,7 % ist außerdem **im Zuschussmodus 2 („spitz“) unerreichbar**: dort -> deckelt § 1a Abs. 1a BetrAVG den Zuschuss auf die tatsächliche SV-Ersparnis des Arbeitgebers, -> im Basisfall rund 21 % des umgewandelten Betrags. Ab da ändert der Zuschussregler nichts mehr. -> In Modus 0 liegt der Break-even (Monatsleistung) bei knapp über 30 %. +## § 9 Herkunft -Die Rendite der bAV **fällt streng monoton** in der Beitragshöhe, weil der Freibetrag -absolut ist und seine Schutzwirkung wie 1/K abnimmt. Es gibt kein inneres Optimum. -Der einzige beitragsfreie Bereich (Kapital ≤ 120 × Freibetrag ≈ 46.000 €, entspricht -~42 €/Monat) ist zu klein, um als Vorsorgestrategie zu taugen — und hängt vollständig -an einer politisch gesetzten Zahl. +Die vorliegende Anwendung ist aus einer vollständig formelbasierten Excel-Arbeitsmappe (6.359 +Formeln) hervorgegangen, welche ihrerseits durch ein Python-Skript erzeugt worden ist. Beide +Bestandteile sind zwischenzeitlich entfallen, da die Webanwendung an ihre Stelle getreten ist; +sie sind ausschließlich über die Versionsgeschichte zugänglich. Der Rechenkern in Teil 1 von +`app/index.html` ist zeichengenau aus dem ursprünglichen Formelgenerator übertragen worden und +stellt nunmehr **die einzige Stelle dar, an der gerechnet wird.** --- -## 8. Offene Punkte - -- [ ] Anwendungsschreiben zur pAV-Reform abwarten → Sonderausgaben-Höchstbetrag und - Besteuerung der nicht geförderten Schicht bestätigen -- [ ] Tatsächliche DYNO-Vertragsdaten einsetzen: Durchführungsweg, Effektivkosten aus dem - Produktinformationsblatt, zugesagter Zuschuss laut Versorgungsordnung -- [ ] Klären, ob der Zuschuss auch oberhalb der Beitragsbemessungsgrenzen gezahlt wird - (entscheidet 116 Basispunkte) -- [ ] Prüfen, ob bereits andere Versorgungsbezüge bestehen — der Freibetrag gilt pro - Person, nicht pro Vertrag -- [x] ~~Verrentung des Altersvorsorgedepots~~ — eingebaut: eigene Eingabe `av_auszform`, - unabhängig von der bAV-Auszahlungsform, mit eigenem Rentenfaktor und eigener Dynamik. - Nicht geförderte Schicht dann mit dem Ertragsanteil statt dem halben Unterschiedsbetrag, - zweite Memo-Zeile für Zahlungen nach dem Vergleichshorizont. -- [ ] Teilkapitalisierung der **bAV** (0–30 % einmalig, Rest verrentet). Beim Depot ist das seit - der Erweiterung möglich, bei der bAV noch nicht — das Modell kennt dort nur ganz oder gar - nicht. Die einzige verbliebene Asymmetrie zwischen den beiden geförderten Produkten. -- [ ] Optional: jahresweise Inversion des Nettoaufwands statt nur im ersten Jahr -- [ ] Optional: Sensitivitätstabelle über Rendite × Option (Excel-Datentabellen werden von - openpyxl nicht geschrieben; Alternative wäre eine vorgerechnete Matrix) +## § 10 Offene Punkte + +- [ ] Das Anwendungsschreiben zur Reform der geförderten privaten Altersvorsorge ist abzuwarten; + sodann sind der Sonderausgaben-Höchstbetrag sowie die Besteuerung der nicht geförderten + Schicht zu bestätigen. +- [ ] Es ist zu klären, ob der Zuschuss auch oberhalb der Beitragsbemessungsgrenzen geleistet + wird; hiervon hängen 116 Basispunkte ab. +- [ ] Es ist zu prüfen, ob bereits weitere Versorgungsbezüge bestehen; der Freibetrag gilt je + Person und nicht je Vertrag. +- [ ] Die Teilkapitalisierung der **betrieblichen Altersversorgung** (0 bis 30 vom Hundert + einmalig, im Übrigen verrentet) ist noch abzubilden. Beim Altersvorsorgedepot ist dies + bereits möglich; es handelt sich um die einzig verbliebene Asymmetrie zwischen den beiden + geförderten Produkten. +- [ ] Fakultativ: jahresweise Umkehrung des Nettoaufwands anstelle der Umkehrung allein im + ersten Jahr. +- [x] ~~Verrentung des Altersvorsorgedepots~~ — eingerichtet: eigene Eingabe `av_auszform`, + unabhängig von der Auszahlungsform der betrieblichen Altersversorgung, mit eigenem + Rentenfaktor und eigener Dynamik. --- -## 9. Quellen +## § 11 Quellen - [SVBezGrV 2026](https://www.gesetze-im-internet.de/svbezgrv_2026/BJNR1160A0025.html) - [§ 32a EStG](https://www.gesetze-im-internet.de/estg/__32a.html) -- [BMF, FAQ Reform der geförderten privaten Altersvorsorge (05.05.2026)](https://www.bundesfinanzministerium.de/Content/DE/FAQ/reform-der-privaten-altersvorsorge.html) +- [BMF, FAQ zur Reform der geförderten privaten Altersvorsorge (05.05.2026)](https://www.bundesfinanzministerium.de/Content/DE/FAQ/reform-der-privaten-altersvorsorge.html) - [Bundesregierung, Private Altersvorsorge wird attraktiver (01.06.2026)](https://www.bundesregierung.de/breg-de/aktuelles/reform-private-altersvorsorge-2400072) -- [BMF-Schreiben 13.01.2026, Basiszins Vorabpauschale § 18 Abs. 4 InvStG](https://www.bundesfinanzministerium.de/Content/DE/Downloads/BMF_Schreiben/Steuerarten/Investmentsteuer/2026-01-13-basiszins-berechnung-vorabpauschale.html) +- [BMF-Schreiben vom 13.01.2026, Basiszins zur Vorabpauschale gemäß § 18 Abs. 4 InvStG](https://www.bundesfinanzministerium.de/Content/DE/Downloads/BMF_Schreiben/Steuerarten/Investmentsteuer/2026-01-13-basiszins-berechnung-vorabpauschale.html) - [GKV-Spitzenverband, Rechengrößen 2026](https://www.gkv-spitzenverband.de/media/dokumente/presse/zahlen_und_grafiken/20260101_Faktenblatt_Rechengroessen_Beitragsrecht.pdf) -- [DYNO](https://heydyno.de) --- -*Keine Steuer- oder Anlageberatung. Das Modell ersetzt keine Prüfung des konkreten Vertrags.* +*Es wird abschließend darauf hingewiesen, dass mit der vorliegenden Anwendung weder eine +Steuer- noch eine Anlageberatung erbracht wird. Ein Modell ist kein Vertrag; die Prüfung des +jeweils konkreten Vertragswerks wird hierdurch nicht ersetzt.* diff --git a/app/README.md b/app/README.md index 522018c..fab1593 100644 --- a/app/README.md +++ b/app/README.md @@ -1,244 +1,265 @@ -# Altersvorsorge-Vergleich — Web-App +# Altersvorsorge-Vergleich — Webanwendung -Progressive Web-App zum Excel-Modell im übergeordneten Ordner. Derselbe Rechenkern, dieselben -Ergebnisse, aber bedienbar von Menschen, die keine Tabellenkalkulation aufmachen wollen. +Progressive Webanwendung (PWA) zum Vergleich dreier Gestaltungsvarianten der Altersvorsorge. +Es handelt sich um das eigentliche Erzeugnis dieses Bestandes; hinsichtlich einer allgemeinen +Einführung wird auf das [Wurzel-README](../README.md) verwiesen. Der Rechenkern ist aus einer +zwischenzeitlich entfallenen Excel-Arbeitsmappe übernommen worden, welche ausschließlich über +die Versionsgeschichte zugänglich ist; die Ergebnisse sind dieselben, die Bedienung ist jedoch +auch denjenigen Personen eröffnet, welche eine Tabellenkalkulation nicht zu öffnen beabsichtigen. -| Datei | Rolle | +| Datei | Zweckbestimmung | |---|---| -| `index.html` | **Die ganze App.** Rechenkern, Oberfläche, Diagramme — eine Datei, keine externen Abhängigkeiten außer den Wörterbüchern. Läuft per Doppelklick. | +| `index.html` | **Die vollständige Anwendung.** Rechenkern, Bedienoberfläche und Diagramme in einer einzigen Datei, ohne externe Abhängigkeiten mit Ausnahme der Wörterbücher. Der Aufruf erfolgt mittels Doppelklicks. | | `i18n.de.js` | Wörterbuch Deutsch. Hauptsprache und Rückfallebene. **Vollständig.** | | `i18n.en.js` `i18n.nl.js` `i18n.fr.js` `i18n.la.js` `i18n.ja.js` | Englisch, Niederländisch, Französisch, Latein, Japanisch. **Vollständig** (459 Schlüssel). | -| `i18n.nds.js` `i18n.bar.js` `i18n.eu.js` `i18n.eo.js` `i18n.tr.js` `i18n.uk.js` | Niederdeutsch, Bairisch, Baskisch, Esperanto, Türkisch, Ukrainisch. **Teilweise** (315 Schlüssel, siehe 3b). | -| `i18n.got.js` `i18n.goh.js` `i18n.gmh.js` `i18n.grc.js` `i18n.sa.js` | Gotisch, Althochdeutsch, Mittelhochdeutsch, Altgriechisch, Sanskrit. **Teilweise**. | -| `i18n.ine-x-proto.js` | Urindogermanisch, LIV²/Rix-Notation mit Laryngalen und Asterisk. Kein ISO-639-3-Code möglich (639-3 vergibt keine Codes an Rekonstruate), daher BCP-47-Privatuntertag `ine-x-proto`. **Vollständig**. | -| `i18n.jbo.js` `i18n.tok.js` | Lojban, Toki Pona. Toki Pona speichert sitelen Lasina (ASCII); das Stilblatt setzt für `lang="tok"` ligaturfähige sitelen-pona-Zeichensätze, die die ASCII-Wörter zu Logographen binden — ohne installierten Zeichensatz bleibt lesbares Latein statt PUA-Kästchen. **Vollständig**. | -| `i18n.akk-x-ob.js` | Altbabylonisch in Keilschrift (U+12000…). Erzeugt aus `i18n.akk-x-ob.translit.js` durch `node akk-keilschrift.js`; die Umschrift ist die Quelle, die Keilschrift das Erzeugnis. Codepunkte werden zur Bauzeit über die Unicode-Namenstabelle aufgelöst statt von Hand gesetzt. **Vollständig**. | -| `manifest.json` | Macht die App installierbar (Name, Farben, Symbole). | -| `service-worker.js` | Offline-Cache, `stale-while-revalidate`. | -| `icon-*.png` | App-Symbole, 192 / 512 / 512-maskable. | +| `i18n.nds.js` `i18n.bar.js` `i18n.eu.js` `i18n.eo.js` `i18n.tr.js` `i18n.uk.js` | Niederdeutsch, Bairisch, Baskisch, Esperanto, Türkisch, Ukrainisch. **Vollständig** (siehe § 3b). | +| `i18n.got.js` `i18n.goh.js` `i18n.gmh.js` `i18n.grc.js` `i18n.sa.js` | Gotisch, Althochdeutsch, Mittelhochdeutsch, Altgriechisch, Sanskrit. **Vollständig.** | +| `i18n.ine-x-proto.js` | Urindogermanisch in LIV²/Rix-Notation nebst Laryngalen und Asterisk. Ein Code nach ISO 639-3 ist nicht zu erlangen, da für Rekonstruate keine Codes vergeben werden; es wird daher der Privatuntertag `ine-x-proto` nach BCP 47 geführt. **Vollständig.** | +| `i18n.jbo.js` `i18n.tok.js` | Lojban, Toki Pona. Toki Pona wird in sitelen Lasina (ASCII) vorgehalten; das Stilblatt setzt für `lang="tok"` ligaturfähige sitelen-pona-Zeichensätze, welche die ASCII-Wörter zu Logographen binden. Ist ein solcher Zeichensatz nicht installiert, verbleibt lesbares Latein anstelle leerer Kästchen. **Vollständig.** | +| `i18n.akk-x-ob.js` | Altbabylonisch in Keilschrift (U+12000 ff.). Erzeugt aus `i18n.akk-x-ob.translit.js` mittels `node akk-keilschrift.js`; die Umschrift ist die Quelle, die Keilschrift das Erzeugnis. Die Codepunkte werden zur Bauzeit über die Unicode-Namenstabelle aufgelöst und nicht von Hand gesetzt. **Vollständig.** | +| `manifest.json` | Bewirkt die Installierbarkeit (Bezeichnung, Farben, Symbole). | +| `service-worker.js` | Offline-Zwischenspeicher, Verfahren `stale-while-revalidate`. | +| `icon-*.png` | Symbole der Anwendung, 192 / 512 / 512-maskable. | --- -## 1. Weitergeben — drei Wege +## § 1 Weitergabe — drei Wege -**a) Nur die Dateien.** `index.html` samt allen dreiundzwanzig `i18n.*.js` verschicken — sie gehören -zusammen und müssen im selben Ordner liegen. Doppelklick genügt, -alles rechnet, Eingaben werden im Browser gespeichert. Was fehlt, ist nur die PWA-Hülle — -kein Symbol auf dem Startbildschirm, kein Offline-Cache. Beides braucht es hier auch nicht, -die Datei liegt ja schon auf dem Gerät. Die App sagt das dem Nutzer auch selbst. +**a) Ausschließlich die Dateien.** Es sind `index.html` nebst sämtlichen dreiundzwanzig +`i18n.*.js` zu übersenden; sie gehören zusammen und haben in demselben Ordner zu liegen. Ein +Doppelklick genügt, sämtliche Berechnungen werden durchgeführt, und die Eingaben werden im +Browser vorgehalten. Es fehlt lediglich die PWA-Hülle — mithin das Symbol auf dem +Startbildschirm sowie der Offline-Zwischenspeicher. Beides ist hier entbehrlich, da die Datei +bereits auf dem Gerät vorliegt. Die Anwendung weist hierauf von sich aus hin. -**b) Der ganze Ordner auf einem Webspace.** Irgendein HTTPS-Hosting genügt (GitHub Pages, -Netlify, ein Unterverzeichnis auf der eigenen Domain). Dann ist sie installierbar und -offlinefähig. Es gibt kein Backend, keine Datenbank, keine Build-Kette. +**b) Der vollständige Ordner auf einem Webspeicherplatz.** Ein beliebiges HTTPS-Hosting genügt +(GitHub Pages, Netlify, ein Unterverzeichnis der eigenen Domäne). Sodann ist die Anwendung +installierbar und offlinefähig. Ein Hintergrundsystem, eine Datenbank sowie eine Baukette +bestehen nicht. ```bash -# lokal ausprobieren, mit Service Worker: +# örtliche Erprobung einschließlich Dienstarbeiter: cd app && python3 -m http.server 8000 # -> http://localhost:8000 ``` -Service Worker laufen auch auf `http://localhost` — als „secure context“ ist localhost -ausdrücklich ausgenommen. +Dienstarbeiter (*service worker*) sind auch über `http://localhost` betriebsfähig; localhost ist +als sicherer Kontext ausdrücklich ausgenommen. -**c) Als Link.** Der Knopf *„Link mit meinen Zahlen kopieren“* kodiert den kompletten -Eingabestand base64url in den Fragment-Bezeichner. Fragmente werden vom Browser **nicht** an -den Server geschickt (RFC 3986 § 3.5) — der Link enthält also persönliche Zahlen, überträgt -sie aber an niemanden außer den Empfänger. +**c) Als Verweis.** Die Schaltfläche *„Link mit meinen Zahlen kopieren"* kodiert den +vollständigen Eingabestand base64url in den Fragmentbezeichner. Fragmente werden vom Browser +**nicht** an den Server übermittelt (RFC 3986 § 3.5); der Verweis enthält mithin persönliche +Zahlen, überträgt diese jedoch an niemanden außer den Empfänger. -## 2. Wo die Daten liegen +## § 2 Verbleib der Daten -Ausschließlich in `localStorage` unter dem Schlüssel `altersvorsorge.v1`, also im Browser des -Nutzers. Kein Server, keine Analytik, keine Schriftarten von fremden Domains, keine externen -Skripte. Die einzigen Netzwerkzugriffe der App sind die, die der Service Worker macht, um sich -selbst zu aktualisieren. +Ausschließlich in `localStorage` unter dem Schlüssel `altersvorsorge.v1`, mithin im Browser der +nutzenden Person. Ein Server, eine Auswertung, Schriftarten von fremden Domänen sowie externe +Skripte bestehen nicht. Die einzigen Netzwerkzugriffe der Anwendung sind diejenigen, welche der +Dienstarbeiter zum Zwecke seiner eigenen Aktualisierung vornimmt. -## 3. Aufbau der Datei +## § 3 Aufbau der Datei `index.html` ist in nummerierte Teile gegliedert: | Teil | Inhalt | |---|---| | 0 | **Sprachen** — `t()`, Sprachwahl, Rückfall auf Deutsch | -| 1 | **Rechenkern** — Portierung von `build_bav.py`. Reine Funktionen, kein DOM | -| 2 | Felddefinitionen: 80 Eingaben mit Bereich, Einheit, Wörterbuchschlüssel | -| 3 | Zustand, `localStorage`, Kodierung für den Teilen-Link | +| 1 | **Rechenkern** — Portierung des ursprünglichen Formelgenerators. Reine Funktionen, kein DOM | +| 2 | Felddefinitionen: 80 Eingaben nebst Bereich, Einheit und Wörterbuchschlüssel | +| 3 | Zustand, `localStorage`, Kodierung für den Weitergabeverweis | | 4 | Formatierung und Zahleneingabe, sprachabhängig | | 5 | Kennzahlen | -| 6 | Aufbau der Oberfläche | -| 7 | Ergebniskarten mit Δ-Anzeige | -| 7b | Klartext-Fazit, Beispielwert-Hinweis, mitlaufende Ergebnisleiste | -| 8 | Diagramme, reines Canvas | +| 6 | Aufbau der Bedienoberfläche | +| 7 | Ergebniskarten nebst Δ-Anzeige | +| 7b | Klartextfazit, Hinweis auf Beispielwerte, mitlaufende Ergebnisleiste | +| 8 | Diagramme, ausschließlich Canvas | | 9 | Rechenweg | | 10 | Render-Schleife | | 11 | Installation und Offline-Betrieb | | 12 | Fensterrahmen: Titelleisten und Minimieren | -| 13 | Kachelung: ein, zwei oder drei Fensterspalten | -| 14 | Sprachumschaltung in der Oberfläche | +| 13 | Kachelung: eine, zwei oder drei Fensterspalten | +| 14 | Sprachumschaltung in der Bedienoberfläche | Der Rechenkern in Teil 1 ist **die einzige Stelle, an der gerechnet wird.** Er ist zeichengenau -aus `build_bav.py` übertragen; Änderungen an der Rechtslage gehören in beide Dateien. +aus dem ursprünglichen Formelgenerator übertragen worden; Änderungen der Rechtslage sind mithin +ausschließlich dort vorzunehmen. -### Brutto und Netto sind gekoppelt +### Brutto- und Nettobetrag sind gekoppelt -Es gibt keinen Umschalter „ich gebe vor: Brutto / Netto“ mehr. Beide Felder zeigen dieselbe -Größe, nur in verschiedener Währung: +Ein Umschalter „Vorgabe: Brutto / Netto" besteht nicht mehr. Beide Felder weisen dieselbe Größe +aus, lediglich in verschiedener Währung: ``` N(B) = B − SV-Ersparnis_AN(B) − Steuerersparnis(B) ``` `N` ist auf `[0, Bruttogehalt]` stetig und wegen `dN/dB = 1 − Grenz-SV-Satz − Grenzsteuersatz > 0` -streng monoton wachsend, also eine Bijektion auf `[0, N(Bruttogehalt)]`. Ein Umschalter wäre -eine Auswahl zwischen einer Funktion und ihrer Umkehrfunktion — also keine. +streng monoton wachsend, mithin eine Bijektion auf `[0, N(Bruttogehalt)]`. Ein Umschalter wäre +eine Auswahl zwischen einer Funktion und ihrer Umkehrfunktion, mithin keine Auswahl. -`beitrag` bleibt die einzige Quelle der Wahrheit; `netto_ziel` ist ein **abgeleitetes Feld** mit -`get` (Vorwärtsrechnung, Jahr 0 der Ansparphase) und `set` (Bisektion, `bruttoVonNetto`). -Beide werten dasselbe erste Jahr aus — Lohn- und Tarifindex sind dort 1 —, weshalb die -Richtungen exakt invers sind. Gemessen über 12 Parameterkombinationen × 5 Stützstellen: +`beitrag` verbleibt die einzige maßgebliche Größe; `netto_ziel` ist ein **abgeleitetes Feld** mit +`get` (Vorwärtsrechnung, Jahr 0 der Ansparphase) und `set` (Intervallhalbierung, +`bruttoVonNetto`). Beide werten dasselbe erste Jahr aus — Lohn- und Tarifindex betragen dort 1 —, +weshalb die Richtungen exakt invers sind. Gemessen über 12 Parameterkombinationen × 5 +Stützstellen: | Richtung | größter relativer Fehler | |---|---| | B → N → B | 2,3 · 10⁻⁸ | | N → B → N | 2,1 · 10⁻⁸ | -Das ist genau die Auflösung der Bisektion: 34 Halbierungen auf `[0, 250.000 €]` sind -1,5 · 10⁻⁵ €/Jahr, also gut ein Millionstel Cent im Monat. Die Monotonie ist zusätzlich auf -`1 … 1.500 €/Monat` in Ein-Euro-Schritten geprüft; die kleinste beobachtete Steigung ist -`dN/dB = 0,545`, d. h. Steuer und Sozialabgaben tragen zusammen nie mehr als 45,5 % des -Bruttobeitrags. +Dies entspricht genau der Auflösung des Halbierungsverfahrens: 34 Halbierungen auf +`[0, 250.000 €]` ergeben 1,5 · 10⁻⁵ €/Jahr, mithin gut ein Millionstel Cent im Monat. Die +Monotonie ist ergänzend auf `1 … 1.500 €/Monat` in Ein-Euro-Schritten geprüft worden; die +geringste beobachtete Steigung beträgt `dN/dB = 0,545`, mithin tragen Steuer und Sozialabgaben +zusammen niemals mehr als 45,5 vom Hundert des Bruttobeitrags. -Fällt der Nettoaufwand für das erste Jahr auf null — weil man dann bereits ausgeschieden ist —, -existiert die Umkehrung nicht. Die App sagt das statt still nichts zu tun. +Fällt der Nettoaufwand für das erste Jahr auf null — weil zu diesem Zeitpunkt bereits ein +Ausscheiden vorliegt —, so existiert die Umkehrung nicht. Die Anwendung weist hierauf hin, +anstatt untätig zu verbleiben. -## 3b. Neunzehn Sprachen +## § 3b Dreiundzwanzig Sprachfassungen -Deutsch ist die Hauptsprache; alle übrigen sind Übersetzungen derselben Rechtslage, kein -zweiter Rechtsstand. **Die Normzitate bleiben in allen Sprachen deutsch** -(`§ 1a BetrAVG`, `§ 226 Abs. 2 S. 2 SGB V`, …) — sie sind die Primärquellen und haben keine -amtliche Übersetzung; eine eigene wäre hier keine Hilfe, sondern eine Fehlerquelle. Ebenso -bleiben zwei Produktnamen stehen, weil sie Eigennamen sind: `Altersvorsorgedepot` und -`Versorgungsbezüge`; im Japanischen mit Glosse (`Versorgungsbezüge(企業年金等の給付)`). +Deutsch ist die Hauptsprache; sämtliche übrigen Fassungen sind Übersetzungen derselben +Rechtslage und nicht etwa ein zweiter Rechtsstand. **Die Normzitate verbleiben in sämtlichen +Sprachfassungen in deutscher Sprache** (`§ 1a BetrAVG`, `§ 226 Abs. 2 S. 2 SGB V`, …) — es +handelt sich um die Primärquellen, für welche eine amtliche Übersetzung nicht vorliegt; eine +eigene wäre insoweit keine Hilfe, sondern eine Fehlerquelle. Gleichermaßen verbleiben zwei +Produktbezeichnungen unübersetzt, da es sich um Eigennamen handelt: `Altersvorsorgedepot` und +`Versorgungsbezüge`; im Japanischen nebst Glosse +(`Versorgungsbezüge(企業年金等の給付)`). | | Sprachen | Schlüssel | |---|---|---| -| **vollständig** | `de` `de-x-amt` `de-x-sales` `en` `nl` `fr` `la` `ja` `nds` `bar` `eu` `eo` `tr` `uk` `got` `goh` `gmh` `grc` `sa` | 459 | +| **vollständig** | `de` `de-x-amt` `de-x-sales` `en` `nl` `fr` `la` `ja` `nds` `bar` `eu` `eo` `tr` `uk` `got` `goh` `gmh` `grc` `sa` `ine-x-proto` `jbo` `tok` `akk-x-ob` | 459 | | **teilweise** | — | — | -Alle dreiundzwanzig Sprachen sind inzwischen vollständige Wörterbücher (459 von 459 Schlüsseln); die -Tabellenzeile „teilweise“ bleibt stehen, weil `TEILWEISE` in `index.html` als Mechanismus -weiterlebt — sie ist nur derzeit leer. Ursprünglich war die Auswahl strukturell, nicht nach -Zeichenzahl: zuerst übersetzt wurde, was man anfasst oder als Überschrift liest — -Feldbeschriftungen, Einheiten, Auswahlwerte, Fenstertitel, Kennzahlen, Tabellenköpfe, -Diagrammlegenden, Meldungen; die langen juristischen Erläuterungen (die `?`-Texte an den -Feldern, das Fazit, die Notizen unter den Feldern, der ganze Rechenweg) kamen erst in einer -zweiten Fassung dazu. Für die drei historischen Sprachstufen und für Sanskrit und Altgriechisch -ist der Vertrauensgrad in diesen Fließtext-Passagen entsprechend niedriger als in den -Feldbeschriftungen selbst — siehe die Kopfkommentare der jeweiligen `i18n.*.js`-Datei für die -genauen Prozentsätze und die dort neu geprägten Fachbegriffe. +Sämtliche dreiundzwanzig Sprachfassungen sind zwischenzeitlich vollständige Wörterbücher (459 von +459 Schlüsseln); die Tabellenzeile „teilweise" verbleibt, weil `TEILWEISE` in `index.html` als +Mechanismus fortbesteht — sie ist lediglich derzeit unbesetzt. Ursprünglich erfolgte die Auswahl +strukturell und nicht nach Zeichenzahl: zuerst übersetzt wurde dasjenige, was betätigt oder als +Überschrift gelesen wird — Feldbeschriftungen, Einheiten, Auswahlwerte, Fenstertitel, +Kennzahlen, Tabellenköpfe, Diagrammlegenden, Meldungen; die ausführlichen juristischen +Erläuterungen (die `?`-Texte an den Feldern, das Fazit, die Notizen unter den Feldern, der +gesamte Rechenweg) sind erst in einer zweiten Fassung hinzugetreten. Für die drei historischen +Sprachstufen sowie für Sanskrit und Altgriechisch ist der Vertrauensgrad in diesen +Fließtextpassagen entsprechend geringer als in den Feldbeschriftungen selbst; die genauen +Prozentsätze sowie die dort neu geprägten Fachbegriffe sind den Kopfkommentaren der jeweiligen +`i18n.*.js`-Datei zu entnehmen. **Die drei alten germanischen Fassungen** (`got` Gotisch, `goh` Althochdeutsch, -`gmh` Mittelhochdeutsch) sind kein Scherz, sondern eine Probe darauf, wie viel Fachsprache eine -Sprachstufe trägt. Nur `goh` und `gmh` sind Vorstufen des Deutschen; **Gotisch ist ostgermanisch -und damit eine Schwester, keine Ahnin** — es steht hier, weil es das älteste umfangreich -überlieferte Germanisch überhaupt ist. Das Ergebnis ist ein klares Gefälle, und es folgt genau -der Verstädterung: - -- **Gotisch** hat mit Wulfilas Bibel ein Korpus von rund 3.000 Lexemen, praktisch keines - davon wirtschaftlich. Belegt sind immerhin `faihu` (Vermögen), `gild` (Abgabe), `wokrs` (Zins, - Lk 19,23 *miþ wokra*), `mizdo` (Lohn), `asneis` (Lohnarbeiter). Alles Übrige — `haubidafaihu` - für Kapital, `gagaleikeins` für Vergleich — ist geprägt. Vertrauensgrad ≈ 30 %. +`gmh` Mittelhochdeutsch) sind nicht als Scherz zu verstehen, sondern als Probe darauf, wie viel +Fachsprache eine Sprachstufe zu tragen vermag. Lediglich `goh` und `gmh` sind Vorstufen des +Deutschen; **das Gotische ist ostgermanisch und mithin eine Schwester, keine Ahnin** — es steht +hier, weil es das älteste umfangreich überlieferte Germanisch überhaupt darstellt. Das Ergebnis +ist ein deutliches Gefälle, welches genau der Verstädterung folgt: + +- **Gotisch** verfügt mit der Wulfila-Bibel über ein Korpus von rund 3.000 Lexemen, von welchen + praktisch keines wirtschaftlicher Natur ist. Belegt sind immerhin `faihu` (Vermögen), `gild` + (Abgabe), `wokrs` (Zins, Lk 19,23 *miþ wokra*), `mizdo` (Lohn), `asneis` (Lohnarbeiter). Alles + Übrige — `haubidafaihu` für Kapital, `gagaleikeins` für Vergleich — ist geprägt. + Vertrauensgrad ≈ 30 vom Hundert. - **Althochdeutsch** gewinnt durch Tatian und Notker: `gelt`, `zins`, `lon`, `wuohhar` sind belegt, und **`widarmezzon` steht im Tatian genau für lateinisch *comparare*** — der - Fenstertitel ist also kein Kunstwort. Vertrauensgrad ≈ 50 %. -- **Mittelhochdeutsch** ist die tragfähigste Stufe, weil es bereits eine städtische Geld- und - Rechtssprache gibt. Drei Treffer sind keine Prägung, sondern der jeweilige Terminus: + Fenstertitel ist mithin kein Kunstwort. Vertrauensgrad ≈ 50 vom Hundert. +- **Mittelhochdeutsch** ist die tragfähigste Stufe, da bereits eine städtische Geld- und + Rechtssprache besteht. Drei Treffer sind keine Prägung, sondern der jeweilige Terminus: **`houbetguot`** ist das Kapital, **`lîpgedinge`** die lebenslange Leibrente, **`tiurunge`** - der Preisanstieg — also die Inflation. Dazu `gülte`, `stiure`, `wuocher`, `gewin`, `koste`. - Vertrauensgrad ≈ 65 %. - -**Gotisch steht in lateinischer Umschrift** (Streitberg), nicht im Wulfila-Alphabet -(U+10330–1034F). Der Grund ist der Grundsatz aus § 2: die App lädt keine Schriften von fremden -Domains. Für gotische Schrift gibt es auf keinem verbreiteten System eine vorinstallierte Datei -— 𐌰𐌻𐌻𐌰𐌹𐌼 wären leere Kästchen. Die Umschrift ist ohnehin die Form, in der das Gotische gelesen -wird. Wer die Schrift will, braucht eine eingebettete Schriftart und damit eine andere -Grundsatzentscheidung. - -### Registervarianten des Deutschen: gebaut - -**„Beamtendeutsch“ und „Vertrieb“** sind keine Sprachen, sondern Stilebenen derselben Sprache — -sie stehen daher nach BCP 47 § 2.2.7 unter `de` mit privatem Untertag: `de-x-amt` und -`de-x-sales`, in `i18n.de-x-amt.js` und `i18n.de-x-sales.js`. Anders als bei den übrigen -Sprachen genügt hier keine Teilfassung: der Witz liegt gerade im Fließtext, den eine -Teilübersetzung weglassen würde. Derselbe § 1a BetrAVG heißt im Amtsdeutsch „Ein Rechtsanspruch + der Preisanstieg, mithin die Inflation. Hinzu treten `gülte`, `stiure`, `wuocher`, `gewin`, + `koste`. Vertrauensgrad ≈ 65 vom Hundert. + +**Das Gotische steht in lateinischer Umschrift** (Streitberg) und nicht im Wulfila-Alphabet +(U+10330–1034F). Maßgeblich hierfür ist der Grundsatz gemäß § 2: die Anwendung lädt keine +Schriften von fremden Domänen. Für die gotische Schrift liegt auf keinem verbreiteten System +eine vorinstallierte Datei vor — 𐌰𐌻𐌻𐌰𐌹𐌼 erschiene als leere Kästchen. Die Umschrift ist +ohnehin diejenige Form, in welcher das Gotische gelesen wird. Wer die Schrift wünscht, bedarf +einer eingebetteten Schriftart und mithin einer abweichenden Grundsatzentscheidung. + +### Registervarianten des Deutschen: eingerichtet + +**„Beamtendeutsch" und „Vertrieb"** sind keine Sprachen, sondern Stilebenen derselben Sprache; +sie werden daher nach BCP 47 § 2.2.7 unter `de` mit privatem Untertag geführt: `de-x-amt` und +`de-x-sales`, in `i18n.de-x-amt.js` und `i18n.de-x-sales.js`. Abweichend von den übrigen +Sprachfassungen genügt hier keine Teilfassung: der Witz liegt gerade im Fließtext, welchen eine +Teilübersetzung fortließe. Derselbe § 1a BetrAVG lautet im Amtsdeutsch „Ein Rechtsanspruch besteht ausschließlich bis zur Höhe von 4 vom Hundert der Beitragsbemessungsgrenze der -Rentenversicherung“ und im Vertriebsdeutsch „Bis zu 4 % on top — geschenkt vom Gesetzgeber!“ — -beide beschreiben exakt dieselbe Rechtslage, und der Vergleich ist der Punkt. Die Zahlen ändern -sich auch dort nicht; `pruefe.js` prüft das wie bei jeder anderen Sprache ohne Sonderfall. - -Technisch brauchte das drei Änderungen: `pickLang()` matcht seither zusätzlich zur -Grundsprache beliebig viele `-x-[a-z0-9]{1,8}`-Untertags; `LANGS` und `DICT` bekamen -Einträge mit Bindestrich; `LOCALES`/`GRUPPEN` brauchten dagegen **keine** neuen Einträge, weil -ihre bestehenden `||`-Rückfälle (`'de-DE'` bzw. `'.'`) für beide Varianten schon das Richtige -liefern. Der Sprachknopf zeigt nicht den vollen Code (`DE-X-AMT` wäre zu lang für die -zweizeilige Schaltfläche), sondern nur den Teil nach dem letzten Bindestrich (`AMT`, `SALES`); -`lang="…"` und das Autonym im `title` tragen weiterhin den vollen Code bzw. den vollen Namen. - -### Vorgemerkt, noch nicht gebaut - -**Rechtsläufige Sprachen (`he`, `fa`, `ar`).** Die Übersetzung ist der billige Teil. Teuer ist -dreierlei: `applyStatic()` muss neben `lang` auch `dir` setzen; im Stilblatt müssen -`margin-left`/`-right` durch die logischen Eigenschaften ersetzt werden, sonst kippt die -Kachelung; und Teil 8 zeichnet auf Canvas, wo es **keinen Bidi-Algorithmus gibt** — Achsen, -Legenden und der Wasserfall müssten von Hand gespiegelt werden. Dazu `fa-u-nu-latn` und -`ar-u-nu-latn` in `LOCALES`, sonst liefert ICU ostarabische Ziffern (۱۲۳۴) neben einem `€`. -Die Einzelheiten stehen als Kommentarblock in `index.html` direkt bei `TEILWEISE`. - -**Codes.** ISO 639-1, wo es einen gibt, sonst 639-3. Dreibuchstabig sind `grc` -(**nicht** `el` — das wäre Neugriechisch), `nds` und `bar`; keine der drei hat einen -zweibuchstabigen Code. Deshalb matcht `pickLang()` `[a-z]{2,3}` als Grundcode, optional gefolgt -von den erwähnten `-x-…`-Untertags. - -**Wahl der Sprache**, in dieser Reihenfolge: - -1. `?lang=…` in der Adresse — teilbar, überschreibt alles, -2. die gemerkte Wahl in `localStorage` unter `altersvorsorge.lang`, +Rentenversicherung" und im Vertriebsdeutsch „Bis zu 4 % on top — geschenkt vom Gesetzgeber!" — +beide Fassungen beschreiben exakt dieselbe Rechtslage, und der Vergleich ist der Punkt. Die +Zahlen ändern sich auch dort nicht; `pruefe.js` prüft dies wie bei jeder anderen Sprache ohne +Sonderfall. + +Technisch waren hierfür drei Änderungen erforderlich: `pickLang()` erkennt seither zusätzlich +zur Grundsprache beliebig viele `-x-[a-z0-9]{1,8}`-Untertags; `LANGS` und `DICT` haben Einträge +mit Bindestrich erhalten; `LOCALES` und `GRUPPEN` bedurften hingegen **keiner** neuen Einträge, +da deren bestehende `||`-Rückfälle (`'de-DE'` bzw. `'.'`) für beide Varianten bereits das +Zutreffende liefern. Die Sprachschaltfläche weist nicht den vollständigen Code aus (`DE-X-AMT` +wäre für die zweizeilige Schaltfläche zu lang), sondern lediglich den Teil nach dem letzten +Bindestrich (`AMT`, `SALES`); `lang="…"` sowie das Autonym im `title` tragen weiterhin den +vollständigen Code bzw. die vollständige Bezeichnung. + +### Vorgemerkt, noch nicht eingerichtet + +**Rechtsläufige Sprachen (`he`, `fa`, `ar`).** Die Übersetzung stellt den geringeren Aufwand +dar. Aufwendig ist Dreierlei: `applyStatic()` hat neben `lang` auch `dir` zu setzen; im Stilblatt +sind `margin-left`/`-right` durch die logischen Eigenschaften zu ersetzen, da andernfalls die +Kachelung kippt; und Teil 8 zeichnet auf Canvas, wo **ein Bidi-Algorithmus nicht besteht** — +Achsen, Legenden und der Wasserfall wären mithin von Hand zu spiegeln. Hinzu treten +`fa-u-nu-latn` und `ar-u-nu-latn` in `LOCALES`, da ICU andernfalls ostarabische Ziffern (۱۲۳۴) +neben einem `€` liefert. Die Einzelheiten sind als Kommentarblock in `index.html` unmittelbar +bei `TEILWEISE` niedergelegt. + +**Codes.** ISO 639-1, soweit ein solcher besteht, im Übrigen 639-3. Dreibuchstabig sind `grc` +(**nicht** `el` — dies wäre Neugriechisch), `nds` und `bar`; für keine der drei Sprachen besteht +ein zweibuchstabiger Code. `pickLang()` erkennt daher `[a-z]{2,3}` als Grundcode, fakultativ +gefolgt von den vorgenannten `-x-…`-Untertags. + +**Wahl der Sprache**, in nachstehender Reihenfolge: + +1. `?lang=…` in der Adresse — weitergabefähig, überschreibt alles Übrige, +2. die vorgehaltene Wahl in `localStorage` unter `altersvorsorge.lang`, 3. `navigator.language`, nach BCP-47-Teilkette (`xx` oder `xx-…`). - **Latein, Altgriechisch, Sanskrit und Esperanto werden nie automatisch gewählt** — ein - Browser, der `la` meldet, meint es fast sicher nicht als Anzeigesprache. + **Latein, Altgriechisch, Sanskrit und Esperanto werden niemals selbsttätig gewählt** — ein + Browser, welcher `la` meldet, meint dies mit an Sicherheit grenzender Wahrscheinlichkeit + nicht als Anzeigesprache. -Die Knöpfe tragen das Kürzel, der `title` das **Autonym** (`Українська`, `Plattdüütsch`, -`संस्कृतम्`) — nicht den übersetzten Namen. Wer Ukrainisch sucht, erkennt `Українська` auch dann, -wenn die Oberfläche gerade auf Baskisch steht; nebenbei spart das 14 × 14 Wörterbucheinträge. +Die Schaltflächen tragen das Kürzel, der `title` hingegen das **Autonym** (`Українська`, +`Plattdüütsch`, `संस्कृतम्`) und nicht die übersetzte Bezeichnung. Wer Ukrainisch sucht, erkennt +`Українська` auch dann, wenn die Oberfläche gegenwärtig auf Baskisch eingestellt ist; nebenbei +werden hierdurch 14 × 14 Wörterbucheinträge eingespart. **Zahlenformat.** `LOCALES` bildet jeden Code auf ein ICU-Tag ab, `GRUPPEN` auf das -Tausenderzeichen, das `parseNum()` beim mehrdeutigen `1,234` heranzieht. Sprachen ohne eigene -ICU-Daten (`nds`, `bar`, `eo`, `la`, `grc`, `sa`) bekommen `de-DE`: Devanāgarī-Ziffern neben -einem `€` wären eine Schikane, keine Genauigkeit, und griechische Buchstabenzahlen erst recht. -`fr` gruppiert mit U+202F, `uk` mit U+00A0 — beides so, wie ICU es tatsächlich setzt, nachgeprüft -gegen `formatToParts`. - -**Zu Latein und Japanisch.** Das Latein ist pragmatisches Neulatein: klassische Syntax, -aber gebildete Neuprägungen für Moderne (`pensio operativa`, `impensa pura`, `valor praesens`, -`usura interna`). Römische Ziffern wären ein Witz auf Kosten der Lesbarkeit — und die +Tausenderzeichen, welches `parseNum()` beim mehrdeutigen `1,234` heranzieht. Sprachen ohne +eigene ICU-Daten (`nds`, `bar`, `eo`, `la`, `grc`, `sa`) erhalten `de-DE`: Devanāgarī-Ziffern +neben einem `€` wären eine Schikane und keine Genauigkeit, griechische Buchstabenzahlen erst +recht. `fr` gruppiert mit U+202F, `uk` mit U+00A0 — beides so, wie ICU es tatsächlich setzt, +nachgeprüft gegen `formatToParts`. + +**Zu Latein und Japanisch.** Das Latein ist pragmatisches Neulatein: klassische Syntax, jedoch +gebildete Neuprägungen für die Moderne (`pensio operativa`, `impensa pura`, `valor praesens`, +`usura interna`). Römische Ziffern wären ein Witz zu Lasten der Lesbarkeit — und die Trennzeichenkonvention ist ohnehin jünger als jede lateinische Quelle. Das Japanische folgt -dem, was für Software dieser Art dort üblich ist: Erklärtexte in です・ます, Feldbeschriftungen -als Nominalphrasen im 体言止め. Für die Schrift ist der `--ui`-Stapel um MS PGothic, Hiragino, -Yu Gothic und Meiryo erweitert — eine Rasterschrift mit harten Kanten passt zum Thema. +demjenigen, was für Software dieser Art dort üblich ist: Erläuterungstexte in です・ます, +Feldbeschriftungen als Nominalphrasen im 体言止め. Für die Schrift ist der `--ui`-Stapel um +MS PGothic, Hiragino, Yu Gothic und Meiryo erweitert worden — eine Rasterschrift mit harten +Kanten ist dem Gegenstand angemessen. -Der japanische Satzbau erzwingt, wofür die Funktionsform der Einträge da ist. Das Fazit lautet -im Deutschen „X liegt vorn mit W — D mehr als Y“, im Japanischen dagegen -`Xが首位です(W)。YをD上回ります。` — Verb am Ende, Vergleichsgröße mit を statt „als“. Als -Verkettung fester Bausteine ließe sich das nicht bauen. +Der japanische Satzbau erzwingt dasjenige, wozu die Funktionsform der Einträge bestimmt ist. Das +Fazit lautet im Deutschen „X liegt vorn mit W — D mehr als Y", im Japanischen hingegen +`Xが首位です(W)。YをD上回ります。` — das Verb am Ende, die Vergleichsgröße mit を anstelle von +„als". Als Verkettung fester Bausteine ließe sich dies nicht herstellen. -Der Umschalter oben im Kopffenster schreibt beides fort, Speicher und Adresse. Der Teilen-Link -nimmt die Suchzeichenfolge mit, der Zustand steckt weiter im Fragment — beides stört sich nicht. +Der Umschalter oben im Kopffenster schreibt beides fort, mithin Speicher und Adresse. Der +Weitergabeverweis führt die Suchzeichenfolge mit, der Zustand verbleibt im Fragment; beides +stört sich nicht. **Aufbau der Wörterbücher.** Ein Eintrag ist entweder eine Zeichenkette oder eine Funktion -`(p, f) → string`. Die Funktionsform ist keine Bequemlichkeit, sondern notwendig: ein Satz ist -nicht die Verkettung seiner Teile. Stellung, Numerus und Rektion hängen an der Sprache, und -`'mehr als ' + nom` funktioniert nur, solange beide Sprachen denselben Satzbau haben. Deshalb -bekommen die Funktionen **Rohwerte** — Zahlen, keine fertigen Textstücke — und formatieren -selbst über `f` (`f.eur`, `f.pct`, `f.nf2`, …). Sichtbar wird der Unterschied etwa im Fazit: -das Deutsche braucht dort einen Genitiv (`der bAV`), das Englische eine Präposition. +`(p, f) → string`. Die Funktionsform ist keine Bequemlichkeit, sondern zwingend erforderlich: ein +Satz ist nicht die Verkettung seiner Teile. Stellung, Numerus und Rektion hängen an der Sprache, +und `'mehr als ' + nom` ist lediglich so lange tragfähig, wie beide Sprachen denselben Satzbau +aufweisen. Den Funktionen werden daher **Rohwerte** übergeben — Zahlen und keine fertigen +Textstücke —, und die Formatierung erfolgt selbsttätig über `f` (`f.eur`, `f.pct`, `f.nf2`, …). +Sichtbar wird der Unterschied etwa im Fazit: das Deutsche bedarf dort eines Genitivs (`der bAV`), +das Englische einer Präposition. ``` t('n.beitrag.ueber8', { v8: v8 }) @@ -246,213 +267,228 @@ t('n.beitrag.ueber8', { v8: v8 }) en: 'Above 8 % of the pension-insurance contribution ceiling (' + f.eur(p.v8) + ' per year). …' ``` -**Schlüsselschema.** Eingabefelder liegen unter `f.:.label|hint|unit|o`, -die Optionen also unter ihrem *Wert*, nicht unter ihrem Index — dann bleibt die Zuordnung -richtig, wenn eine Option dazukommt. `FIELDS`, `OPTS` und `METRICS` tragen ihre Texte nicht +**Schlüsselschema.** Eingabefelder liegen unter `f.:.label|hint|unit|o`, die +Optionen mithin unter ihrem *Wert* und nicht unter ihrem Index; sodann verbleibt die Zuordnung +zutreffend, wenn eine Option hinzutritt. `FIELDS`, `OPTS` und `METRICS` führen ihre Texte nicht mehr als Feld, sondern als `Object.defineProperty`-Zugriffsfunktion: `f.label` steht unverändert an jeder Aufrufstelle und liefert nach einem Sprachwechsel von selbst den neuen Wert. -**Fehlt ein Eintrag**, greift Deutsch; fehlt auch der, erscheint der Schlüssel selbst im -Klartext. Ein stiller Leerstring wäre die schlechtere Wahl — er verschwindet unbemerkt. +**Fehlt ein Eintrag**, so greift Deutsch; fehlt auch dieser, so erscheint der Schlüssel selbst im +Klartext. Ein stiller Leerstring wäre die schlechtere Wahl, da er unbemerkt verschwände. -**Zahlen.** Umgeschaltet wird nur die Zifferngruppierung — `de` und `la` → `de-DE`, -`en` → `en-GB`, `ja` → `ja-JP`; die Währung bleibt überall der nachgestellte Euro: -`75.000,00 €` bzw. `75,000.00 €`. Die Eingabe nimmt **beide** -Schreibweisen an, damit ein Sprachwechsel keine getippte Zahl entwertet. Die Regel in -`parseNum`: stehen beide Zeichen im Text, ist das rechte das Dezimalzeichen; steht nur eines -und folgen ihm genau drei Ziffern, ist es die Tausendergruppe der aktuellen Sprache -(`GRUPPEN`: `.` für de und la, `,` für en und ja). Damit -bleibt allein `1,234` mehrdeutig — und genau dort entscheidet die Sprache. +**Zahlen.** Umgeschaltet wird ausschließlich die Zifferngruppierung — `de` und `la` → `de-DE`, +`en` → `en-GB`, `ja` → `ja-JP`; die Währung verbleibt durchgängig der nachgestellte Euro: +`75.000,00 €` bzw. `75,000.00 €`. Die Eingabe nimmt **beide** Schreibweisen an, damit ein +Sprachwechsel eine eingegebene Zahl nicht entwertet. Die Regel in `parseNum` lautet: stehen beide +Zeichen im Text, so ist das rechte das Dezimalzeichen; steht lediglich eines und folgen ihm genau +drei Ziffern, so handelt es sich um die Tausendergruppe der gegenwärtigen Sprache (`GRUPPEN`: +`.` für de und la, `,` für en und ja). Damit verbleibt allein `1,234` mehrdeutig — und genau dort +entscheidet die Sprache. **Was ein Sprachwechsel nicht anfasst:** die Eingaben, den Referenzstand und die Ergebnisse. -`setLang` baut nur die Teile neu, deren Beschriftungen beim Aufbau festgeschrieben werden -(Kennzahlenleiste, Registerkarten, Felder, Fenstertitel); alles Übrige zeichnet `refresh()` -ohnehin bei jedem Durchgang. Der Referenzstand merkt sich deshalb den *Feldschlüssel* und -nicht den fertigen Satz — sonst stünde nach dem Wechsel „vor der Änderung von …“ noch in der -alten Sprache da. - -**Prüfung.** `pruefe.js` (Entwicklungswerkzeug, wird vom Service Worker nicht ausgeliefert) lädt die Seite kopflos in -jsdom, schaltet alle dreiundzwanzig Sprachen durch, klappt jeden Abschnitt auf, erzwingt über fünf -Szenarien die bedingten Texte und prüft: kein unaufgelöster Schlüssel, keine deutschen Reste im -englischen Modus außer den erlaubten Fachbegriffen, kein sichtbar gebliebener Schlüssel, und -— die eigentliche Invariante — -**identische Rechenergebnisse in allen dreiundzwanzig Sprachen**. - -Die Liste der Wörterbücher liest das Skript aus `index.html` statt sie zu pflegen: eine neue -Sprache soll den Test nicht stillschweigend an einem leeren Objekt vorbeilaufen lassen. Das +`setLang` baut lediglich diejenigen Teile neu auf, deren Beschriftungen beim Aufbau +festgeschrieben werden (Kennzahlenleiste, Registerkarten, Felder, Fenstertitel); alles Übrige +zeichnet `refresh()` ohnehin bei jedem Durchgang. Der Referenzstand hält daher den +*Feldschlüssel* vor und nicht den fertigen Satz; andernfalls stünde nach dem Wechsel „vor der +Änderung von …" noch in der vormaligen Sprache da. + +**Prüfung.** `pruefe.js` (Entwicklungswerkzeug, wird vom Dienstarbeiter nicht ausgeliefert) lädt +die Seite kopflos in jsdom, schaltet sämtliche dreiundzwanzig Sprachfassungen durch, klappt jeden +Abschnitt auf, erzwingt über fünf Szenarien die bedingten Texte und prüft: kein unaufgelöster +Schlüssel, keine deutschen Reste im englischen Modus außer den zugelassenen Fachbegriffen, kein +sichtbar verbliebener Schlüssel, und — die eigentliche Invariante — **identische +Rechenergebnisse in sämtlichen dreiundzwanzig Sprachfassungen**. + +Die Liste der Wörterbücher liest das Skript aus `index.html` aus, anstatt sie zu pflegen: eine +neue Sprache soll den Test nicht stillschweigend an einem leeren Objekt vorbeilaufen lassen. Das Regex für die `