diff --git a/Jint.Benchmark/IntlColdStartBenchmark.cs b/Jint.Benchmark/IntlColdStartBenchmark.cs
new file mode 100644
index 0000000000..123e13cb3a
--- /dev/null
+++ b/Jint.Benchmark/IntlColdStartBenchmark.cs
@@ -0,0 +1,43 @@
+using BenchmarkDotNet.Attributes;
+using Jint.Native;
+
+namespace Jint.Benchmark;
+
+[MemoryDiagnoser]
+public class IntlColdStartBenchmark
+{
+ [Benchmark]
+ public JsValue IntlNumberFormat()
+ {
+ var engine = new Engine();
+ return engine.Evaluate("new Intl.NumberFormat('de', {notation: 'compact'}).format(1234567)");
+ }
+
+ [Benchmark]
+ public JsValue IntlDateTimeFormat()
+ {
+ var engine = new Engine();
+ return engine.Evaluate("new Intl.DateTimeFormat('en').format(new Date())");
+ }
+
+ [Benchmark]
+ public JsValue IntlListFormat()
+ {
+ var engine = new Engine();
+ return engine.Evaluate("new Intl.ListFormat('en').format(['a','b','c'])");
+ }
+
+ [Benchmark]
+ public JsValue IntlRelativeTimeFormat()
+ {
+ var engine = new Engine();
+ return engine.Evaluate("new Intl.RelativeTimeFormat('en').format(-1, 'day')");
+ }
+
+ [Benchmark]
+ public JsValue LocaleCanonicalization()
+ {
+ var engine = new Engine();
+ return engine.Evaluate("new Intl.Locale('en-US').maximize().toString()");
+ }
+}
diff --git a/Jint/Jint.csproj b/Jint/Jint.csproj
index d07b934ebc..68e7a621f4 100644
--- a/Jint/Jint.csproj
+++ b/Jint/Jint.csproj
@@ -42,13 +42,7 @@
-
-
-
-
-
-
diff --git a/Jint/Native/Intl/Data/CompactPatterns.Data.cs b/Jint/Native/Intl/Data/CompactPatterns.Data.cs
new file mode 100644
index 0000000000..e53ab98855
--- /dev/null
+++ b/Jint/Native/Intl/Data/CompactPatterns.Data.cs
@@ -0,0 +1,166 @@
+namespace Jint.Native.Intl.Data;
+
+internal static partial class CompactPatterns
+{
+ private static readonly Dictionary _patterns = new(12, StringComparer.OrdinalIgnoreCase)
+ {
+ ["en"] = new LocaleCompactData
+ {
+ ShortThousand = "K",
+ ShortMillion = "M",
+ ShortBillion = "B",
+ ShortTrillion = "T",
+ Threshold = 1000,
+ ShortSpace = false,
+ },
+ ["de"] = new LocaleCompactData
+ {
+ ShortThousand = "",
+ ShortMillion = "Mio.",
+ ShortBillion = "Mrd.",
+ ShortTrillion = "Bio.",
+ LongThousand = "Tausend",
+ LongMillion = "Millionen",
+ LongBillion = "Milliarden",
+ LongTrillion = "Billionen",
+ Threshold = 1000000,
+ ThresholdLong = 1000,
+ },
+ ["ja"] = new LocaleCompactData
+ {
+ ShortThousand = "",
+ ShortMillion = "万",
+ ShortBillion = "億",
+ ShortTrillion = "兆",
+ LongThousand = "",
+ LongMillion = "万",
+ LongBillion = "億",
+ LongTrillion = "兆",
+ Threshold = 10000,
+ DivisorMillion = 10000,
+ DivisorBillion = 100000000,
+ ShortSpace = false,
+ LongSpace = false,
+ },
+ ["ko"] = new LocaleCompactData
+ {
+ ShortThousand = "천",
+ ShortMillion = "만",
+ ShortBillion = "억",
+ ShortTrillion = "조",
+ LongThousand = "천",
+ LongMillion = "만",
+ LongBillion = "억",
+ LongTrillion = "조",
+ Threshold = 1000,
+ DivisorMillion = 10000,
+ DivisorBillion = 100000000,
+ ShortSpace = false,
+ LongSpace = false,
+ },
+ ["zh"] = new LocaleCompactData
+ {
+ ShortThousand = "",
+ ShortMillion = "万",
+ ShortBillion = "亿",
+ ShortTrillion = "兆",
+ LongThousand = "",
+ LongMillion = "万",
+ LongBillion = "亿",
+ LongTrillion = "兆",
+ Threshold = 10000,
+ DivisorMillion = 10000,
+ DivisorBillion = 100000000,
+ ShortSpace = false,
+ LongSpace = false,
+ },
+ ["zh-TW"] = new LocaleCompactData
+ {
+ ShortThousand = "",
+ ShortMillion = "萬",
+ ShortBillion = "億",
+ ShortTrillion = "兆",
+ LongThousand = "",
+ LongMillion = "萬",
+ LongBillion = "億",
+ LongTrillion = "兆",
+ Threshold = 10000,
+ DivisorMillion = 10000,
+ DivisorBillion = 100000000,
+ ShortSpace = false,
+ LongSpace = false,
+ },
+ ["fr"] = new LocaleCompactData
+ {
+ ShortThousand = "k",
+ ShortMillion = "M",
+ ShortBillion = "Md",
+ ShortTrillion = "Bn",
+ LongThousand = "millier",
+ LongMillion = "millions",
+ LongBillion = "milliards",
+ LongTrillion = "billions",
+ Threshold = 1000,
+ },
+ ["es"] = new LocaleCompactData
+ {
+ ShortThousand = "k",
+ ShortMillion = "M",
+ ShortBillion = "mil M",
+ ShortTrillion = "B",
+ LongThousand = "mil",
+ LongMillion = "millones",
+ LongBillion = "mil millones",
+ LongTrillion = "billones",
+ Threshold = 1000,
+ },
+ ["it"] = new LocaleCompactData
+ {
+ ShortThousand = "",
+ ShortMillion = "Mln",
+ ShortBillion = "Mrd",
+ ShortTrillion = "Bln",
+ LongThousand = "mila",
+ LongMillion = "milioni",
+ LongBillion = "miliardi",
+ LongTrillion = "bilioni",
+ Threshold = 1000000,
+ },
+ ["pt"] = new LocaleCompactData
+ {
+ ShortThousand = "mil",
+ ShortMillion = "mi",
+ ShortBillion = "bi",
+ ShortTrillion = "tri",
+ LongThousand = "mil",
+ LongMillion = "milhões",
+ LongBillion = "bilhões",
+ LongTrillion = "trilhões",
+ Threshold = 1000,
+ },
+ ["ru"] = new LocaleCompactData
+ {
+ ShortThousand = "тыс.",
+ ShortMillion = "млн",
+ ShortBillion = "млрд",
+ ShortTrillion = "трлн",
+ LongThousand = "тысяч",
+ LongMillion = "миллионов",
+ LongBillion = "миллиардов",
+ LongTrillion = "триллионов",
+ Threshold = 1000,
+ },
+ ["ar"] = new LocaleCompactData
+ {
+ ShortThousand = "ألف",
+ ShortMillion = "مليون",
+ ShortBillion = "مليار",
+ ShortTrillion = "ترليون",
+ LongThousand = "ألف",
+ LongMillion = "مليون",
+ LongBillion = "مليار",
+ LongTrillion = "ترليون",
+ Threshold = 1000,
+ },
+ };
+}
diff --git a/Jint/Native/Intl/Data/CompactPatterns.cs b/Jint/Native/Intl/Data/CompactPatterns.cs
index a532491c7c..cf86a16eeb 100644
--- a/Jint/Native/Intl/Data/CompactPatterns.cs
+++ b/Jint/Native/Intl/Data/CompactPatterns.cs
@@ -1,29 +1,20 @@
-using System.Threading;
-
namespace Jint.Native.Intl.Data;
///
/// Provides CLDR compact number patterns for locale-aware compact notation.
-/// Data is loaded from embedded CompactPatterns.txt resource.
///
-internal static class CompactPatterns
+internal static partial class CompactPatterns
{
- private static readonly Lock _lock = new();
- private static Dictionary? _patterns;
- private static volatile bool _loaded;
-
///
/// Gets compact patterns for a language code.
/// Falls back to English if not found.
///
public static LocaleCompactData GetPatterns(string? language)
{
- EnsureLoaded();
-
if (!string.IsNullOrEmpty(language))
{
// Try exact match first
- if (_patterns!.TryGetValue(language!, out var data))
+ if (_patterns.TryGetValue(language!, out var data))
{
return data;
}
@@ -38,7 +29,7 @@ public static LocaleCompactData GetPatterns(string? language)
language.Contains("-MO", StringComparison.OrdinalIgnoreCase) ||
language.Contains("-Hant", StringComparison.OrdinalIgnoreCase);
var zhKey = isTraditional ? "zh-TW" : "zh";
- if (_patterns.TryGetValue(zhKey, out data))
+ if (_patterns!.TryGetValue(zhKey, out data))
{
return data;
}
@@ -57,142 +48,7 @@ public static LocaleCompactData GetPatterns(string? language)
}
// Fall back to English
- return _patterns!.TryGetValue("en", out var enData) ? enData : LocaleCompactData.Default;
- }
-
- private static void EnsureLoaded()
- {
- if (_loaded)
- {
- return;
- }
-
- lock (_lock)
- {
- if (_loaded)
- {
- return;
- }
-
- _patterns = new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- var assembly = typeof(CompactPatterns).Assembly;
- using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.CompactPatterns.txt");
- if (stream is null)
- {
- _loaded = true;
- return;
- }
-
- using var reader = new StreamReader(stream);
- string? currentLang = null;
- LocaleCompactData? currentData = null;
-
- while (reader.ReadLine() is { } line)
- {
- if (string.IsNullOrWhiteSpace(line))
- {
- continue;
- }
-
- if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']')
- {
- // Save previous locale data
- if (currentLang != null && currentData != null)
- {
- _patterns[currentLang] = currentData;
- }
-
- currentLang = line.Substring(1, line.Length - 2);
- currentData = new LocaleCompactData();
- continue;
- }
-
- if (currentData == null)
- {
- continue;
- }
-
- var eqIndex = line.IndexOf('=');
- if (eqIndex < 0)
- {
- continue;
- }
-
- var key = line.Substring(0, eqIndex);
- var value = line.Substring(eqIndex + 1);
-
- switch (key)
- {
- case "short_thousand":
- currentData.ShortThousand = value;
- break;
- case "short_million":
- currentData.ShortMillion = value;
- break;
- case "short_billion":
- currentData.ShortBillion = value;
- break;
- case "short_trillion":
- currentData.ShortTrillion = value;
- break;
- case "long_thousand":
- currentData.LongThousand = value;
- break;
- case "long_million":
- currentData.LongMillion = value;
- break;
- case "long_billion":
- currentData.LongBillion = value;
- break;
- case "long_trillion":
- currentData.LongTrillion = value;
- break;
- case "threshold":
- if (long.TryParse(value, System.Globalization.NumberStyles.Integer,
- System.Globalization.CultureInfo.InvariantCulture, out var threshold))
- {
- currentData.Threshold = threshold;
- }
- break;
- case "threshold_long":
- if (long.TryParse(value, System.Globalization.NumberStyles.Integer,
- System.Globalization.CultureInfo.InvariantCulture, out var thresholdLong))
- {
- currentData.ThresholdLong = thresholdLong;
- }
- break;
- case "divisor_million":
- if (long.TryParse(value, System.Globalization.NumberStyles.Integer,
- System.Globalization.CultureInfo.InvariantCulture, out var divMillion))
- {
- currentData.DivisorMillion = divMillion;
- }
- break;
- case "divisor_billion":
- if (long.TryParse(value, System.Globalization.NumberStyles.Integer,
- System.Globalization.CultureInfo.InvariantCulture, out var divBillion))
- {
- currentData.DivisorBillion = divBillion;
- }
- break;
- case "short_space":
- currentData.ShortSpace = !string.Equals(value, "false", StringComparison.OrdinalIgnoreCase);
- break;
- case "long_space":
- currentData.LongSpace = !string.Equals(value, "false", StringComparison.OrdinalIgnoreCase);
- break;
- }
- }
-
- // Save last locale data
- if (currentLang != null && currentData != null)
- {
- _patterns[currentLang] = currentData;
- }
-
- _loaded = true;
- }
+ return _patterns.TryGetValue("en", out var enData) ? enData : LocaleCompactData.Default;
}
internal sealed class LocaleCompactData
diff --git a/Jint/Native/Intl/Data/LikelySubtagsData.cs b/Jint/Native/Intl/Data/LikelySubtagsData.cs
index a774a6b978..9fd69e807b 100644
--- a/Jint/Native/Intl/Data/LikelySubtagsData.cs
+++ b/Jint/Native/Intl/Data/LikelySubtagsData.cs
@@ -6,13 +6,11 @@ namespace Jint.Native.Intl.Data;
///
internal static class LikelySubtagsData
{
- private static Dictionary? _likelySubtags;
-
- private static Dictionary LikelySubtags => _likelySubtags ??= Load();
+ private static readonly Lazy> _likelySubtags = new(Load);
public static bool TryResolve(string key, out string value)
{
- return LikelySubtags.TryGetValue(key, out value!);
+ return _likelySubtags.Value.TryGetValue(key, out value!);
}
private static Dictionary Load()
diff --git a/Jint/Native/Intl/Data/ListPatternsData.Data.cs b/Jint/Native/Intl/Data/ListPatternsData.Data.cs
new file mode 100644
index 0000000000..d5b9d5947b
--- /dev/null
+++ b/Jint/Native/Intl/Data/ListPatternsData.Data.cs
@@ -0,0 +1,56 @@
+namespace Jint.Native.Intl.Data;
+
+internal static partial class ListPatternsData
+{
+ private static readonly Dictionary> _patterns = new(4, StringComparer.OrdinalIgnoreCase)
+ {
+ ["en"] = new(9, StringComparer.Ordinal)
+ {
+ ["conjunction_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, and {1}", Two = "{0} and {1}" },
+ ["conjunction_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, & {1}", Two = "{0} & {1}" },
+ ["conjunction_narrow"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0}, {1}" },
+ ["disjunction_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, or {1}", Two = "{0} or {1}" },
+ ["disjunction_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, or {1}", Two = "{0} or {1}" },
+ ["disjunction_narrow"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, or {1}", Two = "{0} or {1}" },
+ ["unit_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0}, {1}" },
+ ["unit_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0}, {1}" },
+ ["unit_narrow"] = new ListPatterns { Start = "{0} {1}", Middle = "{0} {1}", End = "{0} {1}", Two = "{0} {1}" },
+ },
+ ["es"] = new(9, StringComparer.Ordinal)
+ {
+ ["conjunction_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} y {1}", Two = "{0} y {1}" },
+ ["conjunction_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} y {1}", Two = "{0} y {1}" },
+ ["conjunction_narrow"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} y {1}", Two = "{0} y {1}" },
+ ["disjunction_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} o {1}", Two = "{0} o {1}" },
+ ["disjunction_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} o {1}", Two = "{0} o {1}" },
+ ["disjunction_narrow"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} o {1}", Two = "{0} o {1}" },
+ ["unit_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} y {1}", Two = "{0} y {1}" },
+ ["unit_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0} y {1}" },
+ ["unit_narrow"] = new ListPatterns { Start = "{0} {1}", Middle = "{0} {1}", End = "{0} {1}", Two = "{0} {1}" },
+ },
+ ["de"] = new(9, StringComparer.Ordinal)
+ {
+ ["conjunction_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} und {1}", Two = "{0} und {1}" },
+ ["conjunction_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0}, {1}" },
+ ["conjunction_narrow"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0}, {1}" },
+ ["disjunction_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} oder {1}", Two = "{0} oder {1}" },
+ ["disjunction_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} od. {1}", Two = "{0} od. {1}" },
+ ["disjunction_narrow"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} od. {1}", Two = "{0} od. {1}" },
+ ["unit_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0}, {1}" },
+ ["unit_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0}, {1}" },
+ ["unit_narrow"] = new ListPatterns { Start = "{0} {1}", Middle = "{0} {1}", End = "{0} {1}", Two = "{0} {1}" },
+ },
+ ["pl"] = new(9, StringComparer.Ordinal)
+ {
+ ["conjunction_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} i {1}", Two = "{0} i {1}" },
+ ["conjunction_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} i {1}", Two = "{0} i {1}" },
+ ["conjunction_narrow"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} i {1}", Two = "{0} i {1}" },
+ ["disjunction_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} lub {1}", Two = "{0} lub {1}" },
+ ["disjunction_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} lub {1}", Two = "{0} lub {1}" },
+ ["disjunction_narrow"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0} lub {1}", Two = "{0} lub {1}" },
+ ["unit_long"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0}, {1}" },
+ ["unit_short"] = new ListPatterns { Start = "{0}, {1}", Middle = "{0}, {1}", End = "{0}, {1}", Two = "{0}, {1}" },
+ ["unit_narrow"] = new ListPatterns { Start = "{0} {1}", Middle = "{0} {1}", End = "{0} {1}", Two = "{0} {1}" },
+ },
+ };
+}
diff --git a/Jint/Native/Intl/Data/ListPatternsData.cs b/Jint/Native/Intl/Data/ListPatternsData.cs
index 8359923a34..107249372b 100644
--- a/Jint/Native/Intl/Data/ListPatternsData.cs
+++ b/Jint/Native/Intl/Data/ListPatternsData.cs
@@ -1,17 +1,10 @@
-using System.Threading;
-
namespace Jint.Native.Intl.Data;
///
/// Provides CLDR list formatting patterns for locale-aware list formatting.
-/// Data is loaded from embedded ListPatternsData.txt resource.
///
-internal static class ListPatternsData
+internal static partial class ListPatternsData
{
- private static readonly Lock _lock = new();
- private static Dictionary>? _patterns;
- private static volatile bool _loaded;
-
///
/// Gets list patterns for a locale.
/// Returns patterns grouped by type_style (e.g., "conjunction_long", "unit_narrow").
@@ -19,15 +12,13 @@ internal static class ListPatternsData
///
public static Dictionary? GetPatternsForLocale(string locale)
{
- EnsureLoaded();
-
if (!string.IsNullOrEmpty(locale))
{
// Get language code from locale (e.g., "es" from "es-ES")
var language = GetLanguageCode(locale);
// Try to find patterns for this language
- if (_patterns!.TryGetValue(language, out var data))
+ if (_patterns.TryGetValue(language, out var data))
{
return data;
}
@@ -36,7 +27,7 @@ internal static class ListPatternsData
// Fall back to English if not found and not already English
if (!IsEnglish(locale))
{
- if (_patterns!.TryGetValue("en", out var enData))
+ if (_patterns.TryGetValue("en", out var enData))
{
return enData;
}
@@ -67,124 +58,4 @@ private static bool IsEnglish(string? locale)
return locale!.StartsWith("en", StringComparison.OrdinalIgnoreCase);
}
- private static void EnsureLoaded()
- {
- if (_loaded)
- {
- return;
- }
-
- lock (_lock)
- {
- if (_loaded)
- {
- return;
- }
-
- _patterns = new Dictionary>(StringComparer.OrdinalIgnoreCase);
-
- var assembly = typeof(ListPatternsData).Assembly;
- using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.ListPatternsData.txt");
- if (stream is null)
- {
- _loaded = true;
- return;
- }
-
- using var reader = new StreamReader(stream);
- string? currentLocale = null;
- Dictionary? currentPatterns = null;
-
- // Temporary storage for building ListPatterns objects
- var tempPatterns = new Dictionary>(StringComparer.Ordinal);
-
- while (reader.ReadLine() is { } line)
- {
- if (string.IsNullOrWhiteSpace(line))
- {
- continue;
- }
-
- if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']')
- {
- // Save previous locale data
- if (currentLocale != null && tempPatterns.Count > 0)
- {
- currentPatterns = BuildListPatternsFromTemp(tempPatterns);
- _patterns[currentLocale] = currentPatterns;
- tempPatterns.Clear();
- }
-
- currentLocale = line.Substring(1, line.Length - 2);
- continue;
- }
-
- if (currentLocale == null)
- {
- continue;
- }
-
- var eqIndex = line.IndexOf('=');
- if (eqIndex < 0)
- {
- continue;
- }
-
- var key = line.Substring(0, eqIndex);
- var value = line.Substring(eqIndex + 1);
-
- // Parse key: type_style_position (e.g., "conjunction_long_end")
- // Store in temp dictionary for later assembly
- var parts = key.Split('_');
- if (parts.Length >= 3)
- {
- var type = parts[0]; // conjunction, disjunction, unit
- var style = parts[1]; // long, short, narrow
- var position = parts[2]; // start, middle, end, two
-
- var typeStyleKey = type + "_" + style;
- if (!tempPatterns.TryGetValue(typeStyleKey, out var positionPatterns))
- {
- positionPatterns = new Dictionary(StringComparer.Ordinal);
- tempPatterns[typeStyleKey] = positionPatterns;
- }
-
- positionPatterns[position] = value;
- }
- }
-
- // Save last locale data
- if (currentLocale != null && tempPatterns.Count > 0)
- {
- currentPatterns = BuildListPatternsFromTemp(tempPatterns);
- _patterns[currentLocale] = currentPatterns;
- }
-
- _loaded = true;
- }
- }
-
- private static Dictionary BuildListPatternsFromTemp(Dictionary> tempPatterns)
- {
- var result = new Dictionary(StringComparer.Ordinal);
-
- foreach (var kvp in tempPatterns)
- {
- var typeStyleKey = kvp.Key;
- var positionPatterns = kvp.Value;
-
- // Build ListPatterns object
- var listPatterns = new ListPatterns
- {
- Start = positionPatterns.TryGetValue("start", out var start) ? start : "{0}, {1}",
- Middle = positionPatterns.TryGetValue("middle", out var middle) ? middle : "{0}, {1}",
- End = positionPatterns.TryGetValue("end", out var end) ? end : "{0}, {1}",
- Two = positionPatterns.TryGetValue("two", out var two) ? two : "{0}, {1}"
- };
-
- result[typeStyleKey] = listPatterns;
- }
-
- return result;
- }
}
diff --git a/Jint/Native/Intl/Data/LocaleData.Data.cs b/Jint/Native/Intl/Data/LocaleData.Data.cs
new file mode 100644
index 0000000000..1d420ba98e
--- /dev/null
+++ b/Jint/Native/Intl/Data/LocaleData.Data.cs
@@ -0,0 +1,1056 @@
+namespace Jint.Native.Intl.Data;
+
+internal static partial class LocaleData
+{
+ private static readonly Dictionary _tagMappings = new(5, StringComparer.OrdinalIgnoreCase)
+ {
+ ["art-lojban"] = "jbo",
+ ["cel-gaulish"] = "xtg",
+ ["zh-guoyu"] = "zh",
+ ["zh-hakka"] = "hak",
+ ["zh-xiang"] = "hsn",
+ };
+
+ private static readonly Dictionary _languageMappings = new(354, StringComparer.OrdinalIgnoreCase)
+ {
+ ["aam"] = "aas",
+ ["aar"] = "aa",
+ ["abk"] = "ab",
+ ["adp"] = "dz",
+ ["afr"] = "af",
+ ["aju"] = "jrb",
+ ["aka"] = "ak",
+ ["alb"] = "sq",
+ ["als"] = "sq",
+ ["amh"] = "am",
+ ["ara"] = "ar",
+ ["arb"] = "ar",
+ ["arg"] = "an",
+ ["arm"] = "hy",
+ ["asd"] = "snz",
+ ["asm"] = "as",
+ ["aue"] = "ktz",
+ ["ava"] = "av",
+ ["ave"] = "ae",
+ ["aym"] = "ay",
+ ["ayr"] = "ay",
+ ["ayx"] = "nun",
+ ["aze"] = "az",
+ ["azj"] = "az",
+ ["bak"] = "ba",
+ ["bam"] = "bm",
+ ["baq"] = "eu",
+ ["bcc"] = "bal",
+ ["bcl"] = "bik",
+ ["bel"] = "be",
+ ["ben"] = "bn",
+ ["bgm"] = "bcg",
+ ["bh"] = "bho",
+ ["bih"] = "bho",
+ ["bis"] = "bi",
+ ["bjd"] = "drl",
+ ["bod"] = "bo",
+ ["bos"] = "bs",
+ ["bre"] = "br",
+ ["bul"] = "bg",
+ ["bur"] = "my",
+ ["bxk"] = "luy",
+ ["bxr"] = "bua",
+ ["cat"] = "ca",
+ ["ccq"] = "rki",
+ ["ces"] = "cs",
+ ["cha"] = "ch",
+ ["che"] = "ce",
+ ["chi"] = "zh",
+ ["chu"] = "cu",
+ ["chv"] = "cv",
+ ["cjr"] = "mom",
+ ["cka"] = "cmr",
+ ["cld"] = "syr",
+ ["cmk"] = "xch",
+ ["cmn"] = "zh",
+ ["cor"] = "kw",
+ ["cos"] = "co",
+ ["coy"] = "pij",
+ ["cqu"] = "quh",
+ ["cre"] = "cr",
+ ["cwd"] = "cr",
+ ["cym"] = "cy",
+ ["cze"] = "cs",
+ ["dan"] = "da",
+ ["deu"] = "de",
+ ["dgo"] = "doi",
+ ["dhd"] = "mwr",
+ ["dik"] = "din",
+ ["diq"] = "zza",
+ ["dit"] = "dif",
+ ["div"] = "dv",
+ ["drh"] = "mn",
+ ["dut"] = "nl",
+ ["dzo"] = "dz",
+ ["ekk"] = "et",
+ ["ell"] = "el",
+ ["emk"] = "man",
+ ["eng"] = "en",
+ ["epo"] = "eo",
+ ["esk"] = "ik",
+ ["est"] = "et",
+ ["eus"] = "eu",
+ ["ewe"] = "ee",
+ ["fao"] = "fo",
+ ["fas"] = "fa",
+ ["fat"] = "ak",
+ ["fij"] = "fj",
+ ["fin"] = "fi",
+ ["fra"] = "fr",
+ ["fre"] = "fr",
+ ["fry"] = "fy",
+ ["fuc"] = "ff",
+ ["ful"] = "ff",
+ ["gav"] = "dev",
+ ["gaz"] = "om",
+ ["gbo"] = "grb",
+ ["geo"] = "ka",
+ ["ger"] = "de",
+ ["gfx"] = "vaj",
+ ["ggn"] = "gvr",
+ ["gla"] = "gd",
+ ["gle"] = "ga",
+ ["glg"] = "gl",
+ ["glv"] = "gv",
+ ["gno"] = "gon",
+ ["gre"] = "el",
+ ["grn"] = "gn",
+ ["gti"] = "nyc",
+ ["gug"] = "gn",
+ ["guj"] = "gu",
+ ["guv"] = "duz",
+ ["gya"] = "gba",
+ ["hat"] = "ht",
+ ["hau"] = "ha",
+ ["hdn"] = "hai",
+ ["hea"] = "hmn",
+ ["heb"] = "he",
+ ["her"] = "hz",
+ ["him"] = "srx",
+ ["hin"] = "hi",
+ ["hmo"] = "ho",
+ ["hrr"] = "jal",
+ ["hrv"] = "hr",
+ ["hun"] = "hu",
+ ["hye"] = "hy",
+ ["ibi"] = "opa",
+ ["ibo"] = "ig",
+ ["ice"] = "is",
+ ["ido"] = "io",
+ ["iii"] = "ii",
+ ["ike"] = "iu",
+ ["iku"] = "iu",
+ ["ile"] = "ie",
+ ["ilw"] = "gal",
+ ["in"] = "id",
+ ["ina"] = "ia",
+ ["ind"] = "id",
+ ["ipk"] = "ik",
+ ["isl"] = "is",
+ ["ita"] = "it",
+ ["iw"] = "he",
+ ["jav"] = "jv",
+ ["jeg"] = "oyb",
+ ["ji"] = "yi",
+ ["jpn"] = "ja",
+ ["jw"] = "jv",
+ ["kal"] = "kl",
+ ["kan"] = "kn",
+ ["kas"] = "ks",
+ ["kat"] = "ka",
+ ["kau"] = "kr",
+ ["kaz"] = "kk",
+ ["kgc"] = "tdf",
+ ["kgh"] = "kml",
+ ["khk"] = "mn",
+ ["khm"] = "km",
+ ["kik"] = "ki",
+ ["kin"] = "rw",
+ ["kir"] = "ky",
+ ["kmr"] = "ku",
+ ["knc"] = "kr",
+ ["kng"] = "kg",
+ ["knn"] = "kok",
+ ["koj"] = "kwv",
+ ["kom"] = "kv",
+ ["kon"] = "kg",
+ ["kor"] = "ko",
+ ["kpv"] = "kv",
+ ["krm"] = "bmf",
+ ["ktr"] = "dtp",
+ ["kua"] = "kj",
+ ["kur"] = "ku",
+ ["kvs"] = "gdj",
+ ["kwq"] = "yam",
+ ["kxe"] = "tvd",
+ ["kzj"] = "dtp",
+ ["kzt"] = "dtp",
+ ["lao"] = "lo",
+ ["lat"] = "la",
+ ["lav"] = "lv",
+ ["lbk"] = "bnc",
+ ["lii"] = "raq",
+ ["lim"] = "li",
+ ["lin"] = "ln",
+ ["lit"] = "lt",
+ ["llo"] = "ngt",
+ ["lmm"] = "rmx",
+ ["ltz"] = "lb",
+ ["lub"] = "lu",
+ ["lug"] = "lg",
+ ["lvs"] = "lv",
+ ["mac"] = "mk",
+ ["mah"] = "mh",
+ ["mal"] = "ml",
+ ["mao"] = "mi",
+ ["mar"] = "mr",
+ ["may"] = "ms",
+ ["meg"] = "cir",
+ ["mhr"] = "chm",
+ ["mkd"] = "mk",
+ ["mlg"] = "mg",
+ ["mlt"] = "mt",
+ ["mnk"] = "man",
+ ["mo"] = "ro",
+ ["mol"] = "ro",
+ ["mon"] = "mn",
+ ["mri"] = "mi",
+ ["msa"] = "ms",
+ ["mst"] = "mry",
+ ["mup"] = "raj",
+ ["mwj"] = "vaj",
+ ["mya"] = "my",
+ ["myd"] = "aog",
+ ["myt"] = "mry",
+ ["nad"] = "xny",
+ ["nau"] = "na",
+ ["nav"] = "nv",
+ ["nbl"] = "nr",
+ ["ncp"] = "kdz",
+ ["nde"] = "nd",
+ ["ndo"] = "ng",
+ ["nep"] = "ne",
+ ["nld"] = "nl",
+ ["nno"] = "nn",
+ ["nns"] = "nbr",
+ ["nnx"] = "ngv",
+ ["no"] = "nb",
+ ["nob"] = "nb",
+ ["nor"] = "nb",
+ ["npi"] = "ne",
+ ["nts"] = "pij",
+ ["nya"] = "ny",
+ ["oci"] = "oc",
+ ["ojg"] = "oj",
+ ["oji"] = "oj",
+ ["ori"] = "or",
+ ["orm"] = "om",
+ ["ory"] = "or",
+ ["oss"] = "os",
+ ["oun"] = "vaj",
+ ["pan"] = "pa",
+ ["pbu"] = "ps",
+ ["pcr"] = "adx",
+ ["per"] = "fa",
+ ["pes"] = "fa",
+ ["pli"] = "pi",
+ ["plt"] = "mg",
+ ["pmc"] = "huw",
+ ["pmu"] = "phr",
+ ["pnb"] = "lah",
+ ["pol"] = "pl",
+ ["por"] = "pt",
+ ["ppa"] = "bfy",
+ ["ppr"] = "lcq",
+ ["pry"] = "prt",
+ ["pus"] = "ps",
+ ["puz"] = "pub",
+ ["que"] = "qu",
+ ["quz"] = "qu",
+ ["rmy"] = "rom",
+ ["roh"] = "rm",
+ ["ron"] = "ro",
+ ["rum"] = "ro",
+ ["run"] = "rn",
+ ["rus"] = "ru",
+ ["sag"] = "sg",
+ ["san"] = "sa",
+ ["sca"] = "hle",
+ ["scc"] = "sr",
+ ["scr"] = "hr",
+ ["sin"] = "si",
+ ["skk"] = "oyb",
+ ["slk"] = "sk",
+ ["slo"] = "sk",
+ ["slv"] = "sl",
+ ["sme"] = "se",
+ ["smo"] = "sm",
+ ["sna"] = "sn",
+ ["snd"] = "sd",
+ ["som"] = "so",
+ ["sot"] = "st",
+ ["spa"] = "es",
+ ["spy"] = "kln",
+ ["sqi"] = "sq",
+ ["src"] = "sc",
+ ["srd"] = "sc",
+ ["srp"] = "sr",
+ ["ssw"] = "ss",
+ ["sun"] = "su",
+ ["swa"] = "sw",
+ ["swe"] = "sv",
+ ["swh"] = "sw",
+ ["tah"] = "ty",
+ ["tam"] = "ta",
+ ["tat"] = "tt",
+ ["tdu"] = "dtp",
+ ["tel"] = "te",
+ ["tgk"] = "tg",
+ ["tgl"] = "fil",
+ ["tha"] = "th",
+ ["thc"] = "tpo",
+ ["thx"] = "oyb",
+ ["tib"] = "bo",
+ ["tie"] = "ras",
+ ["tir"] = "ti",
+ ["tkk"] = "twm",
+ ["tl"] = "fil",
+ ["tlw"] = "weo",
+ ["tmp"] = "tyj",
+ ["tne"] = "kak",
+ ["ton"] = "to",
+ ["tsf"] = "taj",
+ ["tsn"] = "tn",
+ ["tso"] = "ts",
+ ["ttq"] = "tmh",
+ ["tuk"] = "tk",
+ ["tur"] = "tr",
+ ["tw"] = "ak",
+ ["twi"] = "ak",
+ ["uig"] = "ug",
+ ["ukr"] = "uk",
+ ["umu"] = "del",
+ ["uok"] = "ema",
+ ["urd"] = "ur",
+ ["uzb"] = "uz",
+ ["uzn"] = "uz",
+ ["ven"] = "ve",
+ ["vie"] = "vi",
+ ["vol"] = "vo",
+ ["wel"] = "cy",
+ ["wln"] = "wa",
+ ["wol"] = "wo",
+ ["xba"] = "cax",
+ ["xho"] = "xh",
+ ["xia"] = "acn",
+ ["xkh"] = "waw",
+ ["xpe"] = "kpe",
+ ["xsj"] = "suj",
+ ["xsl"] = "den",
+ ["ybd"] = "rki",
+ ["ydd"] = "yi",
+ ["yid"] = "yi",
+ ["yma"] = "lrr",
+ ["ymt"] = "mtm",
+ ["yor"] = "yo",
+ ["yos"] = "zom",
+ ["yuu"] = "yug",
+ ["zai"] = "zap",
+ ["zha"] = "za",
+ ["zho"] = "zh",
+ ["zsm"] = "ms",
+ ["zul"] = "zu",
+ ["zyb"] = "za",
+ };
+
+ private static readonly Dictionary _complexLanguageMappings = new(7, StringComparer.OrdinalIgnoreCase)
+ {
+ ["cnr"] = new ComplexLanguageMapping("sr", null, "ME"),
+ ["drw"] = new ComplexLanguageMapping("fa", null, "AF"),
+ ["hbs"] = new ComplexLanguageMapping("sr", "Latn", null),
+ ["prs"] = new ComplexLanguageMapping("fa", null, "AF"),
+ ["sh"] = new ComplexLanguageMapping("sr", "Latn", null),
+ ["swc"] = new ComplexLanguageMapping("sw", null, "CD"),
+ ["tnf"] = new ComplexLanguageMapping("fa", null, "AF"),
+ };
+
+ private static readonly Dictionary _regionMappings = new(327, StringComparer.OrdinalIgnoreCase)
+ {
+ ["100"] = "BG",
+ ["104"] = "MM",
+ ["108"] = "BI",
+ ["112"] = "BY",
+ ["116"] = "KH",
+ ["120"] = "CM",
+ ["124"] = "CA",
+ ["132"] = "CV",
+ ["136"] = "KY",
+ ["140"] = "CF",
+ ["144"] = "LK",
+ ["148"] = "TD",
+ ["152"] = "CL",
+ ["156"] = "CN",
+ ["158"] = "TW",
+ ["162"] = "CX",
+ ["166"] = "CC",
+ ["170"] = "CO",
+ ["174"] = "KM",
+ ["175"] = "YT",
+ ["178"] = "CG",
+ ["180"] = "CD",
+ ["184"] = "CK",
+ ["188"] = "CR",
+ ["191"] = "HR",
+ ["192"] = "CU",
+ ["196"] = "CY",
+ ["203"] = "CZ",
+ ["204"] = "BJ",
+ ["208"] = "DK",
+ ["212"] = "DM",
+ ["214"] = "DO",
+ ["218"] = "EC",
+ ["222"] = "SV",
+ ["226"] = "GQ",
+ ["230"] = "ET",
+ ["231"] = "ET",
+ ["232"] = "ER",
+ ["233"] = "EE",
+ ["234"] = "FO",
+ ["238"] = "FK",
+ ["239"] = "GS",
+ ["242"] = "FJ",
+ ["246"] = "FI",
+ ["248"] = "AX",
+ ["249"] = "FR",
+ ["250"] = "FR",
+ ["254"] = "GF",
+ ["258"] = "PF",
+ ["260"] = "TF",
+ ["262"] = "DJ",
+ ["266"] = "GA",
+ ["268"] = "GE",
+ ["270"] = "GM",
+ ["275"] = "PS",
+ ["276"] = "DE",
+ ["278"] = "DE",
+ ["280"] = "DE",
+ ["288"] = "GH",
+ ["292"] = "GI",
+ ["296"] = "KI",
+ ["300"] = "GR",
+ ["304"] = "GL",
+ ["308"] = "GD",
+ ["312"] = "GP",
+ ["316"] = "GU",
+ ["320"] = "GT",
+ ["324"] = "GN",
+ ["328"] = "GY",
+ ["332"] = "HT",
+ ["334"] = "HM",
+ ["336"] = "VA",
+ ["340"] = "HN",
+ ["344"] = "HK",
+ ["348"] = "HU",
+ ["352"] = "IS",
+ ["356"] = "IN",
+ ["360"] = "ID",
+ ["364"] = "IR",
+ ["368"] = "IQ",
+ ["372"] = "IE",
+ ["376"] = "IL",
+ ["380"] = "IT",
+ ["384"] = "CI",
+ ["388"] = "JM",
+ ["392"] = "JP",
+ ["398"] = "KZ",
+ ["400"] = "JO",
+ ["404"] = "KE",
+ ["408"] = "KP",
+ ["410"] = "KR",
+ ["414"] = "KW",
+ ["417"] = "KG",
+ ["418"] = "LA",
+ ["422"] = "LB",
+ ["426"] = "LS",
+ ["428"] = "LV",
+ ["430"] = "LR",
+ ["434"] = "LY",
+ ["438"] = "LI",
+ ["440"] = "LT",
+ ["442"] = "LU",
+ ["446"] = "MO",
+ ["450"] = "MG",
+ ["454"] = "MW",
+ ["458"] = "MY",
+ ["462"] = "MV",
+ ["466"] = "ML",
+ ["470"] = "MT",
+ ["474"] = "MQ",
+ ["478"] = "MR",
+ ["480"] = "MU",
+ ["484"] = "MX",
+ ["492"] = "MC",
+ ["496"] = "MN",
+ ["498"] = "MD",
+ ["499"] = "ME",
+ ["500"] = "MS",
+ ["504"] = "MA",
+ ["508"] = "MZ",
+ ["512"] = "OM",
+ ["516"] = "NA",
+ ["520"] = "NR",
+ ["524"] = "NP",
+ ["528"] = "NL",
+ ["531"] = "CW",
+ ["533"] = "AW",
+ ["534"] = "SX",
+ ["535"] = "BQ",
+ ["540"] = "NC",
+ ["548"] = "VU",
+ ["554"] = "NZ",
+ ["558"] = "NI",
+ ["562"] = "NE",
+ ["566"] = "NG",
+ ["570"] = "NU",
+ ["574"] = "NF",
+ ["578"] = "NO",
+ ["580"] = "MP",
+ ["581"] = "UM",
+ ["583"] = "FM",
+ ["584"] = "MH",
+ ["585"] = "PW",
+ ["586"] = "PK",
+ ["591"] = "PA",
+ ["598"] = "PG",
+ ["600"] = "PY",
+ ["604"] = "PE",
+ ["608"] = "PH",
+ ["612"] = "PN",
+ ["616"] = "PL",
+ ["620"] = "PT",
+ ["624"] = "GW",
+ ["626"] = "TL",
+ ["630"] = "PR",
+ ["634"] = "QA",
+ ["638"] = "RE",
+ ["642"] = "RO",
+ ["643"] = "RU",
+ ["646"] = "RW",
+ ["652"] = "BL",
+ ["654"] = "SH",
+ ["659"] = "KN",
+ ["660"] = "AI",
+ ["662"] = "LC",
+ ["663"] = "MF",
+ ["666"] = "PM",
+ ["670"] = "VC",
+ ["674"] = "SM",
+ ["678"] = "ST",
+ ["682"] = "SA",
+ ["686"] = "SN",
+ ["688"] = "RS",
+ ["690"] = "SC",
+ ["694"] = "SL",
+ ["702"] = "SG",
+ ["703"] = "SK",
+ ["704"] = "VN",
+ ["705"] = "SI",
+ ["706"] = "SO",
+ ["710"] = "ZA",
+ ["716"] = "ZW",
+ ["720"] = "YE",
+ ["724"] = "ES",
+ ["728"] = "SS",
+ ["729"] = "SD",
+ ["732"] = "EH",
+ ["736"] = "SD",
+ ["740"] = "SR",
+ ["744"] = "SJ",
+ ["748"] = "SZ",
+ ["752"] = "SE",
+ ["756"] = "CH",
+ ["760"] = "SY",
+ ["762"] = "TJ",
+ ["764"] = "TH",
+ ["768"] = "TG",
+ ["772"] = "TK",
+ ["776"] = "TO",
+ ["780"] = "TT",
+ ["784"] = "AE",
+ ["788"] = "TN",
+ ["792"] = "TR",
+ ["795"] = "TM",
+ ["796"] = "TC",
+ ["798"] = "TV",
+ ["800"] = "UG",
+ ["804"] = "UA",
+ ["807"] = "MK",
+ ["818"] = "EG",
+ ["826"] = "GB",
+ ["830"] = "JE",
+ ["831"] = "GG",
+ ["832"] = "JE",
+ ["833"] = "IM",
+ ["834"] = "TZ",
+ ["840"] = "US",
+ ["850"] = "VI",
+ ["854"] = "BF",
+ ["858"] = "UY",
+ ["860"] = "UZ",
+ ["862"] = "VE",
+ ["876"] = "WF",
+ ["882"] = "WS",
+ ["886"] = "YE",
+ ["887"] = "YE",
+ ["891"] = "RS",
+ ["894"] = "ZM",
+ ["958"] = "AA",
+ ["959"] = "QM",
+ ["960"] = "QN",
+ ["962"] = "QP",
+ ["963"] = "QQ",
+ ["964"] = "QR",
+ ["965"] = "QS",
+ ["966"] = "QT",
+ ["967"] = "EU",
+ ["968"] = "QV",
+ ["969"] = "QW",
+ ["970"] = "QX",
+ ["971"] = "QY",
+ ["972"] = "QZ",
+ ["973"] = "XA",
+ ["974"] = "XB",
+ ["975"] = "XC",
+ ["976"] = "XD",
+ ["977"] = "XE",
+ ["978"] = "XF",
+ ["979"] = "XG",
+ ["980"] = "XH",
+ ["981"] = "XI",
+ ["982"] = "XJ",
+ ["983"] = "XK",
+ ["984"] = "XL",
+ ["985"] = "XM",
+ ["986"] = "XN",
+ ["987"] = "XO",
+ ["988"] = "XP",
+ ["989"] = "XQ",
+ ["990"] = "XR",
+ ["991"] = "XS",
+ ["992"] = "XT",
+ ["993"] = "XU",
+ ["994"] = "XV",
+ ["995"] = "XW",
+ ["996"] = "XX",
+ ["997"] = "XY",
+ ["998"] = "XZ",
+ ["999"] = "ZZ",
+ ["004"] = "AF",
+ ["008"] = "AL",
+ ["010"] = "AQ",
+ ["012"] = "DZ",
+ ["016"] = "AS",
+ ["020"] = "AD",
+ ["024"] = "AO",
+ ["028"] = "AG",
+ ["031"] = "AZ",
+ ["032"] = "AR",
+ ["036"] = "AU",
+ ["040"] = "AT",
+ ["044"] = "BS",
+ ["048"] = "BH",
+ ["050"] = "BD",
+ ["051"] = "AM",
+ ["052"] = "BB",
+ ["056"] = "BE",
+ ["060"] = "BM",
+ ["062"] = "034",
+ ["064"] = "BT",
+ ["068"] = "BO",
+ ["070"] = "BA",
+ ["072"] = "BW",
+ ["074"] = "BV",
+ ["076"] = "BR",
+ ["084"] = "BZ",
+ ["086"] = "IO",
+ ["090"] = "SB",
+ ["092"] = "VG",
+ ["096"] = "BN",
+ ["BU"] = "MM",
+ ["CS"] = "RS",
+ ["CT"] = "KI",
+ ["DD"] = "DE",
+ ["DY"] = "BJ",
+ ["FQ"] = "AQ",
+ ["FX"] = "FR",
+ ["HV"] = "BF",
+ ["JT"] = "UM",
+ ["MI"] = "UM",
+ ["NH"] = "VU",
+ ["NQ"] = "AQ",
+ ["PU"] = "UM",
+ ["PZ"] = "PA",
+ ["QU"] = "EU",
+ ["RH"] = "ZW",
+ ["TP"] = "TL",
+ ["UK"] = "GB",
+ ["VD"] = "VN",
+ ["WK"] = "UM",
+ ["YD"] = "YE",
+ ["YU"] = "RS",
+ ["ZR"] = "CD",
+ ["810"] = "RU",
+ ["NT"] = "SA",
+ ["SU"] = "RU",
+ ["AN"] = "CW",
+ };
+
+ private static readonly Dictionary _variantMappings = new(5, StringComparer.OrdinalIgnoreCase)
+ {
+ ["aaland"] = new VariantMapping("region", "AX"),
+ ["arevela"] = new VariantMapping("language", "hy"),
+ ["arevmda"] = new VariantMapping("language", "hyw"),
+ ["heploc"] = new VariantMapping("variant", "alalc97", "hepburn"),
+ ["polytoni"] = new VariantMapping("variant", "polyton"),
+ };
+
+ private static readonly Dictionary _languageVariantMappings = new(5, StringComparer.OrdinalIgnoreCase)
+ {
+ ["art+lojban"] = "jbo",
+ ["cel+gaulish"] = "xtg",
+ ["zh+guoyu"] = "zh",
+ ["zh+hakka"] = "hak",
+ ["zh+xiang"] = "hsn",
+ };
+
+ private static readonly Dictionary _scriptRegionMappings = new(12, StringComparer.OrdinalIgnoreCase)
+ {
+ ["Armn+SU"] = "AM",
+ ["Cyrl+SU"] = "RU",
+ ["Latn+SU"] = "RU",
+ ["Geor+SU"] = "GE",
+ ["Arab+SU"] = "UZ",
+ ["Armn+810"] = "AM",
+ ["Cyrl+810"] = "RU",
+ ["Latn+810"] = "RU",
+ ["Geor+810"] = "GE",
+ ["Arab+810"] = "UZ",
+ ["Cyrl+CS"] = "RS",
+ ["Latn+CS"] = "RS",
+ };
+
+ private static readonly Dictionary> _unicodeMappings = new(11, StringComparer.OrdinalIgnoreCase)
+ {
+ ["ca"] = new Dictionary(2, StringComparer.OrdinalIgnoreCase)
+ {
+ ["ethiopic-amete-alem"] = "ethioaa",
+ ["islamicc"] = "islamic-civil",
+ },
+ ["kb"] = new Dictionary(1, StringComparer.OrdinalIgnoreCase)
+ {
+ ["yes"] = "true",
+ },
+ ["kc"] = new Dictionary(1, StringComparer.OrdinalIgnoreCase)
+ {
+ ["yes"] = "true",
+ },
+ ["kh"] = new Dictionary(1, StringComparer.OrdinalIgnoreCase)
+ {
+ ["yes"] = "true",
+ },
+ ["kk"] = new Dictionary(1, StringComparer.OrdinalIgnoreCase)
+ {
+ ["yes"] = "true",
+ },
+ ["kn"] = new Dictionary(1, StringComparer.OrdinalIgnoreCase)
+ {
+ ["yes"] = "true",
+ },
+ ["ks"] = new Dictionary(2, StringComparer.OrdinalIgnoreCase)
+ {
+ ["primary"] = "level1",
+ ["tertiary"] = "level3",
+ },
+ ["ms"] = new Dictionary(1, StringComparer.OrdinalIgnoreCase)
+ {
+ ["imperial"] = "uksystem",
+ },
+ ["rg"] = new Dictionary(117, StringComparer.OrdinalIgnoreCase)
+ {
+ ["cn11"] = "cnbj",
+ ["cn12"] = "cntj",
+ ["cn13"] = "cnhe",
+ ["cn14"] = "cnsx",
+ ["cn15"] = "cnmn",
+ ["cn21"] = "cnln",
+ ["cn22"] = "cnjl",
+ ["cn23"] = "cnhl",
+ ["cn31"] = "cnsh",
+ ["cn32"] = "cnjs",
+ ["cn33"] = "cnzj",
+ ["cn34"] = "cnah",
+ ["cn35"] = "cnfj",
+ ["cn36"] = "cnjx",
+ ["cn37"] = "cnsd",
+ ["cn41"] = "cnha",
+ ["cn42"] = "cnhb",
+ ["cn43"] = "cnhn",
+ ["cn44"] = "cngd",
+ ["cn45"] = "cngx",
+ ["cn46"] = "cnhi",
+ ["cn50"] = "cncq",
+ ["cn51"] = "cnsc",
+ ["cn52"] = "cngz",
+ ["cn53"] = "cnyn",
+ ["cn54"] = "cnxz",
+ ["cn61"] = "cnsn",
+ ["cn62"] = "cngs",
+ ["cn63"] = "cnqh",
+ ["cn64"] = "cnnx",
+ ["cn65"] = "cnxj",
+ ["cz10a"] = "cz110",
+ ["cz10b"] = "cz111",
+ ["cz10c"] = "cz112",
+ ["cz10d"] = "cz113",
+ ["cz10e"] = "cz114",
+ ["cz10f"] = "cz115",
+ ["cz611"] = "cz663",
+ ["cz612"] = "cz632",
+ ["cz613"] = "cz633",
+ ["cz614"] = "cz634",
+ ["cz615"] = "cz635",
+ ["cz621"] = "cz641",
+ ["cz622"] = "cz642",
+ ["cz623"] = "cz643",
+ ["cz624"] = "cz644",
+ ["cz626"] = "cz646",
+ ["cz627"] = "cz647",
+ ["czjc"] = "cz31",
+ ["czjm"] = "cz64",
+ ["czka"] = "cz41",
+ ["czkr"] = "cz52",
+ ["czli"] = "cz51",
+ ["czmo"] = "cz80",
+ ["czol"] = "cz71",
+ ["czpa"] = "cz53",
+ ["czpl"] = "cz32",
+ ["czpr"] = "cz10",
+ ["czst"] = "cz20",
+ ["czus"] = "cz42",
+ ["czvy"] = "cz63",
+ ["czzl"] = "cz72",
+ ["fra"] = "frges",
+ ["frb"] = "frnaq",
+ ["frc"] = "frara",
+ ["frd"] = "frbfc",
+ ["fre"] = "frbre",
+ ["frf"] = "frcvl",
+ ["frg"] = "frges",
+ ["frh"] = "frcor",
+ ["fri"] = "frbfc",
+ ["frj"] = "fridf",
+ ["frk"] = "frocc",
+ ["frl"] = "frnaq",
+ ["frm"] = "frges",
+ ["frn"] = "frocc",
+ ["fro"] = "frhdf",
+ ["frp"] = "frnor",
+ ["frq"] = "frnor",
+ ["frr"] = "frpdl",
+ ["frs"] = "frhdf",
+ ["frt"] = "frnaq",
+ ["fru"] = "frpac",
+ ["frv"] = "frara",
+ ["laxn"] = "laxs",
+ ["lud"] = "lucl",
+ ["lug"] = "luec",
+ ["lul"] = "luca",
+ ["mrnkc"] = "mr13",
+ ["no23"] = "no50",
+ ["nzn"] = "nzauk",
+ ["nzs"] = "nzcan",
+ ["omba"] = "ombj",
+ ["omsh"] = "omsj",
+ ["plds"] = "pl02",
+ ["plkp"] = "pl04",
+ ["pllb"] = "pl08",
+ ["plld"] = "pl10",
+ ["pllu"] = "pl06",
+ ["plma"] = "pl12",
+ ["plmz"] = "pl14",
+ ["plop"] = "pl16",
+ ["plpd"] = "pl20",
+ ["plpk"] = "pl18",
+ ["plpm"] = "pl22",
+ ["plsk"] = "pl26",
+ ["plsl"] = "pl24",
+ ["plwn"] = "pl28",
+ ["plwp"] = "pl30",
+ ["plzp"] = "pl32",
+ ["tteto"] = "tttob",
+ ["ttrcm"] = "ttmrc",
+ ["ttwto"] = "tttob",
+ ["twkhq"] = "twkhh",
+ ["twtnq"] = "twtnn",
+ ["twtpq"] = "twnwt",
+ ["twtxq"] = "twtxg",
+ },
+ ["sd"] = new Dictionary(117, StringComparer.OrdinalIgnoreCase)
+ {
+ ["cn11"] = "cnbj",
+ ["cn12"] = "cntj",
+ ["cn13"] = "cnhe",
+ ["cn14"] = "cnsx",
+ ["cn15"] = "cnmn",
+ ["cn21"] = "cnln",
+ ["cn22"] = "cnjl",
+ ["cn23"] = "cnhl",
+ ["cn31"] = "cnsh",
+ ["cn32"] = "cnjs",
+ ["cn33"] = "cnzj",
+ ["cn34"] = "cnah",
+ ["cn35"] = "cnfj",
+ ["cn36"] = "cnjx",
+ ["cn37"] = "cnsd",
+ ["cn41"] = "cnha",
+ ["cn42"] = "cnhb",
+ ["cn43"] = "cnhn",
+ ["cn44"] = "cngd",
+ ["cn45"] = "cngx",
+ ["cn46"] = "cnhi",
+ ["cn50"] = "cncq",
+ ["cn51"] = "cnsc",
+ ["cn52"] = "cngz",
+ ["cn53"] = "cnyn",
+ ["cn54"] = "cnxz",
+ ["cn61"] = "cnsn",
+ ["cn62"] = "cngs",
+ ["cn63"] = "cnqh",
+ ["cn64"] = "cnnx",
+ ["cn65"] = "cnxj",
+ ["cz10a"] = "cz110",
+ ["cz10b"] = "cz111",
+ ["cz10c"] = "cz112",
+ ["cz10d"] = "cz113",
+ ["cz10e"] = "cz114",
+ ["cz10f"] = "cz115",
+ ["cz611"] = "cz663",
+ ["cz612"] = "cz632",
+ ["cz613"] = "cz633",
+ ["cz614"] = "cz634",
+ ["cz615"] = "cz635",
+ ["cz621"] = "cz641",
+ ["cz622"] = "cz642",
+ ["cz623"] = "cz643",
+ ["cz624"] = "cz644",
+ ["cz626"] = "cz646",
+ ["cz627"] = "cz647",
+ ["czjc"] = "cz31",
+ ["czjm"] = "cz64",
+ ["czka"] = "cz41",
+ ["czkr"] = "cz52",
+ ["czli"] = "cz51",
+ ["czmo"] = "cz80",
+ ["czol"] = "cz71",
+ ["czpa"] = "cz53",
+ ["czpl"] = "cz32",
+ ["czpr"] = "cz10",
+ ["czst"] = "cz20",
+ ["czus"] = "cz42",
+ ["czvy"] = "cz63",
+ ["czzl"] = "cz72",
+ ["fra"] = "frges",
+ ["frb"] = "frnaq",
+ ["frc"] = "frara",
+ ["frd"] = "frbfc",
+ ["fre"] = "frbre",
+ ["frf"] = "frcvl",
+ ["frg"] = "frges",
+ ["frh"] = "frcor",
+ ["fri"] = "frbfc",
+ ["frj"] = "fridf",
+ ["frk"] = "frocc",
+ ["frl"] = "frnaq",
+ ["frm"] = "frges",
+ ["frn"] = "frocc",
+ ["fro"] = "frhdf",
+ ["frp"] = "frnor",
+ ["frq"] = "frnor",
+ ["frr"] = "frpdl",
+ ["frs"] = "frhdf",
+ ["frt"] = "frnaq",
+ ["fru"] = "frpac",
+ ["frv"] = "frara",
+ ["laxn"] = "laxs",
+ ["lud"] = "lucl",
+ ["lug"] = "luec",
+ ["lul"] = "luca",
+ ["mrnkc"] = "mr13",
+ ["no23"] = "no50",
+ ["nzn"] = "nzauk",
+ ["nzs"] = "nzcan",
+ ["omba"] = "ombj",
+ ["omsh"] = "omsj",
+ ["plds"] = "pl02",
+ ["plkp"] = "pl04",
+ ["pllb"] = "pl08",
+ ["plld"] = "pl10",
+ ["pllu"] = "pl06",
+ ["plma"] = "pl12",
+ ["plmz"] = "pl14",
+ ["plop"] = "pl16",
+ ["plpd"] = "pl20",
+ ["plpk"] = "pl18",
+ ["plpm"] = "pl22",
+ ["plsk"] = "pl26",
+ ["plsl"] = "pl24",
+ ["plwn"] = "pl28",
+ ["plwp"] = "pl30",
+ ["plzp"] = "pl32",
+ ["tteto"] = "tttob",
+ ["ttrcm"] = "ttmrc",
+ ["ttwto"] = "tttob",
+ ["twkhq"] = "twkhh",
+ ["twtnq"] = "twtnn",
+ ["twtpq"] = "twnwt",
+ ["twtxq"] = "twtxg",
+ },
+ ["tz"] = new Dictionary(28, StringComparer.OrdinalIgnoreCase)
+ {
+ ["aqams"] = "nzakl",
+ ["cnckg"] = "cnsha",
+ ["cnhrb"] = "cnsha",
+ ["cnkhg"] = "cnurc",
+ ["cuba"] = "cuhav",
+ ["egypt"] = "egcai",
+ ["eire"] = "iedub",
+ ["est"] = "papty",
+ ["gmt0"] = "gmt",
+ ["hongkong"] = "hkhkg",
+ ["hst"] = "utcw10",
+ ["iceland"] = "isrey",
+ ["iran"] = "irthr",
+ ["israel"] = "jeruslm",
+ ["jamaica"] = "jmkin",
+ ["japan"] = "jptyo",
+ ["libya"] = "lytip",
+ ["mst"] = "utcw07",
+ ["navajo"] = "usden",
+ ["poland"] = "plwaw",
+ ["portugal"] = "ptlis",
+ ["prc"] = "cnsha",
+ ["roc"] = "twtpe",
+ ["rok"] = "krsel",
+ ["turkey"] = "trist",
+ ["uct"] = "utc",
+ ["usnavajo"] = "usden",
+ ["zulu"] = "utc",
+ },
+ };
+}
diff --git a/Jint/Native/Intl/Data/LocaleData.cs b/Jint/Native/Intl/Data/LocaleData.cs
index dddff84d9a..ba686f56ab 100644
--- a/Jint/Native/Intl/Data/LocaleData.cs
+++ b/Jint/Native/Intl/Data/LocaleData.cs
@@ -1,308 +1,56 @@
-using System.Threading;
-
namespace Jint.Native.Intl.Data;
///
/// Provides CLDR locale data for canonicalization.
-/// Data is loaded from embedded LocaleData.txt resource.
+/// Data is initialized inline in LocaleData.Data.cs.
///
-internal static class LocaleData
+internal static partial class LocaleData
{
- private static readonly Lock _lock = new();
- private static Dictionary? _tagMappings;
- private static Dictionary? _languageMappings;
- private static Dictionary? _complexLanguageMappings;
- private static Dictionary? _regionMappings;
- private static Dictionary? _variantMappings;
- private static Dictionary? _languageVariantMappings;
- private static Dictionary? _scriptRegionMappings;
- private static Dictionary>? _unicodeMappings;
- private static volatile bool _loaded;
-
///
/// Grandfathered tag mappings (e.g., "art-lojban" → "jbo").
///
- public static Dictionary TagMappings
- {
- get
- {
- EnsureLoaded();
- return _tagMappings!;
- }
- }
+ public static Dictionary TagMappings => _tagMappings;
///
/// Simple language code mappings (e.g., "cmn" → "zh", "iw" → "he").
///
- public static Dictionary LanguageMappings
- {
- get
- {
- EnsureLoaded();
- return _languageMappings!;
- }
- }
+ public static Dictionary LanguageMappings => _languageMappings;
///
/// Complex language mappings that may include script/region.
///
- public static Dictionary ComplexLanguageMappings
- {
- get
- {
- EnsureLoaded();
- return _complexLanguageMappings!;
- }
- }
+ public static Dictionary ComplexLanguageMappings => _complexLanguageMappings;
///
/// Region code mappings (e.g., "DD" → "DE", numeric to alpha).
///
- public static Dictionary RegionMappings
- {
- get
- {
- EnsureLoaded();
- return _regionMappings!;
- }
- }
+ public static Dictionary RegionMappings => _regionMappings;
///
/// Variant subtag mappings.
///
- public static Dictionary VariantMappings
- {
- get
- {
- EnsureLoaded();
- return _variantMappings!;
- }
- }
+ public static Dictionary VariantMappings => _variantMappings;
///
/// Language + variant mappings for grandfathered variants.
/// Key format: "language+variant" (e.g., "art+lojban"), Value: new language (e.g., "jbo").
///
- public static Dictionary LanguageVariantMappings
- {
- get
- {
- EnsureLoaded();
- return _languageVariantMappings!;
- }
- }
+ public static Dictionary LanguageVariantMappings => _languageVariantMappings;
///
/// Script + region mappings for deprecated regions (like SU).
/// Key format: "Script+Region" (e.g., "Armn+SU"), Value: new region (e.g., "AM").
///
- public static Dictionary ScriptRegionMappings
- {
- get
- {
- EnsureLoaded();
- return _scriptRegionMappings!;
- }
- }
+ public static Dictionary ScriptRegionMappings => _scriptRegionMappings;
///
/// Unicode extension value mappings, keyed by extension key (e.g., "ca", "tz").
///
- public static Dictionary> UnicodeMappings
- {
- get
- {
- EnsureLoaded();
- return _unicodeMappings!;
- }
- }
-
- private static void EnsureLoaded()
- {
- if (_loaded)
- {
- return;
- }
-
- lock (_lock)
- {
- if (_loaded)
- {
- return;
- }
-
- _tagMappings = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _languageMappings = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _complexLanguageMappings = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _regionMappings = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _variantMappings = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _languageVariantMappings = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _scriptRegionMappings = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _unicodeMappings = new Dictionary>(StringComparer.OrdinalIgnoreCase);
-
- var assembly = typeof(LocaleData).Assembly;
- using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.LocaleData.txt");
- if (stream is null)
- {
- _loaded = true;
- return;
- }
-
- using var reader = new StreamReader(stream);
- string? currentSection = null;
-
- while (reader.ReadLine() is { } line)
- {
- if (string.IsNullOrWhiteSpace(line))
- {
- continue;
- }
-
- if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']')
- {
- currentSection = line.Substring(1, line.Length - 2);
- continue;
- }
-
- var eqIndex = line.IndexOf('=');
- if (eqIndex < 0)
- {
- continue;
- }
-
- var key = line.Substring(0, eqIndex);
- var value = line.Substring(eqIndex + 1);
-
- switch (currentSection)
- {
- case "TAG_MAPPINGS":
- _tagMappings[key] = value;
- break;
-
- case "LANGUAGE_MAPPINGS":
- _languageMappings[key] = value;
- break;
-
- case "COMPLEX_LANGUAGE_MAPPINGS":
- ParseComplexLanguageMapping(key, value);
- break;
-
- case "REGION_MAPPINGS":
- _regionMappings[key] = value;
- break;
-
- case "VARIANT_MAPPINGS":
- ParseVariantMapping(key, value);
- break;
-
- case "LANGUAGE_VARIANT_MAPPINGS":
- _languageVariantMappings![key] = value;
- break;
-
- case "SCRIPT_REGION_MAPPINGS":
- _scriptRegionMappings![key] = value;
- break;
-
- case "UNICODE_MAPPINGS":
- ParseUnicodeMapping(key, value);
- break;
- }
- }
-
- _loaded = true;
- }
- }
-
- private static void ParseComplexLanguageMapping(string key, string value)
- {
- // Format: language,script:Latn,region:ME
- var parts = value.Split(',');
- string? script = null;
- string? region = null;
-
- for (var i = 1; i < parts.Length; i++)
- {
- var part = parts[i];
- if (part.StartsWith("script:", StringComparison.Ordinal))
- {
- script = part.Substring(7);
- }
- else if (part.StartsWith("region:", StringComparison.Ordinal))
- {
- region = part.Substring(7);
- }
- }
-
- _complexLanguageMappings![key] = new ComplexLanguageMapping(parts[0], script, region);
- }
-
- private static void ParseVariantMapping(string key, string value)
- {
- // Format: type,replacement[,prefix:variant]
- var parts = value.Split(',');
- if (parts.Length >= 2)
- {
- string? prefix = null;
- for (var i = 2; i < parts.Length; i++)
- {
- if (parts[i].StartsWith("prefix:", StringComparison.Ordinal))
- {
- prefix = parts[i].Substring(7);
- }
- }
-
- _variantMappings![key] = new VariantMapping(parts[0], parts[1], prefix);
- }
- }
-
- private static void ParseUnicodeMapping(string key, string value)
- {
- // Format key: keyType:oldValue (e.g., "ca:islamicc")
- var colonIndex = key.IndexOf(':');
- if (colonIndex > 0)
- {
- var keyType = key.Substring(0, colonIndex);
- var oldValue = key.Substring(colonIndex + 1);
-
- if (!_unicodeMappings!.TryGetValue(keyType, out var typeDict))
- {
- typeDict = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _unicodeMappings[keyType] = typeDict;
- }
-
- typeDict[oldValue] = value;
- }
- }
-
- internal readonly struct ComplexLanguageMapping
- {
- public ComplexLanguageMapping(string language, string? script, string? region)
- {
- Language = language;
- Script = script;
- Region = region;
- }
-
- public string Language { get; }
- public string? Script { get; }
- public string? Region { get; }
- }
-
- internal readonly struct VariantMapping
- {
- public VariantMapping(string type, string replacement, string? prefix = null)
- {
- Type = type;
- Replacement = replacement;
- Prefix = prefix;
- }
+ public static Dictionary> UnicodeMappings => _unicodeMappings;
- public string Type { get; }
- public string Replacement { get; }
+ [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Auto)]
+ internal readonly record struct ComplexLanguageMapping(string Language, string? Script, string? Region);
- ///
- /// Optional prefix variant that should be removed when this alias is applied.
- ///
- public string? Prefix { get; }
- }
+ [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Auto)]
+ internal readonly record struct VariantMapping(string Type, string Replacement, string? Prefix = null);
}
diff --git a/Jint/Native/Intl/Data/RelativeTimePatternsData.Data.cs b/Jint/Native/Intl/Data/RelativeTimePatternsData.Data.cs
new file mode 100644
index 0000000000..dd2350a884
--- /dev/null
+++ b/Jint/Native/Intl/Data/RelativeTimePatternsData.Data.cs
@@ -0,0 +1,1088 @@
+namespace Jint.Native.Intl.Data;
+
+internal static partial class RelativeTimePatternsData
+{
+ private static readonly Dictionary _data = new(4, StringComparer.OrdinalIgnoreCase)
+ {
+ ["en"] = new LocaleRelativeTimeData
+ {
+ Patterns = new(24, StringComparer.Ordinal)
+ {
+ ["second_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} second",
+ ["future_other"] = "in {0} seconds",
+ ["past_one"] = "{0} second ago",
+ ["past_other"] = "{0} seconds ago",
+ }
+ },
+ ["second_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} sec.",
+ ["future_other"] = "in {0} sec.",
+ ["past_one"] = "{0} sec. ago",
+ ["past_other"] = "{0} sec. ago",
+ }
+ },
+ ["second_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0}s",
+ ["future_other"] = "in {0}s",
+ ["past_one"] = "{0}s ago",
+ ["past_other"] = "{0}s ago",
+ }
+ },
+ ["minute_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} minute",
+ ["future_other"] = "in {0} minutes",
+ ["past_one"] = "{0} minute ago",
+ ["past_other"] = "{0} minutes ago",
+ }
+ },
+ ["minute_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} min.",
+ ["future_other"] = "in {0} min.",
+ ["past_one"] = "{0} min. ago",
+ ["past_other"] = "{0} min. ago",
+ }
+ },
+ ["minute_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0}m",
+ ["future_other"] = "in {0}m",
+ ["past_one"] = "{0}m ago",
+ ["past_other"] = "{0}m ago",
+ }
+ },
+ ["hour_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} hour",
+ ["future_other"] = "in {0} hours",
+ ["past_one"] = "{0} hour ago",
+ ["past_other"] = "{0} hours ago",
+ }
+ },
+ ["hour_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} hr.",
+ ["future_other"] = "in {0} hr.",
+ ["past_one"] = "{0} hr. ago",
+ ["past_other"] = "{0} hr. ago",
+ }
+ },
+ ["hour_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0}h",
+ ["future_other"] = "in {0}h",
+ ["past_one"] = "{0}h ago",
+ ["past_other"] = "{0}h ago",
+ }
+ },
+ ["day_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} day",
+ ["future_other"] = "in {0} days",
+ ["past_one"] = "{0} day ago",
+ ["past_other"] = "{0} days ago",
+ }
+ },
+ ["day_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} day",
+ ["future_other"] = "in {0} days",
+ ["past_one"] = "{0} day ago",
+ ["past_other"] = "{0} days ago",
+ }
+ },
+ ["day_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0}d",
+ ["future_other"] = "in {0}d",
+ ["past_one"] = "{0}d ago",
+ ["past_other"] = "{0}d ago",
+ }
+ },
+ ["week_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} week",
+ ["future_other"] = "in {0} weeks",
+ ["past_one"] = "{0} week ago",
+ ["past_other"] = "{0} weeks ago",
+ }
+ },
+ ["week_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} wk.",
+ ["future_other"] = "in {0} wk.",
+ ["past_one"] = "{0} wk. ago",
+ ["past_other"] = "{0} wk. ago",
+ }
+ },
+ ["week_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0}w",
+ ["future_other"] = "in {0}w",
+ ["past_one"] = "{0}w ago",
+ ["past_other"] = "{0}w ago",
+ }
+ },
+ ["month_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} month",
+ ["future_other"] = "in {0} months",
+ ["past_one"] = "{0} month ago",
+ ["past_other"] = "{0} months ago",
+ }
+ },
+ ["month_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} mo.",
+ ["future_other"] = "in {0} mo.",
+ ["past_one"] = "{0} mo. ago",
+ ["past_other"] = "{0} mo. ago",
+ }
+ },
+ ["month_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0}mo",
+ ["future_other"] = "in {0}mo",
+ ["past_one"] = "{0}mo ago",
+ ["past_other"] = "{0}mo ago",
+ }
+ },
+ ["quarter_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} quarter",
+ ["future_other"] = "in {0} quarters",
+ ["past_one"] = "{0} quarter ago",
+ ["past_other"] = "{0} quarters ago",
+ }
+ },
+ ["quarter_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} qtr.",
+ ["future_other"] = "in {0} qtrs.",
+ ["past_one"] = "{0} qtr. ago",
+ ["past_other"] = "{0} qtrs. ago",
+ }
+ },
+ ["quarter_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0}q",
+ ["future_other"] = "in {0}q",
+ ["past_one"] = "{0}q ago",
+ ["past_other"] = "{0}q ago",
+ }
+ },
+ ["year_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} year",
+ ["future_other"] = "in {0} years",
+ ["past_one"] = "{0} year ago",
+ ["past_other"] = "{0} years ago",
+ }
+ },
+ ["year_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} yr.",
+ ["future_other"] = "in {0} yr.",
+ ["past_one"] = "{0} yr. ago",
+ ["past_other"] = "{0} yr. ago",
+ }
+ },
+ ["year_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0}y",
+ ["future_other"] = "in {0}y",
+ ["past_one"] = "{0}y ago",
+ ["past_other"] = "{0}y ago",
+ }
+ },
+ }
+ },
+ ["es"] = new LocaleRelativeTimeData
+ {
+ Patterns = new(24, StringComparer.Ordinal)
+ {
+ ["second_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} segundo",
+ ["future_other"] = "dentro de {0} segundos",
+ ["past_one"] = "hace {0} segundo",
+ ["past_other"] = "hace {0} segundos",
+ }
+ },
+ ["second_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} s",
+ ["future_other"] = "dentro de {0} s",
+ ["past_one"] = "hace {0} s",
+ ["past_other"] = "hace {0} s",
+ }
+ },
+ ["second_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "en {0} s",
+ ["future_other"] = "en {0} s",
+ ["past_one"] = "hace {0} s",
+ ["past_other"] = "hace {0} s",
+ }
+ },
+ ["minute_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} minuto",
+ ["future_other"] = "dentro de {0} minutos",
+ ["past_one"] = "hace {0} minuto",
+ ["past_other"] = "hace {0} minutos",
+ }
+ },
+ ["minute_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} min",
+ ["future_other"] = "dentro de {0} min",
+ ["past_one"] = "hace {0} min",
+ ["past_other"] = "hace {0} min",
+ }
+ },
+ ["minute_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "en {0} min",
+ ["future_other"] = "en {0} min",
+ ["past_one"] = "hace {0} min",
+ ["past_other"] = "hace {0} min",
+ }
+ },
+ ["hour_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} hora",
+ ["future_other"] = "dentro de {0} horas",
+ ["past_one"] = "hace {0} hora",
+ ["past_other"] = "hace {0} horas",
+ }
+ },
+ ["hour_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} h",
+ ["future_other"] = "dentro de {0} h",
+ ["past_one"] = "hace {0} h",
+ ["past_other"] = "hace {0} h",
+ }
+ },
+ ["hour_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "en {0} h",
+ ["future_other"] = "en {0} h",
+ ["past_one"] = "hace {0} h",
+ ["past_other"] = "hace {0} h",
+ }
+ },
+ ["day_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} d\u00eda",
+ ["future_other"] = "dentro de {0} d\u00edas",
+ ["past_one"] = "hace {0} d\u00eda",
+ ["past_other"] = "hace {0} d\u00edas",
+ }
+ },
+ ["day_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} d\u00eda",
+ ["future_other"] = "dentro de {0} d\u00edas",
+ ["past_one"] = "hace {0} d\u00eda",
+ ["past_other"] = "hace {0} d\u00edas",
+ }
+ },
+ ["day_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "en {0} d",
+ ["future_other"] = "en {0} d",
+ ["past_one"] = "hace {0} d",
+ ["past_other"] = "hace {0} d",
+ }
+ },
+ ["week_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} semana",
+ ["future_other"] = "dentro de {0} semanas",
+ ["past_one"] = "hace {0} semana",
+ ["past_other"] = "hace {0} semanas",
+ }
+ },
+ ["week_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} sem.",
+ ["future_other"] = "dentro de {0} sem.",
+ ["past_one"] = "hace {0} sem.",
+ ["past_other"] = "hace {0} sem.",
+ }
+ },
+ ["week_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "en {0} sem.",
+ ["future_other"] = "en {0} sem.",
+ ["past_one"] = "hace {0} sem.",
+ ["past_other"] = "hace {0} sem.",
+ }
+ },
+ ["month_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} mes",
+ ["future_other"] = "dentro de {0} meses",
+ ["past_one"] = "hace {0} mes",
+ ["past_other"] = "hace {0} meses",
+ }
+ },
+ ["month_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} m",
+ ["future_other"] = "dentro de {0} m",
+ ["past_one"] = "hace {0} m",
+ ["past_other"] = "hace {0} m",
+ }
+ },
+ ["month_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "en {0} m",
+ ["future_other"] = "en {0} m",
+ ["past_one"] = "hace {0} m",
+ ["past_other"] = "hace {0} m",
+ }
+ },
+ ["quarter_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} trimestre",
+ ["future_other"] = "dentro de {0} trimestres",
+ ["past_one"] = "hace {0} trimestre",
+ ["past_other"] = "hace {0} trimestres",
+ }
+ },
+ ["quarter_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} trim.",
+ ["future_other"] = "dentro de {0} trim.",
+ ["past_one"] = "hace {0} trim.",
+ ["past_other"] = "hace {0} trim.",
+ }
+ },
+ ["quarter_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "en {0} T",
+ ["future_other"] = "en {0} T",
+ ["past_one"] = "hace {0} T",
+ ["past_other"] = "hace {0} T",
+ }
+ },
+ ["year_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} a\u00f1o",
+ ["future_other"] = "dentro de {0} a\u00f1os",
+ ["past_one"] = "hace {0} a\u00f1o",
+ ["past_other"] = "hace {0} a\u00f1os",
+ }
+ },
+ ["year_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "dentro de {0} a",
+ ["future_other"] = "dentro de {0} a",
+ ["past_one"] = "hace {0} a",
+ ["past_other"] = "hace {0} a",
+ }
+ },
+ ["year_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "en {0} a",
+ ["future_other"] = "en {0} a",
+ ["past_one"] = "hace {0} a",
+ ["past_other"] = "hace {0} a",
+ }
+ },
+ }
+ },
+ ["de"] = new LocaleRelativeTimeData
+ {
+ Patterns = new(24, StringComparer.Ordinal)
+ {
+ ["second_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Sekunde",
+ ["future_other"] = "in {0} Sekunden",
+ ["past_one"] = "vor {0} Sekunde",
+ ["past_other"] = "vor {0} Sekunden",
+ }
+ },
+ ["second_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Sek.",
+ ["future_other"] = "in {0} Sek.",
+ ["past_one"] = "vor {0} Sek.",
+ ["past_other"] = "vor {0} Sek.",
+ }
+ },
+ ["second_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} s",
+ ["future_other"] = "in {0} s",
+ ["past_one"] = "vor {0} s",
+ ["past_other"] = "vor {0} s",
+ }
+ },
+ ["minute_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Minute",
+ ["future_other"] = "in {0} Minuten",
+ ["past_one"] = "vor {0} Minute",
+ ["past_other"] = "vor {0} Minuten",
+ }
+ },
+ ["minute_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Min.",
+ ["future_other"] = "in {0} Min.",
+ ["past_one"] = "vor {0} Min.",
+ ["past_other"] = "vor {0} Min.",
+ }
+ },
+ ["minute_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Min.",
+ ["future_other"] = "in {0} Min.",
+ ["past_one"] = "vor {0} Min.",
+ ["past_other"] = "vor {0} Min.",
+ }
+ },
+ ["hour_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Stunde",
+ ["future_other"] = "in {0} Stunden",
+ ["past_one"] = "vor {0} Stunde",
+ ["past_other"] = "vor {0} Stunden",
+ }
+ },
+ ["hour_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Std.",
+ ["future_other"] = "in {0} Std.",
+ ["past_one"] = "vor {0} Std.",
+ ["past_other"] = "vor {0} Std.",
+ }
+ },
+ ["hour_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Std.",
+ ["future_other"] = "in {0} Std.",
+ ["past_one"] = "vor {0} Std.",
+ ["past_other"] = "vor {0} Std.",
+ }
+ },
+ ["day_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Tag",
+ ["future_other"] = "in {0} Tagen",
+ ["past_one"] = "vor {0} Tag",
+ ["past_other"] = "vor {0} Tagen",
+ }
+ },
+ ["day_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Tag",
+ ["future_other"] = "in {0} Tagen",
+ ["past_one"] = "vor {0} Tag",
+ ["past_other"] = "vor {0} Tagen",
+ }
+ },
+ ["day_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} T",
+ ["future_other"] = "in {0} T",
+ ["past_one"] = "vor {0} T",
+ ["past_other"] = "vor {0} T",
+ }
+ },
+ ["week_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Woche",
+ ["future_other"] = "in {0} Wochen",
+ ["past_one"] = "vor {0} Woche",
+ ["past_other"] = "vor {0} Wochen",
+ }
+ },
+ ["week_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Wo.",
+ ["future_other"] = "in {0} Wo.",
+ ["past_one"] = "vor {0} Wo.",
+ ["past_other"] = "vor {0} Wo.",
+ }
+ },
+ ["week_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} W",
+ ["future_other"] = "in {0} W",
+ ["past_one"] = "vor {0} W",
+ ["past_other"] = "vor {0} W",
+ }
+ },
+ ["month_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Monat",
+ ["future_other"] = "in {0} Monaten",
+ ["past_one"] = "vor {0} Monat",
+ ["past_other"] = "vor {0} Monaten",
+ }
+ },
+ ["month_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Mon.",
+ ["future_other"] = "in {0} Mon.",
+ ["past_one"] = "vor {0} Mon.",
+ ["past_other"] = "vor {0} Mon.",
+ }
+ },
+ ["month_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} M",
+ ["future_other"] = "in {0} M",
+ ["past_one"] = "vor {0} M",
+ ["past_other"] = "vor {0} M",
+ }
+ },
+ ["quarter_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Quartal",
+ ["future_other"] = "in {0} Quartalen",
+ ["past_one"] = "vor {0} Quartal",
+ ["past_other"] = "vor {0} Quartalen",
+ }
+ },
+ ["quarter_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Quart.",
+ ["future_other"] = "in {0} Quart.",
+ ["past_one"] = "vor {0} Quart.",
+ ["past_other"] = "vor {0} Quart.",
+ }
+ },
+ ["quarter_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Q",
+ ["future_other"] = "in {0} Q",
+ ["past_one"] = "vor {0} Q",
+ ["past_other"] = "vor {0} Q",
+ }
+ },
+ ["year_long"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} Jahr",
+ ["future_other"] = "in {0} Jahren",
+ ["past_one"] = "vor {0} Jahr",
+ ["past_other"] = "vor {0} Jahren",
+ }
+ },
+ ["year_short"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} J",
+ ["future_other"] = "in {0} J",
+ ["past_one"] = "vor {0} J",
+ ["past_other"] = "vor {0} J",
+ }
+ },
+ ["year_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(4, StringComparer.Ordinal)
+ {
+ ["future_one"] = "in {0} J",
+ ["future_other"] = "in {0} J",
+ ["past_one"] = "vor {0} J",
+ ["past_other"] = "vor {0} J",
+ }
+ },
+ }
+ },
+ ["pl"] = new LocaleRelativeTimeData
+ {
+ Patterns = new(24, StringComparer.Ordinal)
+ {
+ ["second_long"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} sekund\u0119",
+ ["future_few"] = "za {0} sekundy",
+ ["future_many"] = "za {0} sekund",
+ ["future_other"] = "za {0} sekundy",
+ ["past_one"] = "{0} sekund\u0119 temu",
+ ["past_few"] = "{0} sekundy temu",
+ ["past_many"] = "{0} sekund temu",
+ ["past_other"] = "{0} sekundy temu",
+ }
+ },
+ ["second_short"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} sek.",
+ ["future_few"] = "za {0} sek.",
+ ["future_many"] = "za {0} sek.",
+ ["future_other"] = "za {0} sek.",
+ ["past_one"] = "{0} sek. temu",
+ ["past_few"] = "{0} sek. temu",
+ ["past_many"] = "{0} sek. temu",
+ ["past_other"] = "{0} sek. temu",
+ }
+ },
+ ["second_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} s",
+ ["future_few"] = "za {0} s",
+ ["future_many"] = "za {0} s",
+ ["future_other"] = "za {0} s",
+ ["past_one"] = "{0} s temu",
+ ["past_few"] = "{0} s temu",
+ ["past_many"] = "{0} s temu",
+ ["past_other"] = "{0} s temu",
+ }
+ },
+ ["minute_long"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} minut\u0119",
+ ["future_few"] = "za {0} minuty",
+ ["future_many"] = "za {0} minut",
+ ["future_other"] = "za {0} minuty",
+ ["past_one"] = "{0} minut\u0119 temu",
+ ["past_few"] = "{0} minuty temu",
+ ["past_many"] = "{0} minut temu",
+ ["past_other"] = "{0} minuty temu",
+ }
+ },
+ ["minute_short"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} min",
+ ["future_few"] = "za {0} min",
+ ["future_many"] = "za {0} min",
+ ["future_other"] = "za {0} min",
+ ["past_one"] = "{0} min temu",
+ ["past_few"] = "{0} min temu",
+ ["past_many"] = "{0} min temu",
+ ["past_other"] = "{0} min temu",
+ }
+ },
+ ["minute_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} min",
+ ["future_few"] = "za {0} min",
+ ["future_many"] = "za {0} min",
+ ["future_other"] = "za {0} min",
+ ["past_one"] = "{0} min temu",
+ ["past_few"] = "{0} min temu",
+ ["past_many"] = "{0} min temu",
+ ["past_other"] = "{0} min temu",
+ }
+ },
+ ["hour_long"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} godzin\u0119",
+ ["future_few"] = "za {0} godziny",
+ ["future_many"] = "za {0} godzin",
+ ["future_other"] = "za {0} godziny",
+ ["past_one"] = "{0} godzin\u0119 temu",
+ ["past_few"] = "{0} godziny temu",
+ ["past_many"] = "{0} godzin temu",
+ ["past_other"] = "{0} godziny temu",
+ }
+ },
+ ["hour_short"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} godz.",
+ ["future_few"] = "za {0} godz.",
+ ["future_many"] = "za {0} godz.",
+ ["future_other"] = "za {0} godz.",
+ ["past_one"] = "{0} godz. temu",
+ ["past_few"] = "{0} godz. temu",
+ ["past_many"] = "{0} godz. temu",
+ ["past_other"] = "{0} godz. temu",
+ }
+ },
+ ["hour_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} g.",
+ ["future_few"] = "za {0} g.",
+ ["future_many"] = "za {0} g.",
+ ["future_other"] = "za {0} g.",
+ ["past_one"] = "{0} g. temu",
+ ["past_few"] = "{0} g. temu",
+ ["past_many"] = "{0} g. temu",
+ ["past_other"] = "{0} g. temu",
+ }
+ },
+ ["day_long"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} dzie\u0144",
+ ["future_few"] = "za {0} dni",
+ ["future_many"] = "za {0} dni",
+ ["future_other"] = "za {0} dnia",
+ ["past_one"] = "{0} dzie\u0144 temu",
+ ["past_few"] = "{0} dni temu",
+ ["past_many"] = "{0} dni temu",
+ ["past_other"] = "{0} dnia temu",
+ }
+ },
+ ["day_short"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} dzie\u0144",
+ ["future_few"] = "za {0} dni",
+ ["future_many"] = "za {0} dni",
+ ["future_other"] = "za {0} dnia",
+ ["past_one"] = "{0} dzie\u0144 temu",
+ ["past_few"] = "{0} dni temu",
+ ["past_many"] = "{0} dni temu",
+ ["past_other"] = "{0} dnia temu",
+ }
+ },
+ ["day_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} dzie\u0144",
+ ["future_few"] = "za {0} dni",
+ ["future_many"] = "za {0} dni",
+ ["future_other"] = "za {0} dnia",
+ ["past_one"] = "{0} dzie\u0144 temu",
+ ["past_few"] = "{0} dni temu",
+ ["past_many"] = "{0} dni temu",
+ ["past_other"] = "{0} dnia temu",
+ }
+ },
+ ["week_long"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} tydzie\u0144",
+ ["future_few"] = "za {0} tygodnie",
+ ["future_many"] = "za {0} tygodni",
+ ["future_other"] = "za {0} tygodnia",
+ ["past_one"] = "{0} tydzie\u0144 temu",
+ ["past_few"] = "{0} tygodnie temu",
+ ["past_many"] = "{0} tygodni temu",
+ ["past_other"] = "{0} tygodnia temu",
+ }
+ },
+ ["week_short"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} tydz.",
+ ["future_few"] = "za {0} tyg.",
+ ["future_many"] = "za {0} tyg.",
+ ["future_other"] = "za {0} tyg.",
+ ["past_one"] = "{0} tydz. temu",
+ ["past_few"] = "{0} tyg. temu",
+ ["past_many"] = "{0} tyg. temu",
+ ["past_other"] = "{0} tyg. temu",
+ }
+ },
+ ["week_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} tydz.",
+ ["future_few"] = "za {0} tyg.",
+ ["future_many"] = "za {0} tyg.",
+ ["future_other"] = "za {0} tyg.",
+ ["past_one"] = "{0} tydz. temu",
+ ["past_few"] = "{0} tyg. temu",
+ ["past_many"] = "{0} tyg. temu",
+ ["past_other"] = "{0} tyg. temu",
+ }
+ },
+ ["month_long"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} miesi\u0105c",
+ ["future_few"] = "za {0} miesi\u0105ce",
+ ["future_many"] = "za {0} miesi\u0119cy",
+ ["future_other"] = "za {0} miesi\u0105ca",
+ ["past_one"] = "{0} miesi\u0105c temu",
+ ["past_few"] = "{0} miesi\u0105ce temu",
+ ["past_many"] = "{0} miesi\u0119cy temu",
+ ["past_other"] = "{0} miesi\u0105ca temu",
+ }
+ },
+ ["month_short"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} mies.",
+ ["future_few"] = "za {0} mies.",
+ ["future_many"] = "za {0} mies.",
+ ["future_other"] = "za {0} mies.",
+ ["past_one"] = "{0} mies. temu",
+ ["past_few"] = "{0} mies. temu",
+ ["past_many"] = "{0} mies. temu",
+ ["past_other"] = "{0} mies. temu",
+ }
+ },
+ ["month_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} mies.",
+ ["future_few"] = "za {0} mies.",
+ ["future_many"] = "za {0} mies.",
+ ["future_other"] = "za {0} mies.",
+ ["past_one"] = "{0} mies. temu",
+ ["past_few"] = "{0} mies. temu",
+ ["past_many"] = "{0} mies. temu",
+ ["past_other"] = "{0} mies. temu",
+ }
+ },
+ ["quarter_long"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} kwarta\u0142",
+ ["future_few"] = "za {0} kwarta\u0142y",
+ ["future_many"] = "za {0} kwarta\u0142\u00f3w",
+ ["future_other"] = "za {0} kwarta\u0142u",
+ ["past_one"] = "{0} kwarta\u0142 temu",
+ ["past_few"] = "{0} kwarta\u0142y temu",
+ ["past_many"] = "{0} kwarta\u0142\u00f3w temu",
+ ["past_other"] = "{0} kwarta\u0142u temu",
+ }
+ },
+ ["quarter_short"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} kw.",
+ ["future_few"] = "za {0} kw.",
+ ["future_many"] = "za {0} kw.",
+ ["future_other"] = "za {0} kw.",
+ ["past_one"] = "{0} kw. temu",
+ ["past_few"] = "{0} kw. temu",
+ ["past_many"] = "{0} kw. temu",
+ ["past_other"] = "{0} kw. temu",
+ }
+ },
+ ["quarter_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} kw.",
+ ["future_few"] = "za {0} kw.",
+ ["future_many"] = "za {0} kw.",
+ ["future_other"] = "za {0} kw.",
+ ["past_one"] = "{0} kw. temu",
+ ["past_few"] = "{0} kw. temu",
+ ["past_many"] = "{0} kw. temu",
+ ["past_other"] = "{0} kw. temu",
+ }
+ },
+ ["year_long"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} rok",
+ ["future_few"] = "za {0} lata",
+ ["future_many"] = "za {0} lat",
+ ["future_other"] = "za {0} roku",
+ ["past_one"] = "{0} rok temu",
+ ["past_few"] = "{0} lata temu",
+ ["past_many"] = "{0} lat temu",
+ ["past_other"] = "{0} roku temu",
+ }
+ },
+ ["year_short"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} rok",
+ ["future_few"] = "za {0} lata",
+ ["future_many"] = "za {0} lat",
+ ["future_other"] = "za {0} roku",
+ ["past_one"] = "{0} rok temu",
+ ["past_few"] = "{0} lata temu",
+ ["past_many"] = "{0} lat temu",
+ ["past_other"] = "{0} roku temu",
+ }
+ },
+ ["year_narrow"] = new UnitStylePatterns
+ {
+ Patterns = new(8, StringComparer.Ordinal)
+ {
+ ["future_one"] = "za {0} rok",
+ ["future_few"] = "za {0} lata",
+ ["future_many"] = "za {0} lat",
+ ["future_other"] = "za {0} roku",
+ ["past_one"] = "{0} rok temu",
+ ["past_few"] = "{0} lata temu",
+ ["past_many"] = "{0} lat temu",
+ ["past_other"] = "{0} roku temu",
+ }
+ },
+ }
+ },
+ };
+}
diff --git a/Jint/Native/Intl/Data/RelativeTimePatternsData.cs b/Jint/Native/Intl/Data/RelativeTimePatternsData.cs
index fde97e5256..42cc8dbbbb 100644
--- a/Jint/Native/Intl/Data/RelativeTimePatternsData.cs
+++ b/Jint/Native/Intl/Data/RelativeTimePatternsData.cs
@@ -1,32 +1,23 @@
-using System.Threading;
-
namespace Jint.Native.Intl.Data;
///
/// Provides CLDR relative time formatting patterns for locale-aware relative time formatting.
-/// Data is loaded from embedded RelativeTimePatternsData.txt resource.
///
-internal static class RelativeTimePatternsData
+internal static partial class RelativeTimePatternsData
{
- private static readonly Lock _lock = new();
- private static Dictionary? _data;
- private static volatile bool _loaded;
-
///
/// Gets relative time data for a locale.
/// Falls back to English if locale not found.
///
public static LocaleRelativeTimeData? GetDataForLocale(string locale)
{
- EnsureLoaded();
-
if (!string.IsNullOrEmpty(locale))
{
// Get language code from locale (e.g., "es" from "es-ES")
var language = GetLanguageCode(locale);
// Try to find data for this language
- if (_data!.TryGetValue(language, out var data))
+ if (_data.TryGetValue(language, out var data))
{
return data;
}
@@ -35,7 +26,7 @@ internal static class RelativeTimePatternsData
// Fall back to English if not found and not already English
if (!IsEnglish(locale))
{
- if (_data!.TryGetValue("en", out var enData))
+ if (_data.TryGetValue("en", out var enData))
{
return enData;
}
@@ -66,126 +57,6 @@ private static bool IsEnglish(string? locale)
return locale!.StartsWith("en", StringComparison.OrdinalIgnoreCase);
}
- private static void EnsureLoaded()
- {
- if (_loaded)
- {
- return;
- }
-
- lock (_lock)
- {
- if (_loaded)
- {
- return;
- }
-
- _data = new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- var assembly = typeof(RelativeTimePatternsData).Assembly;
- using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.RelativeTimePatternsData.txt");
- if (stream is null)
- {
- _loaded = true;
- return;
- }
-
- using var reader = new StreamReader(stream);
- string? currentLocale = null;
-
- // Temporary storage for building patterns
- var tempPatterns = new Dictionary>(StringComparer.Ordinal);
-
- while (reader.ReadLine() is { } line)
- {
- if (string.IsNullOrWhiteSpace(line))
- {
- continue;
- }
-
- if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']')
- {
- // Save previous locale data
- if (currentLocale != null && tempPatterns.Count > 0)
- {
- var localeData = BuildLocaleDataFromTemp(tempPatterns);
- _data[currentLocale] = localeData;
- tempPatterns.Clear();
- }
-
- currentLocale = line.Substring(1, line.Length - 2);
- continue;
- }
-
- if (currentLocale == null)
- {
- continue;
- }
-
- var eqIndex = line.IndexOf('=');
- if (eqIndex < 0)
- {
- continue;
- }
-
- var key = line.Substring(0, eqIndex);
- var value = line.Substring(eqIndex + 1);
-
- // Parse key: unit_style_direction_pluralForm
- // Example: "second_long_future_one" or "second_long_past_other"
- var parts = key.Split('_');
- if (parts.Length >= 4)
- {
- var unit = parts[0]; // second, minute, hour, day, week, month, quarter, year
- var style = parts[1]; // long, short, narrow
- var direction = parts[2]; // future, past
- var pluralForm = parts[3]; // one, few, many, other
-
- var unitStyleKey = unit + "_" + style;
- if (!tempPatterns.TryGetValue(unitStyleKey, out var directionPatterns))
- {
- directionPatterns = new Dictionary(StringComparer.Ordinal);
- tempPatterns[unitStyleKey] = directionPatterns;
- }
-
- var directionPluralKey = direction + "_" + pluralForm;
- directionPatterns[directionPluralKey] = value;
- }
- }
-
- // Save last locale data
- if (currentLocale != null && tempPatterns.Count > 0)
- {
- var localeData = BuildLocaleDataFromTemp(tempPatterns);
- _data[currentLocale] = localeData;
- }
-
- _loaded = true;
- }
- }
-
- private static LocaleRelativeTimeData BuildLocaleDataFromTemp(Dictionary> tempPatterns)
- {
- var patterns = new Dictionary(StringComparer.Ordinal);
-
- foreach (var kvp in tempPatterns)
- {
- var unitStyleKey = kvp.Key;
- var directionPatterns = kvp.Value;
-
- var unitStylePatterns = new UnitStylePatterns
- {
- Patterns = new Dictionary(directionPatterns, StringComparer.Ordinal)
- };
-
- patterns[unitStyleKey] = unitStylePatterns;
- }
-
- return new LocaleRelativeTimeData
- {
- Patterns = patterns
- };
- }
}
///
diff --git a/Jint/Native/Intl/Data/UnitPatternsData.cs b/Jint/Native/Intl/Data/UnitPatternsData.cs
index 2f7f9b9730..fe40e1bf09 100644
--- a/Jint/Native/Intl/Data/UnitPatternsData.cs
+++ b/Jint/Native/Intl/Data/UnitPatternsData.cs
@@ -1,16 +1,43 @@
-using System.Threading;
-
namespace Jint.Native.Intl.Data;
///
/// Provides CLDR unit formatting patterns for locale-aware unit formatting.
-/// Data is loaded from embedded UnitPatternsData.txt resource.
///
internal static class UnitPatternsData
{
- private static readonly Lock _lock = new();
- private static Dictionary>? _patterns;
- private static volatile bool _loaded;
+ private static readonly Dictionary> _patterns = new(5, StringComparer.OrdinalIgnoreCase)
+ {
+ ["en"] = new(3, StringComparer.Ordinal)
+ {
+ ["kilometer-per-hour_short"] = "{0} km/h",
+ ["kilometer-per-hour_narrow"] = "{0}km/h",
+ ["kilometer-per-hour_long"] = "{0} kilometers per hour",
+ },
+ ["de"] = new(3, StringComparer.Ordinal)
+ {
+ ["kilometer-per-hour_short"] = "{0} km/h",
+ ["kilometer-per-hour_narrow"] = "{0} km/h",
+ ["kilometer-per-hour_long"] = "{0} Kilometer pro Stunde",
+ },
+ ["ja"] = new(3, StringComparer.Ordinal)
+ {
+ ["kilometer-per-hour_short"] = "{0} km/h",
+ ["kilometer-per-hour_narrow"] = "{0}km/h",
+ ["kilometer-per-hour_long"] = "時速 {0} キロメートル",
+ },
+ ["ko"] = new(3, StringComparer.Ordinal)
+ {
+ ["kilometer-per-hour_short"] = "{0}km/h",
+ ["kilometer-per-hour_narrow"] = "{0}km/h",
+ ["kilometer-per-hour_long"] = "시속 {0}킬로미터",
+ },
+ ["zh"] = new(3, StringComparer.Ordinal)
+ {
+ ["kilometer-per-hour_short"] = "{0} 公里/小時",
+ ["kilometer-per-hour_narrow"] = "{0}公里/小時",
+ ["kilometer-per-hour_long"] = "每小時 {0} 公里",
+ },
+ };
///
/// Gets unit patterns for a locale.
@@ -19,15 +46,13 @@ internal static class UnitPatternsData
///
public static Dictionary? GetPatternsForLocale(string locale)
{
- EnsureLoaded();
-
if (!string.IsNullOrEmpty(locale))
{
// Get language code from locale (e.g., "zh" from "zh-TW")
var language = GetLanguageCode(locale);
// Try to find patterns for this language
- if (_patterns!.TryGetValue(language, out var data))
+ if (_patterns.TryGetValue(language, out var data))
{
return data;
}
@@ -36,7 +61,7 @@ internal static class UnitPatternsData
// Fall back to English if not found and not already English
if (!IsEnglish(locale))
{
- if (_patterns!.TryGetValue("en", out var enData))
+ if (_patterns.TryGetValue("en", out var enData))
{
return enData;
}
@@ -66,79 +91,4 @@ private static bool IsEnglish(string? locale)
return locale!.StartsWith("en", StringComparison.OrdinalIgnoreCase);
}
-
- private static void EnsureLoaded()
- {
- if (_loaded)
- {
- return;
- }
-
- lock (_lock)
- {
- if (_loaded)
- {
- return;
- }
-
- _patterns = new Dictionary>(StringComparer.OrdinalIgnoreCase);
-
- var assembly = typeof(UnitPatternsData).Assembly;
- using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.UnitPatternsData.txt");
- if (stream is null)
- {
- _loaded = true;
- return;
- }
-
- using var reader = new StreamReader(stream);
- string? currentLocale = null;
- Dictionary? currentPatterns = null;
-
- while (reader.ReadLine() is { } line)
- {
- if (string.IsNullOrWhiteSpace(line))
- {
- continue;
- }
-
- if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']')
- {
- // Save previous locale data
- if (currentLocale != null && currentPatterns != null)
- {
- _patterns[currentLocale] = currentPatterns;
- }
-
- currentLocale = line.Substring(1, line.Length - 2);
- currentPatterns = new Dictionary(StringComparer.Ordinal);
- continue;
- }
-
- if (currentLocale == null || currentPatterns == null)
- {
- continue;
- }
-
- var eqIndex = line.IndexOf('=');
- if (eqIndex < 0)
- {
- continue;
- }
-
- var key = line.Substring(0, eqIndex);
- var value = line.Substring(eqIndex + 1);
-
- currentPatterns[key] = value;
- }
-
- // Save last locale data
- if (currentLocale != null && currentPatterns != null)
- {
- _patterns[currentLocale] = currentPatterns;
- }
-
- _loaded = true;
- }
- }
}
diff --git a/Jint/Native/Intl/Data/WeekData.Data.cs b/Jint/Native/Intl/Data/WeekData.Data.cs
new file mode 100644
index 0000000000..35182c9f45
--- /dev/null
+++ b/Jint/Native/Intl/Data/WeekData.Data.cs
@@ -0,0 +1,256 @@
+namespace Jint.Native.Intl.Data;
+
+internal static partial class WeekData
+{
+ private static readonly Dictionary _firstDay = new(151, StringComparer.OrdinalIgnoreCase)
+ {
+ ["001"] = "mon",
+ ["AD"] = "mon",
+ ["AE"] = "mon",
+ ["AF"] = "sat",
+ ["AG"] = "sun",
+ ["AI"] = "mon",
+ ["AL"] = "mon",
+ ["AM"] = "mon",
+ ["AN"] = "mon",
+ ["AR"] = "mon",
+ ["AS"] = "sun",
+ ["AT"] = "mon",
+ ["AU"] = "mon",
+ ["AX"] = "mon",
+ ["AZ"] = "mon",
+ ["BA"] = "mon",
+ ["BD"] = "sun",
+ ["BE"] = "mon",
+ ["BG"] = "mon",
+ ["BH"] = "sat",
+ ["BM"] = "mon",
+ ["BN"] = "mon",
+ ["BR"] = "sun",
+ ["BS"] = "sun",
+ ["BT"] = "sun",
+ ["BW"] = "sun",
+ ["BY"] = "mon",
+ ["BZ"] = "sun",
+ ["CA"] = "sun",
+ ["CH"] = "mon",
+ ["CL"] = "mon",
+ ["CM"] = "mon",
+ ["CN"] = "mon",
+ ["CO"] = "sun",
+ ["CR"] = "mon",
+ ["CY"] = "mon",
+ ["CZ"] = "mon",
+ ["DE"] = "mon",
+ ["DJ"] = "sat",
+ ["DK"] = "mon",
+ ["DM"] = "sun",
+ ["DO"] = "sun",
+ ["DZ"] = "sat",
+ ["EC"] = "mon",
+ ["EE"] = "mon",
+ ["EG"] = "sat",
+ ["ES"] = "mon",
+ ["ET"] = "sun",
+ ["FI"] = "mon",
+ ["FJ"] = "mon",
+ ["FO"] = "mon",
+ ["FR"] = "mon",
+ ["GB"] = "mon",
+ ["GB-alt-variant"] = "sun",
+ ["GE"] = "mon",
+ ["GF"] = "mon",
+ ["GP"] = "mon",
+ ["GR"] = "mon",
+ ["GT"] = "sun",
+ ["GU"] = "sun",
+ ["HK"] = "sun",
+ ["HN"] = "sun",
+ ["HR"] = "mon",
+ ["HU"] = "mon",
+ ["ID"] = "sun",
+ ["IE"] = "mon",
+ ["IL"] = "sun",
+ ["IN"] = "sun",
+ ["IQ"] = "sat",
+ ["IR"] = "sat",
+ ["IS"] = "mon",
+ ["IT"] = "mon",
+ ["JM"] = "sun",
+ ["JO"] = "sat",
+ ["JP"] = "sun",
+ ["KE"] = "sun",
+ ["KG"] = "mon",
+ ["KH"] = "sun",
+ ["KR"] = "sun",
+ ["KW"] = "sat",
+ ["KZ"] = "mon",
+ ["LA"] = "sun",
+ ["LB"] = "mon",
+ ["LI"] = "mon",
+ ["LK"] = "mon",
+ ["LT"] = "mon",
+ ["LU"] = "mon",
+ ["LV"] = "mon",
+ ["LY"] = "sat",
+ ["MC"] = "mon",
+ ["MD"] = "mon",
+ ["ME"] = "mon",
+ ["MH"] = "sun",
+ ["MK"] = "mon",
+ ["MM"] = "sun",
+ ["MN"] = "mon",
+ ["MO"] = "sun",
+ ["MQ"] = "mon",
+ ["MT"] = "sun",
+ ["MV"] = "fri",
+ ["MX"] = "sun",
+ ["MY"] = "mon",
+ ["MZ"] = "sun",
+ ["NI"] = "sun",
+ ["NL"] = "mon",
+ ["NO"] = "mon",
+ ["NP"] = "sun",
+ ["NZ"] = "mon",
+ ["OM"] = "sat",
+ ["PA"] = "sun",
+ ["PE"] = "sun",
+ ["PH"] = "sun",
+ ["PK"] = "sun",
+ ["PL"] = "mon",
+ ["PR"] = "sun",
+ ["PT"] = "sun",
+ ["PY"] = "sun",
+ ["QA"] = "sat",
+ ["RE"] = "mon",
+ ["RO"] = "mon",
+ ["RS"] = "mon",
+ ["RU"] = "mon",
+ ["SA"] = "sun",
+ ["SD"] = "sat",
+ ["SE"] = "mon",
+ ["SG"] = "sun",
+ ["SI"] = "mon",
+ ["SK"] = "mon",
+ ["SM"] = "mon",
+ ["SV"] = "sun",
+ ["SY"] = "sat",
+ ["TH"] = "sun",
+ ["TJ"] = "mon",
+ ["TM"] = "mon",
+ ["TR"] = "mon",
+ ["TT"] = "sun",
+ ["TW"] = "sun",
+ ["UA"] = "mon",
+ ["UM"] = "sun",
+ ["US"] = "sun",
+ ["UY"] = "mon",
+ ["UZ"] = "mon",
+ ["VA"] = "mon",
+ ["VE"] = "sun",
+ ["VI"] = "sun",
+ ["VN"] = "mon",
+ ["WS"] = "sun",
+ ["XK"] = "mon",
+ ["YE"] = "sun",
+ ["ZA"] = "sun",
+ ["ZW"] = "sun",
+ };
+
+ private static readonly Dictionary _minDays = new(49, StringComparer.OrdinalIgnoreCase)
+ {
+ ["001"] = 1,
+ ["AD"] = 4,
+ ["AN"] = 4,
+ ["AT"] = 4,
+ ["AX"] = 4,
+ ["BE"] = 4,
+ ["BG"] = 4,
+ ["CH"] = 4,
+ ["CZ"] = 4,
+ ["DE"] = 4,
+ ["DK"] = 4,
+ ["EE"] = 4,
+ ["ES"] = 4,
+ ["FI"] = 4,
+ ["FJ"] = 4,
+ ["FO"] = 4,
+ ["FR"] = 4,
+ ["GB"] = 4,
+ ["GF"] = 4,
+ ["GG"] = 4,
+ ["GI"] = 4,
+ ["GP"] = 4,
+ ["GR"] = 4,
+ ["GU"] = 1,
+ ["HU"] = 4,
+ ["IE"] = 4,
+ ["IM"] = 4,
+ ["IS"] = 4,
+ ["IT"] = 4,
+ ["JE"] = 4,
+ ["LI"] = 4,
+ ["LT"] = 4,
+ ["LU"] = 4,
+ ["MC"] = 4,
+ ["MQ"] = 4,
+ ["NL"] = 4,
+ ["NO"] = 4,
+ ["PL"] = 4,
+ ["PT"] = 4,
+ ["RE"] = 4,
+ ["RU"] = 4,
+ ["SE"] = 4,
+ ["SJ"] = 4,
+ ["SK"] = 4,
+ ["SM"] = 4,
+ ["UM"] = 1,
+ ["US"] = 1,
+ ["VA"] = 4,
+ ["VI"] = 1,
+ };
+
+ private static readonly Dictionary _weekendStart = new(19, StringComparer.OrdinalIgnoreCase)
+ {
+ ["001"] = "sat",
+ ["AF"] = "thu",
+ ["BH"] = "fri",
+ ["DZ"] = "fri",
+ ["EG"] = "fri",
+ ["IL"] = "fri",
+ ["IN"] = "sun",
+ ["IQ"] = "fri",
+ ["IR"] = "fri",
+ ["JO"] = "fri",
+ ["KW"] = "fri",
+ ["LY"] = "fri",
+ ["OM"] = "fri",
+ ["QA"] = "fri",
+ ["SA"] = "fri",
+ ["SD"] = "fri",
+ ["SY"] = "fri",
+ ["UG"] = "sun",
+ ["YE"] = "fri",
+ };
+
+ private static readonly Dictionary _weekendEnd = new(17, StringComparer.OrdinalIgnoreCase)
+ {
+ ["001"] = "sun",
+ ["AF"] = "fri",
+ ["BH"] = "sat",
+ ["DZ"] = "sat",
+ ["EG"] = "sat",
+ ["IL"] = "sat",
+ ["IQ"] = "sat",
+ ["IR"] = "fri",
+ ["JO"] = "sat",
+ ["KW"] = "sat",
+ ["LY"] = "sat",
+ ["OM"] = "sat",
+ ["QA"] = "sat",
+ ["SA"] = "sat",
+ ["SD"] = "sat",
+ ["SY"] = "sat",
+ ["YE"] = "sat",
+ };
+}
diff --git a/Jint/Native/Intl/Data/WeekData.cs b/Jint/Native/Intl/Data/WeekData.cs
index af09dcda14..67388ece9c 100644
--- a/Jint/Native/Intl/Data/WeekData.cs
+++ b/Jint/Native/Intl/Data/WeekData.cs
@@ -1,71 +1,33 @@
-using System.Threading;
-
namespace Jint.Native.Intl.Data;
///
/// Provides CLDR week data for locale-aware week information.
-/// Data is loaded from embedded WeekData.txt resource.
///
-internal static class WeekData
+internal static partial class WeekData
{
- private static readonly Lock _lock = new();
- private static Dictionary? _firstDay;
- private static Dictionary? _minDays;
- private static Dictionary? _weekendStart;
- private static Dictionary? _weekendEnd;
- private static volatile bool _loaded;
-
///
/// First day of week per region (mon, tue, wed, thu, fri, sat, sun).
/// Key "001" is the default/world value.
///
- public static Dictionary FirstDay
- {
- get
- {
- EnsureLoaded();
- return _firstDay!;
- }
- }
+ public static Dictionary FirstDay => _firstDay;
///
/// Minimum days in first week per region (typically 1 or 4).
/// Key "001" is the default/world value.
///
- public static Dictionary MinDays
- {
- get
- {
- EnsureLoaded();
- return _minDays!;
- }
- }
+ public static Dictionary MinDays => _minDays;
///
/// Weekend start day per region.
/// Key "001" is the default/world value (typically "sat").
///
- public static Dictionary WeekendStart
- {
- get
- {
- EnsureLoaded();
- return _weekendStart!;
- }
- }
+ public static Dictionary WeekendStart => _weekendStart;
///
/// Weekend end day per region.
/// Key "001" is the default/world value (typically "sun").
///
- public static Dictionary WeekendEnd
- {
- get
- {
- EnsureLoaded();
- return _weekendEnd!;
- }
- }
+ public static Dictionary WeekendEnd => _weekendEnd;
///
/// Gets the first day of week for a region (1=Monday, 7=Sunday).
@@ -81,15 +43,13 @@ public static int GetFirstDayOfWeek(string? region)
///
public static string GetFirstDayName(string? region)
{
- EnsureLoaded();
-
- if (!string.IsNullOrEmpty(region) && _firstDay!.TryGetValue(region!, out var day))
+ if (!string.IsNullOrEmpty(region) && _firstDay.TryGetValue(region!, out var day))
{
return day;
}
// Default to world value
- return _firstDay!.TryGetValue("001", out var defaultDay) ? defaultDay : "mon";
+ return _firstDay.TryGetValue("001", out var defaultDay) ? defaultDay : "mon";
}
///
@@ -97,15 +57,13 @@ public static string GetFirstDayName(string? region)
///
public static int GetMinDays(string? region)
{
- EnsureLoaded();
-
- if (!string.IsNullOrEmpty(region) && _minDays!.TryGetValue(region!, out var days))
+ if (!string.IsNullOrEmpty(region) && _minDays.TryGetValue(region!, out var days))
{
return days;
}
// Default to world value
- return _minDays!.TryGetValue("001", out var defaultDays) ? defaultDays : 1;
+ return _minDays.TryGetValue("001", out var defaultDays) ? defaultDays : 1;
}
///
@@ -113,26 +71,24 @@ public static int GetMinDays(string? region)
///
public static int[] GetWeekend(string? region)
{
- EnsureLoaded();
-
string startDay, endDay;
- if (!string.IsNullOrEmpty(region) && _weekendStart!.TryGetValue(region!, out var start))
+ if (!string.IsNullOrEmpty(region) && _weekendStart.TryGetValue(region!, out var start))
{
startDay = start;
}
else
{
- startDay = _weekendStart!.TryGetValue("001", out var defaultStart) ? defaultStart : "sat";
+ startDay = _weekendStart.TryGetValue("001", out var defaultStart) ? defaultStart : "sat";
}
- if (!string.IsNullOrEmpty(region) && _weekendEnd!.TryGetValue(region!, out var end))
+ if (!string.IsNullOrEmpty(region) && _weekendEnd.TryGetValue(region!, out var end))
{
endDay = end;
}
else
{
- endDay = _weekendEnd!.TryGetValue("001", out var defaultEnd) ? defaultEnd : "sun";
+ endDay = _weekendEnd.TryGetValue("001", out var defaultEnd) ? defaultEnd : "sun";
}
var startNum = DayNameToNumber(startDay);
@@ -173,82 +129,4 @@ private static int DayNameToNumber(string dayName)
};
}
- private static void EnsureLoaded()
- {
- if (_loaded)
- {
- return;
- }
-
- lock (_lock)
- {
- if (_loaded)
- {
- return;
- }
-
- _firstDay = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _minDays = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _weekendStart = new Dictionary(StringComparer.OrdinalIgnoreCase);
- _weekendEnd = new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- var assembly = typeof(WeekData).Assembly;
- using var stream = assembly.GetManifestResourceStream("Jint.Native.Intl.Data.WeekData.txt");
- if (stream is null)
- {
- _loaded = true;
- return;
- }
-
- using var reader = new StreamReader(stream);
- string? currentSection = null;
-
- while (reader.ReadLine() is { } line)
- {
- if (string.IsNullOrWhiteSpace(line))
- {
- continue;
- }
-
- if (line.Length > 2 && line[0] == '[' && line[line.Length - 1] == ']')
- {
- currentSection = line.Substring(1, line.Length - 2);
- continue;
- }
-
- var eqIndex = line.IndexOf('=');
- if (eqIndex < 0)
- {
- continue;
- }
-
- var key = line.Substring(0, eqIndex);
- var value = line.Substring(eqIndex + 1);
-
- switch (currentSection)
- {
- case "FIRST_DAY":
- _firstDay[key] = value;
- break;
-
- case "MIN_DAYS":
- if (int.TryParse(value, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out var minDays))
- {
- _minDays[key] = minDays;
- }
- break;
-
- case "WEEKEND_START":
- _weekendStart[key] = value;
- break;
-
- case "WEEKEND_END":
- _weekendEnd[key] = value;
- break;
- }
- }
-
- _loaded = true;
- }
- }
}