@nice2dev/i18n 1.1.9 → 1.2.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 (98) hide show
  1. package/README.md +74 -35
  2. package/dist/all.cjs +1 -0
  3. package/dist/all.d.ts +136 -0
  4. package/dist/all.mjs +25 -0
  5. package/dist/calendar-systems.cjs +1 -0
  6. package/dist/calendar-systems.mjs +412 -0
  7. package/dist/dictionaries/ar.cjs +1 -0
  8. package/dist/dictionaries/ar.mjs +375 -0
  9. package/dist/dictionaries/bg.cjs +1 -0
  10. package/dist/dictionaries/bg.mjs +67 -0
  11. package/dist/dictionaries/bn.cjs +1 -0
  12. package/dist/dictionaries/bn.mjs +23 -0
  13. package/dist/dictionaries/cs.cjs +1 -0
  14. package/dist/dictionaries/cs.mjs +375 -0
  15. package/dist/dictionaries/da.cjs +1 -0
  16. package/dist/dictionaries/da.mjs +75 -0
  17. package/dist/dictionaries/de.cjs +1 -0
  18. package/dist/dictionaries/de.mjs +4405 -0
  19. package/dist/dictionaries/en.cjs +1 -0
  20. package/dist/dictionaries/en.mjs +4450 -0
  21. package/dist/dictionaries/es.cjs +1 -0
  22. package/dist/dictionaries/es.mjs +4403 -0
  23. package/dist/dictionaries/fi.cjs +1 -0
  24. package/dist/dictionaries/fi.mjs +75 -0
  25. package/dist/dictionaries/fil.cjs +1 -0
  26. package/dist/dictionaries/fil.mjs +19 -0
  27. package/dist/dictionaries/fr.cjs +1 -0
  28. package/dist/dictionaries/fr.mjs +4405 -0
  29. package/dist/dictionaries/hi.cjs +1 -0
  30. package/dist/dictionaries/hi.mjs +23 -0
  31. package/dist/dictionaries/hu.cjs +1 -0
  32. package/dist/dictionaries/hu.mjs +75 -0
  33. package/dist/dictionaries/id.cjs +1 -0
  34. package/dist/dictionaries/id.mjs +23 -0
  35. package/dist/dictionaries/index.cjs +1 -0
  36. package/dist/dictionaries/index.mjs +95 -0
  37. package/dist/dictionaries/it.cjs +1 -0
  38. package/dist/dictionaries/it.mjs +297 -0
  39. package/dist/dictionaries/ja.cjs +1 -0
  40. package/dist/dictionaries/ja.mjs +375 -0
  41. package/dist/dictionaries/ko.cjs +1 -0
  42. package/dist/dictionaries/ko.mjs +375 -0
  43. package/dist/dictionaries/ms.cjs +1 -0
  44. package/dist/dictionaries/ms.mjs +23 -0
  45. package/dist/dictionaries/nl.cjs +1 -0
  46. package/dist/dictionaries/nl.mjs +97 -0
  47. package/dist/dictionaries/no.cjs +1 -0
  48. package/dist/dictionaries/no.mjs +75 -0
  49. package/dist/dictionaries/pl.cjs +1 -0
  50. package/dist/dictionaries/pl.mjs +4411 -0
  51. package/dist/dictionaries/pt.cjs +1 -0
  52. package/dist/dictionaries/pt.mjs +375 -0
  53. package/dist/dictionaries/ro.cjs +1 -0
  54. package/dist/dictionaries/ro.mjs +67 -0
  55. package/dist/dictionaries/sk.cjs +1 -0
  56. package/dist/dictionaries/sk.mjs +75 -0
  57. package/dist/dictionaries/sv.cjs +1 -0
  58. package/dist/dictionaries/sv.mjs +82 -0
  59. package/dist/dictionaries/sw.cjs +1 -0
  60. package/dist/dictionaries/sw.mjs +23 -0
  61. package/dist/dictionaries/th.cjs +1 -0
  62. package/dist/dictionaries/th.mjs +23 -0
  63. package/dist/dictionaries/uk.cjs +1 -0
  64. package/dist/dictionaries/uk.mjs +4403 -0
  65. package/dist/dictionaries/vi.cjs +1 -0
  66. package/dist/dictionaries/vi.mjs +23 -0
  67. package/dist/dictionaries/zh.cjs +1 -0
  68. package/dist/dictionaries/zh.mjs +375 -0
  69. package/dist/dynamic-loading.cjs +1 -0
  70. package/dist/dynamic-loading.mjs +274 -0
  71. package/dist/i18n.cjs +1 -0
  72. package/dist/i18n.mjs +16 -0
  73. package/dist/i18nContext.cjs +1 -0
  74. package/dist/i18nContext.mjs +11 -0
  75. package/dist/i18nDictionaries.cjs +1 -0
  76. package/dist/i18nDictionaries.mjs +61 -0
  77. package/dist/icu.cjs +1 -0
  78. package/dist/icu.mjs +242 -0
  79. package/dist/index.cjs +1 -24
  80. package/dist/index.d.ts +67 -121
  81. package/dist/index.mjs +109 -25811
  82. package/dist/languages.cjs +1 -0
  83. package/dist/languages.mjs +56 -0
  84. package/dist/lazyDictionaries.cjs +1 -0
  85. package/dist/lazyDictionaries.mjs +96 -0
  86. package/dist/locale.cjs +1 -0
  87. package/dist/locale.mjs +94 -0
  88. package/dist/pseudo-localization.cjs +1 -0
  89. package/dist/pseudo-localization.mjs +272 -0
  90. package/dist/rtl.cjs +1 -0
  91. package/dist/rtl.mjs +155 -0
  92. package/dist/timezone.cjs +1 -0
  93. package/dist/timezone.mjs +195 -0
  94. package/dist/translate-pipeline.cjs +24 -0
  95. package/dist/translate-pipeline.mjs +79 -0
  96. package/dist/translationMemory.cjs +1 -0
  97. package/dist/translationMemory.mjs +207 -0
  98. package/package.json +6 -1
