wuchale 0.3.2 → 0.4.1
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.
- package/README.md +7 -7
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/preprocess/compile.d.ts +4 -0
- package/dist/preprocess/compile.js +50 -0
- package/dist/preprocess/compile.js.map +1 -0
- package/dist/preprocess/gemini.d.ts +4 -0
- package/{preprocess → dist/preprocess}/gemini.js +26 -37
- package/dist/preprocess/gemini.js.map +1 -0
- package/dist/preprocess/index.d.ts +45 -0
- package/{preprocess → dist/preprocess}/index.js +115 -140
- package/dist/preprocess/index.js.map +1 -0
- package/dist/preprocess/prep.d.ts +89 -0
- package/dist/preprocess/prep.js +560 -0
- package/dist/preprocess/prep.js.map +1 -0
- package/dist/runtime.svelte.d.ts +5 -0
- package/dist/runtime.svelte.js +32 -0
- package/dist/runtime.svelte.js.map +1 -0
- package/package.json +18 -6
- package/runtime.svelte +1 -47
- package/index.js +0 -3
- package/preprocess/compile.js +0 -52
- package/preprocess/prep.js +0 -652
package/README.md
CHANGED
|
@@ -102,7 +102,7 @@ then set it up in your main component. Assuming `/src/App.svelte`:
|
|
|
102
102
|
|
|
103
103
|
```svelte
|
|
104
104
|
<script>
|
|
105
|
-
import {setTranslations} from 'wuchale/runtime.svelte'
|
|
105
|
+
import {setTranslations} from 'wuchale/runtime.svelte.js'
|
|
106
106
|
|
|
107
107
|
let locale = $state('en')
|
|
108
108
|
|
|
@@ -292,9 +292,9 @@ This includes all JS/TS code that is:
|
|
|
292
292
|
The rule for this is that all strings and template strings that start with
|
|
293
293
|
capital letters are extracted. Additionally, if they are used inside the
|
|
294
294
|
`<script>` tags and in their own files (third case above), there is the
|
|
295
|
-
additional restriction that they must be inside a `$derived`
|
|
296
|
-
declaration. This is to make the behavior less magic and being more
|
|
297
|
-
Example:
|
|
295
|
+
additional restriction that they must be inside a `$derived` or `$derived.by`
|
|
296
|
+
variable declaration. This is to make the behavior less magic and being more
|
|
297
|
+
explicit. Example:
|
|
298
298
|
|
|
299
299
|
```svelte
|
|
300
300
|
<script>
|
|
@@ -349,10 +349,10 @@ To configure `wuchale`, you pass an object that looks like the following (the
|
|
|
349
349
|
default) to `wuchale()` in your `vite.config.js` `vite.config.ts`:
|
|
350
350
|
|
|
351
351
|
```javascript
|
|
352
|
-
export const defaultOptions = {
|
|
352
|
+
export const defaultOptions: Options = {
|
|
353
353
|
sourceLocale: 'en',
|
|
354
|
-
otherLocales: [
|
|
355
|
-
localesDir: './locales',
|
|
354
|
+
otherLocales: [],
|
|
355
|
+
localesDir: './src/locales',
|
|
356
356
|
heuristic: defaultHeuristic,
|
|
357
357
|
geminiAPIKey: 'env',
|
|
358
358
|
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,uBAAuB,CAAA;AAE1C,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// $$ cd .. && npm run test
|
|
2
|
+
import { parse } from "svelte/compiler";
|
|
3
|
+
function walkCompileNodes(node) {
|
|
4
|
+
if (node.type === 'Text') {
|
|
5
|
+
return [node.data];
|
|
6
|
+
}
|
|
7
|
+
if (node.type === 'Literal') {
|
|
8
|
+
if (typeof node.value === 'number') {
|
|
9
|
+
return [node.value];
|
|
10
|
+
}
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
if (node.type === 'ExpressionTag') {
|
|
14
|
+
return walkCompileNodes(node.expression);
|
|
15
|
+
}
|
|
16
|
+
if (node.type === 'Component') {
|
|
17
|
+
return [[
|
|
18
|
+
Number(node.name.slice(1)),
|
|
19
|
+
...walkCompileNodes(node.fragment),
|
|
20
|
+
]];
|
|
21
|
+
}
|
|
22
|
+
if (node.type === 'Fragment') {
|
|
23
|
+
const parts = [];
|
|
24
|
+
for (const child of node.nodes) {
|
|
25
|
+
parts.push(...walkCompileNodes(child));
|
|
26
|
+
}
|
|
27
|
+
return parts;
|
|
28
|
+
}
|
|
29
|
+
console.error('Unexpected node type', node);
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
export default function compileTranslation(text, fallback) {
|
|
33
|
+
if (!text) {
|
|
34
|
+
return fallback;
|
|
35
|
+
}
|
|
36
|
+
if (!text.includes('<') && !text.includes('{')) {
|
|
37
|
+
return text;
|
|
38
|
+
}
|
|
39
|
+
// <0></0> to <X0></X0> to please svelte parser
|
|
40
|
+
text = text.replace(/(<|(<\/))(\d+)/g, '$1X$3');
|
|
41
|
+
try {
|
|
42
|
+
const ast = parse(text, { modern: true });
|
|
43
|
+
return walkCompileNodes(ast.fragment);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error(err);
|
|
47
|
+
return fallback;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/preprocess/compile.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAOvC,SAAS,gBAAgB,CAAC,IAAgG;IACtH,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACvB,CAAC;QACD,OAAO,EAAE,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAChC,OAAO,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC5C,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC5B,OAAO,CAAC;gBACJ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC1B,GAAG,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;aACrC,CAAC,CAAA;IACN,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,EAAE,CAAA;QAChB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAA;QAC1C,CAAC;QACD,OAAO,KAAK,CAAA;IAChB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAA;IAC3C,OAAO,EAAE,CAAA;AACb,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,IAAY,EAAE,QAA0B;IAC/E,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,QAAQ,CAAA;IACnB,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAA;IACf,CAAC;IACD,+CAA+C;IAC/C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;IAC/C,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QACzC,OAAO,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAClB,OAAO,QAAQ,CAAA;IACnB,CAAC;AACL,CAAC"}
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
// $$ cd .. && npm run test
|
|
2
2
|
// $$ node %f
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @param {import('pofile').Item[]} fragments
|
|
11
|
-
* @param {string} sourceLocale
|
|
12
|
-
* @param {string} targetLocale
|
|
13
|
-
*/
|
|
3
|
+
import PO from 'pofile';
|
|
4
|
+
const baseURL = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=';
|
|
5
|
+
const h = { 'Content-Type': 'application/json' };
|
|
6
|
+
function codeStandard(locale) {
|
|
7
|
+
return `ISO 639-${locale.length === 2 ? 1 : 3}`;
|
|
8
|
+
}
|
|
14
9
|
function prepareData(fragments, sourceLocale, targetLocale) {
|
|
15
10
|
const instruction = `
|
|
16
11
|
You will be given the contents of a gettext .po file for a web app.
|
|
17
12
|
Translate each of the items from the source to the target language.
|
|
18
|
-
|
|
19
|
-
The
|
|
20
|
-
The target language is: ${targetLocale}.
|
|
13
|
+
The source language ${codeStandard(sourceLocale)} code is: ${sourceLocale}.
|
|
14
|
+
The target language ${codeStandard(targetLocale)} code is: ${targetLocale}.
|
|
21
15
|
You can read all of the information for the items including contexts,
|
|
22
16
|
comments and references to get the appropriate context about each item.
|
|
23
17
|
Provide the translated fragments in the in the same order, preserving
|
|
@@ -27,40 +21,35 @@ function prepareData(fragments, sourceLocale, targetLocale) {
|
|
|
27
21
|
- <0>something</0>: means something enclosed in some tags, like HTML tags
|
|
28
22
|
- <0/>: means a self closing tag, like in HTML
|
|
29
23
|
In all of the examples, 0 is an example for any integer.
|
|
30
|
-
|
|
31
|
-
const po = new PO()
|
|
32
|
-
po.items = fragments
|
|
24
|
+
`;
|
|
25
|
+
const po = new PO();
|
|
26
|
+
po.items = fragments;
|
|
33
27
|
return {
|
|
34
28
|
system_instruction: {
|
|
35
29
|
parts: [{ text: instruction }]
|
|
36
30
|
},
|
|
37
|
-
contents: [{parts: [{text: po.toString()}]}]
|
|
38
|
-
}
|
|
31
|
+
contents: [{ parts: [{ text: po.toString() }] }]
|
|
32
|
+
};
|
|
39
33
|
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* @param {string} targetLocale
|
|
43
|
-
* @param {string | undefined} apiKey
|
|
44
|
-
*/
|
|
45
|
-
function setupGemini(sourceLocale = 'en', targetLocale, apiKey) {
|
|
34
|
+
function setupGemini(sourceLocale, targetLocale, apiKey) {
|
|
46
35
|
if (apiKey === 'env') {
|
|
47
|
-
apiKey = process.env.GEMINI_API_KEY
|
|
36
|
+
apiKey = process.env.GEMINI_API_KEY;
|
|
48
37
|
}
|
|
49
38
|
if (!apiKey) {
|
|
50
|
-
return
|
|
39
|
+
return;
|
|
51
40
|
}
|
|
52
|
-
const url = `${baseURL}${apiKey}
|
|
53
|
-
return async (
|
|
54
|
-
const data = prepareData(fragments, sourceLocale, targetLocale)
|
|
55
|
-
const res = await fetch(url, {method: 'POST', headers: h, body: JSON.stringify(data)})
|
|
56
|
-
const json = await res.json()
|
|
57
|
-
const resText = json.candidates[0]
|
|
41
|
+
const url = `${baseURL}${apiKey}`;
|
|
42
|
+
return async (fragments) => {
|
|
43
|
+
const data = prepareData(fragments, sourceLocale, targetLocale);
|
|
44
|
+
const res = await fetch(url, { method: 'POST', headers: h, body: JSON.stringify(data) });
|
|
45
|
+
const json = await res.json();
|
|
46
|
+
const resText = json.candidates[0]?.content.parts[0].text;
|
|
58
47
|
for (const [i, item] of PO.parse(resText).items.entries()) {
|
|
59
48
|
if (item.msgstr[0]) {
|
|
60
|
-
fragments[i].msgstr = item.msgstr
|
|
49
|
+
fragments[i].msgstr = item.msgstr;
|
|
61
50
|
}
|
|
62
51
|
}
|
|
63
|
-
}
|
|
52
|
+
};
|
|
64
53
|
}
|
|
65
|
-
|
|
66
|
-
|
|
54
|
+
export default setupGemini;
|
|
55
|
+
//# sourceMappingURL=gemini.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/preprocess/gemini.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,aAAa;AAEb,OAAO,EAAE,MAAM,QAAQ,CAAA;AAEvB,MAAM,OAAO,GAAG,+FAA+F,CAAA;AAC/G,MAAM,CAAC,GAAG,EAAC,cAAc,EAAE,kBAAkB,EAAC,CAAA;AAE9C,SAAS,YAAY,CAAC,MAAc;IAChC,OAAO,WAAW,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACnD,CAAC;AAID,SAAS,WAAW,CAAC,SAAqB,EAAE,YAAoB,EAAE,YAAoB;IAClF,MAAM,WAAW,GAAG;;;8BAGM,YAAY,CAAC,YAAY,CAAC,aAAa,YAAY;8BACnD,YAAY,CAAC,YAAY,CAAC,aAAa,YAAY;;;;;;;;;;KAU5E,CAAA;IACD,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,CAAA;IACnB,EAAE,CAAC,KAAK,GAAG,SAAS,CAAA;IACpB,OAAO;QACH,kBAAkB,EAAE;YAChB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;SACjC;QACD,QAAQ,EAAE,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAC,CAAC,EAAC,CAAC;KAC/C,CAAA;AACL,CAAC;AAUD,SAAS,WAAW,CAAC,YAAoB,EAAE,YAAoB,EAAE,MAAqB;IAClF,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACnB,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;IACvC,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAM;IACV,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,OAAO,GAAG,MAAM,EAAE,CAAA;IACjC,OAAO,KAAK,EAAE,SAAqB,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,CAAA;QAC/D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAC,CAAC,CAAA;QACtF,MAAM,IAAI,GAAc,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACzD,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YACxD,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjB,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YACrC,CAAC;QACL,CAAC;IACL,CAAC,CAAA;AACL,CAAC;AAED,eAAe,WAAW,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type HeuristicFunc } from "./prep.js";
|
|
2
|
+
import { type AST } from "svelte/compiler";
|
|
3
|
+
import { type CompiledFragment } from "./compile.js";
|
|
4
|
+
import type { Program } from 'estree';
|
|
5
|
+
export interface Options {
|
|
6
|
+
sourceLocale?: string;
|
|
7
|
+
otherLocales?: string[];
|
|
8
|
+
localesDir?: string;
|
|
9
|
+
heuristic?: HeuristicFunc;
|
|
10
|
+
geminiAPIKey?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const defaultOptions: Options;
|
|
13
|
+
export default function wuchale(options?: Options): Promise<{
|
|
14
|
+
name: string;
|
|
15
|
+
configResolved(config: {
|
|
16
|
+
env: {
|
|
17
|
+
PROD?: boolean;
|
|
18
|
+
};
|
|
19
|
+
root: string;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
transform: {
|
|
22
|
+
order: "pre";
|
|
23
|
+
handler: (code: string, id: string) => Promise<{
|
|
24
|
+
code?: undefined;
|
|
25
|
+
map?: undefined;
|
|
26
|
+
} | {
|
|
27
|
+
code: string;
|
|
28
|
+
map: import("magic-string").SourceMap;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
31
|
+
buildEnd(): Promise<void>;
|
|
32
|
+
setupTesting(): {
|
|
33
|
+
translations: {};
|
|
34
|
+
compiled: {
|
|
35
|
+
[locale: string]: CompiledFragment[];
|
|
36
|
+
};
|
|
37
|
+
preprocess: (content: string, ast: AST.Root | Program, filename: string) => Promise<{
|
|
38
|
+
code?: undefined;
|
|
39
|
+
map?: undefined;
|
|
40
|
+
} | {
|
|
41
|
+
code: string;
|
|
42
|
+
map: import("magic-string").SourceMap;
|
|
43
|
+
}>;
|
|
44
|
+
};
|
|
45
|
+
}>;
|
|
@@ -1,248 +1,223 @@
|
|
|
1
|
-
import Preprocess, { defaultHeuristic, IndexTracker, NestText } from "./prep.js"
|
|
2
|
-
import { parse } from "svelte/compiler"
|
|
3
|
-
import {writeFile} from 'node:fs/promises'
|
|
4
|
-
import compileTranslation from "./compile.js"
|
|
5
|
-
import setupGemini from "./gemini.js"
|
|
6
|
-
import PO from "pofile"
|
|
7
|
-
import { normalize, relative } from "node:path"
|
|
8
|
-
|
|
1
|
+
import Preprocess, { defaultHeuristic, IndexTracker, NestText } from "./prep.js";
|
|
2
|
+
import { parse } from "svelte/compiler";
|
|
3
|
+
import { writeFile } from 'node:fs/promises';
|
|
4
|
+
import compileTranslation, {} from "./compile.js";
|
|
5
|
+
import setupGemini, {} from "./gemini.js";
|
|
6
|
+
import PO from "pofile";
|
|
7
|
+
import { normalize, relative } from "node:path";
|
|
9
8
|
export const defaultOptions = {
|
|
10
9
|
sourceLocale: 'en',
|
|
11
|
-
otherLocales: [
|
|
10
|
+
otherLocales: [],
|
|
12
11
|
localesDir: './src/locales',
|
|
13
12
|
heuristic: defaultHeuristic,
|
|
14
13
|
geminiAPIKey: 'env',
|
|
14
|
+
};
|
|
15
|
+
function mergeOptionsWithDefault(options = defaultOptions) {
|
|
16
|
+
for (const key of Object.keys(defaultOptions)) {
|
|
17
|
+
if (key in options) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
options[key] = defaultOptions[key];
|
|
21
|
+
}
|
|
15
22
|
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* @param {string} filename
|
|
19
|
-
*/
|
|
20
23
|
async function loadPONoFail(filename) {
|
|
21
24
|
return new Promise((res) => {
|
|
22
25
|
PO.load(filename, (err, po) => {
|
|
23
|
-
const translations = {}
|
|
24
|
-
let total = 0
|
|
25
|
-
let obsolete = 0
|
|
26
|
-
let untranslated = 0
|
|
26
|
+
const translations = {};
|
|
27
|
+
let total = 0;
|
|
28
|
+
let obsolete = 0;
|
|
29
|
+
let untranslated = 0;
|
|
27
30
|
if (!err) {
|
|
28
31
|
for (const item of po.items) {
|
|
29
|
-
total
|
|
32
|
+
total++;
|
|
30
33
|
if (item.obsolete) {
|
|
31
|
-
obsolete
|
|
32
|
-
continue
|
|
34
|
+
obsolete++;
|
|
35
|
+
continue;
|
|
33
36
|
}
|
|
34
37
|
if (!item.msgstr[0]) {
|
|
35
|
-
untranslated
|
|
38
|
+
untranslated++;
|
|
36
39
|
}
|
|
37
|
-
const nTxt = new NestText(item.msgid, null, item.msgctxt)
|
|
38
|
-
translations[nTxt.toKey()] = item
|
|
40
|
+
const nTxt = new NestText(item.msgid, null, item.msgctxt);
|
|
41
|
+
translations[nTxt.toKey()] = item;
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
|
-
res({translations, total, obsolete, untranslated})
|
|
42
|
-
})
|
|
43
|
-
})
|
|
44
|
+
res({ translations, total, obsolete, untranslated });
|
|
45
|
+
});
|
|
46
|
+
});
|
|
44
47
|
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @param {{ [s: string]: any; } | ArrayLike<any>} translations
|
|
48
|
-
* @param {string} filename
|
|
49
|
-
*/
|
|
50
48
|
async function savePO(translations, filename) {
|
|
51
|
-
const po = new PO()
|
|
49
|
+
const po = new PO();
|
|
52
50
|
for (const item of Object.values(translations)) {
|
|
53
|
-
po.items.push(item)
|
|
51
|
+
po.items.push(item);
|
|
54
52
|
}
|
|
55
53
|
return new Promise((res, rej) => {
|
|
56
54
|
po.save(filename, err => {
|
|
57
55
|
if (err) {
|
|
58
|
-
rej(err)
|
|
59
|
-
} else {
|
|
60
|
-
res()
|
|
56
|
+
rej(err);
|
|
61
57
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
for (const key of Object.keys(defaultOptions)) {
|
|
68
|
-
if (key in options) {
|
|
69
|
-
continue
|
|
70
|
-
}
|
|
71
|
-
options[key] = defaultOptions[key]
|
|
72
|
-
}
|
|
58
|
+
else {
|
|
59
|
+
res(null);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
73
63
|
}
|
|
74
|
-
|
|
75
64
|
export default async function wuchale(options = defaultOptions) {
|
|
76
|
-
mergeOptionsWithDefault(options)
|
|
77
|
-
const locales = [options.sourceLocale, ...options.otherLocales]
|
|
78
|
-
const translations = {}
|
|
79
|
-
const compiledFname = {}
|
|
80
|
-
const translationsFname = {}
|
|
65
|
+
mergeOptionsWithDefault(options);
|
|
66
|
+
const locales = [options.sourceLocale, ...options.otherLocales];
|
|
67
|
+
const translations = {};
|
|
68
|
+
const compiledFname = {};
|
|
69
|
+
const translationsFname = {};
|
|
81
70
|
for (const loc of locales) {
|
|
82
|
-
compiledFname[loc] = `${options.localesDir}/${loc}.json
|
|
83
|
-
translationsFname[loc] = `${options.localesDir}/${loc}.po
|
|
71
|
+
compiledFname[loc] = `${options.localesDir}/${loc}.json`;
|
|
72
|
+
translationsFname[loc] = `${options.localesDir}/${loc}.po`;
|
|
84
73
|
}
|
|
85
|
-
|
|
86
|
-
let
|
|
87
|
-
let
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
let indexTracker = new IndexTracker({})
|
|
91
|
-
|
|
92
|
-
const compiled = {}
|
|
93
|
-
|
|
74
|
+
let forProduction = false;
|
|
75
|
+
let projectRoot = '';
|
|
76
|
+
let sourceTranslations = {};
|
|
77
|
+
let indexTracker = new IndexTracker({});
|
|
78
|
+
const compiled = {};
|
|
94
79
|
async function loadFilesAndSetup() {
|
|
95
80
|
for (const loc of locales) {
|
|
96
|
-
const {translations: trans, total, obsolete, untranslated} = await loadPONoFail(translationsFname[loc])
|
|
97
|
-
translations[loc] = trans
|
|
98
|
-
console.info(`i18n stats (${loc}): total: ${total}, obsolete: ${obsolete}, untranslated: ${untranslated}`)
|
|
81
|
+
const { translations: trans, total, obsolete, untranslated } = await loadPONoFail(translationsFname[loc]);
|
|
82
|
+
translations[loc] = trans;
|
|
83
|
+
console.info(`i18n stats (${loc}): total: ${total}, obsolete: ${obsolete}, untranslated: ${untranslated}`);
|
|
99
84
|
}
|
|
100
|
-
sourceTranslations = translations[options.sourceLocale]
|
|
101
|
-
indexTracker = new IndexTracker(sourceTranslations)
|
|
85
|
+
sourceTranslations = translations[options.sourceLocale];
|
|
86
|
+
indexTracker = new IndexTracker(sourceTranslations);
|
|
102
87
|
// startup compile
|
|
103
88
|
for (const loc of locales) {
|
|
104
|
-
compiled[loc] = []
|
|
89
|
+
compiled[loc] = [];
|
|
105
90
|
for (const key in translations[loc]) {
|
|
106
|
-
const poItem = translations[loc][key]
|
|
91
|
+
const poItem = translations[loc][key];
|
|
107
92
|
if (forProduction) {
|
|
108
|
-
poItem.references = []
|
|
93
|
+
poItem.references = [];
|
|
109
94
|
}
|
|
110
|
-
const index = indexTracker.get(key)
|
|
111
|
-
compiled[loc][index] = compileTranslation(poItem.msgstr[0], compiled[options.sourceLocale][index])
|
|
95
|
+
const index = indexTracker.get(key);
|
|
96
|
+
compiled[loc][index] = compileTranslation(poItem.msgstr[0], compiled[options.sourceLocale][index]);
|
|
112
97
|
}
|
|
113
|
-
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc], null, 2))
|
|
98
|
+
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc], null, 2));
|
|
114
99
|
}
|
|
115
100
|
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* @param {string} content
|
|
119
|
-
* @param {import('estree').Program | import("svelte/compiler").AST.Root} ast
|
|
120
|
-
* @param {string} filename
|
|
121
|
-
*/
|
|
122
101
|
async function preprocess(content, ast, filename) {
|
|
123
|
-
const prep = new Preprocess(indexTracker, options.heuristic)
|
|
124
|
-
const txts = prep.process(content, ast)
|
|
102
|
+
const prep = new Preprocess(indexTracker, options.heuristic);
|
|
103
|
+
const txts = prep.process(content, ast);
|
|
125
104
|
if (!txts.length) {
|
|
126
|
-
return {}
|
|
105
|
+
return {};
|
|
127
106
|
}
|
|
128
107
|
for (const loc of locales) {
|
|
129
|
-
const newTxts = []
|
|
108
|
+
const newTxts = [];
|
|
130
109
|
for (const nTxt of txts) {
|
|
131
|
-
let key = nTxt.toKey()
|
|
132
|
-
let translated = translations[loc][key]
|
|
110
|
+
let key = nTxt.toKey();
|
|
111
|
+
let translated = translations[loc][key];
|
|
133
112
|
if (translated == null) {
|
|
134
|
-
translated = new PO.Item()
|
|
135
|
-
translated.msgid = nTxt.toString()
|
|
136
|
-
translations[loc][key] = translated
|
|
113
|
+
translated = new PO.Item();
|
|
114
|
+
translated.msgid = nTxt.toString();
|
|
115
|
+
translations[loc][key] = translated;
|
|
137
116
|
}
|
|
138
117
|
if (nTxt.context) {
|
|
139
|
-
translated.msgctxt = nTxt.context
|
|
118
|
+
translated.msgctxt = nTxt.context;
|
|
140
119
|
}
|
|
141
120
|
if (!translated.references.includes(filename)) {
|
|
142
|
-
translated.references.push(filename)
|
|
121
|
+
translated.references.push(filename);
|
|
143
122
|
}
|
|
144
123
|
if (loc === options.sourceLocale) {
|
|
145
|
-
const txt = nTxt.toString()
|
|
124
|
+
const txt = nTxt.toString();
|
|
146
125
|
if (translated.msgstr[0] !== txt) {
|
|
147
|
-
translated.msgstr = [txt]
|
|
148
|
-
newTxts.push(translated)
|
|
126
|
+
translated.msgstr = [txt];
|
|
127
|
+
newTxts.push(translated);
|
|
149
128
|
}
|
|
150
|
-
}
|
|
151
|
-
|
|
129
|
+
}
|
|
130
|
+
else if (!translated.msgstr[0]) {
|
|
131
|
+
newTxts.push(translated);
|
|
152
132
|
}
|
|
153
133
|
}
|
|
154
134
|
if (loc !== options.sourceLocale && newTxts.length) {
|
|
155
|
-
const geminiT = setupGemini(options.sourceLocale, loc, options.geminiAPIKey)
|
|
135
|
+
const geminiT = setupGemini(options.sourceLocale, loc, options.geminiAPIKey);
|
|
156
136
|
if (geminiT) {
|
|
157
|
-
console.info('Gemini translate', newTxts.length, 'items...')
|
|
158
|
-
await geminiT(newTxts) // will update because it's by reference
|
|
137
|
+
console.info('Gemini translate', newTxts.length, 'items...');
|
|
138
|
+
await geminiT(newTxts); // will update because it's by reference
|
|
159
139
|
}
|
|
160
140
|
}
|
|
161
141
|
for (const nTxt of txts) {
|
|
162
|
-
const key = nTxt.toKey()
|
|
163
|
-
const index = indexTracker.get(key)
|
|
164
|
-
compiled[loc][index] = compileTranslation(translations[loc][key].msgstr[0], compiled[options.sourceLocale][index])
|
|
142
|
+
const key = nTxt.toKey();
|
|
143
|
+
const index = indexTracker.get(key);
|
|
144
|
+
compiled[loc][index] = compileTranslation(translations[loc][key].msgstr[0], compiled[options.sourceLocale][index]);
|
|
165
145
|
}
|
|
166
146
|
for (const [i, c] of compiled[loc].entries()) {
|
|
167
147
|
if (c == null) {
|
|
168
|
-
compiled[loc][i] = 0 // reduce json size for jumped indices, instead of null
|
|
148
|
+
compiled[loc][i] = 0; // reduce json size for jumped indices, instead of null
|
|
169
149
|
}
|
|
170
150
|
}
|
|
171
151
|
if (!newTxts.length) {
|
|
172
|
-
continue
|
|
152
|
+
continue;
|
|
173
153
|
}
|
|
174
154
|
}
|
|
175
155
|
return {
|
|
176
156
|
code: prep.mstr.toString(),
|
|
177
157
|
map: prep.mstr.generateMap(),
|
|
178
|
-
}
|
|
158
|
+
};
|
|
179
159
|
}
|
|
180
|
-
|
|
160
|
+
const order = 'pre';
|
|
181
161
|
return {
|
|
182
162
|
name: 'wuchale',
|
|
183
|
-
/**
|
|
184
|
-
* @param {{ env: { PROD: boolean; }, root: string; }} config
|
|
185
|
-
*/
|
|
186
163
|
async configResolved(config) {
|
|
187
|
-
forProduction = config.env.PROD
|
|
188
|
-
projectRoot = config.root
|
|
189
|
-
await loadFilesAndSetup()
|
|
164
|
+
forProduction = config.env.PROD;
|
|
165
|
+
projectRoot = config.root;
|
|
166
|
+
await loadFilesAndSetup();
|
|
190
167
|
},
|
|
191
168
|
transform: {
|
|
192
|
-
order
|
|
193
|
-
|
|
194
|
-
* @param {string} code
|
|
195
|
-
* @param {string} id
|
|
196
|
-
*/
|
|
197
|
-
handler: async function(code, id) {
|
|
169
|
+
order,
|
|
170
|
+
handler: async function (code, id) {
|
|
198
171
|
if (!id.startsWith(projectRoot) || id.startsWith(normalize(projectRoot + '/node_modules'))) {
|
|
199
|
-
return
|
|
172
|
+
return;
|
|
200
173
|
}
|
|
201
|
-
const isModule = id.endsWith('.svelte.js') || id.endsWith('.svelte.ts')
|
|
174
|
+
const isModule = id.endsWith('.svelte.js') || id.endsWith('.svelte.ts');
|
|
202
175
|
if (!id.endsWith('.svelte') && !isModule) {
|
|
203
|
-
return
|
|
176
|
+
return;
|
|
204
177
|
}
|
|
205
|
-
let ast
|
|
178
|
+
let ast;
|
|
206
179
|
if (isModule) {
|
|
207
|
-
ast = this.parse(code)
|
|
208
|
-
}
|
|
209
|
-
|
|
180
|
+
ast = this.parse(code);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
ast = parse(code, { modern: true });
|
|
210
184
|
}
|
|
211
|
-
const filename = relative(projectRoot, id)
|
|
212
|
-
const processed = await preprocess(code, ast, filename)
|
|
185
|
+
const filename = relative(projectRoot, id);
|
|
186
|
+
const processed = await preprocess(code, ast, filename);
|
|
213
187
|
if (processed.code) {
|
|
214
188
|
for (const loc of locales) {
|
|
215
|
-
await savePO(translations[loc], translationsFname[loc])
|
|
216
|
-
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc]))
|
|
189
|
+
await savePO(translations[loc], translationsFname[loc]);
|
|
190
|
+
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc]));
|
|
217
191
|
}
|
|
218
192
|
}
|
|
219
|
-
return processed
|
|
193
|
+
return processed;
|
|
220
194
|
}
|
|
221
195
|
},
|
|
222
196
|
async buildEnd() {
|
|
223
197
|
if (!forProduction) {
|
|
224
198
|
// just being pragmatic
|
|
225
|
-
return
|
|
199
|
+
return;
|
|
226
200
|
}
|
|
227
201
|
for (const loc of locales) {
|
|
228
202
|
for (const key in translations[loc]) {
|
|
229
|
-
const poItem = translations[loc][key]
|
|
230
|
-
poItem.obsolete = poItem.references.length === 0
|
|
203
|
+
const poItem = translations[loc][key];
|
|
204
|
+
poItem.obsolete = poItem.references.length === 0;
|
|
231
205
|
}
|
|
232
|
-
await savePO(translations[loc], translationsFname[loc])
|
|
206
|
+
await savePO(translations[loc], translationsFname[loc]);
|
|
233
207
|
}
|
|
234
208
|
},
|
|
235
209
|
setupTesting() {
|
|
236
210
|
for (const loc of locales) {
|
|
237
|
-
translations[loc] = {}
|
|
238
|
-
compiled[loc] = []
|
|
211
|
+
translations[loc] = {};
|
|
212
|
+
compiled[loc] = [];
|
|
239
213
|
}
|
|
240
|
-
sourceTranslations = translations[options.sourceLocale]
|
|
214
|
+
sourceTranslations = translations[options.sourceLocale];
|
|
241
215
|
return {
|
|
242
216
|
translations,
|
|
243
217
|
compiled,
|
|
244
218
|
preprocess,
|
|
245
|
-
}
|
|
219
|
+
};
|
|
246
220
|
}
|
|
247
|
-
}
|
|
221
|
+
};
|
|
248
222
|
}
|
|
223
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/preprocess/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,EAAE,EAAE,gBAAgB,EAAE,YAAY,EAAE,QAAQ,EAAyC,MAAM,WAAW,CAAA;AACvH,OAAO,EAAE,KAAK,EAAY,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,kBAAkB,EAAE,EAAyB,MAAM,cAAc,CAAA;AACxE,OAAO,WAAW,EAAE,EAAiB,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,MAAM,QAAQ,CAAA;AACvB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAW/C,MAAM,CAAC,MAAM,cAAc,GAAY;IACnC,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,EAAE;IAChB,UAAU,EAAE,eAAe;IAC3B,SAAS,EAAE,gBAAgB;IAC3B,YAAY,EAAE,KAAK;CACtB,CAAA;AAED,SAAS,uBAAuB,CAAC,OAAO,GAAG,cAAc;IACrD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5C,IAAI,GAAG,IAAI,OAAO,EAAE,CAAC;YACjB,SAAQ;QACZ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;IACtC,CAAC;AACL,CAAC;AASD,KAAK,UAAU,YAAY,CAAC,QAAgB;IACxC,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACvB,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;YAC1B,MAAM,YAAY,GAAiB,EAAE,CAAA;YACrC,IAAI,KAAK,GAAG,CAAC,CAAA;YACb,IAAI,QAAQ,GAAG,CAAC,CAAA;YAChB,IAAI,YAAY,GAAG,CAAC,CAAA;YACpB,IAAI,CAAC,GAAG,EAAE,CAAC;gBACP,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;oBAC1B,KAAK,EAAE,CAAA;oBACP,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;wBAChB,QAAQ,EAAE,CAAA;wBACV,SAAQ;oBACZ,CAAC;oBACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;wBAClB,YAAY,EAAE,CAAA;oBAClB,CAAC;oBACD,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;oBACzD,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;gBACrC,CAAC;YACL,CAAC;YACD,GAAG,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAA;QACxD,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,YAAwB,EAAE,QAAgB;IAC5D,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,CAAA;IACnB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7C,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACvB,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC5B,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE;YACpB,IAAI,GAAG,EAAE,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,CAAA;YACZ,CAAC;iBAAM,CAAC;gBACJ,GAAG,CAAC,IAAI,CAAC,CAAA;YACb,CAAC;QACL,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,OAAO,CAAC,OAAO,GAAG,cAAc;IAC1D,uBAAuB,CAAC,OAAO,CAAC,CAAA;IAChC,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAC/D,MAAM,YAAY,GAAG,EAAE,CAAA;IACvB,MAAM,aAAa,GAAG,EAAE,CAAA;IACxB,MAAM,iBAAiB,GAAG,EAAE,CAAA;IAC5B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QACxB,aAAa,CAAC,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,UAAU,IAAI,GAAG,OAAO,CAAA;QACxD,iBAAiB,CAAC,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,UAAU,IAAI,GAAG,KAAK,CAAA;IAC9D,CAAC;IAED,IAAI,aAAa,GAAG,KAAK,CAAA;IACzB,IAAI,WAAW,GAAG,EAAE,CAAA;IAEpB,IAAI,kBAAkB,GAAG,EAAE,CAAA;IAC3B,IAAI,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAA;IAEvC,MAAM,QAAQ,GAA6C,EAAE,CAAA;IAE7D,KAAK,UAAU,iBAAiB;QAC5B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,YAAY,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAA;YACzG,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;YACzB,OAAO,CAAC,IAAI,CAAC,eAAe,GAAG,aAAa,KAAK,eAAe,QAAQ,mBAAmB,YAAY,EAAE,CAAC,CAAA;QAC9G,CAAC;QACD,kBAAkB,GAAG,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QACvD,YAAY,GAAG,IAAI,YAAY,CAAC,kBAAkB,CAAC,CAAA;QACnD,kBAAkB;QAClB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YACxB,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;YAClB,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;gBACrC,IAAI,aAAa,EAAE,CAAC;oBAChB,MAAM,CAAC,UAAU,GAAG,EAAE,CAAA;gBAC1B,CAAC;gBACD,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBACnC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;YACtG,CAAC;YACD,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAC/E,CAAC;IACL,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,GAAuB,EAAE,QAAgB;QAChF,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QACvC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACf,OAAO,EAAE,CAAA;QACb,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,EAAE,CAAA;YAClB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;gBACtB,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;gBACtB,IAAI,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;gBACvC,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;oBACrB,UAAU,GAAG,IAAI,EAAE,CAAC,IAAI,EAAE,CAAA;oBAC1B,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;oBAClC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAA;gBACvC,CAAC;gBACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACf,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;gBACrC,CAAC;gBACD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC5C,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;gBACxC,CAAC;gBACD,IAAI,GAAG,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC;oBAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;oBAC3B,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;wBAC/B,UAAU,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAA;wBACzB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;oBAC5B,CAAC;gBACL,CAAC;qBAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC/B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;gBAC5B,CAAC;YACL,CAAC;YACD,IAAI,GAAG,KAAK,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACjD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;gBAC5E,IAAI,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;oBAC5D,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA,CAAC,wCAAwC;gBACnE,CAAC;YACL,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;gBACtB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;gBACxB,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBACnC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;YACtH,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC3C,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;oBACZ,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA,CAAC,uDAAuD;gBAChF,CAAC;YACL,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBAClB,SAAQ;YACZ,CAAC;QACL,CAAC;QACD,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC1B,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;SAC/B,CAAA;IACL,CAAC;IAED,MAAM,KAAK,GAAU,KAAK,CAAA;IAC1B,OAAO;QACH,IAAI,EAAE,SAAS;QACf,KAAK,CAAC,cAAc,CAAC,MAAmD;YACpE,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAA;YAC/B,WAAW,GAAG,MAAM,CAAC,IAAI,CAAA;YACzB,MAAM,iBAAiB,EAAE,CAAA;QAC7B,CAAC;QACD,SAAS,EAAE;YACP,KAAK;YACL,OAAO,EAAE,KAAK,WAAU,IAAY,EAAE,EAAU;gBAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,WAAW,GAAG,eAAe,CAAC,CAAC,EAAE,CAAC;oBACzF,OAAM;gBACV,CAAC;gBACD,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;gBACvE,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACvC,OAAM;gBACV,CAAC;gBACD,IAAI,GAAuB,CAAA;gBAC3B,IAAI,QAAQ,EAAE,CAAC;oBACX,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBAC1B,CAAC;qBAAM,CAAC;oBACJ,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;gBACvC,CAAC;gBACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;gBAC1C,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;gBACvD,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;oBACjB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;wBACxB,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAA;wBACvD,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;oBACtE,CAAC;gBACL,CAAC;gBACD,OAAO,SAAS,CAAA;YACpB,CAAC;SACJ;QACD,KAAK,CAAC,QAAQ;YACV,IAAI,CAAC,aAAa,EAAE,CAAC;gBACjB,uBAAuB;gBACvB,OAAM;YACV,CAAC;YACD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBACxB,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;oBAClC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;oBACrC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAA;gBACpD,CAAC;gBACD,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAA;YAC3D,CAAC;QACL,CAAC;QACD,YAAY;YACR,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBACxB,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;gBACtB,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;YACtB,CAAC;YACD,kBAAkB,GAAG,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;YACvD,OAAO;gBACH,YAAY;gBACZ,QAAQ;gBACR,UAAU;aACb,CAAA;QACL,CAAC;KACJ,CAAA;AACL,CAAC"}
|