Three documentation inaccuracies, all independent of each other.
1. `media_id`, `image` and `gif_url` were typed `string | null`, but no
record has a null in any of them (0/1324 each) and the JSON Schema
declares all three as required, non-nullable strings — `image` and
`gif_url` even carry path patterns. The optional type pushed needless
null-handling onto every consumer. Narrowed to `string`.
2. `instruction_steps` was missing from the interface entirely, even
though every record carries it and the field table documents it.
Added, typed `string[]` per language.
3. The Python example stopped at Hindi, skipping Polish and Korean; the
JavaScript example right below it lists both. Added the two lines.
Docs only — no data or schema changes.
Adds a tenth language to all 1,324 exercises: `instructions.fr` and
`instruction_steps.fr`, plus the schema, README, viewer and setup guide.
Register matches the existing Spanish/Italian/Polish translations —
informal second-person imperative (tutoiement):
en: Lie flat on your back with your knees bent and feet flat on the ground.
fr: Allonge-toi sur le dos, les genoux fléchis et les pieds à plat au sol.
How it was produced
-------------------
The 7,710 English step sentences deduplicate to 4,414 unique strings.
Those were translated (LLM-assisted, glossary-constrained, then audited),
and the per-exercise arrays were rebuilt deterministically by mapping each
English step back through that table. `instructions.fr` is the join of
`instruction_steps.fr`, so the two can never drift.
A fixed glossary pinned the recurring terms — répétitions, position de
départ, haltère/barre, sangle abdominale, omoplates, largeur des épaules —
so terminology is consistent across all 1,324 records rather than varying
sentence by sentence.
Verified
--------
- 1,324 records validate against the updated schema; a record missing `fr`
is now rejected.
- fr step count == en step count in every record (the dataset's existing
invariant across all nine prior languages).
- instructions.fr == ' '.join(instruction_steps.fr) in every record.
- Every pre-existing field is byte-identical; `fr` is purely additive.
- No empty strings, none left in English, no vouvoiement across 7,710 steps.
- index.html embed stays in sync with data/exercises.json; the language
picker renders "Français" and the steps display correctly.
Note for review: these are machine translations, reviewed programmatically
rather than by a native speaker. Happy to adjust any wording.
The schema was added before the Hindi (73b0c68) and Polish/Korean
(118e4bd) instructions landed, so languageMap and languageStepsMap
still only declared en, es, it, tr, ru, zh.
All 1,324 records carry all nine languages and the README documents
nine, but `additionalProperties` let hi/pl/ko through unvalidated and
unrequired — a record silently missing them still passed validation.
Declare all nine in `properties` and `required` for both maps.
Verified: the 1,324 records validate cleanly against the updated
schema, and a record missing hi/pl/ko is now rejected.