ai-i18n-tools 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +157 -0
  3. package/dist/api/openrouter.d.ts +115 -0
  4. package/dist/api/openrouter.d.ts.map +1 -0
  5. package/dist/api/openrouter.js +399 -0
  6. package/dist/api/openrouter.js.map +1 -0
  7. package/dist/cli/doc-translate.d.ts +90 -0
  8. package/dist/cli/doc-translate.d.ts.map +1 -0
  9. package/dist/cli/doc-translate.js +1153 -0
  10. package/dist/cli/doc-translate.js.map +1 -0
  11. package/dist/cli/export-ui-xliff.d.ts +32 -0
  12. package/dist/cli/export-ui-xliff.d.ts.map +1 -0
  13. package/dist/cli/export-ui-xliff.js +153 -0
  14. package/dist/cli/export-ui-xliff.js.map +1 -0
  15. package/dist/cli/extract-strings.d.ts +12 -0
  16. package/dist/cli/extract-strings.d.ts.map +1 -0
  17. package/dist/cli/extract-strings.js +80 -0
  18. package/dist/cli/extract-strings.js.map +1 -0
  19. package/dist/cli/file-utils.d.ts +10 -0
  20. package/dist/cli/file-utils.d.ts.map +1 -0
  21. package/dist/cli/file-utils.js +77 -0
  22. package/dist/cli/file-utils.js.map +1 -0
  23. package/dist/cli/format.d.ts +21 -0
  24. package/dist/cli/format.d.ts.map +1 -0
  25. package/dist/cli/format.js +75 -0
  26. package/dist/cli/format.js.map +1 -0
  27. package/dist/cli/helpers.d.ts +27 -0
  28. package/dist/cli/helpers.d.ts.map +1 -0
  29. package/dist/cli/helpers.js +84 -0
  30. package/dist/cli/helpers.js.map +1 -0
  31. package/dist/cli/index.d.ts +3 -0
  32. package/dist/cli/index.d.ts.map +1 -0
  33. package/dist/cli/index.js +772 -0
  34. package/dist/cli/index.js.map +1 -0
  35. package/dist/cli/log-output.d.ts +13 -0
  36. package/dist/cli/log-output.d.ts.map +1 -0
  37. package/dist/cli/log-output.js +75 -0
  38. package/dist/cli/log-output.js.map +1 -0
  39. package/dist/cli/translate-svg.d.ts +7 -0
  40. package/dist/cli/translate-svg.d.ts.map +1 -0
  41. package/dist/cli/translate-svg.js +167 -0
  42. package/dist/cli/translate-svg.js.map +1 -0
  43. package/dist/cli/translate-ui-strings.d.ts +27 -0
  44. package/dist/cli/translate-ui-strings.d.ts.map +1 -0
  45. package/dist/cli/translate-ui-strings.js +357 -0
  46. package/dist/cli/translate-ui-strings.js.map +1 -0
  47. package/dist/core/cache-tracking-keys.d.ts +12 -0
  48. package/dist/core/cache-tracking-keys.d.ts.map +1 -0
  49. package/dist/core/cache-tracking-keys.js +20 -0
  50. package/dist/core/cache-tracking-keys.js.map +1 -0
  51. package/dist/core/cache.d.ts +153 -0
  52. package/dist/core/cache.d.ts.map +1 -0
  53. package/dist/core/cache.js +546 -0
  54. package/dist/core/cache.js.map +1 -0
  55. package/dist/core/config.d.ts +58 -0
  56. package/dist/core/config.d.ts.map +1 -0
  57. package/dist/core/config.js +392 -0
  58. package/dist/core/config.js.map +1 -0
  59. package/dist/core/doc-file-tracking.d.ts +8 -0
  60. package/dist/core/doc-file-tracking.d.ts.map +1 -0
  61. package/dist/core/doc-file-tracking.js +27 -0
  62. package/dist/core/doc-file-tracking.js.map +1 -0
  63. package/dist/core/errors.d.ts +19 -0
  64. package/dist/core/errors.d.ts.map +1 -0
  65. package/dist/core/errors.js +23 -0
  66. package/dist/core/errors.js.map +1 -0
  67. package/dist/core/locale-utils.d.ts +20 -0
  68. package/dist/core/locale-utils.d.ts.map +1 -0
  69. package/dist/core/locale-utils.js +75 -0
  70. package/dist/core/locale-utils.js.map +1 -0
  71. package/dist/core/output-paths.d.ts +22 -0
  72. package/dist/core/output-paths.d.ts.map +1 -0
  73. package/dist/core/output-paths.js +130 -0
  74. package/dist/core/output-paths.js.map +1 -0
  75. package/dist/core/prompt-builder.d.ts +62 -0
  76. package/dist/core/prompt-builder.d.ts.map +1 -0
  77. package/dist/core/prompt-builder.js +232 -0
  78. package/dist/core/prompt-builder.js.map +1 -0
  79. package/dist/core/prompts.d.ts +27 -0
  80. package/dist/core/prompts.d.ts.map +1 -0
  81. package/dist/core/prompts.js +57 -0
  82. package/dist/core/prompts.js.map +1 -0
  83. package/dist/core/svg-asset-paths.d.ts +40 -0
  84. package/dist/core/svg-asset-paths.d.ts.map +1 -0
  85. package/dist/core/svg-asset-paths.js +107 -0
  86. package/dist/core/svg-asset-paths.js.map +1 -0
  87. package/dist/core/types.d.ts +388 -0
  88. package/dist/core/types.d.ts.map +1 -0
  89. package/dist/core/types.js +265 -0
  90. package/dist/core/types.js.map +1 -0
  91. package/dist/core/ui-languages.d.ts +66 -0
  92. package/dist/core/ui-languages.d.ts.map +1 -0
  93. package/dist/core/ui-languages.js +277 -0
  94. package/dist/core/ui-languages.js.map +1 -0
  95. package/dist/core/user-edited-model.d.ts +3 -0
  96. package/dist/core/user-edited-model.d.ts.map +1 -0
  97. package/dist/core/user-edited-model.js +3 -0
  98. package/dist/core/user-edited-model.js.map +1 -0
  99. package/dist/edit-cache-app/app.js +1326 -0
  100. package/dist/edit-cache-app/index.html +287 -0
  101. package/dist/edit-cache-app/styles.css +664 -0
  102. package/dist/extractors/base-extractor.d.ts +15 -0
  103. package/dist/extractors/base-extractor.d.ts.map +1 -0
  104. package/dist/extractors/base-extractor.js +23 -0
  105. package/dist/extractors/base-extractor.js.map +1 -0
  106. package/dist/extractors/classify-segment.d.ts +6 -0
  107. package/dist/extractors/classify-segment.d.ts.map +1 -0
  108. package/dist/extractors/classify-segment.js +20 -0
  109. package/dist/extractors/classify-segment.js.map +1 -0
  110. package/dist/extractors/json-extractor.d.ts +16 -0
  111. package/dist/extractors/json-extractor.d.ts.map +1 -0
  112. package/dist/extractors/json-extractor.js +128 -0
  113. package/dist/extractors/json-extractor.js.map +1 -0
  114. package/dist/extractors/markdown-extractor.d.ts +15 -0
  115. package/dist/extractors/markdown-extractor.d.ts.map +1 -0
  116. package/dist/extractors/markdown-extractor.js +205 -0
  117. package/dist/extractors/markdown-extractor.js.map +1 -0
  118. package/dist/extractors/svg-extractor.d.ts +19 -0
  119. package/dist/extractors/svg-extractor.d.ts.map +1 -0
  120. package/dist/extractors/svg-extractor.js +132 -0
  121. package/dist/extractors/svg-extractor.js.map +1 -0
  122. package/dist/extractors/ui-string-extractor.d.ts +40 -0
  123. package/dist/extractors/ui-string-extractor.d.ts.map +1 -0
  124. package/dist/extractors/ui-string-extractor.js +146 -0
  125. package/dist/extractors/ui-string-extractor.js.map +1 -0
  126. package/dist/extractors/ui-string-locations.d.ts +23 -0
  127. package/dist/extractors/ui-string-locations.d.ts.map +1 -0
  128. package/dist/extractors/ui-string-locations.js +138 -0
  129. package/dist/extractors/ui-string-locations.js.map +1 -0
  130. package/dist/glossary/glossary.d.ts +34 -0
  131. package/dist/glossary/glossary.d.ts.map +1 -0
  132. package/dist/glossary/glossary.js +260 -0
  133. package/dist/glossary/glossary.js.map +1 -0
  134. package/dist/glossary/matcher.d.ts +10 -0
  135. package/dist/glossary/matcher.d.ts.map +1 -0
  136. package/dist/glossary/matcher.js +12 -0
  137. package/dist/glossary/matcher.js.map +1 -0
  138. package/dist/index.d.ts +44 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +44 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/processors/admonition-placeholders.d.ts +8 -0
  143. package/dist/processors/admonition-placeholders.d.ts.map +1 -0
  144. package/dist/processors/admonition-placeholders.js +59 -0
  145. package/dist/processors/admonition-placeholders.js.map +1 -0
  146. package/dist/processors/anchor-placeholders.d.ts +8 -0
  147. package/dist/processors/anchor-placeholders.d.ts.map +1 -0
  148. package/dist/processors/anchor-placeholders.js +37 -0
  149. package/dist/processors/anchor-placeholders.js.map +1 -0
  150. package/dist/processors/batch-processor.d.ts +10 -0
  151. package/dist/processors/batch-processor.d.ts.map +1 -0
  152. package/dist/processors/batch-processor.js +33 -0
  153. package/dist/processors/batch-processor.js.map +1 -0
  154. package/dist/processors/bold-code-placeholders.d.ts +14 -0
  155. package/dist/processors/bold-code-placeholders.d.ts.map +1 -0
  156. package/dist/processors/bold-code-placeholders.js +116 -0
  157. package/dist/processors/bold-code-placeholders.js.map +1 -0
  158. package/dist/processors/doc-postprocess.d.ts +51 -0
  159. package/dist/processors/doc-postprocess.d.ts.map +1 -0
  160. package/dist/processors/doc-postprocess.js +215 -0
  161. package/dist/processors/doc-postprocess.js.map +1 -0
  162. package/dist/processors/emphasis-placeholders.d.ts +6 -0
  163. package/dist/processors/emphasis-placeholders.d.ts.map +1 -0
  164. package/dist/processors/emphasis-placeholders.js +262 -0
  165. package/dist/processors/emphasis-placeholders.js.map +1 -0
  166. package/dist/processors/flat-link-rewrite.d.ts +32 -0
  167. package/dist/processors/flat-link-rewrite.d.ts.map +1 -0
  168. package/dist/processors/flat-link-rewrite.js +90 -0
  169. package/dist/processors/flat-link-rewrite.js.map +1 -0
  170. package/dist/processors/glossary-force-placeholders.d.ts +12 -0
  171. package/dist/processors/glossary-force-placeholders.d.ts.map +1 -0
  172. package/dist/processors/glossary-force-placeholders.js +58 -0
  173. package/dist/processors/glossary-force-placeholders.js.map +1 -0
  174. package/dist/processors/inline-code-placeholders.d.ts +11 -0
  175. package/dist/processors/inline-code-placeholders.d.ts.map +1 -0
  176. package/dist/processors/inline-code-placeholders.js +87 -0
  177. package/dist/processors/inline-code-placeholders.js.map +1 -0
  178. package/dist/processors/placeholder-handler.d.ts +38 -0
  179. package/dist/processors/placeholder-handler.d.ts.map +1 -0
  180. package/dist/processors/placeholder-handler.js +55 -0
  181. package/dist/processors/placeholder-handler.js.map +1 -0
  182. package/dist/processors/translation-placeholder-leaks.d.ts +2 -0
  183. package/dist/processors/translation-placeholder-leaks.d.ts.map +1 -0
  184. package/dist/processors/translation-placeholder-leaks.js +9 -0
  185. package/dist/processors/translation-placeholder-leaks.js.map +1 -0
  186. package/dist/processors/url-placeholders.d.ts +10 -0
  187. package/dist/processors/url-placeholders.d.ts.map +1 -0
  188. package/dist/processors/url-placeholders.js +29 -0
  189. package/dist/processors/url-placeholders.js.map +1 -0
  190. package/dist/processors/validator.d.ts +23 -0
  191. package/dist/processors/validator.d.ts.map +1 -0
  192. package/dist/processors/validator.js +186 -0
  193. package/dist/processors/validator.js.map +1 -0
  194. package/dist/runtime/i18next-helpers.d.ts +146 -0
  195. package/dist/runtime/i18next-helpers.d.ts.map +1 -0
  196. package/dist/runtime/i18next-helpers.js +192 -0
  197. package/dist/runtime/i18next-helpers.js.map +1 -0
  198. package/dist/runtime/index.d.ts +4 -0
  199. package/dist/runtime/index.d.ts.map +1 -0
  200. package/dist/runtime/index.js +4 -0
  201. package/dist/runtime/index.js.map +1 -0
  202. package/dist/runtime/template.d.ts +21 -0
  203. package/dist/runtime/template.d.ts.map +1 -0
  204. package/dist/runtime/template.js +28 -0
  205. package/dist/runtime/template.js.map +1 -0
  206. package/dist/runtime/ui-language-display.d.ts +16 -0
  207. package/dist/runtime/ui-language-display.d.ts.map +1 -0
  208. package/dist/runtime/ui-language-display.js +26 -0
  209. package/dist/runtime/ui-language-display.js.map +1 -0
  210. package/dist/server/translation-editor.d.ts +25 -0
  211. package/dist/server/translation-editor.d.ts.map +1 -0
  212. package/dist/server/translation-editor.js +583 -0
  213. package/dist/server/translation-editor.js.map +1 -0
  214. package/dist/utils/concurrency.d.ts +31 -0
  215. package/dist/utils/concurrency.d.ts.map +1 -0
  216. package/dist/utils/concurrency.js +103 -0
  217. package/dist/utils/concurrency.js.map +1 -0
  218. package/dist/utils/hash.d.ts +5 -0
  219. package/dist/utils/hash.d.ts.map +1 -0
  220. package/dist/utils/hash.js +9 -0
  221. package/dist/utils/hash.js.map +1 -0
  222. package/dist/utils/ignore-parser.d.ts +7 -0
  223. package/dist/utils/ignore-parser.d.ts.map +1 -0
  224. package/dist/utils/ignore-parser.js +26 -0
  225. package/dist/utils/ignore-parser.js.map +1 -0
  226. package/dist/utils/logger.d.ts +45 -0
  227. package/dist/utils/logger.d.ts.map +1 -0
  228. package/dist/utils/logger.js +158 -0
  229. package/dist/utils/logger.js.map +1 -0
  230. package/docs/GETTING_STARTED.md +697 -0
  231. package/docs/PACKAGE_OVERVIEW.md +427 -0
  232. package/docs/ai-i18n-tools-context.md +481 -0
  233. package/package.json +117 -0
  234. package/translated-docs/README.de.md +157 -0
  235. package/translated-docs/README.es.md +157 -0
  236. package/translated-docs/README.fr.md +157 -0
  237. package/translated-docs/README.hi.md +157 -0
  238. package/translated-docs/README.ja.md +157 -0
  239. package/translated-docs/README.ko.md +157 -0
  240. package/translated-docs/README.pt-BR.md +157 -0
  241. package/translated-docs/README.zh-CN.md +157 -0
  242. package/translated-docs/README.zh-TW.md +157 -0
  243. package/translated-docs/docs/GETTING_STARTED.de.md +682 -0
  244. package/translated-docs/docs/GETTING_STARTED.es.md +682 -0
  245. package/translated-docs/docs/GETTING_STARTED.fr.md +682 -0
  246. package/translated-docs/docs/GETTING_STARTED.hi.md +682 -0
  247. package/translated-docs/docs/GETTING_STARTED.ja.md +682 -0
  248. package/translated-docs/docs/GETTING_STARTED.ko.md +682 -0
  249. package/translated-docs/docs/GETTING_STARTED.pt-BR.md +682 -0
  250. package/translated-docs/docs/GETTING_STARTED.zh-CN.md +682 -0
  251. package/translated-docs/docs/GETTING_STARTED.zh-TW.md +682 -0
  252. package/translated-docs/docs/PACKAGE_OVERVIEW.de.md +428 -0
  253. package/translated-docs/docs/PACKAGE_OVERVIEW.es.md +428 -0
  254. package/translated-docs/docs/PACKAGE_OVERVIEW.fr.md +428 -0
  255. package/translated-docs/docs/PACKAGE_OVERVIEW.hi.md +428 -0
  256. package/translated-docs/docs/PACKAGE_OVERVIEW.ja.md +428 -0
  257. package/translated-docs/docs/PACKAGE_OVERVIEW.ko.md +428 -0
  258. package/translated-docs/docs/PACKAGE_OVERVIEW.pt-BR.md +428 -0
  259. package/translated-docs/docs/PACKAGE_OVERVIEW.zh-CN.md +428 -0
  260. package/translated-docs/docs/PACKAGE_OVERVIEW.zh-TW.md +428 -0
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Framework-agnostic i18next setup helpers for key-as-default projects.
3
+ *
4
+ * These helpers do NOT import from `i18next` or `react-i18next` directly -
5
+ * they accept a loose `I18nLike` interface so you are not locked to a specific version.
6
+ *
7
+ * Typical usage in a React / Next.js project:
8
+ *
9
+ * ```js
10
+ * // src/i18n.js
11
+ * import i18n from 'i18next';
12
+ * import { initReactI18next } from 'react-i18next';
13
+ * import uiLanguages from './locales/ui-languages.json';
14
+ * import {
15
+ * defaultI18nInitOptions, wrapI18nWithKeyTrim,
16
+ * makeLoadLocale, applyDirection,
17
+ * } from 'ai-i18n-tools/runtime';
18
+ *
19
+ * // Must match sourceLocale in ai-i18n-tools.config.json
20
+ * export const SOURCE_LOCALE = 'en-GB';
21
+ *
22
+ * void i18n.use(initReactI18next).init(defaultI18nInitOptions(SOURCE_LOCALE));
23
+ * wrapI18nWithKeyTrim(i18n);
24
+ * i18n.on('languageChanged', applyDirection);
25
+ * applyDirection(i18n.language);
26
+ *
27
+ * const localeLoaders = Object.fromEntries(
28
+ * uiLanguages
29
+ * .filter(({ code }) => code !== SOURCE_LOCALE)
30
+ * .map(({ code }) => [code, () => import(`./locales/${code}.json`)])
31
+ * );
32
+ * export const loadLocale = makeLoadLocale(i18n, localeLoaders, SOURCE_LOCALE);
33
+ * export default i18n;
34
+ * ```
35
+ */
36
+ /**
37
+ * BCP-47 base language codes that use a right-to-left script.
38
+ * Covers Arabic script (ar, fa, ur, ps, sd, ug), Hebrew (he, yi), Syriac (syr, aii, cld),
39
+ * Thaana (dv), Adlam (ff), N'Ko (nqo), Hanifi Rohingya (rhg).
40
+ */
41
+ export declare const RTL_LANGS: ReadonlySet<string>;
42
+ /**
43
+ * Detect text direction from a BCP-47 locale code.
44
+ * Strips region/script subtags and checks the base language against {@link RTL_LANGS}.
45
+ *
46
+ * @example getTextDirection('ar') // 'rtl'
47
+ * @example getTextDirection('fa-IR') // 'rtl'
48
+ * @example getTextDirection('en-GB') // 'ltr'
49
+ */
50
+ export declare function getTextDirection(lng: string): "ltr" | "rtl";
51
+ /**
52
+ * Minimal DOM interface needed by {@link applyDirection}. Compatible with the browser
53
+ * `Element` type without requiring a `lib: ["dom"]` tsconfig entry.
54
+ */
55
+ export interface DirectionTarget {
56
+ setAttribute(name: string, value: string): void;
57
+ }
58
+ /**
59
+ * Set the `dir` attribute on an element (defaults to `document.documentElement`).
60
+ * Safe to call in Node.js - checks for `document` existence before accessing DOM.
61
+ *
62
+ * @example i18n.on('languageChanged', applyDirection);
63
+ */
64
+ export declare function applyDirection(lng: string, element?: DirectionTarget): void;
65
+ /**
66
+ * Standard i18next `init()` options for key-as-default projects.
67
+ *
68
+ * - `parseMissingKeyHandler` returns the key itself, so missing translations
69
+ * display the source-language string rather than an error.
70
+ * - `nsSeparator: false` allows keys that contain colons (e.g. `"Label:"`).
71
+ * - `interpolation.escapeValue: false` - safe to disable: React escapes values itself,
72
+ * and Node.js / CLI output has no HTML to escape.
73
+ *
74
+ * Spread into `i18n.init()`:
75
+ * ```js
76
+ * i18n.use(initReactI18next).init(defaultI18nInitOptions('en-GB'));
77
+ * ```
78
+ *
79
+ * @param sourceLocale - BCP-47 code used as `lng` and `fallbackLng`. Defaults to `'en'`.
80
+ */
81
+ export declare function defaultI18nInitOptions(sourceLocale?: string): {
82
+ resources: Record<string, never>;
83
+ lng: string;
84
+ fallbackLng: string;
85
+ parseMissingKeyHandler: (key: string) => string;
86
+ interpolation: {
87
+ escapeValue: false;
88
+ };
89
+ nsSeparator: false;
90
+ };
91
+ /**
92
+ * Minimal interface for an i18next instance (or any compatible translate object).
93
+ * Accepts the full i18next instance without requiring an import of `i18next` itself.
94
+ */
95
+ export interface I18nLike {
96
+ t: (key: string, ...rest: unknown[]) => string;
97
+ }
98
+ /**
99
+ * Wrap `i18n.t` so that:
100
+ * 1. Keys are trimmed before lookup - the extract script stores keys trimmed
101
+ * (e.g. `"Label"` not `"Label "`), so `t("Label ")` would miss the cache without this.
102
+ * 2. Source-locale `{{var}}` interpolation is applied as a fallback - in key-as-default
103
+ * mode `parseMissingKeyHandler` returns the raw key string without running
104
+ * interpolation, so `t("Hello {{name}}", { name })` would return `"Hello {{name}}"`
105
+ * instead of `"Hello World"` for the source locale. This wrapper detects that case
106
+ * (result === trimmed key) and applies `interpolateTemplate` automatically.
107
+ *
108
+ * Mutates the `t` property on the passed instance in-place.
109
+ *
110
+ * @example wrapI18nWithKeyTrim(i18n);
111
+ */
112
+ export declare function wrapI18nWithKeyTrim(i18n: I18nLike): void;
113
+ /**
114
+ * Extended i18next interface that includes the resource bundle API needed by `makeLoadLocale`.
115
+ */
116
+ export interface I18nWithResources extends I18nLike {
117
+ addResourceBundle(lng: string, ns: string, resources: Record<string, string>, deep?: boolean, overwrite?: boolean): void;
118
+ }
119
+ /**
120
+ * Create a `loadLocale(lang)` function for dynamic locale loading.
121
+ *
122
+ * Pass a map of `{ [localeCode]: () => import('./locales/<code>.json') }` and the
123
+ * returned function handles loading on demand, skipping the source locale (no file needed).
124
+ *
125
+ * @param i18n - i18next instance (must have `addResourceBundle`).
126
+ * @param localeLoaders - map of locale code → dynamic import factory.
127
+ * @param sourceLocale - locale code that requires no file (key-as-default); defaults to `'en'`.
128
+ *
129
+ * @example
130
+ * ```js
131
+ * const localeLoaders = Object.fromEntries(
132
+ * uiLanguages
133
+ * .filter(({ code }) => code !== SOURCE_LOCALE)
134
+ * .map(({ code }) => [code, () => import(`./locales/${code}.json`)])
135
+ * );
136
+ * export const loadLocale = makeLoadLocale(i18n, localeLoaders, SOURCE_LOCALE);
137
+ *
138
+ * // Later, when the user changes language:
139
+ * await loadLocale('de');
140
+ * i18n.changeLanguage('de');
141
+ * ```
142
+ */
143
+ export declare function makeLoadLocale(i18n: I18nWithResources, localeLoaders: Record<string, () => Promise<{
144
+ default?: unknown;
145
+ } | unknown>>, sourceLocale?: string): (lang: string) => Promise<void>;
146
+ //# sourceMappingURL=i18next-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18next-helpers.d.ts","sourceRoot":"","sources":["../../src/runtime/i18next-helpers.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,WAAW,CAAC,MAAM,CAgBxC,CAAC;AAEH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAG3D;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACjD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI,CAa3E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,SAAO,GAAG;IAC3D,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,aAAa,EAAE;QAAE,WAAW,EAAE,KAAK,CAAA;KAAE,CAAC;IACtC,WAAW,EAAE,KAAK,CAAC;CACpB,CASA;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC;CAChD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAgBxD;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,QAAQ;IACjD,iBAAiB,CACf,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,IAAI,CAAC,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,OAAO,GAClB,IAAI,CAAC;CACT;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,iBAAiB,EACvB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,CAAC,EAC7E,YAAY,SAAO,GAClB,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAsBjC"}
@@ -0,0 +1,192 @@
1
+ import { interpolateTemplate } from "./template.js";
2
+ /**
3
+ * Framework-agnostic i18next setup helpers for key-as-default projects.
4
+ *
5
+ * These helpers do NOT import from `i18next` or `react-i18next` directly -
6
+ * they accept a loose `I18nLike` interface so you are not locked to a specific version.
7
+ *
8
+ * Typical usage in a React / Next.js project:
9
+ *
10
+ * ```js
11
+ * // src/i18n.js
12
+ * import i18n from 'i18next';
13
+ * import { initReactI18next } from 'react-i18next';
14
+ * import uiLanguages from './locales/ui-languages.json';
15
+ * import {
16
+ * defaultI18nInitOptions, wrapI18nWithKeyTrim,
17
+ * makeLoadLocale, applyDirection,
18
+ * } from 'ai-i18n-tools/runtime';
19
+ *
20
+ * // Must match sourceLocale in ai-i18n-tools.config.json
21
+ * export const SOURCE_LOCALE = 'en-GB';
22
+ *
23
+ * void i18n.use(initReactI18next).init(defaultI18nInitOptions(SOURCE_LOCALE));
24
+ * wrapI18nWithKeyTrim(i18n);
25
+ * i18n.on('languageChanged', applyDirection);
26
+ * applyDirection(i18n.language);
27
+ *
28
+ * const localeLoaders = Object.fromEntries(
29
+ * uiLanguages
30
+ * .filter(({ code }) => code !== SOURCE_LOCALE)
31
+ * .map(({ code }) => [code, () => import(`./locales/${code}.json`)])
32
+ * );
33
+ * export const loadLocale = makeLoadLocale(i18n, localeLoaders, SOURCE_LOCALE);
34
+ * export default i18n;
35
+ * ```
36
+ */
37
+ /**
38
+ * BCP-47 base language codes that use a right-to-left script.
39
+ * Covers Arabic script (ar, fa, ur, ps, sd, ug), Hebrew (he, yi), Syriac (syr, aii, cld),
40
+ * Thaana (dv), Adlam (ff), N'Ko (nqo), Hanifi Rohingya (rhg).
41
+ */
42
+ export const RTL_LANGS = new Set([
43
+ "ar",
44
+ "he",
45
+ "fa",
46
+ "ur",
47
+ "yi",
48
+ "ps",
49
+ "sd",
50
+ "ug",
51
+ "dv",
52
+ "ff",
53
+ "syr",
54
+ "aii",
55
+ "cld",
56
+ "rhg",
57
+ "nqo",
58
+ ]);
59
+ /**
60
+ * Detect text direction from a BCP-47 locale code.
61
+ * Strips region/script subtags and checks the base language against {@link RTL_LANGS}.
62
+ *
63
+ * @example getTextDirection('ar') // 'rtl'
64
+ * @example getTextDirection('fa-IR') // 'rtl'
65
+ * @example getTextDirection('en-GB') // 'ltr'
66
+ */
67
+ export function getTextDirection(lng) {
68
+ const base = (lng && lng.split(/[-_]/)[0]) || "";
69
+ return RTL_LANGS.has(base) ? "rtl" : "ltr";
70
+ }
71
+ /**
72
+ * Set the `dir` attribute on an element (defaults to `document.documentElement`).
73
+ * Safe to call in Node.js - checks for `document` existence before accessing DOM.
74
+ *
75
+ * @example i18n.on('languageChanged', applyDirection);
76
+ */
77
+ export function applyDirection(lng, element) {
78
+ const dir = getTextDirection(lng);
79
+ if (element) {
80
+ element.setAttribute("dir", dir);
81
+ return;
82
+ }
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ const doc = globalThis["document"];
85
+ if (doc?.documentElement) {
86
+ doc.documentElement.setAttribute("dir", dir);
87
+ }
88
+ }
89
+ /**
90
+ * Standard i18next `init()` options for key-as-default projects.
91
+ *
92
+ * - `parseMissingKeyHandler` returns the key itself, so missing translations
93
+ * display the source-language string rather than an error.
94
+ * - `nsSeparator: false` allows keys that contain colons (e.g. `"Label:"`).
95
+ * - `interpolation.escapeValue: false` - safe to disable: React escapes values itself,
96
+ * and Node.js / CLI output has no HTML to escape.
97
+ *
98
+ * Spread into `i18n.init()`:
99
+ * ```js
100
+ * i18n.use(initReactI18next).init(defaultI18nInitOptions('en-GB'));
101
+ * ```
102
+ *
103
+ * @param sourceLocale - BCP-47 code used as `lng` and `fallbackLng`. Defaults to `'en'`.
104
+ */
105
+ export function defaultI18nInitOptions(sourceLocale = "en") {
106
+ return {
107
+ resources: {},
108
+ lng: sourceLocale,
109
+ fallbackLng: sourceLocale,
110
+ parseMissingKeyHandler: (key) => key,
111
+ interpolation: { escapeValue: false },
112
+ nsSeparator: false,
113
+ };
114
+ }
115
+ /**
116
+ * Wrap `i18n.t` so that:
117
+ * 1. Keys are trimmed before lookup - the extract script stores keys trimmed
118
+ * (e.g. `"Label"` not `"Label "`), so `t("Label ")` would miss the cache without this.
119
+ * 2. Source-locale `{{var}}` interpolation is applied as a fallback - in key-as-default
120
+ * mode `parseMissingKeyHandler` returns the raw key string without running
121
+ * interpolation, so `t("Hello {{name}}", { name })` would return `"Hello {{name}}"`
122
+ * instead of `"Hello World"` for the source locale. This wrapper detects that case
123
+ * (result === trimmed key) and applies `interpolateTemplate` automatically.
124
+ *
125
+ * Mutates the `t` property on the passed instance in-place.
126
+ *
127
+ * @example wrapI18nWithKeyTrim(i18n);
128
+ */
129
+ export function wrapI18nWithKeyTrim(i18n) {
130
+ const originalT = i18n.t.bind(i18n);
131
+ i18n.t = function (key, ...rest) {
132
+ const normalizedKey = typeof key === "string" ? key.trim() : key;
133
+ const result = originalT(normalizedKey, ...rest);
134
+ const options = rest[0];
135
+ if (result === normalizedKey &&
136
+ options !== null &&
137
+ typeof options === "object" &&
138
+ !Array.isArray(options)) {
139
+ return interpolateTemplate(result, options);
140
+ }
141
+ return result;
142
+ };
143
+ }
144
+ /**
145
+ * Create a `loadLocale(lang)` function for dynamic locale loading.
146
+ *
147
+ * Pass a map of `{ [localeCode]: () => import('./locales/<code>.json') }` and the
148
+ * returned function handles loading on demand, skipping the source locale (no file needed).
149
+ *
150
+ * @param i18n - i18next instance (must have `addResourceBundle`).
151
+ * @param localeLoaders - map of locale code → dynamic import factory.
152
+ * @param sourceLocale - locale code that requires no file (key-as-default); defaults to `'en'`.
153
+ *
154
+ * @example
155
+ * ```js
156
+ * const localeLoaders = Object.fromEntries(
157
+ * uiLanguages
158
+ * .filter(({ code }) => code !== SOURCE_LOCALE)
159
+ * .map(({ code }) => [code, () => import(`./locales/${code}.json`)])
160
+ * );
161
+ * export const loadLocale = makeLoadLocale(i18n, localeLoaders, SOURCE_LOCALE);
162
+ *
163
+ * // Later, when the user changes language:
164
+ * await loadLocale('de');
165
+ * i18n.changeLanguage('de');
166
+ * ```
167
+ */
168
+ export function makeLoadLocale(i18n, localeLoaders, sourceLocale = "en") {
169
+ return async function loadLocale(lang) {
170
+ if (lang === sourceLocale || lang === "en")
171
+ return;
172
+ const loader = localeLoaders[lang];
173
+ if (!loader) {
174
+ console.warn("[i18n] locale not supported:", lang);
175
+ return;
176
+ }
177
+ try {
178
+ const module = await loader();
179
+ const data = module !== null &&
180
+ typeof module === "object" &&
181
+ "default" in module &&
182
+ module.default !== undefined
183
+ ? module.default
184
+ : module;
185
+ i18n.addResourceBundle(lang, "translation", data, true, true);
186
+ }
187
+ catch (e) {
188
+ console.warn("[i18n] locale not found:", lang, e instanceof Error ? e.message : e);
189
+ }
190
+ };
191
+ }
192
+ //# sourceMappingURL=i18next-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18next-helpers.js","sourceRoot":"","sources":["../../src/runtime/i18next-helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { interpolateTemplate, flipUiArrowsForRtl } from "./template.js";
2
+ export { getUILanguageLabel, getUILanguageLabelNative, type TranslateFn, } from "./ui-language-display.js";
3
+ export { RTL_LANGS, getTextDirection, applyDirection, defaultI18nInitOptions, wrapI18nWithKeyTrim, makeLoadLocale, type I18nLike, type I18nWithResources, } from "./i18next-helpers.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,KAAK,WAAW,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,iBAAiB,GACvB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { interpolateTemplate, flipUiArrowsForRtl } from "./template.js";
2
+ export { getUILanguageLabel, getUILanguageLabelNative, } from "./ui-language-display.js";
3
+ export { RTL_LANGS, getTextDirection, applyDirection, defaultI18nInitOptions, wrapI18nWithKeyTrim, makeLoadLocale, } from "./i18next-helpers.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EACL,kBAAkB,EAClB,wBAAwB,GAEzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,GAGf,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Small string helpers for i18next key-as-default setups.
3
+ * No i18n dependency - safe for browser or Node.
4
+ */
5
+ /**
6
+ * Replace `{{key}}` placeholders (ASCII word keys only) in a pre-translated string.
7
+ * Use for non-i18next contexts: CLI output, Node.js scripts, or strings already
8
+ * returned by `t()` that need further substitution outside the React tree.
9
+ *
10
+ * In React/i18next components, prefer `t('key {{var}}', { var })` directly -
11
+ * i18next handles interpolation natively in key-as-default mode.
12
+ *
13
+ * @example interpolateTemplate(t("Hello {{name}}"), { name: userName })
14
+ */
15
+ export declare function interpolateTemplate(str: string, vars: Record<string, string | number | boolean>): string;
16
+ /**
17
+ * Map U+2192 (→) to U+2190 (←) when the UI is RTL so arrows match reading direction.
18
+ * Apply to user-visible strings that may contain → (including translated text).
19
+ */
20
+ export declare function flipUiArrowsForRtl(text: string | null | undefined, isRtl: boolean): string | null | undefined;
21
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/runtime/template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAC9C,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,KAAK,EAAE,OAAO,GACb,MAAM,GAAG,IAAI,GAAG,SAAS,CAK3B"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Small string helpers for i18next key-as-default setups.
3
+ * No i18n dependency - safe for browser or Node.
4
+ */
5
+ /**
6
+ * Replace `{{key}}` placeholders (ASCII word keys only) in a pre-translated string.
7
+ * Use for non-i18next contexts: CLI output, Node.js scripts, or strings already
8
+ * returned by `t()` that need further substitution outside the React tree.
9
+ *
10
+ * In React/i18next components, prefer `t('key {{var}}', { var })` directly -
11
+ * i18next handles interpolation natively in key-as-default mode.
12
+ *
13
+ * @example interpolateTemplate(t("Hello {{name}}"), { name: userName })
14
+ */
15
+ export function interpolateTemplate(str, vars) {
16
+ return str.replace(/\{\{(\w+)\}\}/g, (_, key) => String(vars[key] ?? ""));
17
+ }
18
+ /**
19
+ * Map U+2192 (→) to U+2190 (←) when the UI is RTL so arrows match reading direction.
20
+ * Apply to user-visible strings that may contain → (including translated text).
21
+ */
22
+ export function flipUiArrowsForRtl(text, isRtl) {
23
+ if (!isRtl || text == null || typeof text !== "string") {
24
+ return text;
25
+ }
26
+ return text.replace(/\u2192/g, "\u2190");
27
+ }
28
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/runtime/template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAW,EACX,IAA+C;IAE/C,OAAO,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,GAAW,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACpF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAA+B,EAC/B,KAAc;IAEd,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { UiLanguageEntry } from "../core/ui-languages.js";
2
+ /** Minimal translate function (e.g. react-i18next `t`). */
3
+ export type TranslateFn = (key: string) => string;
4
+ /**
5
+ * Display label for a language row: `englishName`, or `englishName / t(englishName)` when
6
+ * the translated name differs from the English name.
7
+ * Uses `" / "` between parts (avoids nested parentheses in long names).
8
+ */
9
+ export declare function getUILanguageLabel(lang: UiLanguageEntry, t: TranslateFn): string;
10
+ /**
11
+ * Display label using manifest fields only (no `t()` on the row).
12
+ * Returns `englishName / label` when they differ (e.g. `German / Deutsch`),
13
+ * or a single string when they are the same. Suitable for header language menus.
14
+ */
15
+ export declare function getUILanguageLabelNative(lang: UiLanguageEntry): string;
16
+ //# sourceMappingURL=ui-language-display.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-language-display.d.ts","sourceRoot":"","sources":["../../src/runtime/ui-language-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,2DAA2D;AAC3D,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,EAAE,CAAC,EAAE,WAAW,GAAG,MAAM,CAOhF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAMtE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Display label for a language row: `englishName`, or `englishName / t(englishName)` when
3
+ * the translated name differs from the English name.
4
+ * Uses `" / "` between parts (avoids nested parentheses in long names).
5
+ */
6
+ export function getUILanguageLabel(lang, t) {
7
+ const { englishName } = lang;
8
+ const translated = t(englishName);
9
+ if (translated === englishName) {
10
+ return englishName;
11
+ }
12
+ return `${englishName} / ${translated}`;
13
+ }
14
+ /**
15
+ * Display label using manifest fields only (no `t()` on the row).
16
+ * Returns `englishName / label` when they differ (e.g. `German / Deutsch`),
17
+ * or a single string when they are the same. Suitable for header language menus.
18
+ */
19
+ export function getUILanguageLabelNative(lang) {
20
+ const { englishName, label } = lang;
21
+ if (label === englishName) {
22
+ return label;
23
+ }
24
+ return `${englishName} / ${label}`;
25
+ }
26
+ //# sourceMappingURL=ui-language-display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-language-display.js","sourceRoot":"","sources":["../../src/runtime/ui-language-display.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAqB,EAAE,CAAc;IACtE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAC7B,MAAM,UAAU,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;IAClC,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAC/B,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,WAAW,MAAM,UAAU,EAAE,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAqB;IAC5D,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACpC,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,GAAG,WAAW,MAAM,KAAK,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import express from "express";
2
+ import { TranslationCache } from "../core/cache.js";
3
+ export interface TranslationEditorOptions {
4
+ cwd: string;
5
+ /** Resolved absolute or cwd-relative path to strings.json (workspace B). */
6
+ stringsJsonPath?: string | null;
7
+ /** Resolved path to glossary-user.csv (workspace C). */
8
+ glossaryUserPath?: string | null;
9
+ /** BCP-47 locale for source / original strings (from config `sourceLocale`). */
10
+ sourceLocale: string;
11
+ targetLocales: string[];
12
+ /**
13
+ * `documentation.jsonSource` (cwd-relative). Used to print full paths for JSON segments
14
+ * that were stored relative to this root (e.g. `code.json` → `docs-site/i18n/en/code.json`).
15
+ */
16
+ jsonSource?: string | null;
17
+ }
18
+ /** Normalize cache filepath for console log-links (JSON rows may omit jsonSource prefix). */
19
+ export declare function resolveSegmentLogFilepath(filepath: string, jsonSource: string | null | undefined): string;
20
+ /**
21
+ * Express app: workspace A (cache) + B (strings.json) + C (glossary CSV).
22
+ */
23
+ export declare function createTranslationEditorApp(cache: TranslationCache, opts: TranslationEditorOptions): express.Application;
24
+ export declare function resolveEditCacheStaticDir(): string;
25
+ //# sourceMappingURL=translation-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translation-editor.d.ts","sourceRoot":"","sources":["../../src/server/translation-editor.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AA2BpD,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,6FAA6F;AAC7F,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACpC,MAAM,CAOR;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,WAAW,CA4lBrB;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD"}