@el-j/google-sheet-translations 1.3.3 → 2.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 (60) hide show
  1. package/README.md +58 -55
  2. package/dist/action-entrypoint.d.ts +2 -0
  3. package/dist/action-entrypoint.d.ts.map +1 -0
  4. package/dist/esm/index.js +1226 -0
  5. package/dist/esm/package.json +1 -0
  6. package/dist/index.d.ts +8 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1288 -41
  9. package/dist/utils/dataConverter/findLocalChanges.d.ts +2 -1
  10. package/dist/utils/dataConverter/findLocalChanges.d.ts.map +1 -1
  11. package/dist/utils/localeNormalizer.d.ts +31 -0
  12. package/dist/utils/localeNormalizer.d.ts.map +1 -1
  13. package/dist/utils/translationHelpers.d.ts +107 -0
  14. package/dist/utils/translationHelpers.d.ts.map +1 -0
  15. package/package.json +21 -14
  16. package/dist/constants.js +0 -9
  17. package/dist/constants.js.map +0 -1
  18. package/dist/getSpreadSheetData.js +0 -170
  19. package/dist/getSpreadSheetData.js.map +0 -1
  20. package/dist/index.js.map +0 -1
  21. package/dist/types.js +0 -3
  22. package/dist/types.js.map +0 -1
  23. package/dist/utils/auth.js +0 -23
  24. package/dist/utils/auth.js.map +0 -1
  25. package/dist/utils/configurationHandler.js +0 -29
  26. package/dist/utils/configurationHandler.js.map +0 -1
  27. package/dist/utils/dataConverter/convertFromDataJsonFormat.js +0 -47
  28. package/dist/utils/dataConverter/convertFromDataJsonFormat.js.map +0 -1
  29. package/dist/utils/dataConverter/convertToDataJsonFormat.js +0 -51
  30. package/dist/utils/dataConverter/convertToDataJsonFormat.js.map +0 -1
  31. package/dist/utils/dataConverter/findLocalChanges.js +0 -70
  32. package/dist/utils/dataConverter/findLocalChanges.js.map +0 -1
  33. package/dist/utils/fileWriter.js +0 -119
  34. package/dist/utils/fileWriter.js.map +0 -1
  35. package/dist/utils/getFileLastModified.js +0 -23
  36. package/dist/utils/getFileLastModified.js.map +0 -1
  37. package/dist/utils/isDataJsonNewer.js +0 -40
  38. package/dist/utils/isDataJsonNewer.js.map +0 -1
  39. package/dist/utils/localeFilter.js +0 -49
  40. package/dist/utils/localeFilter.js.map +0 -1
  41. package/dist/utils/localeNormalizer.js +0 -176
  42. package/dist/utils/localeNormalizer.js.map +0 -1
  43. package/dist/utils/publicSheetReader.js +0 -109
  44. package/dist/utils/publicSheetReader.js.map +0 -1
  45. package/dist/utils/rateLimiter.js +0 -55
  46. package/dist/utils/rateLimiter.js.map +0 -1
  47. package/dist/utils/readDataJson.js +0 -29
  48. package/dist/utils/readDataJson.js.map +0 -1
  49. package/dist/utils/sheetProcessor.js +0 -121
  50. package/dist/utils/sheetProcessor.js.map +0 -1
  51. package/dist/utils/spreadsheetCreator.js +0 -121
  52. package/dist/utils/spreadsheetCreator.js.map +0 -1
  53. package/dist/utils/spreadsheetUpdater.js +0 -227
  54. package/dist/utils/spreadsheetUpdater.js.map +0 -1
  55. package/dist/utils/syncManager.js +0 -62
  56. package/dist/utils/syncManager.js.map +0 -1
  57. package/dist/utils/validateEnv.js +0 -41
  58. package/dist/utils/validateEnv.js.map +0 -1
  59. package/dist/utils/wait.js +0 -19
  60. package/dist/utils/wait.js.map +0 -1
@@ -7,7 +7,8 @@ import type { TranslationData } from "../../types";
7
7
  * - The sheet or key is absent for the resolved locale.
8
8
  *
9
9
  * Locale matching is fuzzy: `'en'` and `'en-GB'` will both match against
10
- * an `'en-us'` entry in `spreadsheetData` (language-family resolution).
10
+ * an `'en-us'` entry in `spreadsheetData` (language-family resolution via
11
+ * `resolveLocaleWithFallback`).
11
12
  *
12
13
  * @param localData - Data from local languageData.json file
13
14
  * @param spreadsheetData - Data fetched from the spreadsheet
