From dce356cdca046ae5886ed254d1084f20761d8094 Mon Sep 17 00:00:00 2001 From: Daniel Jones Date: Wed, 20 May 2026 14:33:14 +0200 Subject: [PATCH 1/3] feat(snippets): single SupportedLanguages component over vended JSON Replaces the standalone LanguageTable snippet with one `` component. Doc authors drop it anywhere they need to list languages and pass props that mirror the `GET /v3/languages` contract: - `mode`: `inline` (default, comma-separated codes) | `bullets` | `table` (the existing interactive sortable/filterable table). - `resource`: matches a /v3/languages resource (`translate_text`, `translate_document`, `voice`, `write`, `glossary`, `style_rules`, `translation_memory`). - `feature`: API feature key (`style_rules`, `writing_style`, `tone`, `auto_detection`, `glossary`, `tag_handling`, ...). - `direction`: `source` | `target`. - `includeBeta`: bool. The snippet inlines a `RESOURCES` object holding the verbatim /v3/languages responses, refreshed by the hourly workflow via `scripts/generate_language_table.py`. Mintlify's snippet sandbox does not honour ES module imports, so the data has to ship inside the snippet file itself. Operators not supported by the sandbox (`in`, notably) are avoided. Adds `data/v3-languages/translation_memory.json` shaped like a /v3/languages response so the real API response can drop in unchanged once Translation Memory ships as a resource. Wires the regen step into `.github/workflows/refresh-v3-languages.yml` so each hourly refresh produces a single PR containing both the updated JSON and the regenerated snippet. Migrates the two `docs`/`api-reference` places that hand-typed feature language lists to use `` instead. The quality-estimation page keeps its manual list for now because QE is not exposed as a /v3/languages resource yet. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/refresh-v3-languages.yml | 10 +- api-reference/improve-text.mdx | 22 +- data/v3-languages/translation_memory.json | 98 +++ docs/getting-started/supported-languages.mdx | 14 +- scripts/generate_language_table.py | 56 ++ snippets/language-table.jsx | 634 ++++++++++++++----- 6 files changed, 646 insertions(+), 188 deletions(-) create mode 100644 data/v3-languages/translation_memory.json create mode 100755 scripts/generate_language_table.py diff --git a/.github/workflows/refresh-v3-languages.yml b/.github/workflows/refresh-v3-languages.yml index f721ba3..4b09c74 100644 --- a/.github/workflows/refresh-v3-languages.yml +++ b/.github/workflows/refresh-v3-languages.yml @@ -28,6 +28,9 @@ jobs: DEEPL_AUTH_KEY: ${{ secrets.DEEPL_API_KEY }} run: python3 scripts/fetch_v3_languages.py + - name: Regenerate snippets/language-table.jsx from vended data + run: python3 scripts/generate_language_table.py + - name: Open or update refresh PR uses: peter-evans/create-pull-request@v6 with: @@ -37,7 +40,8 @@ jobs: title: "chore(v3-languages): refresh vended responses" body: | Automated refresh of `data/v3-languages/` from `https://api.deepl.com/v3/languages`, - opened by the `refresh-v3-languages` workflow. + with `snippets/language-table.jsx` regenerated from the new responses. Opened by + the `refresh-v3-languages` workflow. This PR is rewritten in place on each run: if the vended responses change again before merge, the branch is force-pushed with a new single squashed commit so the @@ -45,6 +49,8 @@ jobs: responses identical to what is already on the branch, the branch is left untouched. If a run finds the responses match `main` (e.g. the PR was merged), this PR is closed and the branch deleted automatically. - add-paths: data/v3-languages/** + add-paths: | + data/v3-languages/** + snippets/language-table.jsx delete-branch: true labels: automated, v3-languages diff --git a/api-reference/improve-text.mdx b/api-reference/improve-text.mdx index 6fd60bf..f5d69c3 100644 --- a/api-reference/improve-text.mdx +++ b/api-reference/improve-text.mdx @@ -3,6 +3,9 @@ title: "Improve text" public: true sidebarTitle: "Overview" --- + +import { SupportedLanguages } from "/snippets/language-table.jsx" + **Introducing DeepL API for Write** @@ -100,15 +103,7 @@ curl -X POST 'https://api.deepl.com/v2/write/rephrase' \ Currently supported for the following target languages: - * `de` (German) - * `en-GB` (British English) - * `en-US` (American English) - * `es` (Spanish) - * `fr` (French) - * `it` (Italian) - * `pt-BR` (Brazilian Portuguese) - * `pt-PT` (Portuguese) - + Styles prefixed with `prefer_` will fall back to the `default` style when used with a language that does not support styles (this is recommended for cases where no `target_lang` is set), the non-prefixed writing styles (except `default`) will return a HTTP 400 error in that case. @@ -135,14 +130,7 @@ curl -X POST 'https://api.deepl.com/v2/write/rephrase' \ Currently supported for the following target languages: - * `de` (German) - * `en-GB` (British English) - * `en-US` (American English) - * `es` (Spanish) - * `fr` (French) - * `it` (Italian) - * `pt-BR` (Brazilian Portuguese) - * `pt-PT` (Portuguese) + Tones prefixed with `prefer_` will fall back to the `default` tone when used with a language that does not support tones (this is recommended for cases where no `target_lang` is set), the non-prefixed tones (except `default`) will return a HTTP 400 error in that case. diff --git a/data/v3-languages/translation_memory.json b/data/v3-languages/translation_memory.json new file mode 100644 index 0000000..5905921 --- /dev/null +++ b/data/v3-languages/translation_memory.json @@ -0,0 +1,98 @@ +[ + { + "lang": "de", + "name": "German", + "status": "stable", + "usable_as_source": true, + "usable_as_target": true, + "features": {} + }, + { + "lang": "en", + "name": "English", + "status": "stable", + "usable_as_source": true, + "usable_as_target": true, + "features": {} + }, + { + "lang": "en-GB", + "name": "English (British)", + "status": "stable", + "usable_as_source": false, + "usable_as_target": true, + "features": {} + }, + { + "lang": "en-US", + "name": "English (American)", + "status": "stable", + "usable_as_source": false, + "usable_as_target": true, + "features": {} + }, + { + "lang": "es", + "name": "Spanish", + "status": "stable", + "usable_as_source": true, + "usable_as_target": true, + "features": {} + }, + { + "lang": "es-419", + "name": "Spanish (Latin American)", + "status": "stable", + "usable_as_source": false, + "usable_as_target": true, + "features": {} + }, + { + "lang": "fr", + "name": "French", + "status": "stable", + "usable_as_source": true, + "usable_as_target": true, + "features": {} + }, + { + "lang": "it", + "name": "Italian", + "status": "stable", + "usable_as_source": true, + "usable_as_target": true, + "features": {} + }, + { + "lang": "ja", + "name": "Japanese", + "status": "stable", + "usable_as_source": true, + "usable_as_target": true, + "features": {} + }, + { + "lang": "ko", + "name": "Korean", + "status": "stable", + "usable_as_source": true, + "usable_as_target": true, + "features": {} + }, + { + "lang": "zh", + "name": "Chinese", + "status": "stable", + "usable_as_source": true, + "usable_as_target": true, + "features": {} + }, + { + "lang": "zh-Hans", + "name": "Chinese (simplified)", + "status": "stable", + "usable_as_source": false, + "usable_as_target": true, + "features": {} + } +] diff --git a/docs/getting-started/supported-languages.mdx b/docs/getting-started/supported-languages.mdx index ce2d303..79b748c 100644 --- a/docs/getting-started/supported-languages.mdx +++ b/docs/getting-started/supported-languages.mdx @@ -6,18 +6,20 @@ sidebarTitle: "Languages supported" mode: "wide" --- +import { SupportedLanguages } from "/snippets/language-table.jsx" + The DeepL API supports the following languages. These can also be retrieved programmatically via the [`/v3/languages` endpoint](/api-reference/languages/retrieve-supported-languages-by-resource), which returns language support per resource along with feature availability (e.g. formality, glossary, auto-detection). The legacy [`/v2/languages` endpoint](/api-reference/languages/retrieve-supported-languages) is also available but deprecated. ## API Supported Languages -import { LanguageTable } from "/snippets/language-table.jsx" - - + Currently, characters translated into beta languages are not billed. See [Alpha and beta features](/docs/resources/alpha-and-beta-features) for more information. - - Style rules are supported for the following target languages: `de`, `en`, `es`, `fr`, `it`, `ja`, `ko`, and `zh`. For more details, see the [Style Rules API documentation](/api-reference/style-rules). Writing style and tone availability for `/write/rephrase` can also be retrieved via [`GET /v3/languages?resource=write`](/api-reference/languages/retrieve-supported-languages-by-resource). - +Style rules are supported for the following target languages: + + + +For more details, see the [Style Rules API documentation](/api-reference/style-rules). Writing style and tone availability for `/write/rephrase` can also be retrieved via [`GET /v3/languages?resource=write`](/api-reference/languages/retrieve-supported-languages-by-resource). diff --git a/scripts/generate_language_table.py b/scripts/generate_language_table.py new file mode 100755 index 0000000..c20cbe7 --- /dev/null +++ b/scripts/generate_language_table.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +"""Regenerate the inline RESOURCES object in snippets/language-table.jsx +from the vended /v3/languages responses under data/v3-languages/. + +The JSX file must contain `// BEGIN GENERATED` and `// END GENERATED` +marker lines; everything between them is replaced. The output is a +JavaScript object literal keyed by resource name. Each value is the +verbatim JSON array returned by `GET /v3/languages?resource=`, +formatted with one language entry per line for readable diffs. +""" +import json +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +DATA = ROOT / "data" / "v3-languages" +JSX = ROOT / "snippets" / "language-table.jsx" +BEGIN = " // BEGIN GENERATED: RESOURCES (do not edit; run scripts/generate_language_table.py)" +END = " // END GENERATED" + +# Resource files to inline. Order is preserved in the output. +RESOURCE_NAMES = [ + "translate_text", + "translate_document", + "voice", + "write", + "glossary", + "style_rules", + "translation_memory", +] + + +def render_entry(entry: dict) -> str: + return json.dumps(entry, ensure_ascii=False) + + +def render() -> str: + lines = [BEGIN, " const RESOURCES = {"] + for name in RESOURCE_NAMES: + entries = json.loads((DATA / f"{name}.json").read_text()) + lines.append(f' {json.dumps(name)}: [') + for entry in entries: + lines.append(f" {render_entry(entry)},") + lines.append(" ],") + lines.append(" }") + lines.append(END) + return "\n".join(lines) + + +text = JSX.read_text() +start = text.index(BEGIN) +end = text.index(END, start) + len(END) +JSX.write_text(text[:start] + render() + text[end:]) +total = sum( + len(json.loads((DATA / f"{name}.json").read_text())) for name in RESOURCE_NAMES +) +print(f"regenerated {total} entries across {len(RESOURCE_NAMES)} resources") diff --git a/snippets/language-table.jsx b/snippets/language-table.jsx index 1ee1c7b..5862df6 100644 --- a/snippets/language-table.jsx +++ b/snippets/language-table.jsx @@ -1,167 +1,459 @@ -export const LanguageTable = () => { +export const SupportedLanguages = ({ + mode = 'inline', + resource, + feature, + direction, + includeBeta = false, +}) => { const [searchTerm, setSearchTerm] = useState('') const [sortBy, setSortBy] = useState('name') const [sortOrder, setSortOrder] = useState('asc') const [featureFilters, setFeatureFilters] = useState({ translation: false, - glossaries: false, + glossary: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }) - // Language data with individual feature support - const languageData = [ - // Fully supported languages (source + target + glossaries + tag handling) - { code: 'AR', name: 'Arabic', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'BG', name: 'Bulgarian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'CS', name: 'Czech', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'DA', name: 'Danish', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'DE', name: 'German', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: true, styleRules: true }, - { code: 'EL', name: 'Greek', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'EN', name: 'English (all variants)', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: true, styleRules: true }, - { code: 'ES', name: 'Spanish', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: true, styleRules: true }, - { code: 'ET', name: 'Estonian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'FI', name: 'Finnish', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'FR', name: 'French', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: true, styleRules: true }, - { code: 'HU', name: 'Hungarian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'ID', name: 'Indonesian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'IT', name: 'Italian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: true, styleRules: true }, - { code: 'JA', name: 'Japanese', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: true, styleRules: true }, - { code: 'KO', name: 'Korean', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: true, styleRules: true }, - { code: 'LT', name: 'Lithuanian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'LV', name: 'Latvian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'NB', name: 'Norwegian Bokmål', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'NL', name: 'Dutch', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'PL', name: 'Polish', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'PT', name: 'Portuguese (unspecified variant)', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: false, styleRules: false }, - { code: 'RO', name: 'Romanian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'RU', name: 'Russian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'SK', name: 'Slovak', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'SL', name: 'Slovenian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'SV', name: 'Swedish', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TR', name: 'Turkish', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'UK', name: 'Ukrainian', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'ZH', name: 'Chinese (unspecified variant)', translation: true, isVariant: false, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: true, styleRules: true }, - - // Target-only language variants (cannot be used as source) - { code: 'DE-CH', name: 'German (Swiss)', translation: true, isVariant: true, isBeta: true, glossaries: true, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: true }, - { code: 'EN-GB', name: 'English (British)', translation: true, isVariant: true, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: true, styleRules: false }, - { code: 'EN-US', name: 'English (American)', translation: true, isVariant: true, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: true, styleRules: false }, - { code: 'FR-CA', name: 'French (Canadian)', translation: true, isVariant: true, isBeta: true, glossaries: true, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: true }, - { code: 'PT-BR', name: 'Portuguese (Brazilian)', translation: true, isVariant: true, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: false, styleRules: false }, - { code: 'PT-PT', name: 'Portuguese (European)', translation: true, isVariant: true, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'ZH-HANS', name: 'Chinese (simplified)', translation: true, isVariant: true, glossaries: true, tagHandling: true, textImprovement: true, translationMemory: true, styleRules: false }, - { code: 'ZH-HANT', name: 'Chinese (traditional)', translation: true, isVariant: true, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: false, styleRules: false }, + // The RESOURCES object below is the inlined output of running + // `scripts/generate_language_table.py` against `data/v3-languages/`. + // Each key matches a /v3/languages resource and each value is the + // verbatim JSON array returned by `GET /v3/languages?resource=`. + // BEGIN GENERATED: RESOURCES (do not edit; run scripts/generate_language_table.py) + const RESOURCES = { + "translate_text": [ + {"lang": "ace", "name": "Acehnese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "af", "name": "Afrikaans", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "an", "name": "Aragonese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ar", "name": "Arabic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "as", "name": "Assamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ay", "name": "Aymara", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "az", "name": "Azerbaijani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ba", "name": "Bashkir", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "be", "name": "Belarusian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "bg", "name": "Bulgarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "bho", "name": "Bhojpuri", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "bn", "name": "Bengali", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "br", "name": "Breton", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "bs", "name": "Bosnian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ca", "name": "Catalan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ceb", "name": "Cebuano", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ckb", "name": "Kurdish (Sorani)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "cs", "name": "Czech", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "cy", "name": "Welsh", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "da", "name": "Danish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "de-CH", "name": "German (Swiss)", "status": "beta", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "beta"}, "glossary": {"status": "beta"}, "tag_handling": {"status": "beta"}}}, + {"lang": "de-DE", "name": "German", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "el", "name": "Greek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "en-GB", "name": "English (British)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "en-US", "name": "English (American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "eo", "name": "Esperanto", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "es-419", "name": "Spanish (Latin American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "et", "name": "Estonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "eu", "name": "Basque", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "fa", "name": "Persian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "fi", "name": "Finnish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "fr-CA", "name": "French (Canadian)", "status": "beta", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "beta"}, "glossary": {"status": "beta"}, "style_rules": {"status": "beta"}, "tag_handling": {"status": "beta"}}}, + {"lang": "fr-FR", "name": "French", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ga", "name": "Irish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "gl", "name": "Galician", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "gn", "name": "Guarani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "gom", "name": "Konkani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "gu", "name": "Gujarati", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ha", "name": "Hausa", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "he", "name": "Hebrew", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "hi", "name": "Hindi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "hr", "name": "Croatian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ht", "name": "Haitian Creole", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "hu", "name": "Hungarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "hy", "name": "Armenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "id", "name": "Indonesian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ig", "name": "Igbo", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "is", "name": "Icelandic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "jv", "name": "Javanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ka", "name": "Georgian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "kk", "name": "Kazakh", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "kmr", "name": "Kurdish (Kurmanji)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ky", "name": "Kyrgyz", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "la", "name": "Latin", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "lb", "name": "Luxembourgish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "lmo", "name": "Lombard", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ln", "name": "Lingala", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "lt", "name": "Lithuanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "lv", "name": "Latvian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "mai", "name": "Maithili", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "mg", "name": "Malagasy", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "mi", "name": "Maori", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "mk", "name": "Macedonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ml", "name": "Malayalam", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "mn", "name": "Mongolian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "mr", "name": "Marathi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ms", "name": "Malay", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "mt", "name": "Maltese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "my", "name": "Burmese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "nb", "name": "Norwegian (bokmål)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ne", "name": "Nepali", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "nl", "name": "Dutch", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "oc", "name": "Occitan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "om", "name": "Oromo", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "pa", "name": "Punjabi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "pag", "name": "Pangasinan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "pam", "name": "Kapampangan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "pl", "name": "Polish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "prs", "name": "Dari", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ps", "name": "Pashto", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "pt", "name": "Portuguese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "pt-BR", "name": "Portuguese (Brazilian)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "pt-PT", "name": "Portuguese (European)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "qu", "name": "Quechua", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ro", "name": "Romanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ru", "name": "Russian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "sa", "name": "Sanskrit", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "scn", "name": "Sicilian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "sk", "name": "Slovak", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "sl", "name": "Slovenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "sq", "name": "Albanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "sr", "name": "Serbian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "st", "name": "Sesotho", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "su", "name": "Sundanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "sv", "name": "Swedish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "sw", "name": "Swahili", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ta", "name": "Tamil", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "te", "name": "Telugu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "tg", "name": "Tajik", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "th", "name": "Thai", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "tk", "name": "Turkmen", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "tl", "name": "Tagalog", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "tn", "name": "Tswana", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "tr", "name": "Turkish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ts", "name": "Tsonga", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "tt", "name": "Tatar", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "uk", "name": "Ukrainian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "ur", "name": "Urdu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "uz", "name": "Uzbek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "vi", "name": "Vietnamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "wo", "name": "Wolof", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "xh", "name": "Xhosa", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "yi", "name": "Yiddish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "yue", "name": "Cantonese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "zh-Hant", "name": "Chinese (traditional)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + {"lang": "zu", "name": "Zulu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, + ], + "translate_document": [ + {"lang": "ace", "name": "Acehnese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "af", "name": "Afrikaans", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "an", "name": "Aragonese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ar", "name": "Arabic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "as", "name": "Assamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ay", "name": "Aymara", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "az", "name": "Azerbaijani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ba", "name": "Bashkir", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "be", "name": "Belarusian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "bg", "name": "Bulgarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "bho", "name": "Bhojpuri", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "bn", "name": "Bengali", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "br", "name": "Breton", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "bs", "name": "Bosnian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ca", "name": "Catalan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ceb", "name": "Cebuano", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ckb", "name": "Kurdish (Sorani)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "cs", "name": "Czech", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "cy", "name": "Welsh", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "da", "name": "Danish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "el", "name": "Greek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "en-GB", "name": "English (British)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, + {"lang": "en-US", "name": "English (American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, + {"lang": "eo", "name": "Esperanto", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "es-419", "name": "Spanish (Latin American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "et", "name": "Estonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "eu", "name": "Basque", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fa", "name": "Persian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fi", "name": "Finnish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ga", "name": "Irish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "gl", "name": "Galician", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "gn", "name": "Guarani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "gom", "name": "Konkani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "gu", "name": "Gujarati", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ha", "name": "Hausa", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "he", "name": "Hebrew", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "hi", "name": "Hindi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "hr", "name": "Croatian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ht", "name": "Haitian Creole", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "hu", "name": "Hungarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "hy", "name": "Armenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "id", "name": "Indonesian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ig", "name": "Igbo", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "is", "name": "Icelandic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "jv", "name": "Javanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ka", "name": "Georgian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "kk", "name": "Kazakh", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "kmr", "name": "Kurdish (Kurmanji)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ky", "name": "Kyrgyz", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "la", "name": "Latin", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lb", "name": "Luxembourgish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lmo", "name": "Lombard", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ln", "name": "Lingala", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lt", "name": "Lithuanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "lv", "name": "Latvian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "mai", "name": "Maithili", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mg", "name": "Malagasy", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mi", "name": "Maori", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mk", "name": "Macedonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ml", "name": "Malayalam", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mn", "name": "Mongolian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mr", "name": "Marathi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ms", "name": "Malay", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mt", "name": "Maltese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "my", "name": "Burmese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "nb", "name": "Norwegian (bokmål)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ne", "name": "Nepali", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "nl", "name": "Dutch", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "oc", "name": "Occitan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "om", "name": "Oromo", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pa", "name": "Punjabi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pag", "name": "Pangasinan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pam", "name": "Kapampangan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pl", "name": "Polish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "prs", "name": "Dari", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ps", "name": "Pashto", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pt", "name": "Portuguese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "pt-BR", "name": "Portuguese (Brazilian)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "pt-PT", "name": "Portuguese (European)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "qu", "name": "Quechua", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ro", "name": "Romanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ru", "name": "Russian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "sa", "name": "Sanskrit", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "scn", "name": "Sicilian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sk", "name": "Slovak", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "sl", "name": "Slovenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "sq", "name": "Albanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sr", "name": "Serbian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "st", "name": "Sesotho", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "su", "name": "Sundanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sv", "name": "Swedish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "sw", "name": "Swahili", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ta", "name": "Tamil", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "te", "name": "Telugu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tg", "name": "Tajik", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "th", "name": "Thai", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tk", "name": "Turkmen", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tl", "name": "Tagalog", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tn", "name": "Tswana", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tr", "name": "Turkish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "tt", "name": "Tatar", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "uk", "name": "Ukrainian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ur", "name": "Urdu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "uz", "name": "Uzbek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "vi", "name": "Vietnamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "wo", "name": "Wolof", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "xh", "name": "Xhosa", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "yi", "name": "Yiddish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "yue", "name": "Cantonese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, + {"lang": "zh-Hant", "name": "Chinese (traditional)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, + {"lang": "zu", "name": "Zulu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + ], + "voice": [ + {"lang": "ar", "name": "Arabic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "bg", "name": "Bulgarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "bn", "name": "Bengali", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"transcription": {"status": "stable", "external": true}}}, + {"lang": "cs", "name": "Czech", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "da", "name": "Danish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "el", "name": "Greek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "en-GB", "name": "English (British)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "en-US", "name": "English (American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "et", "name": "Estonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}}}, + {"lang": "fi", "name": "Finnish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "ga", "name": "Irish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"transcription": {"status": "stable", "external": true}}}, + {"lang": "he", "name": "Hebrew", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}}}, + {"lang": "hr", "name": "Croatian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"transcription": {"status": "stable", "external": true}}}, + {"lang": "hu", "name": "Hungarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "id", "name": "Indonesian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "lt", "name": "Lithuanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}}}, + {"lang": "lv", "name": "Latvian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}}}, + {"lang": "mt", "name": "Maltese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"transcription": {"status": "stable", "external": true}}}, + {"lang": "nb", "name": "Norwegian (bokmål)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "nl", "name": "Dutch", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "pl", "name": "Polish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "pt", "name": "Portuguese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "pt-BR", "name": "Portuguese (Brazilian)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "pt-PT", "name": "Portuguese (European)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "ro", "name": "Romanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "ru", "name": "Russian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "sk", "name": "Slovak", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "sl", "name": "Slovenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}}}, + {"lang": "sv", "name": "Swedish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "th", "name": "Thai", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"transcription": {"status": "stable", "external": true}}}, + {"lang": "tl", "name": "Tagalog", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"transcription": {"status": "stable", "external": true}}}, + {"lang": "tr", "name": "Turkish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "uk", "name": "Ukrainian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "vi", "name": "Vietnamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}, "transcription": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + {"lang": "zh-Hant", "name": "Chinese (traditional)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "translated_speech": {"status": "stable"}}}, + ], + "write": [ + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tone": {"status": "stable"}, "writing_style": {"status": "stable"}}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}}}, + {"lang": "en-GB", "name": "English (British)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"tone": {"status": "stable"}, "writing_style": {"status": "stable"}}}, + {"lang": "en-US", "name": "English (American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"tone": {"status": "stable"}, "writing_style": {"status": "stable"}}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}}}, + {"lang": "pt", "name": "Portuguese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}}}, + {"lang": "pt-BR", "name": "Portuguese (Brazilian)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + {"lang": "pt-PT", "name": "Portuguese (European)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}}}, + {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + ], + "glossary": [ + {"lang": "ar", "name": "Arabic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "bg", "name": "Bulgarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "cs", "name": "Czech", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "da", "name": "Danish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "el", "name": "Greek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "et", "name": "Estonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fi", "name": "Finnish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "he", "name": "Hebrew", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "hu", "name": "Hungarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "id", "name": "Indonesian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lt", "name": "Lithuanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lv", "name": "Latvian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "nb", "name": "Norwegian (bokmål)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "nl", "name": "Dutch", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pl", "name": "Polish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pt", "name": "Portuguese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ro", "name": "Romanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ru", "name": "Russian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sk", "name": "Slovak", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sl", "name": "Slovenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sv", "name": "Swedish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tr", "name": "Turkish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "uk", "name": "Ukrainian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "vi", "name": "Vietnamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + ], + "style_rules": [ + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + ], + "translation_memory": [ + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "en-GB", "name": "English (British)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + {"lang": "en-US", "name": "English (American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "es-419", "name": "Spanish (Latin American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + ], + } + // END GENERATED - // Target-only variant - { code: 'ES-419', name: 'Spanish (Latin American)', translation: true, isVariant: true, glossaries: true, tagHandling: true, textImprovement: false, translationMemory: true, styleRules: false }, + // ------------------------------------------------------------------ + // mode === 'inline' | 'bullets': render a comma list / bullet list of + // codes drawn directly from the named resource's response. + // ------------------------------------------------------------------ + const inlineRows = useMemo(() => { + const entries = (resource && RESOURCES[resource]) || RESOURCES.translate_text || [] + return entries.filter(entry => { + const features = entry.features || {} + if (!includeBeta && entry.status !== 'stable') return false + if (direction === 'source' && !entry.usable_as_source) return false + if (direction === 'target' && !entry.usable_as_target) return false + if (feature && !features[feature]) return false + return true + }) + }, [resource, feature, direction, includeBeta]) - // Text-only languages (both source and target, but no glossaries or tag handling) - { code: 'ACE', name: 'Acehnese', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'AF', name: 'Afrikaans', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'AN', name: 'Aragonese', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'AS', name: 'Assamese', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'AY', name: 'Aymara', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'AZ', name: 'Azerbaijani', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'BA', name: 'Bashkir', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'BE', name: 'Belarusian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'BHO', name: 'Bhojpuri', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'BN', name: 'Bengali', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'BR', name: 'Breton', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'BS', name: 'Bosnian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'CA', name: 'Catalan', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'CEB', name: 'Cebuano', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'CKB', name: 'Kurdish (Sorani)', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'CY', name: 'Welsh', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'EO', name: 'Esperanto', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'EU', name: 'Basque', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'FA', name: 'Persian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'GA', name: 'Irish', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'GL', name: 'Galician', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'GN', name: 'Guarani', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'GOM', name: 'Konkani', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'GU', name: 'Gujarati', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'HA', name: 'Hausa', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'HE', name: 'Hebrew', translation: true, isVariant: false, glossaries: true, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'HI', name: 'Hindi', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'HR', name: 'Croatian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'HT', name: 'Haitian Creole', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'HY', name: 'Armenian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'IG', name: 'Igbo', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'IS', name: 'Icelandic', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'JV', name: 'Javanese', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'KA', name: 'Georgian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'KK', name: 'Kazakh', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'KMR', name: 'Kurdish (Kurmanji)', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'KY', name: 'Kyrgyz', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'LA', name: 'Latin', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'LB', name: 'Luxembourgish', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'LMO', name: 'Lombard', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'LN', name: 'Lingala', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'MAI', name: 'Maithili', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'MG', name: 'Malagasy', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'MI', name: 'Maori', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'MK', name: 'Macedonian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'ML', name: 'Malayalam', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'MN', name: 'Mongolian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'MR', name: 'Marathi', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'MS', name: 'Malay', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'MT', name: 'Maltese', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'MY', name: 'Burmese', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'NE', name: 'Nepali', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'OC', name: 'Occitan', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'OM', name: 'Oromo', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'PA', name: 'Punjabi', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'PAG', name: 'Pangasinan', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'PAM', name: 'Kapampangan', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'PRS', name: 'Dari', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'PS', name: 'Pashto', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'QU', name: 'Quechua', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'SA', name: 'Sanskrit', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'SCN', name: 'Sicilian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'SQ', name: 'Albanian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'SR', name: 'Serbian', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'ST', name: 'Sesotho', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'SU', name: 'Sundanese', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'SW', name: 'Swahili', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TA', name: 'Tamil', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TE', name: 'Telugu', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TG', name: 'Tajik', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TH', name: 'Thai', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TK', name: 'Turkmen', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TL', name: 'Tagalog', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TN', name: 'Tswana', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TS', name: 'Tsonga', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'TT', name: 'Tatar', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'UR', name: 'Urdu', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'UZ', name: 'Uzbek', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'VI', name: 'Vietnamese', translation: true, isVariant: false, glossaries: true, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'WO', name: 'Wolof', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'XH', name: 'Xhosa', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'YI', name: 'Yiddish', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'YUE', name: 'Cantonese', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - { code: 'ZU', name: 'Zulu', translation: true, isVariant: false, glossaries: false, tagHandling: false, textImprovement: false, translationMemory: false, styleRules: false }, - ] + // ------------------------------------------------------------------ + // mode === 'table': derive a single flat row per language, merging + // signals from every relevant resource. + // ------------------------------------------------------------------ + const tableRows = useMemo(() => { + const tt = RESOURCES.translate_text || [] + const writeSet = new Set((RESOURCES.write || []).map(e => e.lang)) + const glossarySet = new Set((RESOURCES.glossary || []).map(e => e.lang)) + const tmSet = new Set((RESOURCES.translation_memory || []).map(e => e.lang)) + const rows = tt.map(entry => { + const features = entry.features || {} + return { + code: entry.lang.toUpperCase(), + name: entry.name, + translation: true, + isVariant: !entry.usable_as_source && entry.usable_as_target, + isBeta: entry.status !== 'stable', + glossary: glossarySet.has(entry.lang), + tagHandling: Boolean(features.tag_handling), + textImprovement: writeSet.has(entry.lang), + translationMemory: tmSet.has(entry.lang), + styleRules: Boolean(features.style_rules), + } + }) + rows.sort((a, b) => { + if (a.isVariant !== b.isVariant) return a.isVariant ? 1 : -1 + return a.code < b.code ? -1 : a.code > b.code ? 1 : 0 + }) + return rows + }, []) - // Filter and sort data const filteredData = useMemo(() => { - let filtered = languageData.filter(lang => { + let filtered = tableRows.filter(lang => { const matchesSearch = lang.name.toLowerCase().includes(searchTerm.toLowerCase()) || lang.code.toLowerCase().includes(searchTerm.toLowerCase()) - - const matchesFeatureFilters = Object.keys(featureFilters).every(feature => { - if (!featureFilters[feature]) return true - return lang[feature] === true + const matchesFeatureFilters = Object.keys(featureFilters).every(key => { + if (!featureFilters[key]) return true + return lang[key] === true }) - return matchesSearch && matchesFeatureFilters }) - filtered.sort((a, b) => { let aValue, bValue - if (sortBy === 'name') { aValue = a.name.toLowerCase() bValue = b.name.toLowerCase() @@ -169,16 +461,41 @@ export const LanguageTable = () => { aValue = a.code.toLowerCase() bValue = b.code.toLowerCase() } - if (sortOrder === 'asc') { return aValue < bValue ? -1 : aValue > bValue ? 1 : 0 - } else { - return aValue > bValue ? -1 : aValue < bValue ? 1 : 0 } + return aValue > bValue ? -1 : aValue < bValue ? 1 : 0 }) - return filtered - }, [searchTerm, sortBy, sortOrder, featureFilters]) + }, [tableRows, searchTerm, sortBy, sortOrder, featureFilters]) + + if (mode !== 'table') { + if (mode === 'bullets') { + return ( +
    + {inlineRows.map(entry => ( +
  • + {entry.lang} ({entry.name}) +
  • + ))} +
