diff --git a/components/locid/src/extensions/mod.rs b/components/locid/src/extensions/mod.rs index 5f1ad2b1f39..a37bf8b9fcd 100644 --- a/components/locid/src/extensions/mod.rs +++ b/components/locid/src/extensions/mod.rs @@ -23,7 +23,7 @@ //! use icu::locid::extensions::unicode::{Key, Value}; //! use icu::locid::Locale; //! -//! let loc: Locale = "en-US-u-ca-buddhist-t-en-US-h0-hybrid-x-foo" +//! let loc: Locale = "en-US-u-ca-buddhist-t-en-us-h0-hybrid-x-foo" //! .parse() //! .expect("Failed to parse."); //! diff --git a/components/locid/src/extensions/transform/mod.rs b/components/locid/src/extensions/transform/mod.rs index 4156c5910fa..f5bb74e0dbd 100644 --- a/components/locid/src/extensions/transform/mod.rs +++ b/components/locid/src/extensions/transform/mod.rs @@ -16,7 +16,7 @@ //! use icu::locid::{LanguageIdentifier, Locale}; //! //! let mut loc: Locale = -//! "en-US-t-es-AR-h0-hybrid".parse().expect("Parsing failed."); +//! "en-US-t-es-ar-h0-hybrid".parse().expect("Parsing failed."); //! //! let lang: LanguageIdentifier = //! "es-AR".parse().expect("Parsing LanguageIdentifier failed."); @@ -28,7 +28,7 @@ //! assert!(loc.extensions.transform.fields.contains_key(&key)); //! assert_eq!(loc.extensions.transform.fields.get(&key), Some(&value)); //! -//! assert_eq!(&loc.extensions.transform.to_string(), "t-es-AR-h0-hybrid"); +//! assert_eq!(&loc.extensions.transform.to_string(), "t-es-ar-h0-hybrid"); //! ``` mod fields; mod key; @@ -60,7 +60,7 @@ use litemap::LiteMap; /// use icu::locid::{LanguageIdentifier, Locale}; /// /// let mut loc: Locale = -/// "de-t-en-US-h0-hybrid".parse().expect("Parsing failed."); +/// "de-t-en-us-h0-hybrid".parse().expect("Parsing failed."); /// /// let en_us: LanguageIdentifier = "en-US".parse().expect("Parsing failed."); /// @@ -107,7 +107,7 @@ impl Transform { /// ``` /// use icu::locid::Locale; /// - /// let mut loc: Locale = "en-US-t-es-AR".parse().expect("Parsing failed."); + /// let mut loc: Locale = "en-US-t-es-ar".parse().expect("Parsing failed."); /// /// assert!(!loc.extensions.transform.is_empty()); /// ``` @@ -122,7 +122,7 @@ impl Transform { /// ``` /// use icu::locid::Locale; /// - /// let mut loc: Locale = "en-US-t-es-AR".parse().unwrap(); + /// let mut loc: Locale = "en-US-t-es-ar".parse().unwrap(); /// loc.extensions.transform.clear(); /// assert_eq!(loc, "en-US".parse().unwrap()); /// ``` @@ -196,7 +196,7 @@ impl Transform { } f("t")?; if let Some(lang) = &self.lang { - lang.for_each_subtag_str(f)?; + lang.for_each_subtag_str_lowercased(f)?; } self.fields.for_each_subtag_str(f) } @@ -212,7 +212,7 @@ impl writeable::Writeable for Transform { sink.write_str("t")?; if let Some(lang) = &self.lang { sink.write_char('-')?; - writeable::Writeable::write_to(lang, sink)?; + lang.write_lowercased_to(sink)?; } if !self.fields.is_empty() { sink.write_char('-')?; diff --git a/components/locid/src/langid.rs b/components/locid/src/langid.rs index 51295942112..eac8c83713e 100644 --- a/components/locid/src/langid.rs +++ b/components/locid/src/langid.rs @@ -327,6 +327,74 @@ impl LanguageIdentifier { } Ok(()) } + + /// Executes `f` on each subtag string of this `LanguageIdentifier`, with every string in + /// lowercase ascii form. + /// + /// The default canonicalization of language identifiers uses titlecase scripts and uppercase + /// regions. However, this differs from [RFC6497 (BCP 47 Extension T)], which specifies: + /// + /// > _The canonical form for all subtags in the extension is lowercase, with the fields + /// ordered by the separators, alphabetically._ + /// + /// Hence, this method is used inside [`Transform Extensions`] to be able to get the correct + /// canonicalization of the language identifier. + /// + /// As an example, the canonical form of locale **EN-LATN-CA-T-EN-LATN-CA** is + /// **en-Latn-CA-t-en-latn-ca**, with the script and region parts lowercased inside T extensions, + /// but titlecased and uppercased outside T extensions respectively. + /// + /// [RFC6497 (BCP 47 Extension T)]: https://www.ietf.org/rfc/rfc6497.txt + /// [`Transform extensions`]: crate::extensions::transform + pub(crate) fn for_each_subtag_str_lowercased(&self, f: &mut F) -> Result<(), E> + where + F: FnMut(&str) -> Result<(), E>, + { + f(self.language.as_str())?; + if let Some(ref script) = self.script { + f(script.into_tinystr().to_ascii_lowercase().as_str())?; + } + if let Some(ref region) = self.region { + f(region.into_tinystr().to_ascii_lowercase().as_str())?; + } + for variant in self.variants.iter() { + f(variant.as_str())?; + } + Ok(()) + } + + /// Writes this `LanguageIdentifier` to a sink, replacing uppercase ascii chars with + /// lowercase ascii chars. + /// + /// The default canonicalization of language identifiers uses titlecase scripts and uppercase + /// regions. However, this differs from [RFC6497 (BCP 47 Extension T)], which specifies: + /// + /// > _The canonical form for all subtags in the extension is lowercase, with the fields + /// ordered by the separators, alphabetically._ + /// + /// Hence, this method is used inside [`Transform Extensions`] to be able to get the correct + /// canonicalization of the language identifier. + /// + /// As an example, the canonical form of locale **EN-LATN-CA-T-EN-LATN-CA** is + /// **en-Latn-CA-t-en-latn-ca**, with the script and region parts lowercased inside T extensions, + /// but titlecased and uppercased outside T extensions respectively. + /// + /// [RFC6497 (BCP 47 Extension T)]: https://www.ietf.org/rfc/rfc6497.txt + /// [`Transform extensions`]: crate::extensions::transform + pub(crate) fn write_lowercased_to( + &self, + sink: &mut W, + ) -> core::fmt::Result { + let mut initial = true; + self.for_each_subtag_str_lowercased(&mut |subtag| { + if initial { + initial = false; + } else { + sink.write_char('-')?; + } + sink.write_str(subtag) + }) + } } impl AsRef for LanguageIdentifier { diff --git a/components/locid/tests/fixtures/canonicalize.json b/components/locid/tests/fixtures/canonicalize.json index b20e64c4b82..79a50571465 100644 --- a/components/locid/tests/fixtures/canonicalize.json +++ b/components/locid/tests/fixtures/canonicalize.json @@ -14,5 +14,55 @@ { "input": "en-scouse-fonipa", "output": "en-fonipa-scouse" + }, + { + "input": { + "type": "Locale", + "identifier": "en-US-t-es-AR-x-foo" + }, + "output": { + "type": "Locale", + "identifier": "en-US-t-es-ar-x-foo" + } + }, + { + "input": { + "type": "Locale", + "identifier": "en-t-en-Latn-CA-emodeng" + }, + "output": { + "type": "Locale", + "identifier": "en-t-en-latn-ca-emodeng" + } + }, + { + "input": { + "type": "Locale", + "identifier": "EN-US-T-ES-AR-X-FOO" + }, + "output": { + "type": "Locale", + "identifier": "en-US-t-es-ar-x-foo" + } + }, + { + "input": { + "type": "Locale", + "identifier": "EN-T-EN-LATN-CA-EMODENG" + }, + "output": { + "type": "Locale", + "identifier": "en-t-en-latn-ca-emodeng" + } + }, + { + "input": { + "type": "Locale", + "identifier": "UND-CYRL-T-ES-LATN-M0-UNGEGN" + }, + "output": { + "type": "Locale", + "identifier": "und-Cyrl-t-es-latn-m0-ungegn" + } } ] diff --git a/components/locid/tests/fixtures/locale.json b/components/locid/tests/fixtures/locale.json index e876993510a..93679a0667b 100644 --- a/components/locid/tests/fixtures/locale.json +++ b/components/locid/tests/fixtures/locale.json @@ -75,7 +75,7 @@ { "input": { "type": "Locale", - "identifier": "en-US-t-pl-Latn-DE" + "identifier": "en-US-t-pl-latn-de" }, "output": { "type": "Locale", @@ -125,7 +125,7 @@ { "input": { "type": "Locale", - "identifier": "en-US-t-es-AR-x-foo" + "identifier": "en-US-t-es-ar-x-foo" }, "output": { "type": "Locale", @@ -142,7 +142,7 @@ { "input": { "type": "Locale", - "identifier": "en-US-u-ca-buddhist-hc-h12-t-es-AR-h0-hybrid-x-private-foobar" + "identifier": "en-US-u-ca-buddhist-hc-h12-t-es-ar-h0-hybrid-x-private-foobar" }, "output": { "type": "Locale", diff --git a/components/locid/tests/locale.rs b/components/locid/tests/locale.rs index 9cb320ad937..638db413835 100644 --- a/components/locid/tests/locale.rs +++ b/components/locid/tests/locale.rs @@ -72,10 +72,10 @@ fn test_locale_conversions() { #[test] fn test_locale_canonicalize() { - let locale: Locale = "En-latn-US-MacOS" - .parse() - .expect("Failed to parse a locale."); - assert_writeable_eq!(locale, Locale::canonicalize("eN-latN-uS-macOS").unwrap()); + let path = "./tests/fixtures/canonicalize.json"; + let data = helpers::read_fixture(path).expect("Failed to read a fixture"); + + test_langid_fixtures(data); } #[test] diff --git a/experimental/transliterate/tests/data/baked/macros/transliterator_rules_v1.data.rs b/experimental/transliterate/tests/data/baked/macros/transliterator_rules_v1.data.rs index 2da4402a368..14ca509b885 100644 --- a/experimental/transliterate/tests/data/baked/macros/transliterator_rules_v1.data.rs +++ b/experimental/transliterate/tests/data/baked/macros/transliterator_rules_v1.data.rs @@ -58,7 +58,7 @@ macro_rules! __impl_transliterator_rules_v1 { #[allow(unused_unsafe)] icu_collections::codepointinvlist::CodePointInversionList::from_parts_unchecked(unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"\0\0\0\0\0\0\x11\0") }, 1114112u32) }, - id_group_list: unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x02\0\0\0\0\0\0\0\x01\0\0\0\0\0\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0und-t-und-Latn-d0-ascii") }, + id_group_list: unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x02\0\0\0\0\0\0\0\x01\0\0\0\0\0\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0und-t-und-latn-d0-ascii") }, rule_group_list: unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x02\0\0\0\0\0\x0C\x01\t\0\0\0\0\0\x1A\x004\0N\0l\0\x8A\0\xA8\0\xC2\0\xDC\0\x04\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\x04\0\0\0\xF3\xB0\x80\x83ae\x04\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\x04\0\0\0\xF3\xB0\x80\x84oe\x04\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\x04\0\0\0\xF3\xB0\x80\x85ue\x04\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\x08\0\0\0\xF3\xB0\x80\x80\xF3\xB0\x80\x87Ae\x04\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\x08\0\0\0\xF3\xB0\x80\x81\xF3\xB0\x80\x89Oe\x04\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\x08\0\0\0\xF3\xB0\x80\x82\xF3\xB0\x80\x8BUe\x04\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\x04\0\0\0\xF3\xB0\x80\x80AE\x04\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\x04\0\0\0\xF3\xB0\x80\x81OE\x04\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\x04\0\0\0\xF3\xB0\x80\x82UE") }, }; static UND__UND_T_UND_D0_TEST_M0_NIELS_S0_TEST: ::Yokeable = icu_transliterate::provider::RuleBasedTransliterator { @@ -158,7 +158,7 @@ macro_rules! __impl_transliterator_rules_v1 { #[allow(unused_unsafe)] icu_collections::codepointinvlist::CodePointInversionList::from_parts_unchecked(unsafe { zerovec::ZeroVec::from_bytes_unchecked(b"d\t\0\0f\t\0\0\x81\t\0\0\x84\t\0\0\x85\t\0\0\x8D\t\0\0\x8F\t\0\0\x91\t\0\0\x93\t\0\0\xA9\t\0\0\xAA\t\0\0\xB1\t\0\0\xB2\t\0\0\xB3\t\0\0\xB6\t\0\0\xBA\t\0\0\xBC\t\0\0\xC5\t\0\0\xC7\t\0\0\xC9\t\0\0\xCB\t\0\0\xCF\t\0\0\xD7\t\0\0\xD8\t\0\0\xDC\t\0\0\xDE\t\0\0\xDF\t\0\0\xE4\t\0\0\xE6\t\0\0\xFB\t\0\0") }, 93u32) }, - id_group_list: unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x01\0\0\0\0\0\x04\0\0\0\0\0!\0S\0\x81\0\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0x-any-nfd\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0und-t-und-Beng-d0-intindic\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0und-Arab-t-s0-intindic\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0x-any-nfc") }, + id_group_list: unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x01\0\0\0\0\0\x04\0\0\0\0\0!\0S\0\x81\0\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0x-any-nfd\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0und-t-und-beng-d0-intindic\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0und-Arab-t-s0-intindic\x02\0\0\0\0\0\0\0\x0C\0\0\0\0\0\x11\0\0\0\0\0\0\0\x11\0x-any-nfc") }, rule_group_list: unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x01\0\0\0\0\0") }, }; static UND__UND_T_UND_D0_TEST_M0_CURSFILT_S0_TEST: ::Yokeable = icu_transliterate::provider::RuleBasedTransliterator { @@ -171,8 +171,8 @@ macro_rules! __impl_transliterator_rules_v1 { id_group_list: unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x01\0\0\0\0\0") }, rule_group_list: unsafe { zerovec::VarZeroVec::from_bytes_unchecked(b"\x01\0\0\0\0\0\x02\0\0\0\0\0\x1B\0\x04\0\0\0\0\0\0\0\x01\0\0\0\x02\0\0\0\x02\0\0\0xa\xF3\xB0\x80\x80b\x04\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x01\0\0\0xbad") }, }; - static VALUES: [&::Yokeable; 16usize] = [&UND__DE_T_DE_D0_ASCII, &UND__EL_LATN_T_EL_M0_BGN, &UND__UND_ARAB_T_S0_INTINDIC, &UND__UND_ARAB_T_UND_BENG, &UND__UND_LATN_T_S0_ASCII, &UND__UND_T_D0_PUBLISH, &UND__UND_T_S0_PUBLISH, &UND__UND_T_UND_BENG_D0_INTINDIC, &UND__UND_T_UND_LATN_D0_ASCII, &UND__UND_T_UND_D0_TEST_M0_CURSFILT_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_EMTYMACH_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_HEXRUST_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_HEXUNI_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_NIELS_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_RECTESTA_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_RECTESTR_S0_TEST]; - static KEYS: [&str; 16usize] = ["und+de-t-de-d0-ascii", "und+el-Latn-t-el-m0-bgn", "und+und-Arab-t-s0-intindic", "und+und-Arab-t-und-Beng", "und+und-Latn-t-s0-ascii", "und+und-t-d0-publish", "und+und-t-s0-publish", "und+und-t-und-Beng-d0-intindic", "und+und-t-und-Latn-d0-ascii", "und+und-t-und-d0-test-m0-cursfilt-s0-test", "und+und-t-und-d0-test-m0-emtymach-s0-test", "und+und-t-und-d0-test-m0-hexrust-s0-test", "und+und-t-und-d0-test-m0-hexuni-s0-test", "und+und-t-und-d0-test-m0-niels-s0-test", "und+und-t-und-d0-test-m0-rectesta-s0-test", "und+und-t-und-d0-test-m0-rectestr-s0-test"]; + static VALUES: [&::Yokeable; 16usize] = [&UND__DE_T_DE_D0_ASCII, &UND__EL_LATN_T_EL_M0_BGN, &UND__UND_ARAB_T_S0_INTINDIC, &UND__UND_ARAB_T_UND_BENG, &UND__UND_LATN_T_S0_ASCII, &UND__UND_T_D0_PUBLISH, &UND__UND_T_S0_PUBLISH, &UND__UND_T_UND_BENG_D0_INTINDIC, &UND__UND_T_UND_D0_TEST_M0_CURSFILT_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_EMTYMACH_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_HEXRUST_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_HEXUNI_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_NIELS_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_RECTESTA_S0_TEST, &UND__UND_T_UND_D0_TEST_M0_RECTESTR_S0_TEST, &UND__UND_T_UND_LATN_D0_ASCII]; + static KEYS: [&str; 16usize] = ["und+de-t-de-d0-ascii", "und+el-Latn-t-el-m0-bgn", "und+und-Arab-t-s0-intindic", "und+und-Arab-t-und-beng", "und+und-Latn-t-s0-ascii", "und+und-t-d0-publish", "und+und-t-s0-publish", "und+und-t-und-beng-d0-intindic", "und+und-t-und-d0-test-m0-cursfilt-s0-test", "und+und-t-und-d0-test-m0-emtymach-s0-test", "und+und-t-und-d0-test-m0-hexrust-s0-test", "und+und-t-und-d0-test-m0-hexuni-s0-test", "und+und-t-und-d0-test-m0-niels-s0-test", "und+und-t-und-d0-test-m0-rectesta-s0-test", "und+und-t-und-d0-test-m0-rectestr-s0-test", "und+und-t-und-latn-d0-ascii"]; if let Ok(payload) = KEYS.binary_search_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).map(|i| *unsafe { VALUES.get_unchecked(i) }) { Ok(icu_provider::DataResponse { payload: Some(icu_provider::DataPayload::from_static_ref(payload)), metadata: Default::default() }) } else { diff --git a/provider/datagen/tests/data/json/transliterator/rules@1/und+de-t-de-d0-ascii.json b/provider/datagen/tests/data/json/transliterator/rules@1/und+de-t-de-d0-ascii.json index 7b9f71f949f..76ba6fecb2c 100644 --- a/provider/datagen/tests/data/json/transliterator/rules@1/und+de-t-de-d0-ascii.json +++ b/provider/datagen/tests/data/json/transliterator/rules@1/und+de-t-de-d0-ascii.json @@ -2102,7 +2102,7 @@ "filter": [ "\u0000-􏿿" ], - "id": "und-t-und-Latn-d0-ascii" + "id": "und-t-und-latn-d0-ascii" } ] ], diff --git a/provider/datagen/tests/data/json/transliterator/rules@1/und+und-Arab-t-und-Beng.json b/provider/datagen/tests/data/json/transliterator/rules@1/und+und-Arab-t-und-beng.json similarity index 95% rename from provider/datagen/tests/data/json/transliterator/rules@1/und+und-Arab-t-und-Beng.json rename to provider/datagen/tests/data/json/transliterator/rules@1/und+und-Arab-t-und-beng.json index 270f105edfc..0f94a53380f 100644 --- a/provider/datagen/tests/data/json/transliterator/rules@1/und+und-Arab-t-und-Beng.json +++ b/provider/datagen/tests/data/json/transliterator/rules@1/und+und-Arab-t-und-beng.json @@ -40,7 +40,7 @@ "filter": [ "\u0000-􏿿" ], - "id": "und-t-und-Beng-d0-intindic" + "id": "und-t-und-beng-d0-intindic" }, { "filter": [ diff --git a/provider/datagen/tests/data/json/transliterator/rules@1/und+und-t-und-Beng-d0-intindic.json b/provider/datagen/tests/data/json/transliterator/rules@1/und+und-t-und-beng-d0-intindic.json similarity index 100% rename from provider/datagen/tests/data/json/transliterator/rules@1/und+und-t-und-Beng-d0-intindic.json rename to provider/datagen/tests/data/json/transliterator/rules@1/und+und-t-und-beng-d0-intindic.json diff --git a/provider/datagen/tests/data/json/transliterator/rules@1/und+und-t-und-Latn-d0-ascii.json b/provider/datagen/tests/data/json/transliterator/rules@1/und+und-t-und-latn-d0-ascii.json similarity index 100% rename from provider/datagen/tests/data/json/transliterator/rules@1/und+und-t-und-Latn-d0-ascii.json rename to provider/datagen/tests/data/json/transliterator/rules@1/und+und-t-und-latn-d0-ascii.json diff --git a/provider/datagen/tests/data/postcard/fingerprints.csv b/provider/datagen/tests/data/postcard/fingerprints.csv index e3adcabc2ed..b9a776835ef 100644 --- a/provider/datagen/tests/data/postcard/fingerprints.csv +++ b/provider/datagen/tests/data/postcard/fingerprints.csv @@ -2063,15 +2063,14 @@ time_zone/specific_short@1, sr-Latn, 119B, dcdb9855b7df4f90 time_zone/specific_short@1, th, 31B, 4b7af6a019fab889 time_zone/specific_short@1, tr, 31B, 4b7af6a019fab889 time_zone/specific_short@1, und, 31B, 4b7af6a019fab889 -transliterator/rules@1, und+de-t-de-d0-ascii, 16754B, 373dc989a6f2feb0 +transliterator/rules@1, und+de-t-de-d0-ascii, 16754B, 7504fd6441311f8b transliterator/rules@1, und+el-Latn-t-el-m0-bgn, 13802B, 676fd7d03e5f65ba transliterator/rules@1, und+und-Arab-t-s0-intindic, 24093B, bb464298570e790f -transliterator/rules@1, und+und-Arab-t-und-Beng, 320B, 6910c1371f9ed898 +transliterator/rules@1, und+und-Arab-t-und-beng, 320B, 740b227a94b146ff transliterator/rules@1, und+und-Latn-t-s0-ascii, 109B, c4235cb150e12966 transliterator/rules@1, und+und-t-d0-publish, 3476B, 8b78371a1427663b transliterator/rules@1, und+und-t-s0-publish, 1342B, fc819d57a6653613 -transliterator/rules@1, und+und-t-und-Beng-d0-intindic, 2620B, 5d7d726babccafe7 -transliterator/rules@1, und+und-t-und-Latn-d0-ascii, 27083B, 5098d1af741181a3 +transliterator/rules@1, und+und-t-und-beng-d0-intindic, 2620B, 5d7d726babccafe7 transliterator/rules@1, und+und-t-und-d0-test-m0-cursfilt-s0-test, 92B, a3f0d5ed65cba360 transliterator/rules@1, und+und-t-und-d0-test-m0-emtymach-s0-test, 104B, fd8a17f7ffe5a325 transliterator/rules@1, und+und-t-und-d0-test-m0-hexrust-s0-test, 77B, bd697bfcd06ad4ca @@ -2079,4 +2078,5 @@ transliterator/rules@1, und+und-t-und-d0-test-m0-hexuni-s0-test, 80B, 55d96425b7 transliterator/rules@1, und+und-t-und-d0-test-m0-niels-s0-test, 1769B, 45400449cf43ecf6 transliterator/rules@1, und+und-t-und-d0-test-m0-rectesta-s0-test, 369B, 69c41d4b5c828833 transliterator/rules@1, und+und-t-und-d0-test-m0-rectestr-s0-test, 237B, 3345ed066cbb729f +transliterator/rules@1, und+und-t-und-latn-d0-ascii, 27083B, 5098d1af741181a3 units/constants@1, und, 426B, e0c7eeb9e702371c