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,20 @@
1
+ /**
2
+ * Lightweight line/block classifier (plan §2.3 reference). For full markdown splitting use {@link MarkdownExtractor}.
3
+ */
4
+ export function classifySegmentType(text) {
5
+ const t = text.trim();
6
+ if (/^#{1,6}\s/.test(t)) {
7
+ return "heading";
8
+ }
9
+ if (/^!\[.*\]\(.*\)/.test(t)) {
10
+ return "other";
11
+ }
12
+ if (/^import /.test(t)) {
13
+ return "other";
14
+ }
15
+ if (/^</.test(t)) {
16
+ return "other";
17
+ }
18
+ return "paragraph";
19
+ }
20
+ //# sourceMappingURL=classify-segment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify-segment.js","sourceRoot":"","sources":["../../src/extractors/classify-segment.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACtB,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACvB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACjB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Segment, SegmentTranslationMapValue } from "../core/types.js";
2
+ import { BaseExtractor } from "./base-extractor.js";
3
+ /**
4
+ * Docusaurus-style JSON: `{ "key": { "message": "...", "description": "..." } }`.
5
+ * `reassemble` uses the content from the last `extract` call on this instance (one file per instance per pipeline).
6
+ */
7
+ export declare class JsonExtractor extends BaseExtractor {
8
+ readonly name = "json";
9
+ /** Last `extract` input; used by {@link reassemble}. */
10
+ private lastOriginalContent;
11
+ canHandle(filepath: string): boolean;
12
+ extract(content: string, filepath: string): Segment[];
13
+ reassemble(segments: Segment[], translations: Map<string, SegmentTranslationMapValue>): string;
14
+ private escapeRegex;
15
+ }
16
+ //# sourceMappingURL=json-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/json-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOpD;;;GAGG;AACH,qBAAa,aAAc,SAAQ,aAAa;IAC9C,QAAQ,CAAC,IAAI,UAAU;IAEvB,wDAAwD;IACxD,OAAO,CAAC,mBAAmB,CAAM;IAEjC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIpC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE;IAqErD,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,0BAA0B,CAAC,GAAG,MAAM;IAoD9F,OAAO,CAAC,WAAW;CAGpB"}
@@ -0,0 +1,128 @@
1
+ import { BaseExtractor } from "./base-extractor.js";
2
+ /**
3
+ * Docusaurus-style JSON: `{ "key": { "message": "...", "description": "..." } }`.
4
+ * `reassemble` uses the content from the last `extract` call on this instance (one file per instance per pipeline).
5
+ */
6
+ export class JsonExtractor extends BaseExtractor {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.name = "json";
10
+ /** Last `extract` input; used by {@link reassemble}. */
11
+ this.lastOriginalContent = "";
12
+ }
13
+ canHandle(filepath) {
14
+ return filepath.toLowerCase().endsWith(".json");
15
+ }
16
+ extract(content, filepath) {
17
+ this.lastOriginalContent = content;
18
+ const segments = [];
19
+ let segmentIndex = 0;
20
+ const lines = content.split("\n");
21
+ let json;
22
+ try {
23
+ json = JSON.parse(content);
24
+ }
25
+ catch (e) {
26
+ throw new Error(`Failed to parse JSON file ${filepath}: ${e instanceof Error ? e.message : String(e)}`);
27
+ }
28
+ const findLineNumber = (message, key) => {
29
+ for (let i = 0; i < lines.length; i++) {
30
+ const line = lines[i] ?? "";
31
+ const keyPattern = new RegExp(`"${this.escapeRegex(key)}"\\s*:`);
32
+ if (keyPattern.test(line)) {
33
+ return i + 1;
34
+ }
35
+ }
36
+ for (let i = 0; i < lines.length; i++) {
37
+ if ((lines[i] ?? "").includes(`"${message}"`)) {
38
+ return i + 1;
39
+ }
40
+ }
41
+ return 1;
42
+ };
43
+ const walk = (obj, keyPrefix) => {
44
+ if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
45
+ return;
46
+ }
47
+ for (const [key, value] of Object.entries(obj)) {
48
+ const fullKey = keyPrefix ? `${keyPrefix}.${key}` : key;
49
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
50
+ const entry = value;
51
+ if (Object.prototype.hasOwnProperty.call(entry, "message")) {
52
+ const message = entry.message;
53
+ const description = entry.description;
54
+ if (typeof message === "string") {
55
+ const hash = this.computeHash(message);
56
+ const startLine = findLineNumber(message, key);
57
+ segments.push({
58
+ id: `json-${segmentIndex++}`,
59
+ type: "json",
60
+ content: message,
61
+ hash,
62
+ translatable: true,
63
+ startLine,
64
+ jsonKey: fullKey,
65
+ jsonDescription: description,
66
+ });
67
+ }
68
+ }
69
+ else {
70
+ walk(value, fullKey);
71
+ }
72
+ }
73
+ }
74
+ };
75
+ walk(json, "");
76
+ return segments;
77
+ }
78
+ reassemble(segments, translations) {
79
+ const originalContent = this.lastOriginalContent;
80
+ if (!originalContent) {
81
+ throw new Error("JsonExtractor.reassemble: call extract() first");
82
+ }
83
+ const originalJson = JSON.parse(originalContent);
84
+ const segmentMap = new Map();
85
+ const merged = this.mergeTranslations(segments, translations);
86
+ for (const seg of merged) {
87
+ if (seg.jsonKey) {
88
+ segmentMap.set(seg.jsonKey, seg);
89
+ }
90
+ }
91
+ const walk = (src, keyPrefix) => {
92
+ if (typeof src !== "object" || src === null) {
93
+ return src;
94
+ }
95
+ if (Array.isArray(src)) {
96
+ return src.map((item) => walk(item, keyPrefix));
97
+ }
98
+ const result = {};
99
+ for (const [key, value] of Object.entries(src)) {
100
+ const fullKey = keyPrefix ? `${keyPrefix}.${key}` : key;
101
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
102
+ const entry = value;
103
+ if (Object.prototype.hasOwnProperty.call(entry, "message")) {
104
+ const seg = segmentMap.get(fullKey);
105
+ const translatedMessage = seg ? seg.content : entry.message;
106
+ const next = { message: translatedMessage };
107
+ if (Object.prototype.hasOwnProperty.call(entry, "description")) {
108
+ next.description = entry.description;
109
+ }
110
+ result[key] = next;
111
+ }
112
+ else {
113
+ result[key] = walk(value, fullKey);
114
+ }
115
+ }
116
+ else {
117
+ result[key] = value;
118
+ }
119
+ }
120
+ return result;
121
+ };
122
+ return JSON.stringify(walk(originalJson, ""), null, 2) + "\n";
123
+ }
124
+ escapeRegex(str) {
125
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
126
+ }
127
+ }
128
+ //# sourceMappingURL=json-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-extractor.js","sourceRoot":"","sources":["../../src/extractors/json-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { LanguageListBlockConfig, Segment, SegmentTranslationMapValue } from "../core/types.js";
2
+ import { BaseExtractor } from "./base-extractor.js";
3
+ /** Optional extraction behavior for markdown docs (e.g. skip language-list blocks from translation). */
4
+ export type MarkdownExtractOptions = {
5
+ languageListBlock?: LanguageListBlockConfig;
6
+ };
7
+ export declare class MarkdownExtractor extends BaseExtractor {
8
+ readonly name = "markdown";
9
+ canHandle(filepath: string): boolean;
10
+ extract(content: string, filepath: string, options?: MarkdownExtractOptions): Segment[];
11
+ reassemble(segments: Segment[], translations: Map<string, SegmentTranslationMapValue>): string;
12
+ private splitBody;
13
+ private classifySegment;
14
+ }
15
+ //# sourceMappingURL=markdown-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown-extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,uBAAuB,EACvB,OAAO,EACP,0BAA0B,EAC3B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,wGAAwG;AACxG,MAAM,MAAM,sBAAsB,GAAG;IACnC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;CAC7C,CAAC;AAKF,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,QAAQ,CAAC,IAAI,cAAc;IAE3B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIpC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,EAAE;IAkCvF,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,0BAA0B,CAAC,GAAG,MAAM;IAoB9F,OAAO,CAAC,SAAS;IAkIjB,OAAO,CAAC,eAAe;CAyCxB"}
@@ -0,0 +1,205 @@
1
+ import { matter, stringify as matterStringify } from "gray-matter-es";
2
+ import { extractLanguageListBlock } from "../processors/doc-postprocess.js";
3
+ import { BaseExtractor } from "./base-extractor.js";
4
+ /** CommonMark fenced code: line starts (after optional indent) with 3+ ``` or 3+ ~~~. */
5
+ const MD_CODE_FENCE_LINE_RE = /^\s*(?:`{3,}|~{3,})/;
6
+ export class MarkdownExtractor extends BaseExtractor {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.name = "markdown";
10
+ }
11
+ canHandle(filepath) {
12
+ return /\.mdx?$/i.test(filepath);
13
+ }
14
+ extract(content, filepath, options) {
15
+ void filepath;
16
+ const segments = [];
17
+ let segmentIndex = 0;
18
+ const { data: frontMatter, content: body } = matter(content);
19
+ if (Object.keys(frontMatter).length > 0) {
20
+ const frontMatterStr = matterStringify("", frontMatter).trim();
21
+ segments.push({
22
+ id: `seg-${segmentIndex++}`,
23
+ type: "frontmatter",
24
+ content: frontMatterStr,
25
+ hash: this.computeHash(frontMatterStr),
26
+ translatable: true,
27
+ startLine: 1,
28
+ });
29
+ }
30
+ const bodyStartLine = 1 + (content.substring(0, content.indexOf(body)).match(/\n/g) || []).length;
31
+ const bodySegments = this.splitBody(body, bodyStartLine, options?.languageListBlock);
32
+ for (const seg of bodySegments) {
33
+ segments.push({
34
+ id: `seg-${segmentIndex++}`,
35
+ ...seg,
36
+ hash: this.computeHash(seg.content),
37
+ });
38
+ }
39
+ return segments;
40
+ }
41
+ reassemble(segments, translations) {
42
+ const merged = this.mergeTranslations(segments, translations);
43
+ const parts = [];
44
+ for (let i = 0; i < merged.length; i++) {
45
+ const segment = merged[i];
46
+ if (!segment) {
47
+ continue;
48
+ }
49
+ if (segment.type === "frontmatter") {
50
+ parts.push(segment.content);
51
+ parts.push("");
52
+ }
53
+ else {
54
+ parts.push(segment.content);
55
+ }
56
+ }
57
+ return parts.join("\n\n").trim() + "\n";
58
+ }
59
+ splitBody(body, bodyStartLine, languageListBlock) {
60
+ const segments = [];
61
+ const lines = body.split("\n");
62
+ const langListExt = languageListBlock !== undefined ? extractLanguageListBlock(body, languageListBlock) : null;
63
+ const langListStart = langListExt?.startLine ?? -1;
64
+ const langListEnd = langListExt?.endLine ?? -1;
65
+ let currentSegment = [];
66
+ let currentSegmentStartLine = 0;
67
+ let inCodeBlock = false;
68
+ let inAdmonition = false;
69
+ let codeBlockContent = [];
70
+ let codeBlockStartLine = 0;
71
+ let admonitionContent = [];
72
+ let admonitionStartLine = 0;
73
+ const flushCurrentSegment = () => {
74
+ if (currentSegment.length > 0) {
75
+ const segContent = currentSegment.join("\n").trim();
76
+ if (segContent) {
77
+ segments.push(this.classifySegment(segContent, bodyStartLine + currentSegmentStartLine));
78
+ }
79
+ currentSegment = [];
80
+ }
81
+ };
82
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
83
+ const line = lines[lineIndex] ?? "";
84
+ if (MD_CODE_FENCE_LINE_RE.test(line)) {
85
+ if (inCodeBlock) {
86
+ codeBlockContent.push(line);
87
+ segments.push({
88
+ type: "code",
89
+ content: codeBlockContent.join("\n"),
90
+ translatable: false,
91
+ startLine: bodyStartLine + codeBlockStartLine,
92
+ });
93
+ codeBlockContent = [];
94
+ inCodeBlock = false;
95
+ }
96
+ else {
97
+ flushCurrentSegment();
98
+ codeBlockContent.push(line);
99
+ codeBlockStartLine = lineIndex;
100
+ inCodeBlock = true;
101
+ }
102
+ continue;
103
+ }
104
+ if (inCodeBlock) {
105
+ codeBlockContent.push(line);
106
+ continue;
107
+ }
108
+ if (langListStart !== -1 && lineIndex === langListStart && !inAdmonition) {
109
+ flushCurrentSegment();
110
+ const blockLines = lines.slice(langListStart, langListEnd + 1);
111
+ segments.push({
112
+ type: "other",
113
+ content: blockLines.join("\n"),
114
+ translatable: false,
115
+ startLine: bodyStartLine + langListStart,
116
+ });
117
+ lineIndex = langListEnd;
118
+ continue;
119
+ }
120
+ if (line.match(/^:::\w+/)) {
121
+ flushCurrentSegment();
122
+ admonitionContent.push(line);
123
+ admonitionStartLine = lineIndex;
124
+ inAdmonition = true;
125
+ continue;
126
+ }
127
+ if (line === ":::" && inAdmonition) {
128
+ admonitionContent.push(line);
129
+ segments.push({
130
+ type: "admonition",
131
+ content: admonitionContent.join("\n"),
132
+ translatable: true,
133
+ startLine: bodyStartLine + admonitionStartLine,
134
+ });
135
+ admonitionContent = [];
136
+ inAdmonition = false;
137
+ continue;
138
+ }
139
+ if (inAdmonition) {
140
+ admonitionContent.push(line);
141
+ continue;
142
+ }
143
+ if (line.trim() === "") {
144
+ flushCurrentSegment();
145
+ continue;
146
+ }
147
+ if (currentSegment.length === 0) {
148
+ currentSegmentStartLine = lineIndex;
149
+ }
150
+ currentSegment.push(line);
151
+ }
152
+ flushCurrentSegment();
153
+ if (codeBlockContent.length > 0) {
154
+ segments.push({
155
+ type: "code",
156
+ content: codeBlockContent.join("\n"),
157
+ translatable: false,
158
+ startLine: bodyStartLine + codeBlockStartLine,
159
+ });
160
+ }
161
+ if (admonitionContent.length > 0) {
162
+ segments.push({
163
+ type: "admonition",
164
+ content: admonitionContent.join("\n"),
165
+ translatable: true,
166
+ startLine: bodyStartLine + admonitionStartLine,
167
+ });
168
+ }
169
+ return segments;
170
+ }
171
+ classifySegment(content, startLine) {
172
+ const trimmed = content.trim();
173
+ const isSingleLine = !trimmed.includes("\n");
174
+ if (/^<br\s*\/?>$/i.test(trimmed)) {
175
+ return { type: "other", content, translatable: false, startLine };
176
+ }
177
+ if (/^---+$/.test(trimmed)) {
178
+ return { type: "other", content, translatable: false, startLine };
179
+ }
180
+ if (isSingleLine) {
181
+ const textOnly = trimmed
182
+ .replace(/`[^`]*`/g, "")
183
+ .replace(/!\[[^\]]*\]\([^)]*\)/g, "")
184
+ .replace(/\[[^\]]*\]\([^)]*\)/g, "")
185
+ .replace(/[*_#>-]/g, "")
186
+ .replace(/[()[\]{}<>]/g, "")
187
+ .replace(/<[^>]+>/g, "")
188
+ .trim();
189
+ if (!/[A-Za-z0-9]/.test(textOnly)) {
190
+ return { type: "other", content, translatable: false, startLine };
191
+ }
192
+ }
193
+ if (content.match(/^#{1,6}\s/)) {
194
+ return { type: "heading", content, translatable: true, startLine };
195
+ }
196
+ if (content.match(/^!\[.*\]\(.*\)$/)) {
197
+ return { type: "other", content, translatable: false, startLine };
198
+ }
199
+ if (content.startsWith("import ") || /^<[A-Z]/.test(trimmed) || /^<\/\w+>$/.test(trimmed)) {
200
+ return { type: "other", content, translatable: false, startLine };
201
+ }
202
+ return { type: "paragraph", content, translatable: true, startLine };
203
+ }
204
+ }
205
+ //# sourceMappingURL=markdown-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-extractor.js","sourceRoot":"","sources":["../../src/extractors/markdown-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Segment, SegmentTranslationMapValue } from "../core/types.js";
2
+ import { BaseExtractor } from "./base-extractor.js";
3
+ export interface SvgExtractorOptions {
4
+ forceLowercase?: boolean;
5
+ }
6
+ /**
7
+ * SVG `<text>` / `<title>` / `<desc>` extraction (regex-based).
8
+ * `reassemble` uses the SVG from the last `extract` call on this instance.
9
+ */
10
+ export declare class SvgExtractor extends BaseExtractor {
11
+ private readonly options;
12
+ readonly name = "svg";
13
+ private lastSvg;
14
+ constructor(options?: SvgExtractorOptions);
15
+ canHandle(filepath: string): boolean;
16
+ extract(content: string, filepath: string): Segment[];
17
+ reassemble(segments: Segment[], translations: Map<string, SegmentTranslationMapValue>): string;
18
+ }
19
+ //# sourceMappingURL=svg-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/svg-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAsBpD,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,aAAa;IAKjC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,QAAQ,CAAC,IAAI,SAAS;IAEtB,OAAO,CAAC,OAAO,CAAM;gBAEQ,OAAO,GAAE,mBAAwB;IAI9D,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIpC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE;IAsErD,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,0BAA0B,CAAC,GAAG,MAAM;CAiC/F"}
@@ -0,0 +1,132 @@
1
+ import { BaseExtractor } from "./base-extractor.js";
2
+ const TEXT_TAG_RE = /<text([\s\S]*?)>([\s\S]*?)<\/text>/gi;
3
+ const TITLE_TAG_RE = /<title([\s\S]*?)>([\s\S]*?)<\/title>/gi;
4
+ const DESC_TAG_RE = /<desc([\s\S]*?)>([\s\S]*?)<\/desc>/gi;
5
+ function extractTextFromXml(xml) {
6
+ return xml
7
+ .replace(/<[^>]+>/g, " ")
8
+ .replace(/\s+/g, " ")
9
+ .trim();
10
+ }
11
+ function escapeXml(str) {
12
+ return str
13
+ .replace(/&/g, "&amp;")
14
+ .replace(/</g, "&lt;")
15
+ .replace(/>/g, "&gt;")
16
+ .replace(/"/g, "&quot;")
17
+ .replace(/'/g, "&apos;");
18
+ }
19
+ /**
20
+ * SVG `<text>` / `<title>` / `<desc>` extraction (regex-based).
21
+ * `reassemble` uses the SVG from the last `extract` call on this instance.
22
+ */
23
+ export class SvgExtractor extends BaseExtractor {
24
+ constructor(options = {}) {
25
+ super();
26
+ this.options = options;
27
+ this.name = "svg";
28
+ this.lastSvg = "";
29
+ }
30
+ canHandle(filepath) {
31
+ return filepath.toLowerCase().endsWith(".svg");
32
+ }
33
+ extract(content, filepath) {
34
+ void filepath;
35
+ this.lastSvg = content;
36
+ const segments = [];
37
+ let i = 0;
38
+ let match;
39
+ TEXT_TAG_RE.lastIndex = 0;
40
+ while ((match = TEXT_TAG_RE.exec(content)) !== null) {
41
+ const attrs = match[1] ?? "";
42
+ const innerContent = match[2] ?? "";
43
+ const text = extractTextFromXml(innerContent);
44
+ if (!text) {
45
+ continue;
46
+ }
47
+ const fullMatch = match[0];
48
+ const openingTag = `<text${attrs}>`;
49
+ segments.push({
50
+ id: `svg-${i++}`,
51
+ type: "svg-text",
52
+ content: text,
53
+ hash: this.computeHash(text),
54
+ translatable: true,
55
+ svg: { element: "text", fullMatch, openingTag },
56
+ });
57
+ }
58
+ TITLE_TAG_RE.lastIndex = 0;
59
+ while ((match = TITLE_TAG_RE.exec(content)) !== null) {
60
+ const attrs = match[1] ?? "";
61
+ const innerContent = match[2] ?? "";
62
+ const text = extractTextFromXml(innerContent);
63
+ if (!text) {
64
+ continue;
65
+ }
66
+ const fullMatch = match[0];
67
+ const openingTag = (attrs || "").trim();
68
+ segments.push({
69
+ id: `svg-${i++}`,
70
+ type: "svg-text",
71
+ content: text,
72
+ hash: this.computeHash(text),
73
+ translatable: true,
74
+ svg: { element: "title", fullMatch, openingTag },
75
+ });
76
+ }
77
+ DESC_TAG_RE.lastIndex = 0;
78
+ while ((match = DESC_TAG_RE.exec(content)) !== null) {
79
+ const attrs = match[1] ?? "";
80
+ const innerContent = match[2] ?? "";
81
+ const text = extractTextFromXml(innerContent);
82
+ if (!text) {
83
+ continue;
84
+ }
85
+ const fullMatch = match[0];
86
+ const openingTag = (attrs || "").trim();
87
+ segments.push({
88
+ id: `svg-${i++}`,
89
+ type: "svg-text",
90
+ content: text,
91
+ hash: this.computeHash(text),
92
+ translatable: true,
93
+ svg: { element: "desc", fullMatch, openingTag },
94
+ });
95
+ }
96
+ return segments;
97
+ }
98
+ reassemble(segments, translations) {
99
+ if (!this.lastSvg) {
100
+ throw new Error("SvgExtractor.reassemble: call extract() first");
101
+ }
102
+ let result = this.lastSvg;
103
+ const merged = this.mergeTranslations(segments, translations);
104
+ for (const segment of merged) {
105
+ const meta = segment.svg;
106
+ if (!meta) {
107
+ continue;
108
+ }
109
+ let out = segment.content;
110
+ if (this.options.forceLowercase) {
111
+ out = out.toLowerCase();
112
+ }
113
+ const escaped = escapeXml(out);
114
+ if (meta.element === "text") {
115
+ const newContent = `${meta.openingTag}<tspan>${escaped}</tspan></text>`;
116
+ result = result.replace(meta.fullMatch, newContent);
117
+ }
118
+ else if (meta.element === "title") {
119
+ const attrs = meta.openingTag ? ` ${meta.openingTag}` : "";
120
+ const newContent = `<title${attrs}>${escaped}</title>`;
121
+ result = result.replace(meta.fullMatch, newContent);
122
+ }
123
+ else {
124
+ const attrs = meta.openingTag ? ` ${meta.openingTag}` : "";
125
+ const newContent = `<desc${attrs}>${escaped}</desc>`;
126
+ result = result.replace(meta.fullMatch, newContent);
127
+ }
128
+ }
129
+ return result;
130
+ }
131
+ }
132
+ //# sourceMappingURL=svg-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg-extractor.js","sourceRoot":"","sources":["../../src/extractors/svg-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { Segment, SegmentTranslationMapValue, UIStringExtractorConfig } from "../core/types.js";
2
+ import { BaseExtractor } from "./base-extractor.js";
3
+ /**
4
+ * UI string extraction via `i18next-scanner`. Scans any JS/TS source files for
5
+ * `t("literal")` / `i18n.t("literal")` calls (configurable via `funcNames`).
6
+ * Works in React, Next.js, Node.js, and any other JS/TS codebase using i18next.
7
+ * Segment hashes are MD5 first 8 hex (keys in `strings.json`).
8
+ */
9
+ export declare class UIStringExtractor extends BaseExtractor {
10
+ readonly name = "ui-string";
11
+ private readonly extensions;
12
+ private readonly funcNames;
13
+ private readonly includePackageDescription;
14
+ private readonly packageJsonPath;
15
+ /** Locale key used when {@link reassemble} writes `translated` (single-locale snapshot). */
16
+ private readonly defaultReassembleLocale;
17
+ constructor(config?: Partial<UIStringExtractorConfig>, options?: {
18
+ cwd?: string;
19
+ defaultReassembleLocale?: string;
20
+ });
21
+ protected computeHash(content: string): string;
22
+ canHandle(filepath: string): boolean;
23
+ extract(content: string, filepath: string): Segment[];
24
+ /** Optional `package.json` description as a UI string (About tab pattern). */
25
+ packageDescriptionSegments(): Segment[];
26
+ /**
27
+ * Merge package description segments into a deduped list (by hash).
28
+ */
29
+ mergePackageDescription(fileSegments: Segment[]): Segment[];
30
+ /**
31
+ * Build `strings.json` body: `{ [hash]: { source, translated: { [locale]: text } } }`.
32
+ * Existing file is merged when `existingPath` exists.
33
+ */
34
+ buildStringsJson(segments: Segment[], translationsByLocale: Record<string, Map<string, SegmentTranslationMapValue>>, existingPath?: string): string;
35
+ /**
36
+ * `ContentExtractor` reassemble: emit `strings.json` snapshot with one locale (`defaultReassembleLocale`).
37
+ */
38
+ reassemble(segments: Segment[], translations: Map<string, SegmentTranslationMapValue>): string;
39
+ }
40
+ //# sourceMappingURL=ui-string-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-string-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/ui-string-extractor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,OAAO,EACP,0BAA0B,EAC1B,uBAAuB,EACxB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKpD;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,QAAQ,CAAC,IAAI,eAAe;IAE5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAU;IACpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,4FAA4F;IAC5F,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;gBAG/C,MAAM,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,EACzC,OAAO,GAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,MAAM,CAAA;KAAO;IAclE,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAI9C,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAKpC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE;IA8BrD,8EAA8E;IAC9E,0BAA0B,IAAI,OAAO,EAAE;IA0BvC;;OAEG;IACH,uBAAuB,CAAC,YAAY,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE;IAa3D;;;OAGG;IACH,gBAAgB,CACd,QAAQ,EAAE,OAAO,EAAE,EACnB,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC,EAC7E,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM;IA8CT;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,0BAA0B,CAAC,GAAG,MAAM;CAG/F"}