read the glossary from pray.doxa.life instead of a vendored file
config/glossaries.ts was generated from the retired translation repo's DeepL
TSVs, so it had no source left and only the German, Spanish and Portuguese
rows had been hand-patched. Both it and its build script are gone.
- fetch GET /api/glossary/{lang} at runtime, cached ten minutes, serving the
last good answer when the request fails and an empty one when it never
succeeded. A reviewer's correction now reaches auto-translate without a
deploy here
- carry the glossary's notes as well as its terms: register, acronym policy
and number format, placed after the term list so a rule about inflection
governs the pairs above it
- glossary_used on the MCP translate tool now means the locale's terminology
was available, and reads false for a language whose glossary has not been
started
- add /add-language and /sync-language skills for the site strings, the map
widget locales and bundles, the /terms edition, and the CMS pages
This commit is contained in:
parent
10f63df2eb
commit
a994baec4f
10 changed files with 365 additions and 957 deletions
122
.claude/skills/add-language/SKILL.md
Normal file
122
.claude/skills/add-language/SKILL.md
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
---
|
||||
name: add-language
|
||||
description: Bring a new language onto the marketing site — the config/languages.ts entry from its glossary record, the site strings, the map widget locales and bundles, the /terms edition, and the CMS pages. Use after the language has a glossary with reviewed terms. Invoke with /add-language <code>.
|
||||
user-invocable: true
|
||||
---
|
||||
|
||||
# Add a language to doxa.life
|
||||
|
||||
Argument: the language code. The language must already exist in the DOXA
|
||||
glossary, which is maintained in the campaigns server's admin and published at
|
||||
`https://pray.doxa.life/api/glossary/{code}`. That is where a language is born;
|
||||
this site follows it.
|
||||
|
||||
## 1. Refuse to start without a glossary
|
||||
|
||||
```bash
|
||||
curl -s -o /dev/null -w '%{http_code}\n' https://pray.doxa.life/api/glossary/{code}
|
||||
```
|
||||
|
||||
A 404 means the language has no terminology yet. Stop, and say what has to
|
||||
happen first: an admin adds it at `/admin/glossary` on pray.doxa.life, drafts
|
||||
its terms, and a reviewer confirms them. Copy written before that has to be
|
||||
rewritten after.
|
||||
|
||||
Read the whole glossary before writing anything, `notes` included.
|
||||
|
||||
## 2. Create the `config/languages.ts` entry
|
||||
|
||||
From the glossary record:
|
||||
|
||||
| Glossary field | Entry field |
|
||||
|---|---|
|
||||
| `language.name_en` | `name` |
|
||||
| `language.name_local` | `nativeName` |
|
||||
| `language.text_direction` | `dir: 'rtl'`, omitted when `ltr` |
|
||||
| `language.bible_id` | `bibleId` |
|
||||
|
||||
Ask the person for `flag`, and for `translationName` when the plain English name
|
||||
is ambiguous in a translation prompt. Set `latinHeadings: false` for any
|
||||
non-Latin script, so the site does not try to set headings in a display face
|
||||
that has no glyphs for it.
|
||||
|
||||
Add it with `enabled: false`. The language then has routes and can be worked on
|
||||
while the public switcher stays unchanged.
|
||||
|
||||
`hideFromSwitcher: true` is the middle state: routable and translated, but not
|
||||
offered until someone decides it is ready.
|
||||
|
||||
## 3. Site strings
|
||||
|
||||
`i18n/locales/{code}/common.json`, with exactly the key structure of
|
||||
`i18n/locales/en/common.json`.
|
||||
|
||||
Translate from English with the glossary and its notes in front of you. Never
|
||||
add or drop a key. Validate the JSON and compare the key set against English
|
||||
before moving on.
|
||||
|
||||
Missing keys fall back to English rather than showing a key, so a half-finished
|
||||
file is not obviously broken. Check the count, not the appearance.
|
||||
|
||||
## 4. The map widget
|
||||
|
||||
1. Copy `embeddables/micro-frontends/1040-maps/src/i18n/locales/en/` to
|
||||
`{code}/` and translate every file. `legend.json`, `search.json` and
|
||||
`prayerLaps.json` carry terminology; the rest is interface wording.
|
||||
2. Rebuild: `npm run build` inside `embeddables/micro-frontends/1040-maps/`,
|
||||
which writes `public/js/`.
|
||||
3. `public/js/pplr-data-maps.iife.js` has no build profile. If it carries
|
||||
per-language strings for the languages it supports, add this one by patching
|
||||
its literals in place; otherwise leave it and say so.
|
||||
|
||||
## 5. The `/terms` edition
|
||||
|
||||
Create `app/utils/terms/{code}.ts` from `en.ts` and register it in
|
||||
`app/utils/terms/index.ts`. A locale with no edition falls back to English.
|
||||
|
||||
**Entry parity is the rule:** the same 20 entries in the same order as `en.ts`.
|
||||
Per entry, fill what applies — the chosen term, the English original, the
|
||||
definition, the alternatives considered, what Joshua Project and
|
||||
PeopleGroups.org use, and a rationale that cites this language's reference Bible
|
||||
wherever the choice is Scripture-driven. An entry that needed no real decision
|
||||
in this language still appears, with its definition and a one-line rationale.
|
||||
|
||||
Two rendering rules already encoded in `app/pages/terms.vue` that a new edition
|
||||
must not break: entries stay flat children of `.page-body`, because the site's
|
||||
typography uses direct-child selectors and a global rule gives every `<section>`
|
||||
landing-page padding; and a space at the edge of a `<template>` fragment has to
|
||||
be interpolated as `{{ ' ' }}` or Vue's whitespace handling strips it.
|
||||
|
||||
## 6. CMS pages
|
||||
|
||||
Pages live in this site's database. Create the translations through the
|
||||
`doxa-cms` MCP server at `https://doxa.life/mcp`.
|
||||
|
||||
- `list_pages(locale: "en", status: "any", limit: 100)` for the set to
|
||||
translate. Match the set an established language already has rather than
|
||||
translating everything: signed letters and one-off event pages are
|
||||
deliberately left in English.
|
||||
- `upsert_page_translation` creates a draft. `publish_translation` is a separate
|
||||
call, and publishing is the person's decision, not yours. Draft everything,
|
||||
then ask.
|
||||
- Edit `body_json` on any page reported lossy, any page with links, and any page
|
||||
whose heading begins with a line break.
|
||||
- One subagent per page works well, each given the glossary, the language's
|
||||
notes, and the register. Follow it with a pass across all the pages together,
|
||||
because per-page agents diverge on wording the glossary does not fix.
|
||||
|
||||
## 7. Switch it on
|
||||
|
||||
Set `enabled: true` once the site strings and the map locales are done. Then run
|
||||
`npx nuxi typecheck`, start the dev server, and read the home page, a people
|
||||
group page, the adopt flow and `/{code}/terms` end to end. For a right-to-left
|
||||
language, confirm the layout mirrors.
|
||||
|
||||
The typecheck baseline is 122 pre-existing errors in the external layers and
|
||||
`server/api/maps/token.get.ts`. None of them are yours.
|
||||
|
||||
## 8. Report
|
||||
|
||||
What was added, what is still English, which CMS pages are drafted and awaiting
|
||||
a decision to publish, and anything a reviewer must answer. Repository changes
|
||||
stay uncommitted.
|
||||
105
.claude/skills/sync-language/SKILL.md
Normal file
105
.claude/skills/sync-language/SKILL.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
name: sync-language
|
||||
description: Bring the marketing site's existing text for one language into line with the current DOXA glossary — site strings, the map widget locales and their bundles, the /terms edition, and the published CMS pages. Use after a reviewer confirms or changes terminology. Invoke with /sync-language <code>.
|
||||
user-invocable: true
|
||||
---
|
||||
|
||||
# Align doxa.life with the glossary
|
||||
|
||||
Argument: a language code this site already carries. For a new one, use
|
||||
`/add-language`.
|
||||
|
||||
## 1. Read the glossary
|
||||
|
||||
```bash
|
||||
curl -s https://pray.doxa.life/api/glossary/{code}?format=markdown
|
||||
```
|
||||
|
||||
The glossary lives in the campaigns server's admin, where reviewers confirm each
|
||||
term through a magic link, and it is authoritative for every DOXA property. The
|
||||
response also carries `notes`: this language's register, its acronym policy, its
|
||||
number format and its script rules. Read those first; they decide how the terms
|
||||
are used.
|
||||
|
||||
A `draft` term is still authoritative — it is wording nobody has ruled on yet,
|
||||
not wording to ignore.
|
||||
|
||||
## 2. Establish what here was written by a human
|
||||
|
||||
This matters more on this site than anywhere else. Several languages' copy was
|
||||
reviewed by a native-speaking volunteer, and their review documents are not in
|
||||
the repository. `git log` on the locale file and a look at whether the prose
|
||||
reads like a person wrote it are the available evidence. **Ask.**
|
||||
|
||||
**Precedence, highest first:** the reviewer's later notes, then the glossary,
|
||||
then wording a human reviewer approved, then anything AI-generated.
|
||||
|
||||
On reviewed copy, change only a glossary term or an outright defect. Keep their
|
||||
register, their phrasing, their headings. Where the glossary contradicts a
|
||||
reviewed sentence, change the term inside that sentence and leave the rest.
|
||||
|
||||
On machine-translated copy, fix the defects too. Past sweeps have found
|
||||
mistranslations that no reviewer ever saw, not just terminology.
|
||||
|
||||
## 3. Site strings
|
||||
|
||||
`i18n/locales/{code}/common.json`.
|
||||
|
||||
Script the replacements with explicit old-to-new pairs, assert each matches,
|
||||
never change a key, and validate the JSON afterwards. Then grep `app/` and
|
||||
`server/` for the old wording in case a term is hardcoded.
|
||||
|
||||
## 4. The map widget
|
||||
|
||||
Three layers, and all three have to move together or the site shows two
|
||||
vocabularies on one page.
|
||||
|
||||
1. **Source locales** — `embeddables/micro-frontends/1040-maps/src/i18n/locales/{code}/`.
|
||||
`legend.json`, `search.json` and `prayerLaps.json` carry the terminology.
|
||||
These were never human-reviewed, so they follow the glossary outright.
|
||||
2. **Built bundles** — rebuild with `npm run build` inside
|
||||
`embeddables/micro-frontends/1040-maps/`, which writes `public/js/`.
|
||||
3. **`public/js/pplr-data-maps.iife.js`** — has no build profile and carries an
|
||||
older snapshot of the strings. Patch its literals in place with a regex
|
||||
against the minified file. Do not copy source strings in blind: its wording
|
||||
can differ from the current source. Anchor on a nearby unique literal,
|
||||
because several locales' blocks sit within a few kilobytes of each other.
|
||||
|
||||
## 5. The `/terms` edition
|
||||
|
||||
`app/utils/terms/{code}.ts`, registered in `app/utils/terms/index.ts`. It
|
||||
documents this language's terminology decisions: the chosen term, the
|
||||
alternatives considered, what Joshua Project and PeopleGroups.org use, and why.
|
||||
|
||||
Every edition carries the same 20 entries in the same order as `en.ts`. Keep
|
||||
that parity. Update any entry the glossary has moved, and state plainly in the
|
||||
rationale where the glossary and the language's reference Bible disagree rather
|
||||
than quietly picking one.
|
||||
|
||||
## 6. CMS pages
|
||||
|
||||
Pages on doxa.life live in this site's database, not in the repository. Edit
|
||||
them through the `doxa-cms` MCP server at `https://doxa.life/mcp`, which needs
|
||||
an OAuth login with `pages.view` and `pages.write`.
|
||||
|
||||
- `list_pages(locale: "{code}", status: "any", limit: 100)` to find them.
|
||||
- `get_page_translation(page_id, "{code}")`, fix, `upsert_page_translation`.
|
||||
- **Never pass `status` on a published page.** One row holds each page and
|
||||
locale, and the site serves only `published`; passing `draft` takes the page
|
||||
off the live site. Omitting it keeps the page published, which also means
|
||||
**every edit is live the moment it saves**. Say this to the person before the
|
||||
first write.
|
||||
- Edit `body_json`, not markdown, on any page reported lossy, on any page with
|
||||
links, and on any page whose heading starts with a line break. A markdown
|
||||
save rewrites link attributes and drops trailing breaks even on a page
|
||||
reported clean.
|
||||
- Run replacements against the fetched body with an assertion that each matches
|
||||
exactly once, so untouched prose cannot drift.
|
||||
- Responses are cached for an hour at the origin. Verify an edit with a
|
||||
cache-busting query parameter.
|
||||
|
||||
## 7. Report
|
||||
|
||||
Per surface: terms changed, defects fixed, what was deliberately left, what a
|
||||
reviewer still owes an answer on. Repository changes stay uncommitted; CMS
|
||||
pages are already live and must be reported as such.
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -49,5 +49,5 @@ embeddables/micro-frontends/_template/
|
|||
|
||||
package-lock.json
|
||||
plans
|
||||
.claude
|
||||
.claude/settings.local.json
|
||||
.vscode
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
// documenting that language's terminology decisions — the chosen term,
|
||||
// alternatives considered, what Joshua Project and PeopleGroups.org use,
|
||||
// and the rationale. Locales without an edition fall back to English.
|
||||
// New language editions are added as part of the language-stabilization
|
||||
// process (see translation/LANGUAGE-STABILIZATION.md in the doxa monorepo).
|
||||
// A new edition is written when a language is added or its terminology
|
||||
// changes; the `add-language` and `sync-language` skills in .claude/skills
|
||||
// cover it. Terminology itself comes from the DOXA glossary, published at
|
||||
// https://pray.doxa.life/api/glossary/{lang}.
|
||||
|
||||
import { en } from './en'
|
||||
import { fr } from './fr'
|
||||
|
|
|
|||
|
|
@ -1,888 +0,0 @@
|
|||
// Generated by scripts/build-glossaries.ts from ../translation/deepl-glossaries/*.tsv
|
||||
// Do not edit by hand — update the TSVs in the translation repo and re-run:
|
||||
// bun scripts/build-glossaries.ts
|
||||
|
||||
/** English → target-language term pairs, keyed by language code. */
|
||||
export const GLOSSARIES: Record<string, ReadonlyArray<readonly [string, string]>> = {
|
||||
ar: [
|
||||
["people group", "جماعة عرقية"],
|
||||
["people groups", "جماعات عرقية"],
|
||||
["unreached people group", "جماعة عرقية غير مُبلَّغة"],
|
||||
["unreached people groups", "جماعات عرقية غير مُبلَّغة"],
|
||||
["unengaged people group", "جماعة عرقية غير مُنخرَطة"],
|
||||
["unengaged people groups", "جماعات عرقية غير مُنخرَطة"],
|
||||
["unengaged unreached people group", "جماعة عرقية غير مُبلَّغة وغير مُنخرَطة"],
|
||||
["under-engaged", "ناقصة الانخراط"],
|
||||
["frontier people group", "جماعة عرقية حدودية"],
|
||||
["frontier people groups", "جماعات عرقية حدودية"],
|
||||
["ethnolinguistic group", "جماعة إثنولغوية"],
|
||||
["unreached", "غير مُبلَّغ"],
|
||||
["unengaged", "غير مُنخرَط"],
|
||||
["engaged", "مُنخرَط"],
|
||||
["engagement", "انخراط"],
|
||||
["fruitful engagement", "انخراط مثمر"],
|
||||
["gospel access", "الوصول إلى الإنجيل"],
|
||||
["gospel engagement", "الانخراط بالإنجيل"],
|
||||
["the gospel", "الإنجيل"],
|
||||
["church-planting movement", "حركة تأسيس كنائس"],
|
||||
["church planting", "تأسيس كنائس"],
|
||||
["indigenous church", "كنيسة محلّية"],
|
||||
["indigenous churches", "كنائس محلّية"],
|
||||
["self-propagating", "ذاتي الانتشار"],
|
||||
["self-governing", "ذاتي الحكم"],
|
||||
["self-supporting", "ذاتي التمويل"],
|
||||
["self-theologizing", "ذاتي اللاهوت"],
|
||||
["self-missionizing", "ذاتي الإرسال"],
|
||||
["residential engagement", "انخراط إقامي"],
|
||||
["workers in residence", "عاملون مقيمون"],
|
||||
["cross-cultural workers", "عاملون عابرون للثقافات"],
|
||||
["apostolic effort", "جهد رسولي"],
|
||||
["pioneer work", "عمل ريادي"],
|
||||
["heart language", "اللغة الأم"],
|
||||
["movement to Jesus", "حركة نحو يسوع"],
|
||||
["nonresident partners", "شركاء غير مقيمين"],
|
||||
["broader engagement", "انخراط أوسع"],
|
||||
["diaspora", "شتات"],
|
||||
["daily prayer", "صلاة يومية"],
|
||||
["24-hour prayer coverage", "تغطية صلاة على مدار 24 ساعة"],
|
||||
["intercessor", "شفيع"],
|
||||
["intercessors", "شفعاء"],
|
||||
["intercessory prayer", "صلاة شفاعية"],
|
||||
["prayer points", "نقاط صلاة"],
|
||||
["daily prayer guide", "دليل الصلاة اليومي"],
|
||||
["prayer prepares the way", "الصلاة تُمهِّد الطريق"],
|
||||
["Lord of the harvest", "ربّ الحصاد"],
|
||||
["adopt", "تبنّي"],
|
||||
["pray, give, and send", "صلّوا وقدِّموا وأرسِلوا"],
|
||||
["mobilize", "تعبئة"],
|
||||
["mobilization", "تعبئة"],
|
||||
["sending agency", "وكالة إرسال"],
|
||||
["sending agencies", "وكالات إرسال"],
|
||||
["our gift to Jesus", "تقدمتنا ليسوع"],
|
||||
["DOXA partnership missionaries", "مُرسَلون شركاء في DOXA"],
|
||||
["every tribe, tongue, people, and nation", "كلّ قبيلة ولسان وشعب وأمّة"],
|
||||
["make disciples of all the nations", "تلمِذوا جميع الأمم"],
|
||||
["disciple", "تلميذ"],
|
||||
["disciples", "تلاميذ"],
|
||||
["baptized disciples", "تلاميذ مُعمَّدون"],
|
||||
["culturally appropriate", "ملائم ثقافيًّا"],
|
||||
["self-sustaining churches", "كنائس مكتفية ذاتيًّا"],
|
||||
["spiritual generations", "أجيال روحية"],
|
||||
["abide in Jesus", "اثبُتوا في يسوع"],
|
||||
["pray without ceasing", "صلّوا بلا انقطاع"],
|
||||
["deny yourself", "أنكِروا أنفسكم"],
|
||||
["engage the regions beyond", "ابلُغوا المناطق الأبعد"],
|
||||
["Pentecostal", "خمسيني"],
|
||||
["Statement of Faith", "بيان الإيمان"],
|
||||
["new birth", "الولادة الجديدة"],
|
||||
["regeneration", "التجديد"],
|
||||
["justification", "التبرير"],
|
||||
["atonement", "الكفّارة"],
|
||||
["sanctification", "التقديس"],
|
||||
["baptism in water", "المعمودية بالماء"],
|
||||
["Lord's Supper", "العشاء الربّاني"],
|
||||
["baptism in the Holy Spirit", "المعمودية بالروح القدس"],
|
||||
["speaking in tongues", "التكلّم بألسنة"],
|
||||
["gifts of the Holy Spirit", "مواهب الروح القدس"],
|
||||
["pre-millennial return", "الرجوع قبل الألفية"],
|
||||
["bodily resurrection", "القيامة الجسدية"],
|
||||
["pray", "صلّوا"],
|
||||
["engage", "انخرِطوا"],
|
||||
["choose a people group", "اختاروا جماعة عرقية"],
|
||||
["sign up", "التسجيل"]
|
||||
],
|
||||
de: [
|
||||
["people group", "Volksgruppe"],
|
||||
["people groups", "Volksgruppen"],
|
||||
["unreached people group", "unerreichte Volksgruppe"],
|
||||
["unreached people groups", "unerreichte Volksgruppen"],
|
||||
["unengaged people group", "unberührte Volksgruppe"],
|
||||
["unengaged people groups", "unberührte Volksgruppen"],
|
||||
["unengaged unreached people group", "völlig unerreichte Volksgruppe (VUVG)"],
|
||||
["under-engaged", "am wenigsten erreicht"],
|
||||
["frontier people group", "Frontier-Volksgruppe"],
|
||||
["frontier people groups", "Frontier-Volksgruppen"],
|
||||
["ethnolinguistic group", "ethno-linguistische Gruppe"],
|
||||
["unreached", "unerreicht"],
|
||||
["unengaged", "unberührt"],
|
||||
["engaged", "engagiert"],
|
||||
["engagement", "missionarische Arbeit vor Ort"],
|
||||
["fruitful engagement", "fruchtbare Arbeit vor Ort"],
|
||||
["gospel access", "Zugang zum Evangelium"],
|
||||
["gospel engagement", "Evangelisationsarbeit"],
|
||||
["the gospel", "das Evangelium"],
|
||||
["church-planting movement", "Gemeindegründungsbewegung"],
|
||||
["church planting", "Gemeindegründung"],
|
||||
["indigenous church", "einheimische Gemeinde"],
|
||||
["indigenous churches", "einheimische Gemeinden"],
|
||||
["self-propagating", "sich selbst ausbreitend"],
|
||||
["self-governing", "selbstverwaltend"],
|
||||
["self-supporting", "sich selbst finanzierend"],
|
||||
["self-theologizing", "selbsttheologisierend"],
|
||||
["self-missionizing", "selbstmissionierend"],
|
||||
["residential engagement", "Engagement vor Ort"],
|
||||
["workers in residence", "vor Ort ansässige Mitarbeiter/innen"],
|
||||
["cross-cultural workers", "kulturübergreifende Mitarbeiter/innen"],
|
||||
["apostolic effort", "apostolischer Einsatz"],
|
||||
["pioneer work", "Pionierarbeit"],
|
||||
["heart language", "Herzenssprache"],
|
||||
["movement to Jesus", "Bewegung zu Jesus hin"],
|
||||
["nonresident partners", "Projektpartner"],
|
||||
["broader engagement", "weiteres Engagement"],
|
||||
["diaspora", "Diaspora"],
|
||||
["daily prayer", "tägliches Gebet"],
|
||||
["24-hour prayer coverage", "24-Stunden-Gebetsabdeckung"],
|
||||
["intercessor", "Fürbitter/in"],
|
||||
["intercessors", "Fürbitter/innen"],
|
||||
["intercessory prayer", "Fürbittegebet"],
|
||||
["prayer points", "Gebetsanliegen"],
|
||||
["daily prayer guide", "täglicher Gebetsleitfaden"],
|
||||
["prayer prepares the way", "Gebet bahnt den Weg"],
|
||||
["Lord of the harvest", "Herr der Ernte"],
|
||||
["adopt", "adoptieren"],
|
||||
["pray, give, and send", "beten, geben und senden"],
|
||||
["mobilize", "mobilisieren"],
|
||||
["mobilization", "Mobilisierung"],
|
||||
["sending agency", "Sendeorganisation"],
|
||||
["sending agencies", "Sendeorganisationen"],
|
||||
["our gift to Jesus", "unser Geschenk an Jesus"],
|
||||
["DOXA partnership missionaries", "DOXA-Partnermissionare"],
|
||||
["every tribe, tongue, people, and nation", "jeder Stamm, jede Zunge, jedes Volk und jede Nation"],
|
||||
["make disciples of all the nations", "macht zu Jüngern alle Völker"],
|
||||
["disciple", "Jünger"],
|
||||
["disciples", "Jünger"],
|
||||
["baptized disciples", "getaufte Jünger"],
|
||||
["culturally appropriate", "kulturell angemessen"],
|
||||
["self-sustaining churches", "eigenständige Gemeinden"],
|
||||
["spiritual generations", "geistliche Generationen"],
|
||||
["abide in Jesus", "bleibt in Jesus"],
|
||||
["pray without ceasing", "betet ohne Unterlass"],
|
||||
["deny yourself", "verleugnet euch selbst"],
|
||||
["engage the regions beyond", "erreicht die Gebiete darüber hinaus"],
|
||||
["Pentecostal", "pfingstlich"],
|
||||
["Statement of Faith", "Glaubensbekenntnis"],
|
||||
["new birth", "Wiedergeburt"],
|
||||
["regeneration", "Erneuerung"],
|
||||
["justification", "Rechtfertigung"],
|
||||
["atonement", "Sühne"],
|
||||
["sanctification", "Heiligung"],
|
||||
["baptism in water", "Wassertaufe"],
|
||||
["Lord's Supper", "Abendmahl"],
|
||||
["baptism in the Holy Spirit", "Taufe im Heiligen Geist"],
|
||||
["speaking in tongues", "Zungenreden"],
|
||||
["gifts of the Holy Spirit", "Gaben des Heiligen Geistes"],
|
||||
["pre-millennial return", "prämillenniale Wiederkunft"],
|
||||
["bodily resurrection", "leibliche Auferstehung"],
|
||||
["pray", "beten"],
|
||||
["engage", "eine missionarische Arbeit vor Ort beginnen"],
|
||||
["choose a people group", "eine Volksgruppe wählen"],
|
||||
["sign up", "anmelden"]
|
||||
],
|
||||
es: [
|
||||
["people group", "grupo étnico"],
|
||||
["people groups", "grupos étnicos"],
|
||||
["unreached people group", "grupo étnico no alcanzado"],
|
||||
["unreached people groups", "grupos étnicos no alcanzados"],
|
||||
["unengaged people group", "grupo étnico no comprometido"],
|
||||
["unengaged people groups", "grupos étnicos no comprometidos"],
|
||||
["unengaged unreached people group", "grupo étnico no alcanzado no comprometido (GENANC)"],
|
||||
["under-engaged", "poco comprometido"],
|
||||
["frontier people group", "grupo fronterizo"],
|
||||
["frontier people groups", "grupos fronterizos"],
|
||||
["ethnolinguistic group", "grupo etnolingüístico"],
|
||||
["unreached", "no alcanzado"],
|
||||
["unengaged", "no comprometido"],
|
||||
["engaged", "comprometido"],
|
||||
["engagement", "compromiso"],
|
||||
["fruitful engagement", "compromiso fructífero"],
|
||||
["gospel access", "acceso al evangelio"],
|
||||
["gospel engagement", "compromiso con el evangelio"],
|
||||
["the gospel", "el evangelio"],
|
||||
["church-planting movement", "movimiento de plantación de iglesias (MPI)"],
|
||||
["church planting", "plantación de iglesias"],
|
||||
["indigenous church", "iglesia autóctona"],
|
||||
["indigenous churches", "iglesias autóctonas"],
|
||||
["self-propagating", "autopropagador"],
|
||||
["self-governing", "autogobernado"],
|
||||
["self-supporting", "autosustentado"],
|
||||
["self-theologizing", "autoteologizante"],
|
||||
["self-missionizing", "automisionero"],
|
||||
["residential engagement", "compromiso residencial"],
|
||||
["workers in residence", "trabajadores residentes"],
|
||||
["cross-cultural workers", "obreros transculturales"],
|
||||
["apostolic effort", "esfuerzo apostólico"],
|
||||
["pioneer work", "trabajo pionero"],
|
||||
["heart language", "lengua del corazón"],
|
||||
["movement to Jesus", "movimiento hacia Jesús"],
|
||||
["nonresident partners", "asociados no residentes"],
|
||||
["broader engagement", "compromiso más amplio"],
|
||||
["diaspora", "diáspora"],
|
||||
["daily prayer", "oración diaria"],
|
||||
["24-hour prayer coverage", "cobertura de oración de 24 horas"],
|
||||
["intercessor", "intercesor"],
|
||||
["intercessors", "intercesores"],
|
||||
["intercessory prayer", "oración intercesora"],
|
||||
["prayer points", "motivos de oración"],
|
||||
["daily prayer guide", "guía diaria de oración"],
|
||||
["prayer prepares the way", "la oración prepara el camino"],
|
||||
["Lord of the harvest", "Señor de la cosecha"],
|
||||
["adopt", "adoptar"],
|
||||
["pray, give, and send", "orar, dar y enviar"],
|
||||
["mobilize", "movilizar"],
|
||||
["mobilization", "movilización"],
|
||||
["sending agency", "agencia enviadora"],
|
||||
["sending agencies", "agencias enviadoras"],
|
||||
["our gift to Jesus", "nuestro regalo para Jesús"],
|
||||
["DOXA partnership missionaries", "misioneros asociados a DOXA"],
|
||||
["every tribe, tongue, people, and nation", "cada tribu, lengua, pueblo y nación"],
|
||||
["make disciples of all the nations", "hacer discípulos a todas las naciones"],
|
||||
["disciple", "discípulo"],
|
||||
["disciples", "discípulos"],
|
||||
["baptized disciples", "discípulos bautizados"],
|
||||
["culturally appropriate", "culturalmente apropiado"],
|
||||
["self-sustaining churches", "iglesias autosustentables"],
|
||||
["spiritual generations", "generaciones espirituales"],
|
||||
["abide in Jesus", "permanecer en Jesús"],
|
||||
["pray without ceasing", "orar sin cesar"],
|
||||
["deny yourself", "niégate a ti mismo"],
|
||||
["engage the regions beyond", "involucrarse en las regiones más allá"],
|
||||
["Pentecostal", "pentecostal"],
|
||||
["Statement of Faith", "Declaración de fe"],
|
||||
["new birth", "nuevo nacimiento"],
|
||||
["regeneration", "regeneración"],
|
||||
["justification", "justificación"],
|
||||
["atonement", "expiación"],
|
||||
["sanctification", "santificación"],
|
||||
["baptism in water", "bautismo en agua"],
|
||||
["Lord's Supper", "Cena del Señor"],
|
||||
["baptism in the Holy Spirit", "bautismo en el Espíritu Santo"],
|
||||
["speaking in tongues", "hablar en lenguas"],
|
||||
["gifts of the Holy Spirit", "dones del Espíritu Santo"],
|
||||
["pre-millennial return", "retorno premilenial"],
|
||||
["bodily resurrection", "resurrección corporal"],
|
||||
["pray", "orar"],
|
||||
["engage", "comprometer"],
|
||||
["UUPG", "GENANC"],
|
||||
["World Assemblies of God Fellowship", "Fraternidad Mundial de las Asambleas de Dios"],
|
||||
["champion", "defensor"],
|
||||
["champions", "defensores"],
|
||||
["choose a people group", "elegir un grupo étnico"],
|
||||
["sign up", "registrarse"]
|
||||
],
|
||||
fr: [
|
||||
["people group", "peuple"],
|
||||
["people groups", "peuples"],
|
||||
["unreached people group", "peuple non atteint"],
|
||||
["unreached people groups", "peuples non atteints"],
|
||||
["unengaged people group", "peuple non engagé"],
|
||||
["unengaged people groups", "peuples non engagés"],
|
||||
["unengaged unreached people group", "peuple non atteint et non engagé"],
|
||||
["under-engaged", "sous-engagé"],
|
||||
["frontier people group", "peuple frontière"],
|
||||
["frontier people groups", "peuples frontières"],
|
||||
["frontier peoples", "peuples frontières"],
|
||||
["ethnolinguistic group", "groupe ethnolinguistique"],
|
||||
["unreached", "non atteint"],
|
||||
["unengaged", "non engagé"],
|
||||
["engaged", "engagé"],
|
||||
["engagement", "engagement"],
|
||||
["fruitful engagement", "engagement fructueux"],
|
||||
["gospel access", "accès à l'Évangile"],
|
||||
["gospel engagement", "engagement pour l'Évangile"],
|
||||
["the gospel", "l'Évangile"],
|
||||
["church-planting movement", "mouvement d'implantation d'églises"],
|
||||
["church planting", "implantation d'églises"],
|
||||
["indigenous church", "église autochtone"],
|
||||
["indigenous churches", "églises autochtones"],
|
||||
["self-propagating", "auto-propagateur"],
|
||||
["self-governing", "auto-gouverné"],
|
||||
["self-supporting", "auto-financé"],
|
||||
["self-theologizing", "auto-théologisant"],
|
||||
["self-missionizing", "auto-missionnaire"],
|
||||
["residential engagement", "engagement sur le terrain"],
|
||||
["workers in residence", "ouvriers résidents"],
|
||||
["cross-cultural workers", "ouvriers transculturels"],
|
||||
["apostolic effort", "effort pionnier"],
|
||||
["pioneer work", "travail de pionnier"],
|
||||
["heart language", "langue du cœur"],
|
||||
["movement to Jesus", "mouvement vers Jésus"],
|
||||
["nonresident partners", "partenaires extérieurs"],
|
||||
["broader engagement", "engagement élargi"],
|
||||
["diaspora", "diaspora"],
|
||||
["daily prayer", "prière quotidienne"],
|
||||
["24-hour prayer coverage", "couverture de prière 24h/24"],
|
||||
["intercessor", "intercesseur"],
|
||||
["intercessors", "intercesseurs"],
|
||||
["intercessory prayer", "prière d'intercession"],
|
||||
["prayer points", "sujets de prière"],
|
||||
["daily prayer guide", "guide de prière quotidien"],
|
||||
["prayer prepares the way", "la prière prépare le chemin"],
|
||||
["Lord of the harvest", "Maître de la moisson"],
|
||||
["adopt", "adopter"],
|
||||
["pray, give, and send", "prier, donner et envoyer"],
|
||||
["mobilize", "mobiliser"],
|
||||
["mobilization", "mobilisation"],
|
||||
["sending agency", "agence missionnaire"],
|
||||
["sending agencies", "agences missionnaires"],
|
||||
["our gift to Jesus", "notre offrande à Jésus"],
|
||||
["DOXA partnership missionaries", "missionnaires en partenariat DOXA"],
|
||||
["every tribe, tongue, people, and nation", "toute tribu, toute langue, tout peuple et toute nation"],
|
||||
["make disciples of all the nations", "faites de toutes les nations des disciples"],
|
||||
["disciple", "disciple"],
|
||||
["disciples", "disciples"],
|
||||
["baptized disciples", "disciples baptisés"],
|
||||
["culturally appropriate", "culturellement approprié"],
|
||||
["self-sustaining churches", "églises autonomes"],
|
||||
["spiritual generations", "générations spirituelles"],
|
||||
["abide in Jesus", "demeurez en Jésus"],
|
||||
["pray without ceasing", "priez sans cesse"],
|
||||
["deny yourself", "renoncez à vous-même"],
|
||||
["engage the regions beyond", "portez l'Évangile au-delà"],
|
||||
["Pentecostal", "pentecôtiste"],
|
||||
["Statement of Faith", "Déclaration de foi"],
|
||||
["new birth", "nouvelle naissance"],
|
||||
["regeneration", "régénération"],
|
||||
["justification", "justification"],
|
||||
["atonement", "expiation"],
|
||||
["sanctification", "sanctification"],
|
||||
["baptism in water", "baptême d'eau"],
|
||||
["Lord's Supper", "Sainte Cène"],
|
||||
["baptism in the Holy Spirit", "baptême du Saint-Esprit"],
|
||||
["speaking in tongues", "parler en langues"],
|
||||
["gifts of the Holy Spirit", "dons du Saint-Esprit"],
|
||||
["pre-millennial return", "retour prémillénaire"],
|
||||
["bodily resurrection", "résurrection corporelle"],
|
||||
["pray", "prier"],
|
||||
["engage", "engager"],
|
||||
["World Assemblies of God Fellowship", "Fraternité Mondiale des Assemblées de Dieu"],
|
||||
["choose a people group", "choisir un peuple"],
|
||||
["sign up", "s'inscrire"]
|
||||
],
|
||||
hi: [
|
||||
["people group", "जातीय समूह"],
|
||||
["people groups", "जातीय समूह"],
|
||||
["unreached people group", "अगम्य जातीय समूह"],
|
||||
["unreached people groups", "अगम्य जातीय समूह"],
|
||||
["unengaged people group", "अप्रवेशित जातीय समूह"],
|
||||
["unengaged people groups", "अप्रवेशित जातीय समूह"],
|
||||
["unengaged unreached people group", "अगम्य और अप्रवेशित जातीय समूह"],
|
||||
["under-engaged", "अल्प-प्रवेशित"],
|
||||
["frontier people group", "सीमांत जातीय समूह"],
|
||||
["frontier people groups", "सीमांत जातीय समूह"],
|
||||
["ethnolinguistic group", "भाषाई-जातीय समूह"],
|
||||
["unreached", "अगम्य"],
|
||||
["unengaged", "अप्रवेशित"],
|
||||
["engaged", "प्रवेशित"],
|
||||
["engagement", "प्रवेश"],
|
||||
["fruitful engagement", "फलदायक प्रवेश"],
|
||||
["gospel access", "सुसमाचार तक पहुँच"],
|
||||
["gospel engagement", "सुसमाचार प्रवेश"],
|
||||
["the gospel", "सुसमाचार"],
|
||||
["church-planting movement", "कलीसिया रोपण आंदोलन"],
|
||||
["church planting", "कलीसिया रोपण"],
|
||||
["indigenous church", "देशज कलीसिया"],
|
||||
["indigenous churches", "देशज कलीसियाएँ"],
|
||||
["self-propagating", "स्व-प्रचारक"],
|
||||
["self-governing", "स्व-शासित"],
|
||||
["self-supporting", "स्व-पोषित"],
|
||||
["self-theologizing", "स्व-धर्मशास्त्रीय"],
|
||||
["self-missionizing", "स्व-मिशनकारी"],
|
||||
["residential engagement", "आवासीय प्रवेश"],
|
||||
["workers in residence", "निवासी कार्यकर्ता"],
|
||||
["cross-cultural workers", "अंतर-सांस्कृतिक कार्यकर्ता"],
|
||||
["apostolic effort", "प्रेरितिक प्रयास"],
|
||||
["pioneer work", "अग्रणी कार्य"],
|
||||
["heart language", "मातृभाषा"],
|
||||
["movement to Jesus", "यीशु की ओर आंदोलन"],
|
||||
["nonresident partners", "अनिवासी सहभागी"],
|
||||
["broader engagement", "व्यापक प्रवेश"],
|
||||
["diaspora", "प्रवासी समुदाय"],
|
||||
["daily prayer", "दैनिक प्रार्थना"],
|
||||
["24-hour prayer coverage", "24 घंटे की प्रार्थना कवरेज"],
|
||||
["intercessor", "मध्यस्थ प्रार्थनाकर्ता"],
|
||||
["intercessors", "मध्यस्थ प्रार्थनाकर्ता"],
|
||||
["intercessory prayer", "मध्यस्थ प्रार्थना"],
|
||||
["prayer points", "प्रार्थना विषय"],
|
||||
["daily prayer guide", "दैनिक प्रार्थना मार्गदर्शिका"],
|
||||
["prayer prepares the way", "प्रार्थना मार्ग तैयार करती है"],
|
||||
["Lord of the harvest", "कटनी का स्वामी"],
|
||||
["adopt", "अपनाना"],
|
||||
["pray, give, and send", "प्रार्थना करो, दो और भेजो"],
|
||||
["mobilize", "गतिशील करना"],
|
||||
["mobilization", "गतिशीलता"],
|
||||
["sending agency", "भेजने वाली संस्था"],
|
||||
["sending agencies", "भेजने वाली संस्थाएँ"],
|
||||
["our gift to Jesus", "यीशु को हमारी भेंट"],
|
||||
["DOXA partnership missionaries", "DOXA साझेदारी के मिशनरी"],
|
||||
["every tribe, tongue, people, and nation", "हर एक कुल, भाषा, लोग और जाति"],
|
||||
["make disciples of all the nations", "सब जातियों को चेला बनाओ"],
|
||||
["disciple", "चेला"],
|
||||
["disciples", "चेले"],
|
||||
["baptized disciples", "बपतिस्मा प्राप्त चेले"],
|
||||
["culturally appropriate", "सांस्कृतिक रूप से उपयुक्त"],
|
||||
["self-sustaining churches", "स्वावलंबी कलीसियाएँ"],
|
||||
["spiritual generations", "आत्मिक पीढ़ियाँ"],
|
||||
["abide in Jesus", "यीशु में बने रहो"],
|
||||
["pray without ceasing", "निरन्तर प्रार्थना करो"],
|
||||
["deny yourself", "अपने आप का इन्कार करो"],
|
||||
["engage the regions beyond", "परे के क्षेत्रों में सुसमाचार ले जाओ"],
|
||||
["Pentecostal", "पेन्तेकोस्तल"],
|
||||
["Statement of Faith", "विश्वास का वक्तव्य"],
|
||||
["new birth", "नया जन्म"],
|
||||
["regeneration", "नवीनीकरण"],
|
||||
["justification", "धर्मीकरण"],
|
||||
["atonement", "प्रायश्चित्त"],
|
||||
["sanctification", "पवित्रीकरण"],
|
||||
["baptism in water", "जल बपतिस्मा"],
|
||||
["Lord's Supper", "प्रभु भोज"],
|
||||
["baptism in the Holy Spirit", "पवित्र आत्मा का बपतिस्मा"],
|
||||
["speaking in tongues", "अन्य भाषाओं में बोलना"],
|
||||
["gifts of the Holy Spirit", "पवित्र आत्मा के वरदान"],
|
||||
["pre-millennial return", "सहस्राब्दी-पूर्व पुनरागमन"],
|
||||
["bodily resurrection", "शारीरिक पुनरुत्थान"],
|
||||
["pray", "प्रार्थना करना"],
|
||||
["engage", "प्रवेश करना"],
|
||||
["choose a people group", "एक जातीय समूह चुनना"],
|
||||
["sign up", "पंजीकरण करना"]
|
||||
],
|
||||
it: [
|
||||
["people group", "gruppo etnico"],
|
||||
["people groups", "gruppi etnici"],
|
||||
["unreached people group", "gruppo etnico non raggiunto"],
|
||||
["unreached people groups", "gruppi etnici non raggiunti"],
|
||||
["unengaged people group", "gruppo etnico non coinvolto"],
|
||||
["unengaged people groups", "gruppi etnici non coinvolti"],
|
||||
["unengaged unreached people group", "gruppo etnico non raggiunto e non coinvolto"],
|
||||
["under-engaged", "sottocoinvolto"],
|
||||
["frontier people group", "gruppo etnico di frontiera"],
|
||||
["frontier people groups", "gruppi etnici di frontiera"],
|
||||
["ethnolinguistic group", "gruppo etnolinguistico"],
|
||||
["unreached", "non raggiunto"],
|
||||
["unengaged", "non coinvolto"],
|
||||
["engaged", "coinvolto"],
|
||||
["engagement", "coinvolgimento"],
|
||||
["fruitful engagement", "coinvolgimento fruttuoso"],
|
||||
["gospel access", "accesso al Vangelo"],
|
||||
["gospel engagement", "coinvolgimento per il Vangelo"],
|
||||
["the gospel", "il Vangelo"],
|
||||
["church-planting movement", "movimento di fondazione di chiese"],
|
||||
["church planting", "fondazione di chiese"],
|
||||
["indigenous church", "chiesa autoctona"],
|
||||
["indigenous churches", "chiese autoctone"],
|
||||
["self-propagating", "autopropagatrice"],
|
||||
["self-governing", "autogovernata"],
|
||||
["self-supporting", "autofinanziata"],
|
||||
["self-theologizing", "autoteologizzante"],
|
||||
["self-missionizing", "automissionaria"],
|
||||
["residential engagement", "coinvolgimento residenziale"],
|
||||
["workers in residence", "operatori residenti"],
|
||||
["cross-cultural workers", "operatori interculturali"],
|
||||
["apostolic effort", "impegno apostolico"],
|
||||
["pioneer work", "lavoro pionieristico"],
|
||||
["heart language", "lingua madre"],
|
||||
["movement to Jesus", "movimento verso Gesù"],
|
||||
["nonresident partners", "partner non residenti"],
|
||||
["broader engagement", "coinvolgimento più ampio"],
|
||||
["diaspora", "diaspora"],
|
||||
["daily prayer", "preghiera quotidiana"],
|
||||
["24-hour prayer coverage", "copertura di preghiera di 24 ore"],
|
||||
["intercessor", "intercessore"],
|
||||
["intercessors", "intercessori"],
|
||||
["intercessory prayer", "preghiera di intercessione"],
|
||||
["prayer points", "spunti di preghiera"],
|
||||
["daily prayer guide", "guida di preghiera quotidiana"],
|
||||
["prayer prepares the way", "la preghiera prepara la via"],
|
||||
["Lord of the harvest", "Signore della messe"],
|
||||
["adopt", "adottare"],
|
||||
["pray, give, and send", "pregare, dare e inviare"],
|
||||
["mobilize", "mobilitare"],
|
||||
["mobilization", "mobilitazione"],
|
||||
["sending agency", "agenzia di invio"],
|
||||
["sending agencies", "agenzie di invio"],
|
||||
["our gift to Jesus", "la nostra offerta a Gesù"],
|
||||
["DOXA partnership missionaries", "missionari partner di DOXA"],
|
||||
["every tribe, tongue, people, and nation", "ogni tribù, lingua, popolo e nazione"],
|
||||
["make disciples of all the nations", "fate discepoli di tutti i popoli"],
|
||||
["disciple", "discepolo"],
|
||||
["disciples", "discepoli"],
|
||||
["baptized disciples", "discepoli battezzati"],
|
||||
["culturally appropriate", "culturalmente adeguato"],
|
||||
["self-sustaining churches", "chiese autonome"],
|
||||
["spiritual generations", "generazioni spirituali"],
|
||||
["abide in Jesus", "dimorate in Gesù"],
|
||||
["pray without ceasing", "pregate senza cessare"],
|
||||
["deny yourself", "rinnegate voi stessi"],
|
||||
["engage the regions beyond", "portate il Vangelo oltre"],
|
||||
["Pentecostal", "pentecostale"],
|
||||
["Statement of Faith", "Dichiarazione di fede"],
|
||||
["new birth", "nuova nascita"],
|
||||
["regeneration", "rigenerazione"],
|
||||
["justification", "giustificazione"],
|
||||
["atonement", "espiazione"],
|
||||
["sanctification", "santificazione"],
|
||||
["baptism in water", "battesimo in acqua"],
|
||||
["Lord's Supper", "Santa Cena"],
|
||||
["baptism in the Holy Spirit", "battesimo nello Spirito Santo"],
|
||||
["speaking in tongues", "parlare in lingue"],
|
||||
["gifts of the Holy Spirit", "doni dello Spirito Santo"],
|
||||
["pre-millennial return", "ritorno premillenario"],
|
||||
["bodily resurrection", "risurrezione corporea"],
|
||||
["pray", "pregare"],
|
||||
["engage", "coinvolgere"],
|
||||
["choose a people group", "scegliere un gruppo etnico"],
|
||||
["sign up", "iscriversi"]
|
||||
],
|
||||
pt: [
|
||||
["people group", "grupo étnico"],
|
||||
["people groups", "grupos étnicos"],
|
||||
["unreached people group", "grupo étnico não alcançado"],
|
||||
["unreached people groups", "grupos étnicos não alcançados"],
|
||||
["unengaged people group", "grupo étnico não engajado"],
|
||||
["unengaged people groups", "grupos étnicos não engajados"],
|
||||
["unengaged unreached people group", "grupo étnico não alcançado e não engajado (PNANE)"],
|
||||
["under-engaged", "sub-engajado"],
|
||||
["frontier people group", "povo de fronteira"],
|
||||
["frontier people groups", "povos de fronteira"],
|
||||
["ethnolinguistic group", "grupo etnolinguístico"],
|
||||
["unreached", "não alcançado"],
|
||||
["unengaged", "não engajado"],
|
||||
["engaged", "engajado"],
|
||||
["engagement", "engajamento"],
|
||||
["fruitful engagement", "engajamento frutífero"],
|
||||
["gospel access", "acesso ao evangelho"],
|
||||
["gospel engagement", "engajamento do evangelho"],
|
||||
["the gospel", "o evangelho"],
|
||||
["church-planting movement", "movimento de plantação de igrejas (MPI)"],
|
||||
["church planting", "plantação de igrejas"],
|
||||
["indigenous church", "igreja autóctone"],
|
||||
["indigenous churches", "igrejas autóctones"],
|
||||
["self-propagating", "autopropagador"],
|
||||
["self-governing", "autogovernado"],
|
||||
["self-supporting", "autossustentado"],
|
||||
["self-theologizing", "autoteologizante"],
|
||||
["self-missionizing", "automissionário"],
|
||||
["residential engagement", "engajamento residencial"],
|
||||
["workers in residence", "obreiros residentes"],
|
||||
["cross-cultural workers", "obreiros transculturais"],
|
||||
["apostolic effort", "esforço apostólico"],
|
||||
["pioneer work", "trabalho pioneiro"],
|
||||
["heart language", "língua do coração"],
|
||||
["movement to Jesus", "movimento em direção a Jesus"],
|
||||
["nonresident partners", "parceiros não residentes"],
|
||||
["broader engagement", "engajamento mais amplo"],
|
||||
["diaspora", "diáspora"],
|
||||
["daily prayer", "oração diária"],
|
||||
["24-hour prayer coverage", "cobertura de oração de 24 horas"],
|
||||
["intercessor", "intercessor"],
|
||||
["intercessors", "intercessores"],
|
||||
["intercessory prayer", "oração intercessória"],
|
||||
["prayer points", "pontos de oração"],
|
||||
["daily prayer guide", "guia de oração diário"],
|
||||
["prayer prepares the way", "a oração prepara o caminho"],
|
||||
["Lord of the harvest", "Senhor da seara"],
|
||||
["adopt", "adotar"],
|
||||
["pray, give, and send", "orar, doar e enviar"],
|
||||
["mobilize", "mobilizar"],
|
||||
["mobilization", "mobilização"],
|
||||
["sending agency", "secretaria de missões"],
|
||||
["sending agencies", "secretarias de missões"],
|
||||
["our gift to Jesus", "nossa oferta a Jesus"],
|
||||
["DOXA partnership missionaries", "missionários parceiros de DOXA"],
|
||||
["every tribe, tongue, people, and nation", "todas as tribos, línguas, povos e nações"],
|
||||
["make disciples of all the nations", "fazer discípulos de todas as nações"],
|
||||
["disciple", "discípulo"],
|
||||
["disciples", "discípulos"],
|
||||
["baptized disciples", "discípulos batizados"],
|
||||
["culturally appropriate", "culturalmente apropriado"],
|
||||
["self-sustaining churches", "igrejas autossustentáveis"],
|
||||
["spiritual generations", "gerações espirituais"],
|
||||
["abide in Jesus", "permanecer em Jesus"],
|
||||
["pray without ceasing", "orar sem cessar"],
|
||||
["deny yourself", "renunciar a si mesmo"],
|
||||
["engage the regions beyond", "engajar as regiões além"],
|
||||
["Pentecostal", "pentecostal"],
|
||||
["Statement of Faith", "Declaração de fé"],
|
||||
["new birth", "novo nascimento"],
|
||||
["regeneration", "regeneração"],
|
||||
["justification", "justificação"],
|
||||
["atonement", "expiação"],
|
||||
["sanctification", "santificação"],
|
||||
["baptism in water", "batismo nas águas"],
|
||||
["Lord's Supper", "Santa Ceia"],
|
||||
["baptism in the Holy Spirit", "batismo no Espírito Santo"],
|
||||
["speaking in tongues", "falar em línguas"],
|
||||
["gifts of the Holy Spirit", "dons do Espírito Santo"],
|
||||
["pre-millennial return", "retorno pré-milenial"],
|
||||
["bodily resurrection", "ressurreição corporal"],
|
||||
["pray", "orar"],
|
||||
["engage", "engajar"],
|
||||
["UUPG", "PNANE"],
|
||||
["UPG", "PNA"],
|
||||
["World Assemblies of God Fellowship", "Comunhão das Assembléias de Deus Mundial"],
|
||||
["champion", "defensor"],
|
||||
["champions", "defensores"],
|
||||
["choose a people group", "escolher um grupo étnico"],
|
||||
["sign up", "inscrever-se"]
|
||||
],
|
||||
ro: [
|
||||
["people group", "grup etnic"],
|
||||
["people groups", "grupuri etnice"],
|
||||
["unreached people group", "grup etnic neatins"],
|
||||
["unreached people groups", "grupuri etnice neatinse"],
|
||||
["unengaged people group", "grup etnic neangajat"],
|
||||
["unengaged people groups", "grupuri etnice neangajate"],
|
||||
["unengaged unreached people group", "grup etnic neatins și neangajat"],
|
||||
["under-engaged", "insuficient angajat"],
|
||||
["frontier people group", "grup etnic de frontieră"],
|
||||
["frontier people groups", "grupuri etnice de frontieră"],
|
||||
["ethnolinguistic group", "grup etnolingvistic"],
|
||||
["unreached", "neatins"],
|
||||
["unengaged", "neangajat"],
|
||||
["engaged", "angajat"],
|
||||
["engagement", "angajare"],
|
||||
["fruitful engagement", "angajare rodnică"],
|
||||
["gospel access", "acces la Evanghelie"],
|
||||
["gospel engagement", "angajare pentru Evanghelie"],
|
||||
["the gospel", "Evanghelia"],
|
||||
["church-planting movement", "mișcare de plantare de biserici"],
|
||||
["church planting", "plantare de biserici"],
|
||||
["indigenous church", "biserică autohtonă"],
|
||||
["indigenous churches", "biserici autohtone"],
|
||||
["self-propagating", "autopropagator"],
|
||||
["self-governing", "autoguvernat"],
|
||||
["self-supporting", "autofinanțat"],
|
||||
["self-theologizing", "autoteologizant"],
|
||||
["self-missionizing", "automisionar"],
|
||||
["residential engagement", "angajare rezidențială"],
|
||||
["workers in residence", "lucrători rezidenți"],
|
||||
["cross-cultural workers", "lucrători interculturali"],
|
||||
["apostolic effort", "efort apostolic"],
|
||||
["pioneer work", "lucrare pionieră"],
|
||||
["heart language", "limba maternă"],
|
||||
["movement to Jesus", "mișcare spre Isus"],
|
||||
["nonresident partners", "parteneri nerezidenți"],
|
||||
["broader engagement", "angajare extinsă"],
|
||||
["diaspora", "diaspora"],
|
||||
["daily prayer", "rugăciune zilnică"],
|
||||
["24-hour prayer coverage", "acoperire de rugăciune de 24 de ore"],
|
||||
["intercessor", "mijlocitor"],
|
||||
["intercessors", "mijlocitori"],
|
||||
["intercessory prayer", "rugăciune de mijlocire"],
|
||||
["prayer points", "subiecte de rugăciune"],
|
||||
["daily prayer guide", "ghid zilnic de rugăciune"],
|
||||
["prayer prepares the way", "rugăciunea pregătește calea"],
|
||||
["Lord of the harvest", "Stăpânul secerișului"],
|
||||
["adopt", "a adopta"],
|
||||
["pray, give, and send", "rugați-vă, dăruiți și trimiteți"],
|
||||
["mobilize", "a mobiliza"],
|
||||
["mobilization", "mobilizare"],
|
||||
["sending agency", "agenție de trimitere"],
|
||||
["sending agencies", "agenții de trimitere"],
|
||||
["our gift to Jesus", "darul nostru pentru Isus"],
|
||||
["DOXA partnership missionaries", "misionari parteneri DOXA"],
|
||||
["every tribe, tongue, people, and nation", "orice seminție, orice limbă, orice popor și orice națiune"],
|
||||
["make disciples of all the nations", "faceți ucenici din toate neamurile"],
|
||||
["disciple", "ucenic"],
|
||||
["disciples", "ucenici"],
|
||||
["baptized disciples", "ucenici botezați"],
|
||||
["culturally appropriate", "adaptat cultural"],
|
||||
["self-sustaining churches", "biserici autonome"],
|
||||
["spiritual generations", "generații spirituale"],
|
||||
["abide in Jesus", "rămâneți în Isus"],
|
||||
["pray without ceasing", "rugați-vă neîncetat"],
|
||||
["deny yourself", "lepădați-vă de voi înșivă"],
|
||||
["engage the regions beyond", "duceți Evanghelia dincolo de hotare"],
|
||||
["Pentecostal", "penticostal"],
|
||||
["Statement of Faith", "Declarație de credință"],
|
||||
["new birth", "nașterea din nou"],
|
||||
["regeneration", "regenerare"],
|
||||
["justification", "justificare"],
|
||||
["atonement", "ispășire"],
|
||||
["sanctification", "sfințire"],
|
||||
["baptism in water", "botezul în apă"],
|
||||
["Lord's Supper", "Cina Domnului"],
|
||||
["baptism in the Holy Spirit", "botezul în Duhul Sfânt"],
|
||||
["speaking in tongues", "vorbirea în limbi"],
|
||||
["gifts of the Holy Spirit", "darurile Duhului Sfânt"],
|
||||
["pre-millennial return", "revenirea premilenială"],
|
||||
["bodily resurrection", "învierea trupească"],
|
||||
["pray", "a se ruga"],
|
||||
["engage", "a angaja"],
|
||||
["choose a people group", "a alege un grup etnic"],
|
||||
["sign up", "a se înregistra"]
|
||||
],
|
||||
ru: [
|
||||
["people group", "этническая группа"],
|
||||
["people groups", "этнические группы"],
|
||||
["unreached people group", "недостигнутая этническая группа"],
|
||||
["unreached people groups", "недостигнутые этнические группы"],
|
||||
["unengaged people group", "невовлечённая этническая группа"],
|
||||
["unengaged people groups", "невовлечённые этнические группы"],
|
||||
["unengaged unreached people group", "недостигнутая и невовлечённая этническая группа"],
|
||||
["under-engaged", "недостаточно вовлечённая"],
|
||||
["frontier people group", "этническая группа на передовой"],
|
||||
["frontier people groups", "этнические группы на передовой"],
|
||||
["ethnolinguistic group", "этнолингвистическая группа"],
|
||||
["unreached", "недостигнутый"],
|
||||
["unengaged", "невовлечённый"],
|
||||
["engaged", "вовлечённый"],
|
||||
["engagement", "вовлечение"],
|
||||
["fruitful engagement", "плодотворное вовлечение"],
|
||||
["gospel access", "доступ к Евангелию"],
|
||||
["gospel engagement", "евангельское вовлечение"],
|
||||
["the gospel", "Евангелие"],
|
||||
["church-planting movement", "движение насаждения церквей"],
|
||||
["church planting", "насаждение церквей"],
|
||||
["indigenous church", "местная церковь"],
|
||||
["indigenous churches", "местные церкви"],
|
||||
["self-propagating", "самовоспроизводящийся"],
|
||||
["self-governing", "самоуправляемый"],
|
||||
["self-supporting", "самофинансируемый"],
|
||||
["self-theologizing", "самобогословствующий"],
|
||||
["self-missionizing", "самомиссионерский"],
|
||||
["residential engagement", "вовлечение на месте"],
|
||||
["workers in residence", "резидентные работники"],
|
||||
["cross-cultural workers", "межкультурные работники"],
|
||||
["apostolic effort", "апостольское служение"],
|
||||
["pioneer work", "пионерское служение"],
|
||||
["heart language", "родной язык"],
|
||||
["movement to Jesus", "движение к Иисусу"],
|
||||
["nonresident partners", "нерезидентные партнёры"],
|
||||
["broader engagement", "расширенное вовлечение"],
|
||||
["diaspora", "диаспора"],
|
||||
["daily prayer", "ежедневная молитва"],
|
||||
["24-hour prayer coverage", "круглосуточное молитвенное покрытие"],
|
||||
["intercessor", "ходатай"],
|
||||
["intercessors", "ходатаи"],
|
||||
["intercessory prayer", "ходатайственная молитва"],
|
||||
["prayer points", "молитвенные нужды"],
|
||||
["daily prayer guide", "ежедневный молитвенный путеводитель"],
|
||||
["prayer prepares the way", "молитва готовит путь"],
|
||||
["Lord of the harvest", "Господин жатвы"],
|
||||
["adopt", "взять попечение"],
|
||||
["pray, give, and send", "молитесь, жертвуйте и посылайте"],
|
||||
["mobilize", "мобилизовать"],
|
||||
["mobilization", "мобилизация"],
|
||||
["sending agency", "посылающая организация"],
|
||||
["sending agencies", "посылающие организации"],
|
||||
["our gift to Jesus", "наш дар Иисусу"],
|
||||
["DOXA partnership missionaries", "миссионеры-партнёры DOXA"],
|
||||
["every tribe, tongue, people, and nation", "всякое колено, и язык, и народ, и племя"],
|
||||
["make disciples of all the nations", "научите все народы"],
|
||||
["disciple", "ученик"],
|
||||
["disciples", "ученики"],
|
||||
["baptized disciples", "крещёные ученики"],
|
||||
["culturally appropriate", "культурно адаптированный"],
|
||||
["self-sustaining churches", "самостоятельные церкви"],
|
||||
["spiritual generations", "духовные поколения"],
|
||||
["abide in Jesus", "пребывайте в Иисусе"],
|
||||
["pray without ceasing", "непрестанно молитесь"],
|
||||
["deny yourself", "отвергните себя"],
|
||||
["engage the regions beyond", "несите Евангелие за пределы"],
|
||||
["Pentecostal", "пятидесятнический"],
|
||||
["Statement of Faith", "Исповедание веры"],
|
||||
["new birth", "рождение свыше"],
|
||||
["regeneration", "возрождение"],
|
||||
["justification", "оправдание"],
|
||||
["atonement", "искупление"],
|
||||
["sanctification", "освящение"],
|
||||
["baptism in water", "водное крещение"],
|
||||
["Lord's Supper", "Вечеря Господня"],
|
||||
["baptism in the Holy Spirit", "крещение Духом Святым"],
|
||||
["speaking in tongues", "говорение на иных языках"],
|
||||
["gifts of the Holy Spirit", "дары Святого Духа"],
|
||||
["pre-millennial return", "домилленниальное возвращение"],
|
||||
["bodily resurrection", "телесное воскресение"],
|
||||
["pray", "молиться"],
|
||||
["engage", "вовлекать"],
|
||||
["choose a people group", "выбрать этническую группу"],
|
||||
["sign up", "зарегистрироваться"]
|
||||
],
|
||||
zh: [
|
||||
["people group", "族群"],
|
||||
["people groups", "族群"],
|
||||
["unreached people group", "未得之民"],
|
||||
["unreached people groups", "未得之民"],
|
||||
["unengaged people group", "未接触族群"],
|
||||
["unengaged people groups", "未接触族群"],
|
||||
["unengaged unreached people group", "未接触未得之民"],
|
||||
["under-engaged", "接触不足的"],
|
||||
["frontier people group", "前沿族群"],
|
||||
["frontier people groups", "前沿族群"],
|
||||
["ethnolinguistic group", "民族语言群体"],
|
||||
["unreached", "未得的"],
|
||||
["unengaged", "未接触的"],
|
||||
["engaged", "已接触的"],
|
||||
["engagement", "接触"],
|
||||
["fruitful engagement", "有果效的接触"],
|
||||
["gospel access", "福音可及性"],
|
||||
["gospel engagement", "福音接触"],
|
||||
["the gospel", "福音"],
|
||||
["church-planting movement", "植堂运动"],
|
||||
["church planting", "植堂"],
|
||||
["indigenous church", "本土教会"],
|
||||
["indigenous churches", "本土教会"],
|
||||
["self-propagating", "自传的"],
|
||||
["self-governing", "自治的"],
|
||||
["self-supporting", "自养的"],
|
||||
["self-theologizing", "自我神学建构的"],
|
||||
["self-missionizing", "自我差传的"],
|
||||
["residential engagement", "驻地接触"],
|
||||
["workers in residence", "驻地工人"],
|
||||
["cross-cultural workers", "跨文化工人"],
|
||||
["apostolic effort", "使徒性开拓"],
|
||||
["pioneer work", "先锋事工"],
|
||||
["heart language", "母语"],
|
||||
["movement to Jesus", "归主运动"],
|
||||
["nonresident partners", "非驻地伙伴"],
|
||||
["broader engagement", "广义接触"],
|
||||
["diaspora", "散居群体"],
|
||||
["daily prayer", "每日祷告"],
|
||||
["24-hour prayer coverage", "全天候祷告覆盖"],
|
||||
["intercessor", "代祷者"],
|
||||
["intercessors", "代祷者"],
|
||||
["intercessory prayer", "代祷"],
|
||||
["prayer points", "祷告事项"],
|
||||
["daily prayer guide", "每日祷告指南"],
|
||||
["prayer prepares the way", "祷告预备道路"],
|
||||
["Lord of the harvest", "庄稼的主"],
|
||||
["adopt", "认领"],
|
||||
["pray, give, and send", "祷告、奉献、差派"],
|
||||
["mobilize", "动员"],
|
||||
["mobilization", "动员"],
|
||||
["sending agency", "差传机构"],
|
||||
["sending agencies", "差传机构"],
|
||||
["our gift to Jesus", "我们献给耶稣的礼物"],
|
||||
["DOXA partnership missionaries", "DOXA伙伴宣教士"],
|
||||
["every tribe, tongue, people, and nation", "各族、各方、各民、各国"],
|
||||
["make disciples of all the nations", "使万民作主的门徒"],
|
||||
["disciple", "门徒"],
|
||||
["disciples", "门徒"],
|
||||
["baptized disciples", "受洗门徒"],
|
||||
["culturally appropriate", "合乎文化的"],
|
||||
["self-sustaining churches", "自立教会"],
|
||||
["spiritual generations", "属灵世代"],
|
||||
["abide in Jesus", "常在主里面"],
|
||||
["pray without ceasing", "不住地祷告"],
|
||||
["deny yourself", "舍己"],
|
||||
["engage the regions beyond", "进入未及之地"],
|
||||
["Pentecostal", "五旬节派"],
|
||||
["Statement of Faith", "信仰宣言"],
|
||||
["new birth", "重生"],
|
||||
["regeneration", "更新"],
|
||||
["justification", "称义"],
|
||||
["atonement", "赎罪"],
|
||||
["sanctification", "成圣"],
|
||||
["baptism in water", "水的洗礼"],
|
||||
["Lord's Supper", "圣餐"],
|
||||
["baptism in the Holy Spirit", "圣灵的洗"],
|
||||
["speaking in tongues", "说方言"],
|
||||
["gifts of the Holy Spirit", "圣灵的恩赐"],
|
||||
["pre-millennial return", "千禧年前再来"],
|
||||
["bodily resurrection", "身体复活"],
|
||||
["pray", "祷告"],
|
||||
["engage", "接触"],
|
||||
["choose a people group", "选择一个族群"],
|
||||
["sign up", "注册"]
|
||||
]
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/**
|
||||
* Generates config/glossaries.ts from the translation repo's glossary TSVs
|
||||
* (../translation/deepl-glossaries/*.tsv). The generated module is committed
|
||||
* so production builds don't need the translation repo checked out.
|
||||
*
|
||||
* Run after updating the TSVs: bun scripts/build-glossaries.ts
|
||||
*/
|
||||
import { readdirSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
|
||||
const sourceDir = join(import.meta.dir, '../../translation/deepl-glossaries')
|
||||
const outFile = join(import.meta.dir, '../config/glossaries.ts')
|
||||
|
||||
const glossaries: Record<string, Array<[string, string]>> = {}
|
||||
|
||||
for (const file of readdirSync(sourceDir).sort()) {
|
||||
if (!file.endsWith('.tsv')) continue
|
||||
const code = file.replace(/\.tsv$/, '')
|
||||
const pairs: Array<[string, string]> = []
|
||||
for (const line of readFileSync(join(sourceDir, file), 'utf8').split('\n')) {
|
||||
const trimmed = line.trim()
|
||||
if (!trimmed) continue
|
||||
const [source, target] = trimmed.split('\t')
|
||||
if (source && target) pairs.push([source.trim(), target.trim()])
|
||||
}
|
||||
glossaries[code] = pairs
|
||||
}
|
||||
|
||||
const entries = Object.entries(glossaries)
|
||||
.map(([code, pairs]) => {
|
||||
const rows = pairs.map(([s, t]) => ` [${JSON.stringify(s)}, ${JSON.stringify(t)}]`).join(',\n')
|
||||
return ` ${code}: [\n${rows}\n ]`
|
||||
})
|
||||
.join(',\n')
|
||||
|
||||
const output = `// Generated by scripts/build-glossaries.ts from ../translation/deepl-glossaries/*.tsv
|
||||
// Do not edit by hand — update the TSVs in the translation repo and re-run:
|
||||
// bun scripts/build-glossaries.ts
|
||||
|
||||
/** English → target-language term pairs, keyed by language code. */
|
||||
export const GLOSSARIES: Record<string, ReadonlyArray<readonly [string, string]>> = {
|
||||
${entries}
|
||||
}
|
||||
`
|
||||
|
||||
writeFileSync(outFile, output)
|
||||
console.log(`Wrote ${Object.keys(glossaries).length} glossaries (${Object.values(glossaries).reduce((n, p) => n + p.length, 0)} terms) to config/glossaries.ts`)
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// LLM text-translation tool. Generic primitive — Claude composes
|
||||
// with upsert_page_translation when applying translations to pages.
|
||||
//
|
||||
// The vendored glossary for each target locale is always injected into
|
||||
// The approved terminology for each target locale is always injected into
|
||||
// the translation prompt, keeping MCP-driven translations terminologically
|
||||
// consistent with admin auto-translates.
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ Inputs:
|
|||
- \`source_locale\`: defaults to "en"; must be one of the site's enabled locales.
|
||||
- \`target_locales\`: array of locale codes to translate into; each must be enabled and different from the source.
|
||||
|
||||
Output: \`translations: [{locale, text, glossary_used}]\`. \`glossary_used\` is true when a per-locale terminology glossary was applied (consistent with admin auto-translate behavior). After this returns, embed each translated text into the corresponding locale's page via upsert_page_translation.
|
||||
Output: \`translations: [{locale, text, glossary_used}]\`. \`glossary_used\` is true when the locale's approved DOXA terminology was applied (consistent with admin auto-translate behavior); it is false for a locale whose glossary has not been started yet. After this returns, embed each translated text into the corresponding locale's page via upsert_page_translation.
|
||||
|
||||
Limits: 100 KB per call. For longer content, split into sections and translate each separately.`
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
// LLM text-translation service — the canonical primitive both the
|
||||
// MCP translate_text tool and the admin batch-translate flow share.
|
||||
//
|
||||
// The per-locale glossary vendored in config/glossaries.ts is injected
|
||||
// into every translation prompt, so the terminology stays consistent
|
||||
// with admin auto-translates and with the translation/ glossaries repo.
|
||||
// Every translation prompt carries the target locale's approved terminology,
|
||||
// read at runtime from the glossary published by pray.doxa.life, so the
|
||||
// wording here matches the prayer site and the mobile app.
|
||||
|
||||
import type { H3Error } from 'h3'
|
||||
import { translateTexts, translateTiptapContent, isTranslationConfigured } from '../utils/translate'
|
||||
import { OpenRouterError, hasGlossary } from '../utils/openrouter'
|
||||
import { OpenRouterError } from '../utils/openrouter'
|
||||
import { hasGlossary } from '../utils/glossary'
|
||||
import { ENABLED_LANGUAGE_CODES } from '~~/config/languages'
|
||||
import { db } from '../utils/database'
|
||||
import {
|
||||
|
|
@ -84,7 +85,7 @@ export async function translateText(input: TranslateTextInput): Promise<Translat
|
|||
return {
|
||||
locale,
|
||||
text: out[0] ?? '',
|
||||
glossary_used: hasGlossary(locale)
|
||||
glossary_used: await hasGlossary(locale)
|
||||
}
|
||||
})
|
||||
)
|
||||
|
|
|
|||
115
server/utils/glossary.ts
Normal file
115
server/utils/glossary.ts
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
* The approved DOXA terminology, read from pray.doxa.life.
|
||||
*
|
||||
* The glossary is maintained in the campaigns server's admin, where reviewers
|
||||
* confirm each term through a magic link, and published at
|
||||
* `GET /api/glossary/{lang}`. This site reads it at runtime rather than
|
||||
* vendoring a copy, so a reviewer's correction reaches the next translation
|
||||
* without a deploy here.
|
||||
*
|
||||
* Nothing in this module throws: a translation with no glossary is worse than
|
||||
* one with it, but far better than a failed request, so a fetch that fails
|
||||
* serves the last good answer and otherwise an empty one.
|
||||
*/
|
||||
|
||||
export interface GlossaryPair {
|
||||
term: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface Glossary {
|
||||
pairs: GlossaryPair[]
|
||||
/** The language's rules: register, acronym policy, numerals, script and names. */
|
||||
notes: string
|
||||
}
|
||||
|
||||
const EMPTY: Glossary = { pairs: [], notes: '' }
|
||||
|
||||
/** How long a language's glossary is reused before it is fetched again. */
|
||||
const CACHE_MS = 10 * 60 * 1000
|
||||
|
||||
/**
|
||||
* How long a failure or a language with no glossary is remembered. Short
|
||||
* enough that starting a language upstream shows up here the same morning,
|
||||
* long enough that a locale nobody has a glossary for is not refetched on
|
||||
* every fragment of a page translation.
|
||||
*/
|
||||
const MISS_CACHE_MS = 60 * 1000
|
||||
|
||||
interface CacheEntry {
|
||||
glossary: Glossary
|
||||
expires: number
|
||||
}
|
||||
|
||||
const cache = new Map<string, CacheEntry>()
|
||||
|
||||
interface PublishedGlossary {
|
||||
notes?: string
|
||||
terms?: Array<{ term?: string, translation?: string }>
|
||||
}
|
||||
|
||||
/**
|
||||
* The terminology for one language. Cached in the instance; call it per request
|
||||
* rather than holding the result.
|
||||
*/
|
||||
export async function getGlossary(code: string): Promise<Glossary> {
|
||||
const cached = cache.get(code)
|
||||
if (cached && cached.expires > Date.now()) return cached.glossary
|
||||
|
||||
const base = String(useRuntimeConfig().prayBaseUrl || '').replace(/\/$/, '')
|
||||
if (!base) return cached?.glossary ?? EMPTY
|
||||
|
||||
try {
|
||||
const data = await $fetch<PublishedGlossary>(`${base}/api/glossary/${encodeURIComponent(code)}`, {
|
||||
timeout: 5000,
|
||||
retry: 1
|
||||
})
|
||||
|
||||
const pairs = (data?.terms || [])
|
||||
.filter(entry => entry?.term && entry?.translation)
|
||||
.map(entry => ({ term: String(entry.term), value: String(entry.translation) }))
|
||||
|
||||
const glossary: Glossary = { pairs, notes: String(data?.notes || '') }
|
||||
cache.set(code, { glossary, expires: Date.now() + CACHE_MS })
|
||||
return glossary
|
||||
} catch (error) {
|
||||
// A 404 is the ordinary answer for a language whose glossary has not been
|
||||
// started yet, so it is cached briefly rather than logged as a fault.
|
||||
const failure = error as { statusCode?: number, response?: { status?: number }, message?: string }
|
||||
const status = failure?.statusCode ?? failure?.response?.status
|
||||
if (status !== 404) {
|
||||
console.warn(`[Glossary] could not read the ${code} glossary from ${base}: ${failure?.message}`)
|
||||
}
|
||||
const glossary = cached?.glossary ?? EMPTY
|
||||
cache.set(code, { glossary, expires: Date.now() + MISS_CACHE_MS })
|
||||
return glossary
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether approved terminology was available to steer a translation. */
|
||||
export async function hasGlossary(code: string): Promise<boolean> {
|
||||
const glossary = await getGlossary(code)
|
||||
return glossary.pairs.length > 0
|
||||
}
|
||||
|
||||
/** Drop the cached copies so the next translation refetches. */
|
||||
export function clearGlossaryCache(code?: string): void {
|
||||
if (code) cache.delete(code)
|
||||
else cache.clear()
|
||||
}
|
||||
|
||||
/** The glossary as the two blocks a translation prompt carries. */
|
||||
export function renderGlossaryPrompt(glossary: Glossary, targetLanguage: string): string {
|
||||
const pairs = glossary.pairs.map(({ term, value }) => `${term} → ${value}`).join('\n')
|
||||
const terms = glossary.pairs.length
|
||||
? `\nGlossary — always use these translations, inflected correctly for the surrounding grammar:\n${pairs}\n`
|
||||
: ''
|
||||
|
||||
// After the terms, so a rule about register or inflection governs the bare
|
||||
// pairs above it.
|
||||
const notes = glossary.notes.trim()
|
||||
? `\nRules for ${targetLanguage}, from the reviewer who approved the glossary. Follow them everywhere they apply:\n${glossary.notes.trim()}\n`
|
||||
: ''
|
||||
|
||||
return `${terms}${notes}`
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import { getLanguage } from '~~/config/languages'
|
||||
import { GLOSSARIES } from '~~/config/glossaries'
|
||||
import { getGlossary, renderGlossaryPrompt, type Glossary } from './glossary'
|
||||
import { getSetting } from './site-settings'
|
||||
|
||||
const DEFAULT_TRANSLATION_MODEL = 'anthropic/claude-opus-5'
|
||||
|
|
@ -41,19 +41,16 @@ function promptLanguageName(code: string): string {
|
|||
return lang?.translationName || lang?.name || code
|
||||
}
|
||||
|
||||
/** Whether a curated terminology glossary is injected for this language. */
|
||||
export function hasGlossary(code: string): boolean {
|
||||
return Boolean(GLOSSARIES[code]?.length)
|
||||
}
|
||||
|
||||
function buildSystemPrompt(targetLanguage: string, sourceLanguage: string, fragmentCount: number): string {
|
||||
function buildSystemPrompt(
|
||||
targetLanguage: string,
|
||||
sourceLanguage: string,
|
||||
fragmentCount: number,
|
||||
glossary: Glossary
|
||||
): string {
|
||||
const source = promptLanguageName(sourceLanguage)
|
||||
const target = promptLanguageName(targetLanguage)
|
||||
|
||||
const glossary = GLOSSARIES[targetLanguage]
|
||||
const glossaryBlock = glossary?.length
|
||||
? `\nGlossary — always use these translations, inflected correctly for the surrounding grammar:\n${glossary.map(([s, t]) => `${s} → ${t}`).join('\n')}\n`
|
||||
: ''
|
||||
const glossaryBlock = renderGlossaryPrompt(glossary, target)
|
||||
|
||||
return `You are a professional translator for DOXA, a Christian mission organization mobilizing prayer for unreached people groups. Translate marketing and informational website copy from ${source} into ${target}.
|
||||
|
||||
|
|
@ -140,11 +137,12 @@ export async function openrouterTranslateTexts(
|
|||
}
|
||||
|
||||
const model = await getTranslationModel(targetLanguage)
|
||||
const glossary = await getGlossary(targetLanguage)
|
||||
|
||||
const body = JSON.stringify({
|
||||
model,
|
||||
messages: [
|
||||
{ role: 'system', content: buildSystemPrompt(targetLanguage, sourceLanguage, texts.length) },
|
||||
{ role: 'system', content: buildSystemPrompt(targetLanguage, sourceLanguage, texts.length, glossary) },
|
||||
{ role: 'user', content: JSON.stringify({ fragments: texts }) }
|
||||
],
|
||||
response_format: { type: 'json_object' },
|
||||
|
|
|
|||
Loading…
Reference in a new issue