+ ) + } + return ( + + {inlineRows.map((entry, i) => ( + + {i > 0 && ', '} + {entry.lang} + + ))} + + ) + } + + // ------------------------------------------------------------------ + // mode === 'table': full interactive language table. + // ------------------------------------------------------------------ const handleSort = (column) => { if (sortBy === column) { @@ -189,10 +506,10 @@ export const LanguageTable = () => { } } - const handleFeatureFilterChange = (feature) => { + const handleFeatureFilterChange = (key) => { setFeatureFilters(prev => ({ ...prev, - [feature]: !prev[feature] + [key]: !prev[key] })) } @@ -200,9 +517,10 @@ export const LanguageTable = () => { setSearchTerm('') setFeatureFilters({ translation: false, - glossaries: false, + glossary: false, tagHandling: false, textImprovement: false, + translationMemory: false, styleRules: false }) } @@ -214,17 +532,10 @@ export const LanguageTable = () => { return {sortOrder === 'asc' ? '↑' : '↓'} } - const CheckIcon = ({ enabled }) => { - if (enabled) { - return - } - return - - } - const FeatureBadges = ({ lang }) => { const features = [ { key: 'translation', label: 'Translation', variant: lang.isVariant }, - { key: 'glossaries', label: 'Glossaries' }, + { key: 'glossary', label: 'Glossaries' }, { key: 'tagHandling', label: 'Tag Handling' }, { key: 'textImprovement', label: 'Text Improvement' }, { key: 'translationMemory', label: 'Translation Memory' }, @@ -282,7 +593,6 @@ export const LanguageTable = () => { /> - {/* Feature Filters */}
@@ -301,7 +611,7 @@ export const LanguageTable = () => {
{[ { key: 'translation', label: 'Translation' }, - { key: 'glossaries', label: 'Glossaries' }, + { key: 'glossary', label: 'Glossaries' }, { key: 'tagHandling', label: 'Tag Handling', link: '/docs/xml-and-html-handling/xml' }, { key: 'textImprovement', label: 'Text Improvement', link: '/api-reference/improve-text' }, { key: 'translationMemory', label: 'Translation Memory', link: '/docs/learning-how-tos/examples-and-guides/how-to-use-translation-memories' }, @@ -348,12 +658,11 @@ export const LanguageTable = () => {
- Showing {filteredData.length} of {languageData.length} languages + Showing {filteredData.length} of {tableRows.length} languages {activeFiltersCount > 0 && ` (${activeFiltersCount} filter${activeFiltersCount > 1 ? 's' : ''} active)`}
- {/* Desktop table view */}
@@ -409,7 +718,6 @@ export const LanguageTable = () => {
- {/* Mobile card view */}
{filteredData.map((lang) => (
Date: Thu, 21 May 2026 14:43:36 +0200 Subject: [PATCH 2/3] refactor(v3-languages): collapse fetch + generate into one script - Folds scripts/generate_language_table.py into scripts/fetch_v3_languages.py. One script now fetches every /v3/languages response and regenerates the inline RESOURCES block in the snippet (or skips the snippet via --no-snippet). The dedicated workflow step is gone; the cron just runs the fetcher. - Renames snippets/language-table.jsx to snippets/supported-languages.jsx so the filename matches the only component it exports. Updates the two MDX imports and the workflow add-paths to follow. - Discovers per-resource files from data/v3-languages/*.json instead of from a hardcoded list, so new resources (and the manual translation_memory.json) appear in the snippet automatically. - Adds retry-with-backoff for transient API failures: 429 and 5xx statuses plus network errors retry up to five times, honouring Retry-After when the server sets it. Other HTTP errors raise as before. - Validates response schemas before writing them: /resources must be a list of objects with non-empty string `name`; each per-resource response must be a list of objects with non-empty string `lang` and `name`. A schema mismatch raises with the exact path so a workflow failure is actionable. - Hard-fails (instead of warning + continuing) when the snippet file or its BEGIN/END GENERATED markers are missing. - Trims data/v3-languages/README.md down to the data layout; script flags and behaviour now live in the script's module docstring and --help output. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/refresh-v3-languages.yml | 9 +- api-reference/improve-text.mdx | 2 +- data/v3-languages/README.md | 27 +- docs/getting-started/supported-languages.mdx | 2 +- scripts/fetch_v3_languages.py | 203 ++++++++-- scripts/generate_language_table.py | 56 --- ...uage-table.jsx => supported-languages.jsx} | 362 +++++++++--------- 7 files changed, 373 insertions(+), 288 deletions(-) delete mode 100755 scripts/generate_language_table.py rename snippets/{language-table.jsx => supported-languages.jsx} (99%) diff --git a/.github/workflows/refresh-v3-languages.yml b/.github/workflows/refresh-v3-languages.yml index 4b09c74..918bd91 100644 --- a/.github/workflows/refresh-v3-languages.yml +++ b/.github/workflows/refresh-v3-languages.yml @@ -23,14 +23,11 @@ jobs: - name: Checkout uses: actions/checkout@v5 - - name: Fetch latest /v3/languages responses + - name: Fetch latest /v3/languages responses and refresh snippet env: DEEPL_AUTH_KEY: ${{ secrets.DEEPL_API_KEY }} run: python3 scripts/fetch_v3_languages.py - - name: Regenerate snippets/language-table.jsx from vended data - run: python3 scripts/generate_language_table.py - - name: Open or update refresh PR uses: peter-evans/create-pull-request@v6 with: @@ -40,7 +37,7 @@ jobs: title: "chore(v3-languages): refresh vended responses" body: | Automated refresh of `data/v3-languages/` from `https://api.deepl.com/v3/languages`, - with `snippets/language-table.jsx` regenerated from the new responses. Opened by + with `snippets/supported-languages.jsx` regenerated from the new responses. Opened by the `refresh-v3-languages` workflow. This PR is rewritten in place on each run: if the vended responses change again @@ -51,6 +48,6 @@ jobs: closed and the branch deleted automatically. add-paths: | data/v3-languages/** - snippets/language-table.jsx + snippets/supported-languages.jsx delete-branch: true labels: automated, v3-languages diff --git a/api-reference/improve-text.mdx b/api-reference/improve-text.mdx index f5d69c3..c524eef 100644 --- a/api-reference/improve-text.mdx +++ b/api-reference/improve-text.mdx @@ -4,7 +4,7 @@ public: true sidebarTitle: "Overview" --- -import { SupportedLanguages } from "/snippets/language-table.jsx" +import { SupportedLanguages } from "/snippets/supported-languages.jsx" **Introducing DeepL API for Write** diff --git a/data/v3-languages/README.md b/data/v3-languages/README.md index 1d4b943..1c41399 100644 --- a/data/v3-languages/README.md +++ b/data/v3-languages/README.md @@ -7,28 +7,15 @@ This directory holds verbatim JSON responses from the DeepL `/v3/languages` endp | File | Endpoint | |---|---| | `resources.json` | `GET /v3/languages/resources` | -| `translate_text.json` | `GET /v3/languages?resource=translate_text&include=beta&include=external` | -| `translate_document.json` | `GET /v3/languages?resource=translate_document&include=beta&include=external` | -| `voice.json` | `GET /v3/languages?resource=voice&include=beta&include=external` | -| `write.json` | `GET /v3/languages?resource=write&include=beta&include=external` | -| `glossary.json` | `GET /v3/languages?resource=glossary&include=beta&include=external` | -| `style_rules.json` | `GET /v3/languages?resource=style_rules&include=beta&include=external` | +| `.json` | `GET /v3/languages?resource=&include=beta&include=external` | -Each per-resource file requests `include=beta&include=external` so the vended data is the full superset. Consumers filter on the `status` and per-feature `external` fields when they want a narrower view. - -## Refreshing - -Set `DEEPL_AUTH_KEY` in your environment, then run: +where is one of the resources returned by `/resources` (`translate_text`, `translate_document`, +`voice`, `write`, etc.). -```sh -python3 scripts/fetch_v3_languages.py -``` - -Flags: +Each per-resource file requests `include=beta&include=external` so the vended data is the full superset. Consumers filter on the `status` and per-feature `external` fields when they want a narrower view. -- `--free` — hit `https://api-free.deepl.com` instead of the Pro endpoint. -- `--base-url ` — point at any other host (staging, mock, local server). Also configurable via the `DEEPL_API_BASE_URL` environment variable. +These files are refreshed hourly by the [`refresh-v3-languages`](../../.github/workflows/refresh-v3-languages.yml) GitHub Action, which runs [`scripts/fetch_v3_languages.py`](../../scripts/fetch_v3_languages.py) and opens a pull request whenever the API responses change. See that script's module docstring or `--help` for flags and behaviour (auth, alternate endpoints, manual local refresh). -The script overwrites every file in this directory. +## `translation_memory.json` -A scheduled GitHub Action refreshes these files automatically and opens a pull request when the responses change; manual runs are only needed for local testing. +Translation Memory is not yet exposed by `/v3/languages`, so `translation_memory.json` is currently maintained by hand in the shape of a `/v3/languages` response. The fetcher skips it; once the API exposes Translation Memory as a resource, the next refresh will overwrite the manual file with the real response and no other code has to change. diff --git a/docs/getting-started/supported-languages.mdx b/docs/getting-started/supported-languages.mdx index 79b748c..494c2e7 100644 --- a/docs/getting-started/supported-languages.mdx +++ b/docs/getting-started/supported-languages.mdx @@ -6,7 +6,7 @@ sidebarTitle: "Languages supported" mode: "wide" --- -import { SupportedLanguages } from "/snippets/language-table.jsx" +import { SupportedLanguages } from "/snippets/supported-languages.jsx" The DeepL API supports the following languages. These can also be retrieved programmatically via the [`/v3/languages` endpoint](/api-reference/languages/retrieve-supported-languages-by-resource), which returns language support per resource along with feature availability (e.g. formality, glossary, auto-detection). The legacy [`/v2/languages` endpoint](/api-reference/languages/retrieve-supported-languages) is also available but deprecated. diff --git a/scripts/fetch_v3_languages.py b/scripts/fetch_v3_languages.py index e0b2c9d..3896d12 100755 --- a/scripts/fetch_v3_languages.py +++ b/scripts/fetch_v3_languages.py @@ -1,14 +1,37 @@ #!/usr/bin/env python3 -"""Fetch v3/languages responses and write them to data/v3-languages/. +"""Fetch /v3/languages responses and refresh the vended copies in this repo. -Reads DEEPL_AUTH_KEY from the environment. By default uses the Pro -endpoint; pass --free to hit api-free.deepl.com, or --base-url to point -at any other host (e.g. a staging environment or local mock for -testing). The DEEPL_API_BASE_URL environment variable does the same. +What this script does, in order: -The fetcher requests every resource with ?include=beta&include=external so -the vended files contain the full superset of languages and features. -Consumers filter client-side using the status field on languages/features. +1. Calls `GET /v3/languages/resources` and, for every resource, calls + `GET /v3/languages?resource=&include=beta&include=external`. +2. Writes each response verbatim to `data/v3-languages/.json` + (plus `resources.json`). These files are the single source of truth + that the rest of the repo reads. +3. Regenerates the inline `RESOURCES` object in + `snippets/supported-languages.jsx` between its `// BEGIN GENERATED` / + `// END GENERATED` markers so the `` snippet + stays in sync with the vended JSON. Mintlify's snippet sandbox does + not honour ES module imports, so the data has to ship inline. + +Auth and endpoint: + + - Reads `DEEPL_AUTH_KEY` from the environment (required). + - Defaults to the Pro endpoint (`https://api.deepl.com`). + - `--free` switches to `https://api-free.deepl.com`. + - `--base-url ` (or `DEEPL_API_BASE_URL`) points at any other host, + e.g. a staging environment or a local mock for testing. `--base-url` + and `--free` are mutually exclusive. + +Other flags: + + - `--out ` overrides the JSON output directory (defaults to + `data/v3-languages/` relative to this repo). + - `--no-snippet` skips step 3 when you only want to refresh the JSON. + +The hourly `refresh-v3-languages` GitHub Action runs this script and +opens a pull request whenever the responses change. Manual runs are +only needed for local testing or after editing the script itself. """ from __future__ import annotations @@ -16,18 +39,38 @@ import json import os import sys +import time import urllib.error import urllib.parse import urllib.request from pathlib import Path INCLUDES = ("beta", "external") -DATA_DIR = Path(__file__).resolve().parent.parent / "data" / "v3-languages" +REPO_ROOT = Path(__file__).resolve().parent.parent +DATA_DIR = REPO_ROOT / "data" / "v3-languages" +SNIPPET = REPO_ROOT / "snippets" / "supported-languages.jsx" PRO_URL = "https://api.deepl.com" FREE_URL = "https://api-free.deepl.com" +BEGIN_MARKER = " // BEGIN GENERATED: RESOURCES (do not edit; run scripts/fetch_v3_languages.py)" +END_MARKER = " // END GENERATED" + +# Retry config for transient failures (429s, 5xx, network errors). +MAX_RETRIES = 5 +INITIAL_BACKOFF_S = 1.0 +RETRYABLE_STATUSES = frozenset({429, 500, 502, 503, 504}) + +def _retry_delay(attempt: int, retry_after: str | None) -> float: + """Honour Retry-After (seconds) when present; otherwise exponential backoff.""" + if retry_after: + try: + return max(0.0, float(retry_after)) + except ValueError: + # HTTP-date form is rare; fall through to backoff. + pass + return INITIAL_BACKOFF_S * (2 ** attempt) -def get(url: str, key: str) -> object: +def http_get_json(url: str, key: str) -> object: req = urllib.request.Request( url, headers={ @@ -36,36 +79,138 @@ def get(url: str, key: str) -> object: "User-Agent": "deepl-api-docs-vendor/1.0", }, ) - with urllib.request.urlopen(req, timeout=30) as resp: - return json.loads(resp.read()) + for attempt in range(MAX_RETRIES + 1): + try: + with urllib.request.urlopen(req, timeout=30) as resp: + return json.loads(resp.read()) + except urllib.error.HTTPError as e: + if e.code in RETRYABLE_STATUSES and attempt < MAX_RETRIES: + delay = _retry_delay(attempt, e.headers.get("Retry-After")) + print( + f"retry {attempt + 1}/{MAX_RETRIES}: {e.code} {e.reason} from {url} " + f"(sleeping {delay:.1f}s)", + file=sys.stderr, + ) + time.sleep(delay) + continue + raise + except urllib.error.URLError as e: + # Network-level failure (connection reset, DNS, timeout, etc.). + if attempt < MAX_RETRIES: + delay = _retry_delay(attempt, None) + print( + f"retry {attempt + 1}/{MAX_RETRIES}: network error {e.reason} " + f"from {url} (sleeping {delay:.1f}s)", + file=sys.stderr, + ) + time.sleep(delay) + continue + raise + # Unreachable: loop either returns or raises. + raise RuntimeError("retry loop exited unexpectedly") -def fetch(base_url: str, key: str) -> dict[str, object]: - resources = get(f"{base_url}/v3/languages/resources", key) +def _require_str(value: object, path: str) -> str: + if not isinstance(value, str) or not value: + raise RuntimeError(f"unexpected schema at {path}: want non-empty string, got {value!r}") + return value + + +def _validate_resources(resources: object) -> list[dict]: if not isinstance(resources, list): - raise RuntimeError(f"Unexpected resources payload: {resources!r}") + raise RuntimeError(f"unexpected /v3/languages/resources payload: want list, got {type(resources).__name__}") + validated: list[dict] = [] + for i, entry in enumerate(resources): + if not isinstance(entry, dict): + raise RuntimeError(f"unexpected schema at resources[{i}]: want object, got {type(entry).__name__}") + _require_str(entry.get("name"), f"resources[{i}].name") + validated.append(entry) + return validated + + +def _validate_languages(payload: object, resource: str) -> list[dict]: + if not isinstance(payload, list): + raise RuntimeError( + f"unexpected /v3/languages?resource={resource} payload: " + f"want list, got {type(payload).__name__}" + ) + for i, entry in enumerate(payload): + if not isinstance(entry, dict): + raise RuntimeError( + f"unexpected schema at {resource}[{i}]: want object, got {type(entry).__name__}" + ) + _require_str(entry.get("lang"), f"{resource}[{i}].lang") + _require_str(entry.get("name"), f"{resource}[{i}].name") + return payload + - out: dict[str, object] = {"resources.json": resources} +def fetch(base_url: str, key: str) -> dict[str, object]: + resources = _validate_resources( + http_get_json(f"{base_url}/v3/languages/resources", key) + ) + + payloads: dict[str, object] = {"resources.json": resources} qs = urllib.parse.urlencode([("include", v) for v in INCLUDES], doseq=True) for entry in resources: name = entry["name"] - langs = get(f"{base_url}/v3/languages?resource={name}&{qs}", key) - out[f"{name}.json"] = langs - return out + langs = _validate_languages( + http_get_json(f"{base_url}/v3/languages?resource={name}&{qs}", key), + name, + ) + payloads[f"{name}.json"] = langs + return payloads -def write_files(payloads: dict[str, object], out_dir: Path) -> list[Path]: +def write_json_files(payloads: dict[str, object], out_dir: Path) -> list[Path]: out_dir.mkdir(parents=True, exist_ok=True) written: list[Path] = [] for filename, payload in payloads.items(): path = out_dir / filename with path.open("w", encoding="utf-8") as f: - json.dump(payload, f, indent=2, ensure_ascii=False, sort_keys=False) + json.dump(payload, f, indent=2, ensure_ascii=False) f.write("\n") written.append(path) return written +def render_resources_block(data_dir: Path) -> str: + """Build the `const RESOURCES = {...}` literal from every per-resource + JSON file in `data_dir`. `resources.json` (the index) is skipped; every + other `*.json` file is treated as a resource response, including manual + files like `translation_memory.json`. + """ + lines = [BEGIN_MARKER, " const RESOURCES = {"] + for path in sorted(data_dir.glob("*.json")): + if path.stem == "resources": + continue + entries = json.loads(path.read_text(encoding="utf-8")) + lines.append(f' {json.dumps(path.stem)}: [') + for entry in entries: + lines.append(f" {json.dumps(entry, ensure_ascii=False)},") + lines.append(" ],") + lines.append(" }") + lines.append(END_MARKER) + return "\n".join(lines) + + +def update_snippet(data_dir: Path) -> bool: + if not SNIPPET.exists(): + raise SystemExit(f"error: snippet not found at {SNIPPET}") + text = SNIPPET.read_text(encoding="utf-8") + if BEGIN_MARKER not in text or END_MARKER not in text: + raise SystemExit( + f"error: {SNIPPET} is missing the BEGIN/END GENERATED markers" + ) + new_block = render_resources_block(data_dir) + start = text.index(BEGIN_MARKER) + end = text.index(END_MARKER, start) + len(END_MARKER) + updated = text[:start] + new_block + text[end:] + if updated == text: + return False + SNIPPET.write_text(updated, encoding="utf-8") + return True + + def resolve_base_url(cli_base_url: str | None, free: bool) -> str: if cli_base_url and free: raise SystemExit("error: --base-url and --free are mutually exclusive") @@ -96,7 +241,12 @@ def main() -> int: "--out", type=Path, default=DATA_DIR, - help=f"Output directory (default: {DATA_DIR})", + help=f"Output directory for the vended JSON (default: {DATA_DIR})", + ) + parser.add_argument( + "--no-snippet", + action="store_true", + help="Skip regenerating snippets/supported-languages.jsx", ) args = parser.parse_args() @@ -112,9 +262,16 @@ def main() -> int: print(f"error: {e.code} {e.reason} from {e.url}", file=sys.stderr) return 1 - paths = write_files(payloads, args.out) + paths = write_json_files(payloads, args.out) for p in paths: print(p) + + if not args.no_snippet: + if update_snippet(args.out): + print(SNIPPET) + else: + print(f"{SNIPPET}: up to date") + return 0 diff --git a/scripts/generate_language_table.py b/scripts/generate_language_table.py deleted file mode 100755 index c20cbe7..0000000 --- a/scripts/generate_language_table.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -"""Regenerate the inline RESOURCES object in snippets/language-table.jsx -from the vended /v3/languages responses under data/v3-languages/. - -The JSX file must contain `// BEGIN GENERATED` and `// END GENERATED` -marker lines; everything between them is replaced. The output is a -JavaScript object literal keyed by resource name. Each value is the -verbatim JSON array returned by `GET /v3/languages?resource=`, -formatted with one language entry per line for readable diffs. -""" -import json -from pathlib import Path - -ROOT = Path(__file__).resolve().parent.parent -DATA = ROOT / "data" / "v3-languages" -JSX = ROOT / "snippets" / "language-table.jsx" -BEGIN = " // BEGIN GENERATED: RESOURCES (do not edit; run scripts/generate_language_table.py)" -END = " // END GENERATED" - -# Resource files to inline. Order is preserved in the output. -RESOURCE_NAMES = [ - "translate_text", - "translate_document", - "voice", - "write", - "glossary", - "style_rules", - "translation_memory", -] - - -def render_entry(entry: dict) -> str: - return json.dumps(entry, ensure_ascii=False) - - -def render() -> str: - lines = [BEGIN, " const RESOURCES = {"] - for name in RESOURCE_NAMES: - entries = json.loads((DATA / f"{name}.json").read_text()) - lines.append(f' {json.dumps(name)}: [') - for entry in entries: - lines.append(f" {render_entry(entry)},") - lines.append(" ],") - lines.append(" }") - lines.append(END) - return "\n".join(lines) - - -text = JSX.read_text() -start = text.index(BEGIN) -end = text.index(END, start) + len(END) -JSX.write_text(text[:start] + render() + text[end:]) -total = sum( - len(json.loads((DATA / f"{name}.json").read_text())) for name in RESOURCE_NAMES -) -print(f"regenerated {total} entries across {len(RESOURCE_NAMES)} resources") diff --git a/snippets/language-table.jsx b/snippets/supported-languages.jsx similarity index 99% rename from snippets/language-table.jsx rename to snippets/supported-languages.jsx index 5862df6..4ac092e 100644 --- a/snippets/language-table.jsx +++ b/snippets/supported-languages.jsx @@ -18,11 +18,177 @@ export const SupportedLanguages = ({ }) // The RESOURCES object below is the inlined output of running - // `scripts/generate_language_table.py` against `data/v3-languages/`. + // `scripts/fetch_v3_languages.py` against `data/v3-languages/`. // Each key matches a /v3/languages resource and each value is the // verbatim JSON array returned by `GET /v3/languages?resource=`. - // BEGIN GENERATED: RESOURCES (do not edit; run scripts/generate_language_table.py) + // BEGIN GENERATED: RESOURCES (do not edit; run scripts/fetch_v3_languages.py) const RESOURCES = { + "glossary": [ + {"lang": "ar", "name": "Arabic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "bg", "name": "Bulgarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "cs", "name": "Czech", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "da", "name": "Danish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "el", "name": "Greek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "et", "name": "Estonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fi", "name": "Finnish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "he", "name": "Hebrew", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "hu", "name": "Hungarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "id", "name": "Indonesian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lt", "name": "Lithuanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lv", "name": "Latvian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "nb", "name": "Norwegian (bokmål)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "nl", "name": "Dutch", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pl", "name": "Polish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pt", "name": "Portuguese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ro", "name": "Romanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ru", "name": "Russian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sk", "name": "Slovak", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sl", "name": "Slovenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sv", "name": "Swedish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tr", "name": "Turkish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "uk", "name": "Ukrainian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "vi", "name": "Vietnamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + ], + "style_rules": [ + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + ], + "translate_document": [ + {"lang": "ace", "name": "Acehnese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "af", "name": "Afrikaans", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "an", "name": "Aragonese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ar", "name": "Arabic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "as", "name": "Assamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ay", "name": "Aymara", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "az", "name": "Azerbaijani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ba", "name": "Bashkir", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "be", "name": "Belarusian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "bg", "name": "Bulgarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "bho", "name": "Bhojpuri", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "bn", "name": "Bengali", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "br", "name": "Breton", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "bs", "name": "Bosnian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ca", "name": "Catalan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ceb", "name": "Cebuano", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ckb", "name": "Kurdish (Sorani)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "cs", "name": "Czech", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "cy", "name": "Welsh", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "da", "name": "Danish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "el", "name": "Greek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "en-GB", "name": "English (British)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, + {"lang": "en-US", "name": "English (American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, + {"lang": "eo", "name": "Esperanto", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "es-419", "name": "Spanish (Latin American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "et", "name": "Estonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "eu", "name": "Basque", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fa", "name": "Persian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "fi", "name": "Finnish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ga", "name": "Irish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "gl", "name": "Galician", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "gn", "name": "Guarani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "gom", "name": "Konkani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "gu", "name": "Gujarati", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ha", "name": "Hausa", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "he", "name": "Hebrew", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "hi", "name": "Hindi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "hr", "name": "Croatian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ht", "name": "Haitian Creole", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "hu", "name": "Hungarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "hy", "name": "Armenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "id", "name": "Indonesian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ig", "name": "Igbo", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "is", "name": "Icelandic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "jv", "name": "Javanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ka", "name": "Georgian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "kk", "name": "Kazakh", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "kmr", "name": "Kurdish (Kurmanji)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ky", "name": "Kyrgyz", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "la", "name": "Latin", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lb", "name": "Luxembourgish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lmo", "name": "Lombard", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ln", "name": "Lingala", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "lt", "name": "Lithuanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "lv", "name": "Latvian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "mai", "name": "Maithili", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mg", "name": "Malagasy", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mi", "name": "Maori", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mk", "name": "Macedonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ml", "name": "Malayalam", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mn", "name": "Mongolian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mr", "name": "Marathi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ms", "name": "Malay", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "mt", "name": "Maltese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "my", "name": "Burmese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "nb", "name": "Norwegian (bokmål)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ne", "name": "Nepali", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "nl", "name": "Dutch", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "oc", "name": "Occitan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "om", "name": "Oromo", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pa", "name": "Punjabi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pag", "name": "Pangasinan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pam", "name": "Kapampangan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pl", "name": "Polish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "prs", "name": "Dari", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ps", "name": "Pashto", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "pt", "name": "Portuguese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "pt-BR", "name": "Portuguese (Brazilian)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "pt-PT", "name": "Portuguese (European)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "qu", "name": "Quechua", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ro", "name": "Romanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ru", "name": "Russian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "sa", "name": "Sanskrit", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "scn", "name": "Sicilian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sk", "name": "Slovak", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "sl", "name": "Slovenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "sq", "name": "Albanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sr", "name": "Serbian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "st", "name": "Sesotho", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "su", "name": "Sundanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "sv", "name": "Swedish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "sw", "name": "Swahili", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ta", "name": "Tamil", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "te", "name": "Telugu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tg", "name": "Tajik", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "th", "name": "Thai", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tk", "name": "Turkmen", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tl", "name": "Tagalog", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tn", "name": "Tswana", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "tr", "name": "Turkish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "tt", "name": "Tatar", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "uk", "name": "Ukrainian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "ur", "name": "Urdu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "uz", "name": "Uzbek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "vi", "name": "Vietnamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "wo", "name": "Wolof", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "xh", "name": "Xhosa", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "yi", "name": "Yiddish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "yue", "name": "Cantonese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, + {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, + {"lang": "zh-Hant", "name": "Chinese (traditional)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, + {"lang": "zu", "name": "Zulu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + ], "translate_text": [ {"lang": "ace", "name": "Acehnese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, {"lang": "af", "name": "Afrikaans", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, @@ -150,127 +316,19 @@ export const SupportedLanguages = ({ {"lang": "zh-Hant", "name": "Chinese (traditional)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "style_rules": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, {"lang": "zu", "name": "Zulu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "tag_handling": {"status": "stable"}}}, ], - "translate_document": [ - {"lang": "ace", "name": "Acehnese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "af", "name": "Afrikaans", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "an", "name": "Aragonese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ar", "name": "Arabic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "as", "name": "Assamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ay", "name": "Aymara", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "az", "name": "Azerbaijani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ba", "name": "Bashkir", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "be", "name": "Belarusian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "bg", "name": "Bulgarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "bho", "name": "Bhojpuri", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "bn", "name": "Bengali", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "br", "name": "Breton", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "bs", "name": "Bosnian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ca", "name": "Catalan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ceb", "name": "Cebuano", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ckb", "name": "Kurdish (Sorani)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "cs", "name": "Czech", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "cy", "name": "Welsh", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "da", "name": "Danish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "el", "name": "Greek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "en-GB", "name": "English (British)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, - {"lang": "en-US", "name": "English (American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, - {"lang": "eo", "name": "Esperanto", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "es-419", "name": "Spanish (Latin American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "et", "name": "Estonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "eu", "name": "Basque", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "fa", "name": "Persian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "fi", "name": "Finnish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "ga", "name": "Irish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "gl", "name": "Galician", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "gn", "name": "Guarani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "gom", "name": "Konkani", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "gu", "name": "Gujarati", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ha", "name": "Hausa", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "he", "name": "Hebrew", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "hi", "name": "Hindi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "hr", "name": "Croatian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ht", "name": "Haitian Creole", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "hu", "name": "Hungarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "hy", "name": "Armenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "id", "name": "Indonesian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "ig", "name": "Igbo", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "is", "name": "Icelandic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "jv", "name": "Javanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ka", "name": "Georgian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "kk", "name": "Kazakh", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "kmr", "name": "Kurdish (Kurmanji)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "ky", "name": "Kyrgyz", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "la", "name": "Latin", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "lb", "name": "Luxembourgish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "lmo", "name": "Lombard", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ln", "name": "Lingala", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "lt", "name": "Lithuanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "lv", "name": "Latvian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "mai", "name": "Maithili", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "mg", "name": "Malagasy", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "mi", "name": "Maori", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "mk", "name": "Macedonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ml", "name": "Malayalam", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "mn", "name": "Mongolian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "mr", "name": "Marathi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ms", "name": "Malay", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "mt", "name": "Maltese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "my", "name": "Burmese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "nb", "name": "Norwegian (bokmål)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "ne", "name": "Nepali", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "nl", "name": "Dutch", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "oc", "name": "Occitan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "om", "name": "Oromo", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "pa", "name": "Punjabi", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "pag", "name": "Pangasinan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "pam", "name": "Kapampangan", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "pl", "name": "Polish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "prs", "name": "Dari", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ps", "name": "Pashto", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "pt", "name": "Portuguese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "pt-BR", "name": "Portuguese (Brazilian)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "pt-PT", "name": "Portuguese (European)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "qu", "name": "Quechua", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ro", "name": "Romanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "ru", "name": "Russian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "formality": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "sa", "name": "Sanskrit", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "scn", "name": "Sicilian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "sk", "name": "Slovak", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "sl", "name": "Slovenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "sq", "name": "Albanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "sr", "name": "Serbian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "st", "name": "Sesotho", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "su", "name": "Sundanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "sv", "name": "Swedish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "sw", "name": "Swahili", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ta", "name": "Tamil", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "te", "name": "Telugu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "tg", "name": "Tajik", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "th", "name": "Thai", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "tk", "name": "Turkmen", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "tl", "name": "Tagalog", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "tn", "name": "Tswana", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "tr", "name": "Turkish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "tt", "name": "Tatar", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "uk", "name": "Ukrainian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "ur", "name": "Urdu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "uz", "name": "Uzbek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "vi", "name": "Vietnamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "wo", "name": "Wolof", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "xh", "name": "Xhosa", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "yi", "name": "Yiddish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "yue", "name": "Cantonese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}, "glossary": {"status": "stable"}}}, - {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, - {"lang": "zh-Hant", "name": "Chinese (traditional)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {"glossary": {"status": "stable"}}}, - {"lang": "zu", "name": "Zulu", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + "translation_memory": [ + {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "en-GB", "name": "English (British)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + {"lang": "en-US", "name": "English (American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "es-419", "name": "Spanish (Latin American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, + {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, + {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, ], "voice": [ {"lang": "ar", "name": "Arabic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"glossary": {"status": "stable"}, "transcription": {"status": "stable", "external": true}, "translated_speech": {"status": "stable", "external": true}}}, @@ -334,64 +392,6 @@ export const SupportedLanguages = ({ {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {"auto_detection": {"status": "stable"}}}, {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, ], - "glossary": [ - {"lang": "ar", "name": "Arabic", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "bg", "name": "Bulgarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "cs", "name": "Czech", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "da", "name": "Danish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "el", "name": "Greek", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "et", "name": "Estonian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "fi", "name": "Finnish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "he", "name": "Hebrew", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "hu", "name": "Hungarian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "id", "name": "Indonesian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "lt", "name": "Lithuanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "lv", "name": "Latvian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "nb", "name": "Norwegian (bokmål)", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "nl", "name": "Dutch", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "pl", "name": "Polish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "pt", "name": "Portuguese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ro", "name": "Romanian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ru", "name": "Russian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "sk", "name": "Slovak", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "sl", "name": "Slovenian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "sv", "name": "Swedish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "tr", "name": "Turkish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "uk", "name": "Ukrainian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "vi", "name": "Vietnamese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - ], - "style_rules": [ - {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - ], - "translation_memory": [ - {"lang": "de", "name": "German", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "en", "name": "English", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "en-GB", "name": "English (British)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, - {"lang": "en-US", "name": "English (American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, - {"lang": "es", "name": "Spanish", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "es-419", "name": "Spanish (Latin American)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, - {"lang": "fr", "name": "French", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "it", "name": "Italian", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ja", "name": "Japanese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "ko", "name": "Korean", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "zh", "name": "Chinese", "status": "stable", "usable_as_source": true, "usable_as_target": true, "features": {}}, - {"lang": "zh-Hans", "name": "Chinese (simplified)", "status": "stable", "usable_as_source": false, "usable_as_target": true, "features": {}}, - ], } // END GENERATED From 6e75d900ebded7b8702549d05df9febe5b6f970a Mon Sep 17 00:00:00 2001 From: Daniel Jones Date: Thu, 21 May 2026 16:24:44 +0200 Subject: [PATCH 3/3] docs(supported-languages): migrate more prose lists + expand component docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces hand-typed language lists with `` in: - api-reference/improve-text.mdx — `target_lang` ParamField (the earlier commit only migrated `writing_style` and `tone`; the ParamField's own list still hand-typed). - api-reference/style-rules.mdx — POST `language` ParamField. - api-reference/translate.mdx — `formality` and `custom_instructions` ParamFields. - api-reference/document.mdx — `formality` ParamField. - docs/best-practices/custom-instructions.mdx — technical-constraints supported-target-languages bullet. Adds the import to each file that did not already have one. In every case the migrated component output is more accurate than the prose list it replaces (e.g. `formality` for text translation now reflects all 16 langs the API returns rather than the 11-entry manual list, with the regional variants). Also: - Adds a JSDoc-style block above `SupportedLanguages` that documents every prop, when each is required, valid values per resource, and three usage examples. - Promotes the `translation_memory.json` exception in `data/v3-languages/README.md` to a general "Stand-in files for APIs not yet in /v3/languages" pattern with a three-step recipe. The snippet generator already walks `data/v3-languages/*.json`, so any new manual file picked up by the recipe is wired in automatically. Co-Authored-By: Claude Opus 4.7 (1M context) --- api-reference/document.mdx | 8 ++- api-reference/improve-text.mdx | 12 +--- api-reference/style-rules.mdx | 6 +- api-reference/translate.mdx | 14 +++- data/v3-languages/README.md | 18 ++++- docs/best-practices/custom-instructions.mdx | 7 +- snippets/supported-languages.jsx | 75 +++++++++++++++++++++ 7 files changed, 121 insertions(+), 19 deletions(-) diff --git a/api-reference/document.mdx b/api-reference/document.mdx index 29162a2..41342d3 100644 --- a/api-reference/document.mdx +++ b/api-reference/document.mdx @@ -4,6 +4,8 @@ sidebarTitle: "Overview" public: true --- +import { SupportedLanguages } from "/snippets/supported-languages.jsx" + The document translation API allows you to translate whole documents and supports the following file types and extensions: * `docx` / `doc` - Microsoft Word Document @@ -146,7 +148,11 @@ These examples are for demonstration purposes only. In production code, the auth The name of the uploaded file. Can be used as an alternative to including the file name in the file part's content disposition. - Sets whether the translated text should lean towards formal or informal language. This feature currently only works for target languages `DE` (German), `FR` (French), `IT` (Italian), `ES` (Spanish), `NL` (Dutch), `PL` (Polish), `PT-BR` and `PT-PT` (Portuguese), `JA` (Japanese), and `RU` (Russian). Learn more about the plain/polite feature for Japanese here. Setting this parameter with a target language that does not support formality will fail, unless one of the `prefer_...` options are used. To check formality support dynamically, call GET /v3/languages?resource=translate_document and look for the formality feature key on the target language. Possible options are: + Sets whether the translated text should lean towards formal or informal language. Currently supported for the following target languages: + + + + Learn more about the plain/polite feature for Japanese here. Setting this parameter with a target language that does not support formality will fail, unless one of the `prefer_...` options are used. To check formality support dynamically, call GET /v3/languages?resource=translate_document and look for the formality feature key on the target language. Possible options are:
  • `default` (default)
  • `more` - for a more formal language
  • diff --git a/api-reference/improve-text.mdx b/api-reference/improve-text.mdx index c524eef..d2994d0 100644 --- a/api-reference/improve-text.mdx +++ b/api-reference/improve-text.mdx @@ -67,17 +67,7 @@ curl -X POST 'https://api.deepl.com/v2/write/rephrase' \ The language of the improved text. Currently, the following languages are supported: - * `de` (German) - * `en-GB` (British English) - * `en-US` (American English) - * `es` (Spanish) - * `fr` (French) - * `it` (Italian) - * `ja` (Japanese) - * `ko` (Korean) - * `pt-BR` (Brazilian Portuguese) - * `pt-PT` (Portuguese) - * `zh`/`zh-Hans` (simplified Chinese) + You can also retrieve supported languages programmatically via GET /v3/languages?resource=write. diff --git a/api-reference/style-rules.mdx b/api-reference/style-rules.mdx index dbd4a52..9d06b54 100644 --- a/api-reference/style-rules.mdx +++ b/api-reference/style-rules.mdx @@ -4,6 +4,8 @@ sidebarTitle: "Overview" description: "Manage a shared list of rules for style, formatting, and more" --- +import { SupportedLanguages } from "/snippets/supported-languages.jsx" + The Style Rules API is currently available only to Pro API subscribers. @@ -161,7 +163,9 @@ Create a new style rule list with configured rules and optional custom instructi The name of the style rule list. Maximum length: 1024 characters. - The target language for the style rules. Supported values: `de`, `en`, `es`, `fr`, `it`, `ja`, `ko`, `zh`. + The target language for the style rules. Supported values: + + An object containing predefined rules to enable for the style rule list. Rules are organized by category (e.g., `dates_and_times`, `punctuation`). Each category can contain multiple rule options. diff --git a/api-reference/translate.mdx b/api-reference/translate.mdx index 0f99ac3..8497f56 100644 --- a/api-reference/translate.mdx +++ b/api-reference/translate.mdx @@ -5,6 +5,8 @@ description: "API reference for translating text with the DeepL API." public: true --- +import { SupportedLanguages } from "/snippets/supported-languages.jsx" + The text-translation API currently consists of a single endpoint, `translate`, which is described below. For highest translation quality, we recommend using our next-gen models. For details, please see [here](/api-reference/translate#about-the-model_type-parameter). @@ -267,7 +269,11 @@ error. - Sets whether the translated text should lean towards formal or informal language. This feature currently only works for target languages DE (German), FR (French), IT (Italian), ES (Spanish), ES-419 (Latin American Spanish), NL (Dutch), PL (Polish), PT-BR and PT-PT (Portuguese), JA (Japanese), and RU (Russian). Learn more about the plain/polite feature for Japanese ↗️. To check formality support dynamically, call GET /v3/languages?resource=translate_text and look for the formality feature key on the target language. + Sets whether the translated text should lean towards formal or informal language. Currently supported for the following target languages: + + + + Learn more about the plain/polite feature for Japanese ↗️. To check formality support dynamically, call GET /v3/languages?resource=translate_text and look for the formality feature key on the target language.

    Setting this parameter with a target language that does not support formality will fail, unless one of the prefer_... options are used. Possible options are:

      @@ -296,9 +302,11 @@ error. Specify a list of instructions to customize the translation behavior. Up to 10 custom instructions can be specified, each with a maximum of 300 characters. - - The target language must be `de`, `en`, `es`, `fr`, `it`, `ja`, `ko`, `zh` or any variants of these languages. + The target language must be one of: + + + Any request with the `custom_instructions` parameter enabled will default to use the `quality_optimized` model type. Requests combining `custom_instructions` and `model_type: latency_optimized` will be rejected. You can find best practices on how to write custom instructions [here](/docs/best-practices/custom-instructions). To check language support dynamically, call GET /v3/languages?resource=translate_text and check for the style_rules feature key on the target language. diff --git a/data/v3-languages/README.md b/data/v3-languages/README.md index 1c41399..dadcb73 100644 --- a/data/v3-languages/README.md +++ b/data/v3-languages/README.md @@ -16,6 +16,20 @@ Each per-resource file requests `include=beta&include=external` so the vended da These files are refreshed hourly by the [`refresh-v3-languages`](../../.github/workflows/refresh-v3-languages.yml) GitHub Action, which runs [`scripts/fetch_v3_languages.py`](../../scripts/fetch_v3_languages.py) and opens a pull request whenever the API responses change. See that script's module docstring or `--help` for flags and behaviour (auth, alternate endpoints, manual local refresh). -## `translation_memory.json` +## Stand-in files for APIs not yet in `/v3/languages` -Translation Memory is not yet exposed by `/v3/languages`, so `translation_memory.json` is currently maintained by hand in the shape of a `/v3/languages` response. The fetcher skips it; once the API exposes Translation Memory as a resource, the next refresh will overwrite the manual file with the real response and no other code has to change. +When a DeepL API needs a supported-languages list in the docs but is not yet exposed as a `/v3/languages` resource, you can hand-write a stand-in file here and the rest of the tooling will treat it like a real response. This is how `translation_memory.json` works today, and the same pattern applies to any future API that has not landed in `/v3/languages` yet. + +To add one: + +1. Create `data/v3-languages/.json`, where `` is the resource name you expect the API to expose (snake_case, no spaces). +2. Fill it with an array shaped exactly like a real `/v3/languages?resource=` response — each entry needs `lang`, `name`, `status`, `usable_as_source`, `usable_as_target`, and a `features` object (use `{}` if there are no per-language features yet). +3. Commit the file. The snippet generator picks it up on the next run (it walks `data/v3-languages/*.json` and inlines every file it finds), so `` immediately works in MDX. + +You do not need to touch `scripts/fetch_v3_languages.py` or the workflow. The fetcher only writes files it actually fetched, so the manual file is left alone every run. + +Once the API does land in `/v3/languages/resources`, the very next refresh will overwrite the stand-in file with the real response and the docs stay in sync — no code change required. When that happens, double-check the fields match (the manual schema was a best guess) and delete this paragraph from the README if there are no remaining stand-ins. + +### Current stand-ins + +- `translation_memory.json` — Translation Memory languages. Will be replaced automatically once Translation Memory ships as a `/v3/languages` resource. diff --git a/docs/best-practices/custom-instructions.mdx b/docs/best-practices/custom-instructions.mdx index a7c78d8..a563215 100644 --- a/docs/best-practices/custom-instructions.mdx +++ b/docs/best-practices/custom-instructions.mdx @@ -4,6 +4,8 @@ description: "Learn how to create effective custom instructions to customize you public: true --- +import { SupportedLanguages } from "/snippets/supported-languages.jsx" + The `custom_instructions` parameter allows you to provide natural language instructions that customize how the DeepL API translates text. This guide provides best practices for creating effective custom instructions that produce consistent, high-quality results. ## What are custom instructions? @@ -84,9 +86,12 @@ When using custom instructions, keep these constraints in mind: - **Maximum instructions**: Up to 10 custom instructions per request - **Character limit**: Each instruction can contain a maximum of 300 characters -- **Supported target languages**: `de`, `en`, `es`, `fr`, `it`, `ja`, `ko`, `zh`, or any variants of these languages - **Model requirement**: Requests with `custom_instructions` automatically use the `quality_optimized` model type +**Supported target languages:** + + + Combining `custom_instructions` with `model_type: latency_optimized` will result in an error. Custom instructions require the quality-optimized model. diff --git a/snippets/supported-languages.jsx b/snippets/supported-languages.jsx index 4ac092e..084a336 100644 --- a/snippets/supported-languages.jsx +++ b/snippets/supported-languages.jsx @@ -1,3 +1,78 @@ +/** + * Render a list (or the full interactive table) of DeepL-supported + * languages drawn from the vended /v3/languages responses inlined + * below. The component is sandboxed by Mintlify, so the data has to + * ship inside this file; see `scripts/fetch_v3_languages.py` for how + * the `RESOURCES` block is refreshed. + * + * Drop the component wherever you would have hand-typed a language + * list. It must appear at the block level (its own line); MDX does + * not honour component references mid-paragraph. + * + * Props + * ----- + * mode: 'inline' (default) | 'bullets' | 'table' + * - 'inline' - comma-separated `{lang}` list. Use for + * prose like "supported target languages: `de`, `en`, ..." + * - 'bullets' - vertical bulleted list of `{lang} ({name})`. + * Use for API parameter docs where each language has a + * sub-bullet. + * - 'table' - the full interactive sortable / filterable table. + * The `resource`, `feature`, `direction`, and + * `includeBeta` props are ignored in this mode; the + * table merges signals across every relevant resource. + * + * resource: string (required for 'inline' and 'bullets') + * Name of the /v3/languages resource to read from. Must match a + * key in the inlined `RESOURCES` object — i.e. one of + * `translate_text`, `translate_document`, `voice`, `write`, + * `glossary`, `style_rules`, or `translation_memory`. When omitted, + * the component falls back to `translate_text` so the call still + * renders, but you almost always want to set this explicitly so the + * list matches the feature you are documenting. + * + * feature: string (optional) + * API feature key to filter by, exactly as it appears in the + * `features` object of a /v3/languages response (snake_case). Only + * languages that list this feature in their `features` object are + * included. Examples by resource: + * - translate_text / translate_document: 'auto_detection', + * 'formality', 'glossary', 'style_rules', 'tag_handling' + * - write: 'auto_detection', 'tone', 'writing_style' + * - voice: 'auto_detection', 'formality', 'glossary', + * 'transcription', 'translated_speech' + * Omit the prop to include every language in the chosen resource. + * + * direction: 'source' | 'target' (optional) + * - 'source' keeps languages with `usable_as_source: true`. + * - 'target' keeps languages with `usable_as_target: true`. + * Omit to include both. Use this whenever the feature is + * directional (e.g. style_rules / writing_style / tone are + * target-only; auto_detection is source-only). + * + * includeBeta: boolean (default false) + * When true, also include languages whose `status` is not + * 'stable' (e.g. 'beta' or 'early_access'). The hourly refresh + * already vends languages and features at every status, so this + * prop just chooses what to show. + * + * Examples + * -------- + * + * + * + * + * + */ export const SupportedLanguages = ({ mode = 'inline', resource,