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.
160 lines
5.0 KiB
JSON
160 lines
5.0 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json",
|
|
"title": "Exercises Dataset",
|
|
"description": "Schema for data/exercises.json — an array of fitness exercise records with multilingual instructions and media references.",
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/$defs/exercise"
|
|
},
|
|
"$defs": {
|
|
"languageMap": {
|
|
"type": "object",
|
|
"description": "Instruction text keyed by ISO 639-1 language code.",
|
|
"properties": {
|
|
"en": { "type": "string" },
|
|
"es": { "type": "string" },
|
|
"it": { "type": "string" },
|
|
"tr": { "type": "string" },
|
|
"ru": { "type": "string" },
|
|
"zh": { "type": "string" },
|
|
"hi": { "type": "string" },
|
|
"pl": { "type": "string" },
|
|
"ko": { "type": "string" },
|
|
"fr": { "type": "string" }
|
|
},
|
|
"required": ["en", "es", "it", "tr", "ru", "zh", "hi", "pl", "ko", "fr"],
|
|
"additionalProperties": { "type": "string" }
|
|
},
|
|
"languageStepsMap": {
|
|
"type": "object",
|
|
"description": "Step-by-step instructions as an array of strings, keyed by ISO 639-1 language code.",
|
|
"properties": {
|
|
"en": { "$ref": "#/$defs/steps" },
|
|
"es": { "$ref": "#/$defs/steps" },
|
|
"it": { "$ref": "#/$defs/steps" },
|
|
"tr": { "$ref": "#/$defs/steps" },
|
|
"ru": { "$ref": "#/$defs/steps" },
|
|
"zh": { "$ref": "#/$defs/steps" },
|
|
"hi": { "$ref": "#/$defs/steps" },
|
|
"pl": { "$ref": "#/$defs/steps" },
|
|
"ko": { "$ref": "#/$defs/steps" },
|
|
"fr": { "$ref": "#/$defs/steps" }
|
|
},
|
|
"required": ["en", "es", "it", "tr", "ru", "zh", "hi", "pl", "ko", "fr"],
|
|
"additionalProperties": { "$ref": "#/$defs/steps" }
|
|
},
|
|
"steps": {
|
|
"type": "array",
|
|
"items": { "type": "string", "minLength": 1 }
|
|
},
|
|
"exercise": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"description": "Unique numeric identifier, zero-padded to 4 digits (e.g. \"0001\").",
|
|
"pattern": "^[0-9]{4}$"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Full exercise name (e.g. \"3/4 sit-up\").",
|
|
"minLength": 1
|
|
},
|
|
"category": {
|
|
"type": "string",
|
|
"description": "Body part category. Mirrors body_part.",
|
|
"minLength": 1
|
|
},
|
|
"body_part": {
|
|
"type": "string",
|
|
"description": "Body part targeted.",
|
|
"enum": [
|
|
"back",
|
|
"cardio",
|
|
"chest",
|
|
"lower arms",
|
|
"lower legs",
|
|
"neck",
|
|
"shoulders",
|
|
"upper arms",
|
|
"upper legs",
|
|
"waist"
|
|
]
|
|
},
|
|
"equipment": {
|
|
"type": "string",
|
|
"description": "Required equipment (e.g. \"dumbbell\", \"body weight\").",
|
|
"minLength": 1
|
|
},
|
|
"instructions": {
|
|
"$ref": "#/$defs/languageMap",
|
|
"description": "Full step-by-step instructions as a single string per language."
|
|
},
|
|
"instruction_steps": {
|
|
"$ref": "#/$defs/languageStepsMap",
|
|
"description": "Same instructions split into an ordered array of steps per language."
|
|
},
|
|
"muscle_group": {
|
|
"type": "string",
|
|
"description": "Primary synergist muscle group.",
|
|
"minLength": 1
|
|
},
|
|
"secondary_muscles": {
|
|
"type": "array",
|
|
"description": "Additional muscles involved.",
|
|
"items": { "type": "string", "minLength": 1 }
|
|
},
|
|
"target": {
|
|
"type": "string",
|
|
"description": "Primary target muscle (e.g. \"biceps\", \"abs\").",
|
|
"minLength": 1
|
|
},
|
|
"media_id": {
|
|
"type": "string",
|
|
"description": "Original media reference id (e.g. \"2gPfomN\").",
|
|
"minLength": 1
|
|
},
|
|
"image": {
|
|
"type": "string",
|
|
"description": "Path to the 180x180 thumbnail (e.g. \"images/0001-2gPfomN.jpg\").",
|
|
"pattern": "^images/.+\\.(jpg|jpeg|png)$"
|
|
},
|
|
"gif_url": {
|
|
"type": "string",
|
|
"description": "Path to the 180x180 animation GIF (e.g. \"videos/0001-2gPfomN.gif\").",
|
|
"pattern": "^videos/.+\\.gif$"
|
|
},
|
|
"attribution": {
|
|
"type": "string",
|
|
"description": "Media copyright notice.",
|
|
"minLength": 1
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"description": "ISO 8601 timestamp of record creation.",
|
|
"format": "date-time"
|
|
}
|
|
},
|
|
"required": [
|
|
"id",
|
|
"name",
|
|
"category",
|
|
"body_part",
|
|
"equipment",
|
|
"instructions",
|
|
"instruction_steps",
|
|
"muscle_group",
|
|
"secondary_muscles",
|
|
"target",
|
|
"media_id",
|
|
"image",
|
|
"gif_url",
|
|
"attribution",
|
|
"created_at"
|
|
],
|
|
"additionalProperties": false
|
|
}
|
|
}
|
|
}
|