package/README.md CHANGED
@@ -5,7 +5,7 @@ Shared internationalization infrastructure for Nice2Dev UI libraries.
5
5
  ## Features
6
6
 
7
7
  - **NiceI18nProvider** — React context for translations
8
- - **20 built-in languages** — en, pl, de, fr, es, it, pt, nl, sv, no, da, fi, cs, sk, hu, ro, bg, uk, ja, ko, zh, ar
8
+ - **30 built-in languages**, loaded one at a time — en, pl, de, fr, es, it, pt, nl, sv, no, da, fi, cs, sk, hu, ro, bg, uk, ja, ko, zh, ar, hi, bn, th, vi, id, sw, fil, ms
9
9
  - **ICU MessageFormat** — pluralization, gender, ordinals, select
10
10
  - **RTL support** — Arabic, Hebrew with automatic dir attribute
11
11
  - **Browser detection** — `detectBrowserLanguage()` auto-detects user preference
@@ -39,6 +39,27 @@ function App() {
39
39
 
40
40
  All Nice2Dev components automatically pick up translations from the provider.
41
41
 
42
+ The provider loads only the dictionary of `lang`, with `import()`, so your bundler gives each
43
+ language its own chunk. Until it arrives the controls show their built-in English; to start in
44
+ the language, load it before the first render:
45
+
46
+ ```tsx
47
+ import { NiceI18nProvider, loadNiceDictionary } from '@nice2dev/i18n';
48
+
49
+ await loadNiceDictionary('pl');
50
+ root.render(
51
+ <NiceI18nProvider lang="pl">
52
+ <App />
53
+ </NiceI18nProvider>,
54
+ );
55
+ ```
56
+
57
+ Or pass `fallback` to render something else meanwhile. Up to 1.1.x the provider carried all thirty
58
+ dictionaries; 1.1.10 added this loading as `NiceI18nLazyProvider`, which is now the same component.
59
+ If your bundler config groups modules by package (`manualChunks`), leave
60
+ `@nice2dev/i18n/dist/dictionaries/` out of the group — see the
61
+ [setup guide](../../documentation/guides/GLOBAL_THEMING_I18N_SETUP.md#bundler-chunking-manualchunks).
62
+
42
63
  ### Option 2: Custom Translation Function
43
64
 
44
65
  If you use react-i18next, i18next, or any other i18n library:
@@ -70,12 +91,19 @@ All components work without a provider — they show English by default.
70
91
 
71
92
  ### NiceI18nProvider
72
93
 
73
- | Prop | Type | Description |
74
- | ----------- | -------------------------- | -------------------------------------------------------- |
75
- | `lang` | `NiceSupportedLang` | Built-in language code (default: 'en') |
76
- | `t` | `(key, default) => string` | Custom translation function (takes priority over `lang`) |
77
- | `overrides` | `Record<string, string>` | Extra translations merged on top of built-in dictionary |
78
- | `children` | `ReactNode` | App content |
94
+ | Prop | Type | Description |
95
+ | ----------- | -------------------------- | ----------------------------------------------------------------------------- |
96
+ | `lang` | `NiceSupportedLang` | Built-in language code (default: 'en'); its dictionary is loaded on first use |
97
+ | `t` | `(key, default) => string` | Custom translation function (takes priority over `lang`; nothing is loaded) |
98
+ | `overrides` | `Record<string, string>` | Extra translations merged on top of built-in dictionary |
99
+ | `fallback` | `ReactNode` | Rendered instead of `children` until the first dictionary has loaded |
100
+ | `onError` | `(error) => void` | Called when a dictionary fails to load |
101
+ | `children` | `ReactNode` | App content |
102
+
103
+ ### loadNiceDictionary
104
+
105
+ `loadNiceDictionary(lang)` loads one language's dictionary and caches it; concurrent calls share
106
+ one request. `getLoadedNiceDictionary(lang)` returns it once loaded, otherwise `undefined`.
79
107
 
80
108
  ### useNiceTranslation
81
109
 
@@ -90,12 +118,15 @@ function MyComponent() {
90
118
  }
91
119
  ```
92
120
 
93
- ### createTranslator
121
+ ### `@nice2dev/i18n/all` — every dictionary at once
94
122
 
95
- Create a translator function without React context:
123
+ `NICE_I18N_DICTIONARIES`, `createTranslator`, `NICE_I18N_VARIANTS` / `resolvePlVariant` and the
124
+ translation tooling (`getMissingTranslations`, `getTranslationStats`, `NICE_GLOSSARY`, …) need all
125
+ thirty languages, so they live on their own entry (1.2.0). Use it in build scripts, tests or a
126
+ translation editor — not in app code that only shows one language.
96
127
 
97
128
  ```tsx
98
- import { createTranslator } from '@nice2dev/i18n';
129
+ import { createTranslator } from '@nice2dev/i18n/all';
99
130
 
100
131
  const t = createTranslator('de');
101
132
  console.log(t('save', 'Save')); // "Speichern"
@@ -146,30 +177,38 @@ const userLang = detectBrowserLanguage(); // e.g. 'pl' if browser is Polish
146
177
 
147
178
  ## Supported Languages
148
179
 
149
- | Code | Language | Native Name |
150
- | ---- | ------------ | ----------- |
151
- | `en` | English | English |
152
- | `pl` | Polish | Polski |
153
- | `de` | German | Deutsch |
154
- | `fr` | French | Français |
155
- | `es` | Spanish | Español |
156
- | `it` | Italian | Italiano |
157
- | `pt` | Portuguese | Português |
158
- | `nl` | Dutch | Nederlands |
159
- | `sv` | Swedish | Svenska |
160
- | `no` | Norwegian | Norsk |
161
- | `da` | Danish | Dansk |
162
- | `fi` | Finnish | Suomi |
163
- | `cs` | Czech | Čeština |
164
- | `sk` | Slovak | Slovenčina |
165
- | `hu` | Hungarian | Magyar |
166
- | `ro` | Romanian | Română |
167
- | `bg` | Bulgarian | Български |
168
- | `uk` | Ukrainian | Українська |
169
- | `ja` | Japanese | 日本語 |
170
- | `ko` | Korean | 한국어 |
171
- | `zh` | Chinese | 中文 |
172
- | `ar` | Arabic (RTL) | العربية |
180
+ | Code | Language | Native Name |
181
+ | ----- | ------------ | ----------- |
182
+ | `en` | English | English |
183
+ | `pl` | Polish | Polski |
184
+ | `de` | German | Deutsch |
185
+ | `fr` | French | Français |
186
+ | `es` | Spanish | Español |
187
+ | `it` | Italian | Italiano |
188
+ | `pt` | Portuguese | Português |
189
+ | `nl` | Dutch | Nederlands |
190
+ | `sv` | Swedish | Svenska |
191
+ | `no` | Norwegian | Norsk |
192
+ | `da` | Danish | Dansk |
193
+ | `fi` | Finnish | Suomi |
194
+ | `cs` | Czech | Čeština |
195
+ | `sk` | Slovak | Slovenčina |
196
+ | `hu` | Hungarian | Magyar |
197
+ | `ro` | Romanian | Română |
198
+ | `bg` | Bulgarian | Български |
199
+ | `uk` | Ukrainian | Українська |
200
+ | `ja` | Japanese | 日本語 |
201
+ | `ko` | Korean | 한국어 |
202
+ | `zh` | Chinese | 中文 |
203
+ | `ar` | Arabic (RTL) | العربية |
204
+ | `hi` | Hindi | हिन्दी |
205
+ | `bn` | Bengali | বাংলা |
206
+ | `th` | Thai | ไทย |
207
+ | `vi` | Vietnamese | Tiếng Việt |
208
+ | `id` | Indonesian | Indonesia |
209
+ | `sw` | Swahili | Kiswahili |
210
+ | `fil` | Filipino | Filipino |
211
+ | `ms` | Malay | Melayu |
173
212
 
174
213
  ## Adding Custom Translations
175
214
 
@@ -192,7 +231,7 @@ All Nice2Dev components use namespaced keys like:
192
231
  - `dataGrid.sort`, `dataGrid.filter` — grid-specific
193
232
  - `form.required`, `form.invalid` — validation messages
194
233
 
195
- See `src/i18nDictionaries.ts` for the full list.
234
+ See `src/dictionaries/en.ts` for the full list.
196
235
 
197
236
  ## License
198
237
 
package/dist/all.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./i18nDictionaries.cjs"),e=require("./translate-pipeline.cjs"),a=require("./translationMemory.cjs"),t=require("./dictionaries/index.cjs");function g(o="en",r){const n=t.NICE_I18N_DICTIONARIES[o]??t.NICE_I18N_DICTIONARIES.en,i=r?{...n,...r}:n;return(l,I)=>i[l]??I}exports.NICE_I18N_VARIANTS=s.NICE_I18N_VARIANTS;exports.resolvePlVariant=s.resolvePlVariant;exports.generateCoverageReport=e.generateCoverageReport;exports.generateTranslationCode=e.generateTranslationCode;exports.getAllTranslationStats=e.getAllTranslationStats;exports.getMissingTranslations=e.getMissingTranslations;exports.getSourceKeys=e.getSourceKeys;exports.getTranslationStats=e.getTranslationStats;exports.NICE_GLOSSARY=a.NICE_GLOSSARY;exports.findSimilarTranslation=a.findSimilarTranslation;exports.getGlossaryForLanguage=a.getGlossaryForLanguage;exports.lookupGlossary=a.lookupGlossary;exports.validateAgainstGlossary=a.validateAgainstGlossary;exports.NICE_I18N_DICTIONARIES=t.NICE_I18N_DICTIONARIES;exports.createTranslator=g;
package/dist/all.d.ts ADDED
@@ -0,0 +1,136 @@
1
+ /**
2
+ * A translation function without React context, for non-component code. Synchronous, so it
3
+ * reads the full dictionary map; in an app, `await loadNiceDictionary(lang)` from the main
4
+ * entry and look keys up in what it returns instead.
5
+ */
6
+ export declare function createTranslator(lang?: NiceSupportedLang, overrides?: Record<string, string>): NiceTranslateFn;
7
+
8
+ /**
9
+ * Find fuzzy matches in existing translations for reuse.
10
+ * Compares the English value to find similar existing translations.
11
+ */
12
+ export declare function findSimilarTranslation(englishValue: string, lang: NiceSupportedLang, threshold?: number): {
13
+ key: string;
14
+ english: string;
15
+ translated: string;
16
+ similarity: number;
17
+ } | undefined;
18
+
19
+ /**
20
+ * Generate a coverage report in markdown format.
21
+ */
22
+ export declare function generateCoverageReport(): string;
23
+
24
+ /**
25
+ * Generate TypeScript code for translations to be added to the dictionary.
26
+ */
27
+ export declare function generateTranslationCode(lang: NiceSupportedLang, translations: TranslationResult[]): string;
28
+
29
+ /**
30
+ * Get translation statistics for all languages.
31
+ */
32
+ export declare function getAllTranslationStats(): TranslationStats[];
33
+
34
+ /**
35
+ * Get all glossary entries for a specific language.
36
+ */
37
+ export declare function getGlossaryForLanguage(lang: NiceSupportedLang): Array<{
38
+ en: string;
39
+ translation: string;
40
+ }>;
41
+
42
+ /**
43
+ * Find missing translations for a specific language.
44
+ */
45
+ export declare function getMissingTranslations(lang: NiceSupportedLang): MissingTranslation[];
46
+
47
+ /**
48
+ * Get all keys from the English dictionary (source of truth).
49
+ */
50
+ export declare function getSourceKeys(): string[];
51
+
52
+ /**
53
+ * Get translation statistics for a language.
54
+ */
55
+ export declare function getTranslationStats(lang: NiceSupportedLang): TranslationStats;
56
+
57
+ export declare interface GlossaryEntry {
58
+ en: string;
59
+ translations: Partial<Record<NiceSupportedLang, string>>;
60
+ context?: string;
61
+ }
62
+
63
+ /**
64
+ * Look up a term in the glossary for a given language.
65
+ * Returns the approved translation or undefined.
66
+ */
67
+ export declare function lookupGlossary(englishTerm: string, lang: NiceSupportedLang): string | undefined;
68
+
69
+ export declare interface MissingTranslation {
70
+ key: string;
71
+ englishValue: string;
72
+ }
73
+
74
+ export declare const NICE_GLOSSARY: GlossaryEntry[];
75
+
76
+ export declare const NICE_I18N_DICTIONARIES: Record<NiceSupportedLang, Record<string, string>>;
77
+
78
+ /**
79
+ * Locale-and-register variants. Built on top of the base pl dictionary;
80
+ * unspecified keys fall back to NICE_I18N_DICTIONARIES.pl.
81
+ */
82
+ export declare const NICE_I18N_VARIANTS: Partial<Record<string, Partial<Record<NiceI18nVariant, Record<string, string>>>>>;
83
+
84
+ /**
85
+ * The languages with a built-in dictionary, and the two helpers that only need the list.
86
+ *
87
+ * Its own module, free of dictionary imports: the context, `useNiceTranslation` and the
88
+ * provider need the list but must not pull thirty dictionaries in with it. Until 1.1.x
89
+ * `isSupported` and `detectBrowserLanguage` sat next to the eager provider, in a module that
90
+ * imported all of them.
91
+ */
92
+ declare const NICE_SUPPORTED_LANGS: readonly ["en", "pl", "de", "fr", "es", "it", "pt", "nl", "sv", "no", "da", "fi", "cs", "sk", "hu", "ro", "bg", "uk", "ja", "ko", "zh", "ar", "hi", "bn", "th", "vi", "id", "sw", "fil", "ms"];
93
+
94
+ export declare type NiceI18nVariant = 'formal' | 'informal';
95
+
96
+ declare type NiceSupportedLang = (typeof NICE_SUPPORTED_LANGS)[number];
97
+
98
+ /**
99
+ * Translation function type.
100
+ * Accepts a key and a default/fallback value, returns the translated string.
101
+ */
102
+ declare type NiceTranslateFn = (key: string, defaultValue: string) => string;
103
+
104
+ /**
105
+ * Resolve a register-aware dictionary by locale + variant.
106
+ *
107
+ * Reads `pl` from its own module rather than through the aggregate, so this
108
+ * function pulls one language instead of all thirty.
109
+ */
110
+ export declare function resolvePlVariant(variant: NiceI18nVariant): Record<string, string>;
111
+
112
+ export declare interface TranslationResult {
113
+ key: string;
114
+ original: string;
115
+ translated: string;
116
+ }
117
+
118
+ export declare interface TranslationStats {
119
+ lang: NiceSupportedLang;
120
+ totalKeys: number;
121
+ translatedKeys: number;
122
+ missingKeys: number;
123
+ coverage: number;
124
+ }
125
+
126
+ /**
127
+ * Validate translations against the glossary.
128
+ * Returns entries where the translation doesn't match the glossary.
129
+ */
130
+ export declare function validateAgainstGlossary(lang: NiceSupportedLang): Array<{
131
+ key: string;
132
+ currentTranslation: string;
133
+ glossaryTranslation: string;
134
+ }>;
135
+
136
+ export { }
package/dist/all.mjs ADDED
@@ -0,0 +1,25 @@
1
+ import { NICE_I18N_VARIANTS as S, resolvePlVariant as T } from "./i18nDictionaries.mjs";
2
+ import { generateCoverageReport as p, generateTranslationCode as N, getAllTranslationStats as c, getMissingTranslations as f, getSourceKeys as A, getTranslationStats as C } from "./translate-pipeline.mjs";
3
+ import { NICE_GLOSSARY as _, findSimilarTranslation as d, getGlossaryForLanguage as x, lookupGlossary as y, validateAgainstGlossary as E } from "./translationMemory.mjs";
4
+ import { NICE_I18N_DICTIONARIES as r } from "./dictionaries/index.mjs";
5
+ function i(a = "en", t) {
6
+ const e = r[a] ?? r.en, o = t ? { ...e, ...t } : e;
7
+ return (n, s) => o[n] ?? s;
8
+ }
9
+ export {
10
+ _ as NICE_GLOSSARY,
11
+ r as NICE_I18N_DICTIONARIES,
12
+ S as NICE_I18N_VARIANTS,
13
+ i as createTranslator,
14
+ d as findSimilarTranslation,
15
+ p as generateCoverageReport,
16
+ N as generateTranslationCode,
17
+ c as getAllTranslationStats,
18
+ x as getGlossaryForLanguage,
19
+ f as getMissingTranslations,
20
+ A as getSourceKeys,
21
+ C as getTranslationStats,
22
+ y as lookupGlossary,
23
+ T as resolvePlVariant,
24
+ E as validateAgainstGlossary
25
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("react"),C=require("./locale.cjs"),d={gregory:{id:"gregory",displayName:"Gregorian",monthsInYear:12,hasEra:!0,isLunar:!1,associatedLanguages:["en","de","fr","es","it","pt","nl","pl","cs","sk","hu","ro","bg","uk","sv","no","da","fi"]},islamic:{id:"islamic",displayName:"Islamic (Hijri)",monthsInYear:12,hasEra:!0,isLunar:!0,associatedLanguages:["ar"]},"islamic-umalqura":{id:"islamic-umalqura",displayName:"Islamic (Umm al-Qura)",monthsInYear:12,hasEra:!0,isLunar:!0,associatedLanguages:["ar"]},"islamic-tbla":{id:"islamic-tbla",displayName:"Islamic (Tabular)",monthsInYear:12,hasEra:!0,isLunar:!0,associatedLanguages:["ar"]},"islamic-civil":{id:"islamic-civil",displayName:"Islamic (Civil)",monthsInYear:12,hasEra:!0,isLunar:!0,associatedLanguages:["ar"]},hebrew:{id:"hebrew",displayName:"Hebrew",monthsInYear:13,hasEra:!1,isLunar:!0,associatedLanguages:[]},buddhist:{id:"buddhist",displayName:"Buddhist",monthsInYear:12,hasEra:!0,isLunar:!1,associatedLanguages:[]},japanese:{id:"japanese",displayName:"Japanese (Imperial)",monthsInYear:12,hasEra:!0,isLunar:!1,associatedLanguages:["ja"]},persian:{id:"persian",displayName:"Persian (Jalali)",monthsInYear:12,hasEra:!0,isLunar:!1,associatedLanguages:[]},chinese:{id:"chinese",displayName:"Chinese",monthsInYear:12,hasEra:!0,isLunar:!0,associatedLanguages:["zh"]},coptic:{id:"coptic",displayName:"Coptic",monthsInYear:13,hasEra:!0,isLunar:!1,associatedLanguages:[]},ethiopic:{id:"ethiopic",displayName:"Ethiopian",monthsInYear:13,hasEra:!0,isLunar:!1,associatedLanguages:[]},indian:{id:"indian",displayName:"Indian (Saka)",monthsInYear:12,hasEra:!0,isLunar:!1,associatedLanguages:[]},roc:{id:"roc",displayName:"Republic of China",monthsInYear:12,hasEra:!0,isLunar:!1,associatedLanguages:["zh"]}},p={en:"gregory",pl:"gregory",de:"gregory",fr:"gregory",es:"gregory",it:"gregory",pt:"gregory",nl:"gregory",sv:"gregory",no:"gregory",da:"gregory",fi:"gregory",cs:"gregory",sk:"gregory",hu:"gregory",ro:"gregory",bg:"gregory",uk:"gregory",ja:"japanese",ko:"gregory",zh:"gregory",ar:"islamic",hi:"gregory",bn:"gregory",th:"buddhist",vi:"gregory",id:"gregory",sw:"gregory",fil:"gregory",ms:"gregory"};function E(a,e="gregory",n={}){const r=C.getLocaleTag(a),{dateStyle:s="medium",showEra:u=!1,showWeekday:y=!1}=n,o={calendar:e,dateStyle:s};y&&(delete o.dateStyle,o.weekday="long",o.year="numeric",o.month="long",o.day="numeric");const M=new Intl.DateTimeFormat(r,o),H={calendar:e,year:"numeric",month:"long",day:"numeric",era:"long"},R=new Intl.DateTimeFormat(r,H),I=new Intl.DateTimeFormat(r,{calendar:e,month:"long"}),L=new Intl.DateTimeFormat(r,{calendar:e,weekday:"long"});return{format:t=>M.format(t),formatWithEra:t=>R.format(t),getMonthName:t=>I.format(t),getMonthNames:()=>{const t=[],m=new Date(2024,0,15);for(let i=0;i<12;i++)m.setMonth(i),t.push(I.format(m));return t},getWeekdayName:t=>L.format(t),getWeekdayNames:()=>{const t=[],m=new Date(2024,0,7);for(let i=0;i<7;i++)m.setDate(7+i),t.push(L.format(m));return t},parseParts:t=>{var l,c,D,S;const i=new Intl.DateTimeFormat(r,{calendar:e,year:"numeric",month:"numeric",day:"numeric",era:"short"}).formatToParts(t);return{calendar:e,year:parseInt(((l=i.find(g=>g.type==="year"))==null?void 0:l.value)||"0",10),month:parseInt(((c=i.find(g=>g.type==="month"))==null?void 0:c.value)||"0",10),day:parseInt(((D=i.find(g=>g.type==="day"))==null?void 0:D.value)||"0",10),era:(S=i.find(g=>g.type==="era"))==null?void 0:S.value,gregorianDate:t}},getEraName:t=>{var l;return(l=new Intl.DateTimeFormat(r,{calendar:e,era:"long"}).formatToParts(t).find(c=>c.type==="era"))==null?void 0:l.value}}}function N(a,e,n="en"){return E(n,e).parseParts(a)}function T(a,e="en"){return N(new Date,a,e)}const Y=["Muharram","Safar","Rabi' al-Awwal","Rabi' al-Thani","Jumada al-Awwal","Jumada al-Thani","Rajab","Sha'ban","Ramadan","Shawwal","Dhu al-Qi'dah","Dhu al-Hijjah"];function w(a){return(11*a+14)%30<11}function k(a,e){return e===12?w(a)?30:29:e%2===1?30:29}const F=["Tishrei","Cheshvan","Kislev","Tevet","Shevat","Adar","Nisan","Iyar","Sivan","Tammuz","Av","Elul"],j=["Tishrei","Cheshvan","Kislev","Tevet","Shevat","Adar I","Adar II","Nisan","Iyar","Sivan","Tammuz","Av","Elul"];function _(a){return(7*a+1)%19<7}const h=[{name:"Meiji",kanji:"明治",startDate:new Date(1868,9,23)},{name:"Taisho",kanji:"大正",startDate:new Date(1912,6,30)},{name:"Showa",kanji:"昭和",startDate:new Date(1926,11,25)},{name:"Heisei",kanji:"平成",startDate:new Date(1989,0,8)},{name:"Reiwa",kanji:"令和",startDate:new Date(2019,4,1)}];function A(a){for(let e=h.length-1;e>=0;e--)if(a>=h[e].startDate)return h[e];return null}function O(a){const e=A(a);return e?a.getFullYear()-e.startDate.getFullYear()+1:null}const P=["Farvardin","Ordibehesht","Khordad","Tir","Mordad","Shahrivar","Mehr","Aban","Azar","Dey","Bahman","Esfand"];function W(a){return((a-474)%2820+2820)%2820*682%2816<682}const b=["Rat","Ox","Tiger","Rabbit","Dragon","Snake","Horse","Goat","Monkey","Rooster","Dog","Pig"];function J(a){return b[(a-4)%12]}const v=["Jia","Yi","Bing","Ding","Wu","Ji","Geng","Xin","Ren","Gui"];function z(a){return v[(a-4)%10]}function B(a,e,n){const r=e||p[a],s=f.useMemo(()=>E(a,r,n),[a,r,n]),u=f.useMemo(()=>d[r],[r]),y=f.useMemo(()=>T(r,a),[r,a]);return{calendar:r,info:u,current:y,format:s.format,formatWithEra:s.formatWithEra,getMonthName:s.getMonthName,getMonthNames:s.getMonthNames,getWeekdayName:s.getWeekdayName,getWeekdayNames:s.getWeekdayNames,parseParts:s.parseParts,getEraName:s.getEraName,toCalendar:o=>N(o,r,a)}}function q(){return Object.keys(d)}function G(a,e="en"){const n={...d[a]};try{const r=C.getLocaleTag(e),u=new Intl.DisplayNames([r],{type:"calendar"}).of(a);u&&(n.displayName=u)}catch{}return n}function Z(a){const e=p[a],n=new Set([e]);for(const[r,s]of Object.entries(d))s.associatedLanguages.includes(a)&&n.add(r);return n.add("gregory"),Array.from(n)}exports.CALENDAR_INFO=d;exports.CELESTIAL_STEMS=v;exports.CHINESE_ZODIAC=b;exports.DEFAULT_CALENDAR=p;exports.HEBREW_MONTHS=F;exports.HEBREW_MONTHS_LEAP=j;exports.HIJRI_MONTHS=Y;exports.JAPANESE_ERAS=h;exports.PERSIAN_MONTHS=P;exports.createCalendarFormatter=E;exports.getAvailableCalendars=q;exports.getCalendarInfo=G;exports.getCelestialStem=z;exports.getChineseZodiac=J;exports.getCurrentCalendarDate=T;exports.getHijriMonthDays=k;exports.getJapaneseEra=A;exports.getJapaneseYear=O;exports.getRecommendedCalendars=Z;exports.isHebrewLeapYear=_;exports.isHijriLeapYear=w;exports.isPersianLeapYear=W;exports.toCalendar=N;exports.useCalendar=B;