@@ -1 +1 @@
1
- {"version":3,"file":"findLocalChanges.d.ts","sourceRoot":"","sources":["../../../src/utils/dataConverter/findLocalChanges.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA2BnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC/B,SAAS,EAAE,eAAe,EAC1B,eAAe,EAAE,eAAe,GAC9B,eAAe,CAgCjB"}
1
+ {"version":3,"file":"findLocalChanges.d.ts","sourceRoot":"","sources":["../../../src/utils/dataConverter/findLocalChanges.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC/B,SAAS,EAAE,eAAe,EAC1B,eAAe,EAAE,eAAe,GAC9B,eAAe,CAgCjB"}
@@ -54,4 +54,35 @@ export declare function getOriginalHeaderForLocale(normalizedLocale: string, loc
54
54
  * @returns Normalized locale code or undefined if not found
55
55
  */
56
56
  export declare function getNormalizedLocaleForHeader(originalHeader: string, originalMapping: Record<string, string>): string | undefined;
57
+ /**
58
+ * Resolves a locale code to the closest matching locale in an available list
59
+ * using a three-step fallback strategy:
60
+ *
61
+ * 1. **Exact match** — `'en-us'` → `'en-us'`
62
+ * 2. **Lowercase match** — `'en-US'` → `'en-us'`
63
+ * 3. **Language-family prefix** — `'en'` or `'en-GB'` → `'en-us'`
64
+ * when `'en-us'` is the only English variant in `availableLocales`
65
+ *
66
+ * Returns `undefined` when no matching locale is found.
67
+ *
68
+ * This is the same strategy used internally by `findLocalChanges()` when
69
+ * mapping local `languageData.json` keys to spreadsheet locale columns.
70
+ *
71
+ * @param locale - The locale code to resolve (e.g. `'en'`, `'en-GB'`).
72
+ * @param availableLocales - Array of locale codes to search (e.g. from
73
+ * `Object.keys(translations)` or the `locales` array from `getSpreadSheetData`).
74
+ * @returns The matched locale code from `availableLocales`, or `undefined`.
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * import { resolveLocaleWithFallback } from '@el-j/google-sheet-translations';
79
+ *
80
+ * const locales = ['en-us', 'de-de', 'fr-fr'];
81
+ * resolveLocaleWithFallback('en', locales); // → 'en-us'
82
+ * resolveLocaleWithFallback('en-GB', locales); // → 'en-us'
83
+ * resolveLocaleWithFallback('de-DE', locales); // → 'de-de'
84
+ * resolveLocaleWithFallback('ja', locales); // → undefined
85
+ * ```
86
+ */
87
+ export declare function resolveLocaleWithFallback(locale: string, availableLocales: string[]): string | undefined;
57
88
  //# sourceMappingURL=localeNormalizer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"localeNormalizer.d.ts","sourceRoot":"","sources":["../../src/utils/localeNormalizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAExD;AA4CD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA0B1D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,eAAe,EAAE,MAAM,EAAE,EACzB,SAAS,EAAE,MAAM,GACf;IACF,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CA+BA;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CACzC,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,MAAM,GAAG,SAAS,CA2BpB;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC3C,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,MAAM,GAAG,SAAS,CAEpB"}
1
+ {"version":3,"file":"localeNormalizer.d.ts","sourceRoot":"","sources":["../../src/utils/localeNormalizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAExD;AA4CD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA0B1D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,eAAe,EAAE,MAAM,EAAE,EACzB,SAAS,EAAE,MAAM,GACf;IACF,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CA+BA;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CACzC,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,MAAM,GAAG,SAAS,CA2BpB;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC3C,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,MAAM,GAAG,SAAS,CAEpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,yBAAyB,CACxC,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,EAAE,GACxB,MAAM,GAAG,SAAS,CAUpB"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Higher-level translation utility helpers.
3
+ *
4
+ * These utilities solve common patterns that appear when consuming the
5
+ * translation data returned by `getSpreadSheetData()`. They were previously
6
+ * implemented inline in the documentation website; extracting them into the
7
+ * package makes them reusable for every downstream consumer.
8
+ */
9
+ import type { TranslationData, TranslationValue } from '../types';
10
+ /**
11
+ * Per-sheet summary for a single locale: sheet name and the number of
12
+ * translation keys it contains.
13
+ */
14
+ export interface SheetSummary {
15
+ sheet: string;
16
+ count: number;
17
+ }
18
+ /**
19
+ * Translation summary keyed by locale.
20
+ * Each locale maps to an array of sheet summaries with key counts.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const summary = getTranslationSummary(translations);
25
+ * // { 'en-us': [{ sheet: 'landingPage', count: 12 }, { sheet: 'ui', count: 5 }], ... }
26
+ * ```
27
+ */
28
+ export type TranslationSummary = Record<string, SheetSummary[]>;
29
+ /**
30
+ * Builds a summary of translation key counts per locale and sheet.
31
+ *
32
+ * Useful for dashboards, translation coverage reports, and monitoring.
33
+ *
34
+ * @param translations - The `TranslationData` object returned by
35
+ * `getSpreadSheetData()`.
36
+ * @returns A `TranslationSummary` mapping each locale to an array of
37
+ * `{ sheet, count }` entries.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { getSpreadSheetData, getTranslationSummary } from '@el-j/google-sheet-translations';
42
+ *
43
+ * const translations = await getSpreadSheetData(['ui', 'landingPage'], { publicSheet: true, spreadsheetId: '...' });
44
+ * const summary = getTranslationSummary(translations);
45
+ * // summary['en-us'] = [{ sheet: 'ui', count: 5 }, { sheet: 'landingPage', count: 12 }]
46
+ * ```
47
+ */
48
+ export declare function getTranslationSummary(translations: TranslationData): TranslationSummary;
49
+ /**
50
+ * Returns the human-readable display name for a locale by looking it up in
51
+ * the `i18n` sheet of the translation data.
52
+ *
53
+ * The `i18n` sheet is expected to follow the convention used by the demo
54
+ * spreadsheet: translation keys are locale codes (e.g. `"en-us"`,
55
+ * `"de-de"`) and their values are the locale's own name in that language —
56
+ * i.e. the mapping is self-referential. For example:
57
+ * - locale `"en-us"` → key `"en-us"` in the `"i18n"` sheet → `"English"`
58
+ * - locale `"de-de"` → key `"de-de"` in the `"i18n"` sheet → `"Deutsch"`
59
+ *
60
+ * Falls back to the raw locale code if the name is not found.
61
+ *
62
+ * @param locale - The locale code to look up (e.g. `"de-de"`).
63
+ * @param translations - The `TranslationData` object returned by
64
+ * `getSpreadSheetData()`.
65
+ * @param i18nSheet - The sheet that contains locale display names
66
+ * (default: `"i18n"`).
67
+ * @returns Human-readable locale name, or `locale` itself as a fallback.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * import { getSpreadSheetData, getLocaleDisplayName } from '@el-j/google-sheet-translations';
72
+ *
73
+ * const translations = await getSpreadSheetData(['i18n'], { publicSheet: true, spreadsheetId: '...' });
74
+ * const name = getLocaleDisplayName('de-de', translations);
75
+ * // → 'Deutsch'
76
+ * ```
77
+ */
78
+ export declare function getLocaleDisplayName(locale: string, translations: TranslationData, i18nSheet?: string): string;
79
+ /**
80
+ * Selects one or more sheets from the translation data for a given locale and
81
+ * merges them into a single flat key→value map.
82
+ *
83
+ * Later sheets in `sheetNames` overwrite earlier ones when there are duplicate
84
+ * keys (same semantics as `Object.assign`).
85
+ *
86
+ * This is the canonical way to extract a "current locale" translation map for
87
+ * rendering UI strings when translation keys are spread across multiple sheets.
88
+ *
89
+ * @param translations - The `TranslationData` object returned by
90
+ * `getSpreadSheetData()`.
91
+ * @param locale - The locale whose data should be extracted.
92
+ * @param sheetNames - Which sheets to merge (in order). Omit to merge all
93
+ * sheets for the locale.
94
+ * @returns Flat `{ key: value }` map. Returns an empty object if the locale
95
+ * or none of the requested sheets are found.
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * import { getSpreadSheetData, mergeSheets } from '@el-j/google-sheet-translations';
100
+ *
101
+ * const translations = await getSpreadSheetData(['ui', 'landingPage'], { publicSheet: true, spreadsheetId: '...' });
102
+ * const t = mergeSheets(translations, 'de-de', ['ui', 'landingPage']);
103
+ * // t.hero_title === 'Willkommen'
104
+ * ```
105
+ */
106
+ export declare function mergeSheets(translations: TranslationData, locale: string, sheetNames?: string[]): Record<string, TranslationValue>;
107
+ //# sourceMappingURL=translationHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translationHelpers.d.ts","sourceRoot":"","sources":["../../src/utils/translationHelpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAMlE;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;AAMhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,eAAe,GAAG,kBAAkB,CASvF;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,eAAe,EAC7B,SAAS,SAAS,GAChB,MAAM,CAUR;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,WAAW,CAC1B,YAAY,EAAE,eAAe,EAC7B,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,EAAE,GACnB,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAalC"}
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@el-j/google-sheet-translations",
3
- "version": "1.3.3",
3
+ "version": "2.0.0",
4
4
  "description": "A package to manage translations stored in Google Spreadsheets",
5
5
  "main": "dist/index.js",
6
+ "module": "dist/esm/index.js",
6
7
  "types": "dist/index.d.ts",
7
8
  "exports": {
8
9
  ".": {
9
10
  "types": "./dist/index.d.ts",
11
+ "import": "./dist/esm/index.js",
10
12
  "require": "./dist/index.js",
11
- "import": "./dist/index.js",
12
13
  "default": "./dist/index.js"
13
14
  }
14
15
  },
@@ -21,7 +22,11 @@
21
22
  "README.md"
22
23
  ],
23
24
  "scripts": {
24
- "build": "tsc",
25
+ "build:action": "rimraf dist-action && esbuild src/action-entrypoint.ts --bundle --platform=node --format=esm --outfile=dist-action/index.mjs --banner:js=\"import{createRequire}from'module';const require=createRequire(import.meta.url);\" --log-level=info",
26
+ "build:types": "tsc --emitDeclarationOnly",
27
+ "build:cjs": "esbuild src/index.ts --bundle --format=cjs --outfile=dist/index.js --platform=node --packages=external",
28
+ "build:esm": "esbuild src/index.ts --bundle --format=esm --outfile=dist/esm/index.js --platform=node --packages=external && node -e \"require('fs').writeFileSync('dist/esm/package.json', JSON.stringify({type:'module'}))\"",
29
+ "build": "npm run build:types && npm run build:cjs && npm run build:esm",
25
30
  "clean": "rimraf dist",
26
31
  "prebuild": "npm run clean",
27
32
  "prepare": "npm run build",
@@ -54,8 +59,9 @@
54
59
  "author": "el-j",
55
60
  "license": "MIT",
56
61
  "dependencies": {
57
- "google-auth-library": "^10.1.0",
58
- "google-spreadsheet": "^4.1.5"
62
+ "@actions/core": "^3.0.0",
63
+ "google-auth-library": "^10.6.1",
64
+ "google-spreadsheet": "^5.2.0"
59
65
  },
60
66
  "peerDependencies": {
61
67
  "typescript": ">=4.0.0"
@@ -69,19 +75,20 @@
69
75
  "@semantic-release/npm": "^13.1.5",
70
76
  "@semantic-release/release-notes-generator": "^14.1.0",
71
77
  "@types/jest": "^30.0.0",
72
- "@types/node": "^24.0.15",
73
- "@typescript-eslint/eslint-plugin": "^8.56.1",
74
- "@typescript-eslint/parser": "^8.56.1",
78
+ "@types/node": "^25.4.0",
79
+ "@typescript-eslint/eslint-plugin": "^8.57.0",
80
+ "@typescript-eslint/parser": "^8.57.0",
81
+ "esbuild": "^0.26.0",
75
82
  "conventional-changelog-conventionalcommits": "^9.3.0",
76
- "dotenv": "17.2.0",
83
+ "dotenv": "17.3.1",
77
84
  "eslint": "^10.0.3",
78
- "jest": "^30.0.4",
85
+ "jest": "^30.3.0",
79
86
  "jest-mock-extended": "^4.0.0",
80
- "rimraf": "^6.0.1",
87
+ "rimraf": "^6.1.3",
81
88
  "semantic-release": "^25.0.3",
82
- "ts-jest": "^29.4.0",
89
+ "ts-jest": "^29.4.6",
83
90
  "ts-node": "^10.9.2",
84
- "typescript": "^5.8.3",
91
+ "typescript": "^5.9.3",
85
92
  "vitepress": "^1.6.4"
86
93
  },
87
94
  "engines": {
@@ -89,7 +96,7 @@
89
96
  },
90
97
  "overrides": {
91
98
  "google-spreadsheet": {
92
- "google-auth-library": "^10.1.0"
99
+ "google-auth-library": "^10.6.1"
93
100
  }
94
101
  }
95
102
  }
package/dist/constants.js DELETED
@@ -1,9 +0,0 @@
1
- "use strict";
2
- /**
3
- * Package-wide constants
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DEFAULT_WAIT_SECONDS = void 0;
7
- /** Default wait time between Google Sheets API calls (in seconds) */
8
- exports.DEFAULT_WAIT_SECONDS = 1;
9
- //# sourceMappingURL=constants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,qEAAqE;AACxD,QAAA,oBAAoB,GAAG,CAAC,CAAC"}
@@ -1,170 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DEFAULT_WAIT_SECONDS = void 0;
7
- exports.getSpreadSheetData = getSpreadSheetData;
8
- const node_fs_1 = __importDefault(require("node:fs"));
9
- const node_path_1 = __importDefault(require("node:path"));
10
- const google_spreadsheet_1 = require("google-spreadsheet");
11
- const auth_1 = require("./utils/auth");
12
- const configurationHandler_1 = require("./utils/configurationHandler");
13
- const sheetProcessor_1 = require("./utils/sheetProcessor");
14
- const fileWriter_1 = require("./utils/fileWriter");
15
- const syncManager_1 = require("./utils/syncManager");
16
- const rateLimiter_1 = require("./utils/rateLimiter");
17
- const publicSheetReader_1 = require("./utils/publicSheetReader");
18
- const spreadsheetCreator_1 = require("./utils/spreadsheetCreator");
19
- const constants_1 = require("./constants");
20
- Object.defineProperty(exports, "DEFAULT_WAIT_SECONDS", { enumerable: true, get: function () { return constants_1.DEFAULT_WAIT_SECONDS; } });
21
- /**
22
- * Fetches and processes data from a Google Spreadsheet.
23
- *
24
- * Modes:
25
- * - **Authenticated** (default): uses a Google Cloud service account.
26
- * Supports bidirectional sync, auto-translate, and auto-create.
27
- * - **Public** (`publicSheet: true`): reads via the Google Visualization API
28
- * with no credentials. The spreadsheet must be shared publicly.
29
- *
30
- * **Auto-create**: when no spreadsheet ID is available and `autoCreate` is true
31
- * (the default), a new spreadsheet is created automatically on first run.
32
- */
33
- const MAX_SYNC_REFRESH_DEPTH = 1;
34
- /** Appends (or updates) GOOGLE_SPREADSHEET_ID in .env when the file exists. */
35
- async function persistSpreadsheetId(id) {
36
- const envPath = node_path_1.default.join(process.cwd(), '.env');
37
- try {
38
- let content = '';
39
- if (node_fs_1.default.existsSync(envPath)) {
40
- content = node_fs_1.default.readFileSync(envPath, 'utf8');
41
- if (/^GOOGLE_SPREADSHEET_ID=/m.test(content)) {
42
- content = content.replace(/^GOOGLE_SPREADSHEET_ID=.*/m, `GOOGLE_SPREADSHEET_ID=${id}`);
43
- }
44
- else {
45
- content = content.trimEnd() + `\nGOOGLE_SPREADSHEET_ID=${id}\n`;
46
- }
47
- }
48
- else {
49
- content = `GOOGLE_SPREADSHEET_ID=${id}\n`;
50
- }
51
- node_fs_1.default.writeFileSync(envPath, content, 'utf8');
52
- console.log(` Saved GOOGLE_SPREADSHEET_ID to ${envPath}`);
53
- }
54
- catch (err) {
55
- console.warn(` Could not write .env: ${err.message}`);
56
- }
57
- }
58
- async function getSpreadSheetData(_docTitle, options = {}, _refreshDepth = 0) {
59
- const config = (0, configurationHandler_1.normalizeConfig)(options);
60
- const baseDelayMs = config.waitSeconds * 1000;
61
- const docTitle = _docTitle ?? [];
62
- if (docTitle.length === 0) {
63
- console.warn("No sheet titles provided, cannot process spreadsheet data");
64
- return {};
65
- }
66
- if (!docTitle.includes("i18n")) {
67
- docTitle.push("i18n");
68
- }
69
- const finalTranslations = {};
70
- const allLocales = new Set();
71
- const localesWithContent = new Set();
72
- const globalLocaleMapping = {};
73
- const globalOriginalMapping = {};
74
- function mergeResult(result, title) {
75
- if (!result.success)
76
- return;
77
- for (const [normalized, original] of Object.entries(result.localeMapping)) {
78
- if (!globalLocaleMapping[normalized])
79
- globalLocaleMapping[normalized] = original;
80
- }
81
- for (const [original, normalized] of Object.entries(result.originalMapping)) {
82
- if (!globalOriginalMapping[original])
83
- globalOriginalMapping[original] = normalized;
84
- }
85
- for (const locale of result.locales) {
86
- if (finalTranslations[locale]) {
87
- finalTranslations[locale] = { ...finalTranslations[locale], ...result.translations[locale] };
88
- }
89
- else {
90
- finalTranslations[locale] = result.translations[locale];
91
- }
92
- allLocales.add(locale);
93
- if (title !== "i18n" && result.translations[locale]) {
94
- const hasActualTranslations = Object.values(result.translations[locale]).some((sheetTranslations) => Object.keys(sheetTranslations).length > 0);
95
- if (hasActualTranslations)
96
- localesWithContent.add(locale);
97
- }
98
- }
99
- }
100
- if (config.publicSheet) {
101
- // ── Public (unauthenticated) path ──────────────────────────────────────
102
- const spreadsheetId = config.spreadsheetId ?? process.env.GOOGLE_SPREADSHEET_ID;
103
- if (!spreadsheetId) {
104
- throw new Error("No spreadsheet ID provided. Set GOOGLE_SPREADSHEET_ID or pass spreadsheetId in options.");
105
- }
106
- console.log(`Processing ${docTitle.length} sheets: ${docTitle.join(", ")}`);
107
- await Promise.all(docTitle.map(async (title) => {
108
- let rows;
109
- try {
110
- rows = await (0, rateLimiter_1.withRetry)(() => (0, publicSheetReader_1.readPublicSheet)(spreadsheetId, title), `readPublicSheet: ${title}`, baseDelayMs);
111
- }
112
- catch (err) {
113
- console.warn(`Sheet "${title}" could not be fetched: ${err.message}`);
114
- return;
115
- }
116
- mergeResult(await (0, sheetProcessor_1.processRawRows)(rows, title), title);
117
- }));
118
- }
119
- else {
120
- // ── Authenticated path ─────────────────────────────────────────────────
121
- const serviceAuthClient = (0, auth_1.createAuthClient)();
122
- // Resolve spreadsheet ID: option > env var > auto-create
123
- let spreadsheetId = config.spreadsheetId ?? process.env.GOOGLE_SPREADSHEET_ID;
124
- if (!spreadsheetId) {
125
- if (config.autoCreate) {
126
- const created = await (0, spreadsheetCreator_1.createSpreadsheet)(serviceAuthClient, {
127
- title: config.spreadsheetTitle,
128
- sourceLocale: config.sourceLocale,
129
- targetLocales: config.targetLocales,
130
- });
131
- spreadsheetId = created.spreadsheetId;
132
- await persistSpreadsheetId(spreadsheetId);
133
- }
134
- else {
135
- throw new Error("No spreadsheet ID provided. Set GOOGLE_SPREADSHEET_ID or pass spreadsheetId in options.");
136
- }
137
- }
138
- console.log(`Processing ${docTitle.length} sheets: ${docTitle.join(", ")}`);
139
- const doc = new google_spreadsheet_1.GoogleSpreadsheet(spreadsheetId, serviceAuthClient);
140
- try {
141
- await (0, rateLimiter_1.withRetry)(() => doc.loadInfo(true), "loadInfo", baseDelayMs);
142
- }
143
- catch (err) {
144
- throw new Error(`Failed to load spreadsheet "${spreadsheetId}"`, { cause: err });
145
- }
146
- await Promise.all(docTitle.map(async (title) => {
147
- const sheet = doc.sheetsByTitle[title];
148
- if (!sheet) {
149
- console.warn(`Sheet "${title}" not found in the document`);
150
- return;
151
- }
152
- mergeResult(await (0, sheetProcessor_1.processSheet)(sheet, title, config.rowLimit, baseDelayMs), title);
153
- }));
154
- const syncResult = await (0, syncManager_1.handleBidirectionalSync)(doc, config.dataJsonPath, config.translationsOutputDir, config.syncLocalChanges, config.autoTranslate, finalTranslations, config.waitSeconds, globalLocaleMapping);
155
- if (syncResult.shouldRefresh && _refreshDepth < MAX_SYNC_REFRESH_DEPTH) {
156
- return getSpreadSheetData(_docTitle, { ...options, syncLocalChanges: false }, _refreshDepth + 1);
157
- }
158
- }
159
- const localesForOutput = localesWithContent.size > 0 ? Array.from(localesWithContent) : Array.from(allLocales);
160
- const allLocalesArray = Array.from(allLocales);
161
- (0, fileWriter_1.writeTranslationFiles)(finalTranslations, allLocalesArray, config.translationsOutputDir);
162
- (0, fileWriter_1.writeLocalesFile)(localesForOutput, globalLocaleMapping, config.localesOutputPath);
163
- console.log(`Writing locales file with ${localesForOutput.length} locales that have actual translations:`, localesForOutput);
164
- if (Object.keys(finalTranslations).length > 0) {
165
- (0, fileWriter_1.writeLanguageDataFile)(finalTranslations, allLocalesArray, config.dataJsonPath);
166
- }
167
- return finalTranslations;
168
- }
169
- exports.default = getSpreadSheetData;
170
- //# sourceMappingURL=getSpreadSheetData.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getSpreadSheetData.js","sourceRoot":"","sources":["../src/getSpreadSheetData.ts"],"names":[],"mappings":"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"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,mBAAmB;AACnB,2DAAgF;AAAvE,wHAAA,kBAAkB,OAAA;AAAE,0HAAA,oBAAoB,OAAA;AAKjD,2CAA2C;AAC3C,qCAAoC;AAA3B,4FAAA,IAAI,OAAA;AACb,mDAAgD;AAAvC,wGAAA,SAAS,OAAA;AAClB,mDAAkD;AAAzC,0GAAA,WAAW,OAAA;AACpB,qCAAgD;AAAvC,wGAAA,gBAAgB,OAAA;AACzB,yFAAwF;AAA/E,kIAAA,uBAAuB,OAAA;AAChC,6FAA4F;AAAnF,sIAAA,yBAAyB,OAAA;AAClC,2EAA0E;AAAjE,oHAAA,gBAAgB,OAAA;AACzB,iEAA+E;AAAtE,uIAAA,iCAAiC,OAAA;AAE1C,wCAAwC;AACxC,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AAExB,kCAAkC;AAClC,iEAA+D;AAAtD,uHAAA,iBAAiB,OAAA;AAC1B,mDAA0D;AAAjD,kHAAA,mBAAmB,OAAA;AAE5B,kDAAkD;AAClD,qDAAyE;AAAhE,6GAAA,aAAa,OAAA;AAAE,kHAAA,kBAAkB,OAAA;AAU1C,iBAAiB;AACjB,6DAA0D;AAC1D,kBAAe,uCAAkB,CAAC"}
package/dist/types.js DELETED
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=types.js.map
package/dist/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createAuthClient = createAuthClient;
4
- const google_auth_library_1 = require("google-auth-library");
5
- const validateEnv_1 = require("./validateEnv");
6
- /**
7
- * Creates and returns a JWT auth client for Google Sheets API
8
- * @returns JWT authentication client
9
- */
10
- function createAuthClient() {
11
- const { GOOGLE_CLIENT_EMAIL, GOOGLE_PRIVATE_KEY } = (0, validateEnv_1.validateCredentials)();
12
- // GitHub Actions (and many CI systems) store secrets with literal `\n`
13
- // instead of real newlines. The PEM key must have actual newlines for
14
- // OpenSSL to parse it; replace any escaped sequences before use.
15
- const normalizedKey = GOOGLE_PRIVATE_KEY.replace(/\\n/g, "\n");
16
- return new google_auth_library_1.JWT({
17
- email: GOOGLE_CLIENT_EMAIL,
18
- key: normalizedKey,
19
- scopes: ["https://www.googleapis.com/auth/spreadsheets"],
20
- });
21
- }
22
- exports.default = createAuthClient;
23
- //# sourceMappingURL=auth.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":";;AAOA,4CAaC;AApBD,6DAA0C;AAC1C,+CAAoD;AAEpD;;;GAGG;AACH,SAAgB,gBAAgB;IAC/B,MAAM,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,GAAG,IAAA,iCAAmB,GAAE,CAAC;IAE1E,uEAAuE;IACvE,sEAAsE;IACtE,iEAAiE;IACjE,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE/D,OAAO,IAAI,yBAAG,CAAC;QACd,KAAK,EAAE,mBAAmB;QAC1B,GAAG,EAAE,aAAa;QAClB,MAAM,EAAE,CAAC,8CAA8C,CAAC;KACxD,CAAC,CAAC;AACJ,CAAC;AAED,kBAAe,gBAAgB,CAAC"}
@@ -1,29 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.normalizeConfig = normalizeConfig;
7
- const node_path_1 = __importDefault(require("node:path"));
8
- const constants_1 = require("../constants");
9
- /**
10
- * Normalizes configuration options by applying defaults
11
- */
12
- function normalizeConfig(options = {}) {
13
- return {
14
- rowLimit: options.rowLimit ?? 100,
15
- waitSeconds: options.waitSeconds ?? constants_1.DEFAULT_WAIT_SECONDS,
16
- dataJsonPath: options.dataJsonPath ?? node_path_1.default.join(process.cwd(), "src/lib/languageData.json"),
17
- localesOutputPath: options.localesOutputPath ?? node_path_1.default.join(process.cwd(), "src/i18n/locales.ts"),
18
- translationsOutputDir: options.translationsOutputDir ?? node_path_1.default.join(process.cwd(), "translations"),
19
- syncLocalChanges: options.syncLocalChanges !== false, // Default to true
20
- autoTranslate: options.autoTranslate === true, // Default to false
21
- spreadsheetId: options.spreadsheetId,
22
- publicSheet: options.publicSheet === true, // Default to false
23
- autoCreate: options.autoCreate !== false, // Default to true
24
- spreadsheetTitle: options.spreadsheetTitle ?? 'google-sheet-translations',
25
- sourceLocale: options.sourceLocale ?? 'en',
26
- targetLocales: options.targetLocales ?? ['de', 'fr', 'es', 'it', 'pt', 'ja', 'zh'],
27
- };
28
- }
29
- //# sourceMappingURL=configurationHandler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"configurationHandler.js","sourceRoot":"","sources":["../../src/utils/configurationHandler.ts"],"names":[],"mappings":";;;;;AA4EA,0CAgBC;AA5FD,0DAA6B;AAC7B,4CAAoD;AAwEpD;;GAEG;AACH,SAAgB,eAAe,CAAC,UAA8B,EAAE;IAC/D,OAAO;QACN,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,GAAG;QACjC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,gCAAoB;QACxD,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,mBAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,2BAA2B,CAAC;QAC3F,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,mBAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,qBAAqB,CAAC;QAC/F,qBAAqB,EAAE,OAAO,CAAC,qBAAqB,IAAI,mBAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC;QAChG,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,KAAK,KAAK,EAAE,kBAAkB;QACxE,aAAa,EAAE,OAAO,CAAC,aAAa,KAAK,IAAI,EAAE,mBAAmB;QAClE,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,WAAW,EAAE,OAAO,CAAC,WAAW,KAAK,IAAI,EAAE,mBAAmB;QAC9D,UAAU,EAAE,OAAO,CAAC,UAAU,KAAK,KAAK,EAAE,kBAAkB;QAC5D,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,2BAA2B;QACzE,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI;QAC1C,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;KAClF,CAAC;AACH,CAAC"}
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertFromDataJsonFormat = convertFromDataJsonFormat;
4
- /**
5
- * Type-guard: checks that a value has the shape of sheet data
6
- * (an object mapping locale → translation record)
7
- */
8
- function isSheetData(v) {
9
- return typeof v === 'object' && v !== null && !Array.isArray(v);
10
- }
11
- /**
12
- * Converts languageData.json format back to the translation object structure
13
- * @param dataJson - Data in the languageData.json format
14
- * @returns Converted data in the TranslationData format
15
- */
16
- function convertFromDataJsonFormat(dataJson) {
17
- const result = {};
18
- for (const projectData of dataJson) {
19
- for (const sheetTitle of Object.keys(projectData)) {
20
- const raw = projectData[sheetTitle];
21
- if (!isSheetData(raw)) {
22
- console.warn(`Skipping malformed entry for sheet "${sheetTitle}"`);
23
- continue;
24
- }
25
- for (const locale of Object.keys(raw)) {
26
- // Initialize locale if it doesn't exist
27
- if (!result[locale]) {
28
- result[locale] = {};
29
- }
30
- // Initialize sheet if it doesn't exist
31
- if (!result[locale][sheetTitle]) {
32
- result[locale][sheetTitle] = {};
33
- }
34
- const localeData = raw[locale];
35
- if (typeof localeData !== 'object' || localeData === null) {
36
- continue;
37
- }
38
- // Add all translations
39
- for (const key of Object.keys(localeData)) {
40
- result[locale][sheetTitle][key] = localeData[key];
41
- }
42
- }
43
- }
44
- }
45
- return result;
46
- }
47
- //# sourceMappingURL=convertFromDataJsonFormat.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"convertFromDataJsonFormat.js","sourceRoot":"","sources":["../../../src/utils/dataConverter/convertFromDataJsonFormat.ts"],"names":[],"mappings":";;AAiBA,8DAuCC;AAtDD;;;GAGG;AACH,SAAS,WAAW,CACnB,CAAU;IAEV,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,SAAgB,yBAAyB,CACxC,QAAmC;IAEnC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,KAAK,MAAM,WAAW,IAAI,QAAQ,EAAE,CAAC;QACpC,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACnD,MAAM,GAAG,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;YAEpC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,uCAAuC,UAAU,GAAG,CAAC,CAAC;gBACnE,SAAS;YACV,CAAC;YAED,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvC,wCAAwC;gBACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;oBACrB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBACrB,CAAC;gBAED,uCAAuC;gBACvC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC;oBACjC,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;gBACjC,CAAC;gBAED,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC/B,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC3D,SAAS;gBACV,CAAC;gBAED,uBAAuB;gBACvB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;gBACnD,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC"}
@@ -1,51 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertToDataJsonFormat = convertToDataJsonFormat;
4
- /**
5
- * Converts the translation object to the expected languageData.json format
6
- * @param translationObj - The translation object with locale->sheet->key->value structure
7
- * @param locales - Array of locale identifiers
8
- * @returns Converted data in the format expected for languageData.json
9
- */
10
- function convertToDataJsonFormat(translationObj, locales) {
11
- const result = [];
12
- console.log("Converting translation object to languageData.json format...");
13
- // Get all sheet names from all locales to make sure we don't miss any
14
- const allSheets = new Set();
15
- for (const locale of Object.keys(translationObj)) {
16
- if (translationObj[locale]) {
17
- for (const sheet of Object.keys(translationObj[locale])) {
18
- allSheets.add(sheet);
19
- }
20
- }
21
- }
22
- console.log(`Found ${allSheets.size} sheets across all locales`);
23
- // Process each sheet
24
- for (const sheetTitle of allSheets) {
25
- // Create a new project object with the sheet title as the main key
26
- const projectData = {};
27
- projectData[sheetTitle] = {};
28
- // For each locale, add all key-value pairs
29
- for (const locale of locales) {
30
- if (translationObj?.[locale]?.[sheetTitle]) { // Use original locale case for lookup
31
- // Create the locale object
32
- projectData[sheetTitle][locale] = {};
33
- // Add all translations for this locale
34
- const translations = translationObj[locale][sheetTitle];
35
- for (const key of Object.keys(translations)) {
36
- projectData[sheetTitle][locale][key] = translations[key];
37
- }
38
- // Log how many translations we found for debugging
39
- console.log(`Found ${Object.keys(translations).length} keys for locale ${locale} in sheet ${sheetTitle}`);
40
- }
41
- }
42
- // Only add non-empty projects
43
- if (Object.keys(projectData[sheetTitle]).length > 0) {
44
- result.push(projectData);
45
- }
46
- }
47
- console.log(`Created ${result.length} sheet entries for languageData.json`);
48
- return result;
49
- }
50
- exports.default = convertToDataJsonFormat;
51
- //# sourceMappingURL=convertToDataJsonFormat.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"convertToDataJsonFormat.js","sourceRoot":"","sources":["../../../src/utils/dataConverter/convertToDataJsonFormat.ts"],"names":[],"mappings":";;AAQA,0DA0DC;AAhED;;;;;GAKG;AACH,SAAgB,uBAAuB,CACtC,cAA+B,EAC/B,OAAiB;IAEjB,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAE5E,sEAAsE;IACtE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QAClD,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBACzD,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,SAAS,SAAS,CAAC,IAAI,4BAA4B,CAAC,CAAC;IAEjE,qBAAqB;IACrB,KAAK,MAAM,UAAU,IAAI,SAAS,EAAE,CAAC;QACpC,mEAAmE;QACnE,MAAM,WAAW,GAGb,EAAE,CAAC;QACP,WAAW,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;QAE7B,2CAA2C;QAC3C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,IAAI,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,sCAAsC;gBAEnF,2BAA2B;gBAC3B,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBAErC,uCAAuC;gBACvC,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;gBACxD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;oBAC7C,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;gBAC1D,CAAC;gBAED,mDAAmD;gBACnD,OAAO,CAAC,GAAG,CACV,SACC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAC3B,oBAAoB,MAAM,aAAa,UAAU,EAAE,CACnD,CAAC;YACH,CAAC;QACF,CAAC;QAED,8BAA8B;QAC9B,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;IACF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,MAAM,sCAAsC,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AACf,CAAC;AAED,kBAAe,uBAAuB,CAAC"}